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