1 /*
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "MediaPlayer"
20 #include <utils/Log.h>
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26
27 #include <binder/IServiceManager.h>
28 #include <binder/IPCThreadState.h>
29
30 #include <gui/SurfaceTextureClient.h>
31
32 #include <media/mediaplayer.h>
33 #include <media/AudioSystem.h>
34
35 #include <binder/MemoryBase.h>
36
37 #include <utils/KeyedVector.h>
38 #include <utils/String8.h>
39
40 #include <system/audio.h>
41 #include <system/window.h>
42
43 namespace android {
44
MediaPlayer()45 MediaPlayer::MediaPlayer()
46 {
47 ALOGV("constructor");
48 mListener = NULL;
49 mCookie = NULL;
50 mDuration = -1;
51 mStreamType = AUDIO_STREAM_MUSIC;
52 mCurrentPosition = -1;
53 mSeekPosition = -1;
54 mCurrentState = MEDIA_PLAYER_IDLE;
55 mPrepareSync = false;
56 mPrepareStatus = NO_ERROR;
57 mLoop = false;
58 mLeftVolume = mRightVolume = 1.0;
59 mVideoWidth = mVideoHeight = 0;
60 mLockThreadId = 0;
61 mAudioSessionId = AudioSystem::newAudioSessionId();
62 AudioSystem::acquireAudioSessionId(mAudioSessionId);
63 mSendLevel = 0;
64 mRetransmitEndpointValid = false;
65 }
66
~MediaPlayer()67 MediaPlayer::~MediaPlayer()
68 {
69 ALOGV("destructor");
70 AudioSystem::releaseAudioSessionId(mAudioSessionId);
71 disconnect();
72 IPCThreadState::self()->flushCommands();
73 }
74
disconnect()75 void MediaPlayer::disconnect()
76 {
77 ALOGV("disconnect");
78 sp<IMediaPlayer> p;
79 {
80 Mutex::Autolock _l(mLock);
81 p = mPlayer;
82 mPlayer.clear();
83 }
84
85 if (p != 0) {
86 p->disconnect();
87 }
88 }
89
90 // always call with lock held
clear_l()91 void MediaPlayer::clear_l()
92 {
93 mDuration = -1;
94 mCurrentPosition = -1;
95 mSeekPosition = -1;
96 mVideoWidth = mVideoHeight = 0;
97 mRetransmitEndpointValid = false;
98 }
99
setListener(const sp<MediaPlayerListener> & listener)100 status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
101 {
102 ALOGV("setListener");
103 Mutex::Autolock _l(mLock);
104 mListener = listener;
105 return NO_ERROR;
106 }
107
108
attachNewPlayer(const sp<IMediaPlayer> & player)109 status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
110 {
111 status_t err = UNKNOWN_ERROR;
112 sp<IMediaPlayer> p;
113 { // scope for the lock
114 Mutex::Autolock _l(mLock);
115
116 if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
117 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
118 ALOGE("attachNewPlayer called in state %d", mCurrentState);
119 return INVALID_OPERATION;
120 }
121
122 clear_l();
123 p = mPlayer;
124 mPlayer = player;
125 if (player != 0) {
126 mCurrentState = MEDIA_PLAYER_INITIALIZED;
127 err = NO_ERROR;
128 } else {
129 ALOGE("Unable to to create media player");
130 }
131 }
132
133 if (p != 0) {
134 p->disconnect();
135 }
136
137 return err;
138 }
139
setDataSource(const char * url,const KeyedVector<String8,String8> * headers)140 status_t MediaPlayer::setDataSource(
141 const char *url, const KeyedVector<String8, String8> *headers)
142 {
143 ALOGV("setDataSource(%s)", url);
144 status_t err = BAD_VALUE;
145 if (url != NULL) {
146 const sp<IMediaPlayerService>& service(getMediaPlayerService());
147 if (service != 0) {
148 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
149 if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
150 (NO_ERROR != player->setDataSource(url, headers))) {
151 player.clear();
152 }
153 err = attachNewPlayer(player);
154 }
155 }
156 return err;
157 }
158
setDataSource(int fd,int64_t offset,int64_t length)159 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
160 {
161 ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
162 status_t err = UNKNOWN_ERROR;
163 const sp<IMediaPlayerService>& service(getMediaPlayerService());
164 if (service != 0) {
165 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
166 if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
167 (NO_ERROR != player->setDataSource(fd, offset, length))) {
168 player.clear();
169 }
170 err = attachNewPlayer(player);
171 }
172 return err;
173 }
174
setDataSource(const sp<IStreamSource> & source)175 status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
176 {
177 ALOGV("setDataSource");
178 status_t err = UNKNOWN_ERROR;
179 const sp<IMediaPlayerService>& service(getMediaPlayerService());
180 if (service != 0) {
181 sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
182 if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
183 (NO_ERROR != player->setDataSource(source))) {
184 player.clear();
185 }
186 err = attachNewPlayer(player);
187 }
188 return err;
189 }
190
invoke(const Parcel & request,Parcel * reply)191 status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
192 {
193 Mutex::Autolock _l(mLock);
194 const bool hasBeenInitialized =
195 (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
196 ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
197 if ((mPlayer != NULL) && hasBeenInitialized) {
198 ALOGV("invoke %d", request.dataSize());
199 return mPlayer->invoke(request, reply);
200 }
201 ALOGE("invoke failed: wrong state %X", mCurrentState);
202 return INVALID_OPERATION;
203 }
204
setMetadataFilter(const Parcel & filter)205 status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
206 {
207 ALOGD("setMetadataFilter");
208 Mutex::Autolock lock(mLock);
209 if (mPlayer == NULL) {
210 return NO_INIT;
211 }
212 return mPlayer->setMetadataFilter(filter);
213 }
214
getMetadata(bool update_only,bool apply_filter,Parcel * metadata)215 status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
216 {
217 ALOGD("getMetadata");
218 Mutex::Autolock lock(mLock);
219 if (mPlayer == NULL) {
220 return NO_INIT;
221 }
222 return mPlayer->getMetadata(update_only, apply_filter, metadata);
223 }
224
setVideoSurfaceTexture(const sp<ISurfaceTexture> & surfaceTexture)225 status_t MediaPlayer::setVideoSurfaceTexture(
226 const sp<ISurfaceTexture>& surfaceTexture)
227 {
228 ALOGV("setVideoSurfaceTexture");
229 Mutex::Autolock _l(mLock);
230 if (mPlayer == 0) return NO_INIT;
231 return mPlayer->setVideoSurfaceTexture(surfaceTexture);
232 }
233
234 // must call with lock held
prepareAsync_l()235 status_t MediaPlayer::prepareAsync_l()
236 {
237 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
238 mPlayer->setAudioStreamType(mStreamType);
239 mCurrentState = MEDIA_PLAYER_PREPARING;
240 return mPlayer->prepareAsync();
241 }
242 ALOGE("prepareAsync called in state %d", mCurrentState);
243 return INVALID_OPERATION;
244 }
245
246 // TODO: In case of error, prepareAsync provides the caller with 2 error codes,
247 // one defined in the Android framework and one provided by the implementation
248 // that generated the error. The sync version of prepare returns only 1 error
249 // code.
prepare()250 status_t MediaPlayer::prepare()
251 {
252 ALOGV("prepare");
253 Mutex::Autolock _l(mLock);
254 mLockThreadId = getThreadId();
255 if (mPrepareSync) {
256 mLockThreadId = 0;
257 return -EALREADY;
258 }
259 mPrepareSync = true;
260 status_t ret = prepareAsync_l();
261 if (ret != NO_ERROR) {
262 mLockThreadId = 0;
263 return ret;
264 }
265
266 if (mPrepareSync) {
267 mSignal.wait(mLock); // wait for prepare done
268 mPrepareSync = false;
269 }
270 ALOGV("prepare complete - status=%d", mPrepareStatus);
271 mLockThreadId = 0;
272 return mPrepareStatus;
273 }
274
prepareAsync()275 status_t MediaPlayer::prepareAsync()
276 {
277 ALOGV("prepareAsync");
278 Mutex::Autolock _l(mLock);
279 return prepareAsync_l();
280 }
281
start()282 status_t MediaPlayer::start()
283 {
284 ALOGV("start");
285 Mutex::Autolock _l(mLock);
286 if (mCurrentState & MEDIA_PLAYER_STARTED)
287 return NO_ERROR;
288 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
289 MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
290 mPlayer->setLooping(mLoop);
291 mPlayer->setVolume(mLeftVolume, mRightVolume);
292 mPlayer->setAuxEffectSendLevel(mSendLevel);
293 mCurrentState = MEDIA_PLAYER_STARTED;
294 status_t ret = mPlayer->start();
295 if (ret != NO_ERROR) {
296 mCurrentState = MEDIA_PLAYER_STATE_ERROR;
297 } else {
298 if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
299 ALOGV("playback completed immediately following start()");
300 }
301 }
302 return ret;
303 }
304 ALOGE("start called in state %d", mCurrentState);
305 return INVALID_OPERATION;
306 }
307
stop()308 status_t MediaPlayer::stop()
309 {
310 ALOGV("stop");
311 Mutex::Autolock _l(mLock);
312 if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
313 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
314 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
315 status_t ret = mPlayer->stop();
316 if (ret != NO_ERROR) {
317 mCurrentState = MEDIA_PLAYER_STATE_ERROR;
318 } else {
319 mCurrentState = MEDIA_PLAYER_STOPPED;
320 }
321 return ret;
322 }
323 ALOGE("stop called in state %d", mCurrentState);
324 return INVALID_OPERATION;
325 }
326
pause()327 status_t MediaPlayer::pause()
328 {
329 ALOGV("pause");
330 Mutex::Autolock _l(mLock);
331 if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
332 return NO_ERROR;
333 if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
334 status_t ret = mPlayer->pause();
335 if (ret != NO_ERROR) {
336 mCurrentState = MEDIA_PLAYER_STATE_ERROR;
337 } else {
338 mCurrentState = MEDIA_PLAYER_PAUSED;
339 }
340 return ret;
341 }
342 ALOGE("pause called in state %d", mCurrentState);
343 return INVALID_OPERATION;
344 }
345
isPlaying()346 bool MediaPlayer::isPlaying()
347 {
348 Mutex::Autolock _l(mLock);
349 if (mPlayer != 0) {
350 bool temp = false;
351 mPlayer->isPlaying(&temp);
352 ALOGV("isPlaying: %d", temp);
353 if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
354 ALOGE("internal/external state mismatch corrected");
355 mCurrentState = MEDIA_PLAYER_PAUSED;
356 }
357 return temp;
358 }
359 ALOGV("isPlaying: no active player");
360 return false;
361 }
362
getVideoWidth(int * w)363 status_t MediaPlayer::getVideoWidth(int *w)
364 {
365 ALOGV("getVideoWidth");
366 Mutex::Autolock _l(mLock);
367 if (mPlayer == 0) return INVALID_OPERATION;
368 *w = mVideoWidth;
369 return NO_ERROR;
370 }
371
getVideoHeight(int * h)372 status_t MediaPlayer::getVideoHeight(int *h)
373 {
374 ALOGV("getVideoHeight");
375 Mutex::Autolock _l(mLock);
376 if (mPlayer == 0) return INVALID_OPERATION;
377 *h = mVideoHeight;
378 return NO_ERROR;
379 }
380
getCurrentPosition(int * msec)381 status_t MediaPlayer::getCurrentPosition(int *msec)
382 {
383 ALOGV("getCurrentPosition");
384 Mutex::Autolock _l(mLock);
385 if (mPlayer != 0) {
386 if (mCurrentPosition >= 0) {
387 ALOGV("Using cached seek position: %d", mCurrentPosition);
388 *msec = mCurrentPosition;
389 return NO_ERROR;
390 }
391 return mPlayer->getCurrentPosition(msec);
392 }
393 return INVALID_OPERATION;
394 }
395
getDuration_l(int * msec)396 status_t MediaPlayer::getDuration_l(int *msec)
397 {
398 ALOGV("getDuration");
399 bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
400 if (mPlayer != 0 && isValidState) {
401 status_t ret = NO_ERROR;
402 if (mDuration <= 0)
403 ret = mPlayer->getDuration(&mDuration);
404 if (msec)
405 *msec = mDuration;
406 return ret;
407 }
408 ALOGE("Attempt to call getDuration without a valid mediaplayer");
409 return INVALID_OPERATION;
410 }
411
getDuration(int * msec)412 status_t MediaPlayer::getDuration(int *msec)
413 {
414 Mutex::Autolock _l(mLock);
415 return getDuration_l(msec);
416 }
417
seekTo_l(int msec)418 status_t MediaPlayer::seekTo_l(int msec)
419 {
420 ALOGV("seekTo %d", msec);
421 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
422 if ( msec < 0 ) {
423 ALOGW("Attempt to seek to invalid position: %d", msec);
424 msec = 0;
425 } else if ((mDuration > 0) && (msec > mDuration)) {
426 ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration);
427 msec = mDuration;
428 }
429 // cache duration
430 mCurrentPosition = msec;
431 if (mSeekPosition < 0) {
432 getDuration_l(NULL);
433 mSeekPosition = msec;
434 return mPlayer->seekTo(msec);
435 }
436 else {
437 ALOGV("Seek in progress - queue up seekTo[%d]", msec);
438 return NO_ERROR;
439 }
440 }
441 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState);
442 return INVALID_OPERATION;
443 }
444
seekTo(int msec)445 status_t MediaPlayer::seekTo(int msec)
446 {
447 mLockThreadId = getThreadId();
448 Mutex::Autolock _l(mLock);
449 status_t result = seekTo_l(msec);
450 mLockThreadId = 0;
451
452 return result;
453 }
454
reset_l()455 status_t MediaPlayer::reset_l()
456 {
457 mLoop = false;
458 if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
459 mPrepareSync = false;
460 if (mPlayer != 0) {
461 status_t ret = mPlayer->reset();
462 if (ret != NO_ERROR) {
463 ALOGE("reset() failed with return code (%d)", ret);
464 mCurrentState = MEDIA_PLAYER_STATE_ERROR;
465 } else {
466 mCurrentState = MEDIA_PLAYER_IDLE;
467 }
468 // setDataSource has to be called again to create a
469 // new mediaplayer.
470 mPlayer = 0;
471 return ret;
472 }
473 clear_l();
474 return NO_ERROR;
475 }
476
doSetRetransmitEndpoint(const sp<IMediaPlayer> & player)477 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) {
478 Mutex::Autolock _l(mLock);
479
480 if (player == NULL) {
481 return UNKNOWN_ERROR;
482 }
483
484 if (mRetransmitEndpointValid) {
485 return player->setRetransmitEndpoint(&mRetransmitEndpoint);
486 }
487
488 return OK;
489 }
490
reset()491 status_t MediaPlayer::reset()
492 {
493 ALOGV("reset");
494 Mutex::Autolock _l(mLock);
495 return reset_l();
496 }
497
setAudioStreamType(audio_stream_type_t type)498 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
499 {
500 ALOGV("MediaPlayer::setAudioStreamType");
501 Mutex::Autolock _l(mLock);
502 if (mStreamType == type) return NO_ERROR;
503 if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
504 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
505 // Can't change the stream type after prepare
506 ALOGE("setAudioStream called in state %d", mCurrentState);
507 return INVALID_OPERATION;
508 }
509 // cache
510 mStreamType = type;
511 return OK;
512 }
513
setLooping(int loop)514 status_t MediaPlayer::setLooping(int loop)
515 {
516 ALOGV("MediaPlayer::setLooping");
517 Mutex::Autolock _l(mLock);
518 mLoop = (loop != 0);
519 if (mPlayer != 0) {
520 return mPlayer->setLooping(loop);
521 }
522 return OK;
523 }
524
isLooping()525 bool MediaPlayer::isLooping() {
526 ALOGV("isLooping");
527 Mutex::Autolock _l(mLock);
528 if (mPlayer != 0) {
529 return mLoop;
530 }
531 ALOGV("isLooping: no active player");
532 return false;
533 }
534
setVolume(float leftVolume,float rightVolume)535 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
536 {
537 ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
538 Mutex::Autolock _l(mLock);
539 mLeftVolume = leftVolume;
540 mRightVolume = rightVolume;
541 if (mPlayer != 0) {
542 return mPlayer->setVolume(leftVolume, rightVolume);
543 }
544 return OK;
545 }
546
setAudioSessionId(int sessionId)547 status_t MediaPlayer::setAudioSessionId(int sessionId)
548 {
549 ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
550 Mutex::Autolock _l(mLock);
551 if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
552 ALOGE("setAudioSessionId called in state %d", mCurrentState);
553 return INVALID_OPERATION;
554 }
555 if (sessionId < 0) {
556 return BAD_VALUE;
557 }
558 if (sessionId != mAudioSessionId) {
559 AudioSystem::releaseAudioSessionId(mAudioSessionId);
560 AudioSystem::acquireAudioSessionId(sessionId);
561 mAudioSessionId = sessionId;
562 }
563 return NO_ERROR;
564 }
565
getAudioSessionId()566 int MediaPlayer::getAudioSessionId()
567 {
568 Mutex::Autolock _l(mLock);
569 return mAudioSessionId;
570 }
571
setAuxEffectSendLevel(float level)572 status_t MediaPlayer::setAuxEffectSendLevel(float level)
573 {
574 ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
575 Mutex::Autolock _l(mLock);
576 mSendLevel = level;
577 if (mPlayer != 0) {
578 return mPlayer->setAuxEffectSendLevel(level);
579 }
580 return OK;
581 }
582
attachAuxEffect(int effectId)583 status_t MediaPlayer::attachAuxEffect(int effectId)
584 {
585 ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
586 Mutex::Autolock _l(mLock);
587 if (mPlayer == 0 ||
588 (mCurrentState & MEDIA_PLAYER_IDLE) ||
589 (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
590 ALOGE("attachAuxEffect called in state %d", mCurrentState);
591 return INVALID_OPERATION;
592 }
593
594 return mPlayer->attachAuxEffect(effectId);
595 }
596
setParameter(int key,const Parcel & request)597 status_t MediaPlayer::setParameter(int key, const Parcel& request)
598 {
599 ALOGV("MediaPlayer::setParameter(%d)", key);
600 Mutex::Autolock _l(mLock);
601 if (mPlayer != NULL) {
602 return mPlayer->setParameter(key, request);
603 }
604 ALOGV("setParameter: no active player");
605 return INVALID_OPERATION;
606 }
607
getParameter(int key,Parcel * reply)608 status_t MediaPlayer::getParameter(int key, Parcel *reply)
609 {
610 ALOGV("MediaPlayer::getParameter(%d)", key);
611 Mutex::Autolock _l(mLock);
612 if (mPlayer != NULL) {
613 return mPlayer->getParameter(key, reply);
614 }
615 ALOGV("getParameter: no active player");
616 return INVALID_OPERATION;
617 }
618
setRetransmitEndpoint(const char * addrString,uint16_t port)619 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
620 uint16_t port) {
621 ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)",
622 addrString ? addrString : "(null)", port);
623
624 Mutex::Autolock _l(mLock);
625 if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE))
626 return INVALID_OPERATION;
627
628 if (NULL == addrString) {
629 mRetransmitEndpointValid = false;
630 return OK;
631 }
632
633 struct in_addr saddr;
634 if(!inet_aton(addrString, &saddr)) {
635 return BAD_VALUE;
636 }
637
638 memset(&mRetransmitEndpoint, 0, sizeof(&mRetransmitEndpoint));
639 mRetransmitEndpoint.sin_family = AF_INET;
640 mRetransmitEndpoint.sin_addr = saddr;
641 mRetransmitEndpoint.sin_port = htons(port);
642 mRetransmitEndpointValid = true;
643
644 return OK;
645 }
646
notify(int msg,int ext1,int ext2,const Parcel * obj)647 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
648 {
649 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
650 bool send = true;
651 bool locked = false;
652
653 // TODO: In the future, we might be on the same thread if the app is
654 // running in the same process as the media server. In that case,
655 // this will deadlock.
656 //
657 // The threadId hack below works around this for the care of prepare
658 // and seekTo within the same process.
659 // FIXME: Remember, this is a hack, it's not even a hack that is applied
660 // consistently for all use-cases, this needs to be revisited.
661 if (mLockThreadId != getThreadId()) {
662 mLock.lock();
663 locked = true;
664 }
665
666 // Allows calls from JNI in idle state to notify errors
667 if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
668 ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
669 if (locked) mLock.unlock(); // release the lock when done.
670 return;
671 }
672
673 switch (msg) {
674 case MEDIA_NOP: // interface test message
675 break;
676 case MEDIA_PREPARED:
677 ALOGV("prepared");
678 mCurrentState = MEDIA_PLAYER_PREPARED;
679 if (mPrepareSync) {
680 ALOGV("signal application thread");
681 mPrepareSync = false;
682 mPrepareStatus = NO_ERROR;
683 mSignal.signal();
684 }
685 break;
686 case MEDIA_PLAYBACK_COMPLETE:
687 ALOGV("playback complete");
688 if (mCurrentState == MEDIA_PLAYER_IDLE) {
689 ALOGE("playback complete in idle state");
690 }
691 if (!mLoop) {
692 mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
693 }
694 break;
695 case MEDIA_ERROR:
696 // Always log errors.
697 // ext1: Media framework error code.
698 // ext2: Implementation dependant error code.
699 ALOGE("error (%d, %d)", ext1, ext2);
700 mCurrentState = MEDIA_PLAYER_STATE_ERROR;
701 if (mPrepareSync)
702 {
703 ALOGV("signal application thread");
704 mPrepareSync = false;
705 mPrepareStatus = ext1;
706 mSignal.signal();
707 send = false;
708 }
709 break;
710 case MEDIA_INFO:
711 // ext1: Media framework error code.
712 // ext2: Implementation dependant error code.
713 if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
714 ALOGW("info/warning (%d, %d)", ext1, ext2);
715 }
716 break;
717 case MEDIA_SEEK_COMPLETE:
718 ALOGV("Received seek complete");
719 if (mSeekPosition != mCurrentPosition) {
720 ALOGV("Executing queued seekTo(%d)", mSeekPosition);
721 mSeekPosition = -1;
722 seekTo_l(mCurrentPosition);
723 }
724 else {
725 ALOGV("All seeks complete - return to regularly scheduled program");
726 mCurrentPosition = mSeekPosition = -1;
727 }
728 break;
729 case MEDIA_BUFFERING_UPDATE:
730 ALOGV("buffering %d", ext1);
731 break;
732 case MEDIA_SET_VIDEO_SIZE:
733 ALOGV("New video size %d x %d", ext1, ext2);
734 mVideoWidth = ext1;
735 mVideoHeight = ext2;
736 break;
737 case MEDIA_TIMED_TEXT:
738 ALOGV("Received timed text message");
739 break;
740 default:
741 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
742 break;
743 }
744
745 sp<MediaPlayerListener> listener = mListener;
746 if (locked) mLock.unlock();
747
748 // this prevents re-entrant calls into client code
749 if ((listener != 0) && send) {
750 Mutex::Autolock _l(mNotifyLock);
751 ALOGV("callback application");
752 listener->notify(msg, ext1, ext2, obj);
753 ALOGV("back from callback");
754 }
755 }
756
decode(const char * url,uint32_t * pSampleRate,int * pNumChannels,audio_format_t * pFormat)757 /*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
758 {
759 ALOGV("decode(%s)", url);
760 sp<IMemory> p;
761 const sp<IMediaPlayerService>& service = getMediaPlayerService();
762 if (service != 0) {
763 p = service->decode(url, pSampleRate, pNumChannels, pFormat);
764 } else {
765 ALOGE("Unable to locate media service");
766 }
767 return p;
768
769 }
770
died()771 void MediaPlayer::died()
772 {
773 ALOGV("died");
774 notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
775 }
776
decode(int fd,int64_t offset,int64_t length,uint32_t * pSampleRate,int * pNumChannels,audio_format_t * pFormat)777 /*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
778 {
779 ALOGV("decode(%d, %lld, %lld)", fd, offset, length);
780 sp<IMemory> p;
781 const sp<IMediaPlayerService>& service = getMediaPlayerService();
782 if (service != 0) {
783 p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat);
784 } else {
785 ALOGE("Unable to locate media service");
786 }
787 return p;
788
789 }
790
setNextMediaPlayer(const sp<MediaPlayer> & next)791 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
792 if (mPlayer == NULL) {
793 return NO_INIT;
794 }
795 return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
796 }
797
798 }; // namespace android
799