mediaplayer.cpp revision d44b51d9fcb0b5d891d2abece83a551e71ebb73b
1/* mediaplayer.cpp
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 <media/mediaplayer.h>
31#include <media/AudioTrack.h>
32
33#include <surfaceflinger/Surface.h>
34
35#include <binder/MemoryBase.h>
36
37#include <utils/KeyedVector.h>
38#include <utils/String8.h>
39
40namespace android {
41
42MediaPlayer::MediaPlayer()
43{
44    LOGV("constructor");
45    mListener = NULL;
46    mCookie = NULL;
47    mDuration = -1;
48    mStreamType = AudioSystem::MUSIC;
49    mCurrentPosition = -1;
50    mSeekPosition = -1;
51    mCurrentState = MEDIA_PLAYER_IDLE;
52    mPrepareSync = false;
53    mPrepareStatus = NO_ERROR;
54    mLoop = false;
55    mLeftVolume = mRightVolume = 1.0;
56    mVideoWidth = mVideoHeight = 0;
57    mLockThreadId = 0;
58    mAudioSessionId = AudioSystem::newAudioSessionId();
59}
60
61MediaPlayer::~MediaPlayer()
62{
63    LOGV("destructor");
64    disconnect();
65    IPCThreadState::self()->flushCommands();
66}
67
68void MediaPlayer::disconnect()
69{
70    LOGV("disconnect");
71    sp<IMediaPlayer> p;
72    {
73        Mutex::Autolock _l(mLock);
74        p = mPlayer;
75        mPlayer.clear();
76    }
77
78    if (p != 0) {
79        p->disconnect();
80    }
81}
82
83// always call with lock held
84void MediaPlayer::clear_l()
85{
86    mDuration = -1;
87    mCurrentPosition = -1;
88    mSeekPosition = -1;
89    mVideoWidth = mVideoHeight = 0;
90}
91
92status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
93{
94    LOGV("setListener");
95    Mutex::Autolock _l(mLock);
96    mListener = listener;
97    return NO_ERROR;
98}
99
100
101status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player)
102{
103    status_t err = UNKNOWN_ERROR;
104    sp<IMediaPlayer> p;
105    { // scope for the lock
106        Mutex::Autolock _l(mLock);
107
108        if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
109                (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
110            LOGE("setDataSource called in state %d", mCurrentState);
111            return INVALID_OPERATION;
112        }
113
114        clear_l();
115        p = mPlayer;
116        mPlayer = player;
117        if (player != 0) {
118            mCurrentState = MEDIA_PLAYER_INITIALIZED;
119            err = NO_ERROR;
120        } else {
121            LOGE("Unable to to create media player");
122        }
123    }
124
125    if (p != 0) {
126        p->disconnect();
127    }
128
129    return err;
130}
131
132status_t MediaPlayer::setDataSource(
133        const char *url, const KeyedVector<String8, String8> *headers)
134{
135    LOGV("setDataSource(%s)", url);
136    status_t err = BAD_VALUE;
137    if (url != NULL) {
138        const sp<IMediaPlayerService>& service(getMediaPlayerService());
139        if (service != 0) {
140            sp<IMediaPlayer> player(
141                    service->create(getpid(), this, url, headers, mAudioSessionId));
142            err = setDataSource(player);
143        }
144    }
145    return err;
146}
147
148status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
149{
150    LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
151    status_t err = UNKNOWN_ERROR;
152    const sp<IMediaPlayerService>& service(getMediaPlayerService());
153    if (service != 0) {
154        sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length, mAudioSessionId));
155        err = setDataSource(player);
156    }
157    return err;
158}
159
160status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
161{
162    Mutex::Autolock _l(mLock);
163    const bool hasBeenInitialized =
164            (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
165            ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
166    if ((mPlayer != NULL) && hasBeenInitialized) {
167         LOGV("invoke %d", request.dataSize());
168         return  mPlayer->invoke(request, reply);
169    }
170    LOGE("invoke failed: wrong state %X", mCurrentState);
171    return INVALID_OPERATION;
172}
173
174status_t MediaPlayer::suspend() {
175    Mutex::Autolock _l(mLock);
176    return mPlayer->suspend();
177}
178
179status_t MediaPlayer::resume() {
180    Mutex::Autolock _l(mLock);
181    return mPlayer->resume();
182}
183
184status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
185{
186    LOGD("setMetadataFilter");
187    Mutex::Autolock lock(mLock);
188    if (mPlayer == NULL) {
189        return NO_INIT;
190    }
191    return mPlayer->setMetadataFilter(filter);
192}
193
194status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
195{
196    LOGD("getMetadata");
197    Mutex::Autolock lock(mLock);
198    if (mPlayer == NULL) {
199        return NO_INIT;
200    }
201    return mPlayer->getMetadata(update_only, apply_filter, metadata);
202}
203
204status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
205{
206    LOGV("setVideoSurface");
207    Mutex::Autolock _l(mLock);
208    if (mPlayer == 0) return NO_INIT;
209
210    status_t err = mPlayer->setVideoISurface(
211            surface == NULL ? NULL : surface->getISurface());
212
213    if (err != OK) {
214        return err;
215    }
216
217    return mPlayer->setVideoSurface(surface);
218}
219
220// must call with lock held
221status_t MediaPlayer::prepareAsync_l()
222{
223    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
224        mPlayer->setAudioStreamType(mStreamType);
225        mCurrentState = MEDIA_PLAYER_PREPARING;
226        return mPlayer->prepareAsync();
227    }
228    LOGE("prepareAsync called in state %d", mCurrentState);
229    return INVALID_OPERATION;
230}
231
232// TODO: In case of error, prepareAsync provides the caller with 2 error codes,
233// one defined in the Android framework and one provided by the implementation
234// that generated the error. The sync version of prepare returns only 1 error
235// code.
236status_t MediaPlayer::prepare()
237{
238    LOGV("prepare");
239    Mutex::Autolock _l(mLock);
240    mLockThreadId = getThreadId();
241    if (mPrepareSync) {
242        mLockThreadId = 0;
243        return -EALREADY;
244    }
245    mPrepareSync = true;
246    status_t ret = prepareAsync_l();
247    if (ret != NO_ERROR) {
248        mLockThreadId = 0;
249        return ret;
250    }
251
252    if (mPrepareSync) {
253        mSignal.wait(mLock);  // wait for prepare done
254        mPrepareSync = false;
255    }
256    LOGV("prepare complete - status=%d", mPrepareStatus);
257    mLockThreadId = 0;
258    return mPrepareStatus;
259}
260
261status_t MediaPlayer::prepareAsync()
262{
263    LOGV("prepareAsync");
264    Mutex::Autolock _l(mLock);
265    return prepareAsync_l();
266}
267
268status_t MediaPlayer::start()
269{
270    LOGV("start");
271    Mutex::Autolock _l(mLock);
272    if (mCurrentState & MEDIA_PLAYER_STARTED)
273        return NO_ERROR;
274    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
275                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
276        mPlayer->setLooping(mLoop);
277        mPlayer->setVolume(mLeftVolume, mRightVolume);
278        mPlayer->setAuxEffectSendLevel(mSendLevel);
279        mCurrentState = MEDIA_PLAYER_STARTED;
280        status_t ret = mPlayer->start();
281        if (ret != NO_ERROR) {
282            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
283        } else {
284            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
285                LOGV("playback completed immediately following start()");
286            }
287        }
288        return ret;
289    }
290    LOGE("start called in state %d", mCurrentState);
291    return INVALID_OPERATION;
292}
293
294status_t MediaPlayer::stop()
295{
296    LOGV("stop");
297    Mutex::Autolock _l(mLock);
298    if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
299    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
300                    MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
301        status_t ret = mPlayer->stop();
302        if (ret != NO_ERROR) {
303            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
304        } else {
305            mCurrentState = MEDIA_PLAYER_STOPPED;
306        }
307        return ret;
308    }
309    LOGE("stop called in state %d", mCurrentState);
310    return INVALID_OPERATION;
311}
312
313status_t MediaPlayer::pause()
314{
315    LOGV("pause");
316    Mutex::Autolock _l(mLock);
317    if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
318        return NO_ERROR;
319    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
320        status_t ret = mPlayer->pause();
321        if (ret != NO_ERROR) {
322            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
323        } else {
324            mCurrentState = MEDIA_PLAYER_PAUSED;
325        }
326        return ret;
327    }
328    LOGE("pause called in state %d", mCurrentState);
329    return INVALID_OPERATION;
330}
331
332bool MediaPlayer::isPlaying()
333{
334    Mutex::Autolock _l(mLock);
335    if (mPlayer != 0) {
336        bool temp = false;
337        mPlayer->isPlaying(&temp);
338        LOGV("isPlaying: %d", temp);
339        if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
340            LOGE("internal/external state mismatch corrected");
341            mCurrentState = MEDIA_PLAYER_PAUSED;
342        }
343        return temp;
344    }
345    LOGV("isPlaying: no active player");
346    return false;
347}
348
349status_t MediaPlayer::getVideoWidth(int *w)
350{
351    LOGV("getVideoWidth");
352    Mutex::Autolock _l(mLock);
353    if (mPlayer == 0) return INVALID_OPERATION;
354    *w = mVideoWidth;
355    return NO_ERROR;
356}
357
358status_t MediaPlayer::getVideoHeight(int *h)
359{
360    LOGV("getVideoHeight");
361    Mutex::Autolock _l(mLock);
362    if (mPlayer == 0) return INVALID_OPERATION;
363    *h = mVideoHeight;
364    return NO_ERROR;
365}
366
367status_t MediaPlayer::getCurrentPosition(int *msec)
368{
369    LOGV("getCurrentPosition");
370    Mutex::Autolock _l(mLock);
371    if (mPlayer != 0) {
372        if (mCurrentPosition >= 0) {
373            LOGV("Using cached seek position: %d", mCurrentPosition);
374            *msec = mCurrentPosition;
375            return NO_ERROR;
376        }
377        return mPlayer->getCurrentPosition(msec);
378    }
379    return INVALID_OPERATION;
380}
381
382status_t MediaPlayer::getDuration_l(int *msec)
383{
384    LOGV("getDuration");
385    bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
386    if (mPlayer != 0 && isValidState) {
387        status_t ret = NO_ERROR;
388        if (mDuration <= 0)
389            ret = mPlayer->getDuration(&mDuration);
390        if (msec)
391            *msec = mDuration;
392        return ret;
393    }
394    LOGE("Attempt to call getDuration without a valid mediaplayer");
395    return INVALID_OPERATION;
396}
397
398status_t MediaPlayer::getDuration(int *msec)
399{
400    Mutex::Autolock _l(mLock);
401    return getDuration_l(msec);
402}
403
404status_t MediaPlayer::seekTo_l(int msec)
405{
406    LOGV("seekTo %d", msec);
407    if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
408        if ( msec < 0 ) {
409            LOGW("Attempt to seek to invalid position: %d", msec);
410            msec = 0;
411        } else if ((mDuration > 0) && (msec > mDuration)) {
412            LOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration);
413            msec = mDuration;
414        }
415        // cache duration
416        mCurrentPosition = msec;
417        if (mSeekPosition < 0) {
418            getDuration_l(NULL);
419            mSeekPosition = msec;
420            return mPlayer->seekTo(msec);
421        }
422        else {
423            LOGV("Seek in progress - queue up seekTo[%d]", msec);
424            return NO_ERROR;
425        }
426    }
427    LOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState);
428    return INVALID_OPERATION;
429}
430
431status_t MediaPlayer::seekTo(int msec)
432{
433    mLockThreadId = getThreadId();
434    Mutex::Autolock _l(mLock);
435    status_t result = seekTo_l(msec);
436    mLockThreadId = 0;
437
438    return result;
439}
440
441status_t MediaPlayer::reset()
442{
443    LOGV("reset");
444    Mutex::Autolock _l(mLock);
445    mLoop = false;
446    if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
447    mPrepareSync = false;
448    if (mPlayer != 0) {
449        status_t ret = mPlayer->reset();
450        if (ret != NO_ERROR) {
451            LOGE("reset() failed with return code (%d)", ret);
452            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
453        } else {
454            mCurrentState = MEDIA_PLAYER_IDLE;
455        }
456        return ret;
457    }
458    clear_l();
459    return NO_ERROR;
460}
461
462status_t MediaPlayer::setAudioStreamType(int type)
463{
464    LOGV("MediaPlayer::setAudioStreamType");
465    Mutex::Autolock _l(mLock);
466    if (mStreamType == type) return NO_ERROR;
467    if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
468                MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
469        // Can't change the stream type after prepare
470        LOGE("setAudioStream called in state %d", mCurrentState);
471        return INVALID_OPERATION;
472    }
473    // cache
474    mStreamType = type;
475    return OK;
476}
477
478status_t MediaPlayer::setLooping(int loop)
479{
480    LOGV("MediaPlayer::setLooping");
481    Mutex::Autolock _l(mLock);
482    mLoop = (loop != 0);
483    if (mPlayer != 0) {
484        return mPlayer->setLooping(loop);
485    }
486    return OK;
487}
488
489bool MediaPlayer::isLooping() {
490    LOGV("isLooping");
491    Mutex::Autolock _l(mLock);
492    if (mPlayer != 0) {
493        return mLoop;
494    }
495    LOGV("isLooping: no active player");
496    return false;
497}
498
499status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
500{
501    LOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
502    Mutex::Autolock _l(mLock);
503    mLeftVolume = leftVolume;
504    mRightVolume = rightVolume;
505    if (mPlayer != 0) {
506        return mPlayer->setVolume(leftVolume, rightVolume);
507    }
508    return OK;
509}
510
511status_t MediaPlayer::setAudioSessionId(int sessionId)
512{
513    LOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
514    Mutex::Autolock _l(mLock);
515    if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
516        LOGE("setAudioSessionId called in state %d", mCurrentState);
517        return INVALID_OPERATION;
518    }
519    if (sessionId < 0) {
520        return BAD_VALUE;
521    }
522    mAudioSessionId = sessionId;
523    return NO_ERROR;
524}
525
526int MediaPlayer::getAudioSessionId()
527{
528    Mutex::Autolock _l(mLock);
529    return mAudioSessionId;
530}
531
532status_t MediaPlayer::setAuxEffectSendLevel(float level)
533{
534    LOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
535    Mutex::Autolock _l(mLock);
536    mSendLevel = level;
537    if (mPlayer != 0) {
538        return mPlayer->setAuxEffectSendLevel(level);
539    }
540    return OK;
541}
542
543status_t MediaPlayer::attachAuxEffect(int effectId)
544{
545    LOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
546    Mutex::Autolock _l(mLock);
547    if (mPlayer == 0 ||
548        (mCurrentState & MEDIA_PLAYER_IDLE) ||
549        (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
550        LOGE("attachAuxEffect called in state %d", mCurrentState);
551        return INVALID_OPERATION;
552    }
553
554    return mPlayer->attachAuxEffect(effectId);
555}
556
557void MediaPlayer::notify(int msg, int ext1, int ext2)
558{
559    LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
560    bool send = true;
561    bool locked = false;
562
563    // TODO: In the future, we might be on the same thread if the app is
564    // running in the same process as the media server. In that case,
565    // this will deadlock.
566    //
567    // The threadId hack below works around this for the care of prepare
568    // and seekTo within the same process.
569    // FIXME: Remember, this is a hack, it's not even a hack that is applied
570    // consistently for all use-cases, this needs to be revisited.
571     if (mLockThreadId != getThreadId()) {
572        mLock.lock();
573        locked = true;
574    }
575
576    // Allows calls from JNI in idle state to notify errors
577    if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
578        LOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
579        if (locked) mLock.unlock();   // release the lock when done.
580        return;
581    }
582
583    switch (msg) {
584    case MEDIA_NOP: // interface test message
585        break;
586    case MEDIA_PREPARED:
587        LOGV("prepared");
588        mCurrentState = MEDIA_PLAYER_PREPARED;
589        if (mPrepareSync) {
590            LOGV("signal application thread");
591            mPrepareSync = false;
592            mPrepareStatus = NO_ERROR;
593            mSignal.signal();
594        }
595        break;
596    case MEDIA_PLAYBACK_COMPLETE:
597        LOGV("playback complete");
598        if (mCurrentState == MEDIA_PLAYER_IDLE) {
599            LOGE("playback complete in idle state");
600        }
601        if (!mLoop) {
602            mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
603        }
604        break;
605    case MEDIA_ERROR:
606        // Always log errors.
607        // ext1: Media framework error code.
608        // ext2: Implementation dependant error code.
609        LOGE("error (%d, %d)", ext1, ext2);
610        mCurrentState = MEDIA_PLAYER_STATE_ERROR;
611        if (mPrepareSync)
612        {
613            LOGV("signal application thread");
614            mPrepareSync = false;
615            mPrepareStatus = ext1;
616            mSignal.signal();
617            send = false;
618        }
619        break;
620    case MEDIA_INFO:
621        // ext1: Media framework error code.
622        // ext2: Implementation dependant error code.
623        LOGW("info/warning (%d, %d)", ext1, ext2);
624        break;
625    case MEDIA_SEEK_COMPLETE:
626        LOGV("Received seek complete");
627        if (mSeekPosition != mCurrentPosition) {
628            LOGV("Executing queued seekTo(%d)", mSeekPosition);
629            mSeekPosition = -1;
630            seekTo_l(mCurrentPosition);
631        }
632        else {
633            LOGV("All seeks complete - return to regularly scheduled program");
634            mCurrentPosition = mSeekPosition = -1;
635        }
636        break;
637    case MEDIA_BUFFERING_UPDATE:
638        LOGV("buffering %d", ext1);
639        break;
640    case MEDIA_SET_VIDEO_SIZE:
641        LOGV("New video size %d x %d", ext1, ext2);
642        mVideoWidth = ext1;
643        mVideoHeight = ext2;
644        break;
645    default:
646        LOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
647        break;
648    }
649
650    sp<MediaPlayerListener> listener = mListener;
651    if (locked) mLock.unlock();
652
653    // this prevents re-entrant calls into client code
654    if ((listener != 0) && send) {
655        Mutex::Autolock _l(mNotifyLock);
656        LOGV("callback application");
657        listener->notify(msg, ext1, ext2);
658        LOGV("back from callback");
659    }
660}
661
662/*static*/ sp<IMemory> MediaPlayer::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
663{
664    LOGV("decode(%s)", url);
665    sp<IMemory> p;
666    const sp<IMediaPlayerService>& service = getMediaPlayerService();
667    if (service != 0) {
668        p = service->decode(url, pSampleRate, pNumChannels, pFormat);
669    } else {
670        LOGE("Unable to locate media service");
671    }
672    return p;
673
674}
675
676void MediaPlayer::died()
677{
678    LOGV("died");
679    notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
680}
681
682/*static*/ sp<IMemory> MediaPlayer::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
683{
684    LOGV("decode(%d, %lld, %lld)", fd, offset, length);
685    sp<IMemory> p;
686    const sp<IMediaPlayerService>& service = getMediaPlayerService();
687    if (service != 0) {
688        p = service->decode(fd, offset, length, pSampleRate, pNumChannels, pFormat);
689    } else {
690        LOGE("Unable to locate media service");
691    }
692    return p;
693
694}
695
696}; // namespace android
697