android_GenericMediaPlayer.cpp revision e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91
168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi/*
268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * you may not use this file except in compliance with the License.
668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * You may obtain a copy of the License at
768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
1068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * See the License for the specific language governing permissions and
1468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * limitations under the License.
1568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */
1668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
17de015407a89018f9422254624e1b75703f38defdGlenn Kasten//#define USE_LOG SLAndroidLogLevel_Verbose
1868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
1968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include "sles_allinclusive.h"
204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "android_GenericMediaPlayer.h"
214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
2268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include <media/IMediaPlayerService.h>
2368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include <surfaceflinger/ISurfaceComposer.h>
2468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include <surfaceflinger/SurfaceComposerClient.h>
254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include <media/stagefright/foundation/ADebug.h>
2668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi// default delay in Us used when reposting an event when the player is not ready to accept
284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi// the command yet. This is for instance used when seeking on a MediaPlayer that's still preparing
294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#define DEFAULT_COMMAND_DELAY_FOR_REPOST_US (100*1000) // 100ms
304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
31833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten// table of prefixes for known distant protocols; these are immediately dispatched to mediaserver
32833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastenstatic const char* const kDistantProtocolPrefix[] = { "http://", "https://", "rtsp://"};
334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#define NB_DISTANT_PROTOCOLS (sizeof(kDistantProtocolPrefix)/sizeof(kDistantProtocolPrefix[0]))
344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
35833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten// is the specified URI a known distant protocol?
36833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastenbool isDistantProtocol(const char *uri)
37833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten{
38833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    for (unsigned int i = 0; i < NB_DISTANT_PROTOCOLS; i++) {
39833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        if (!strncasecmp(uri, kDistantProtocolPrefix[i], strlen(kDistantProtocolPrefix[i]))) {
40833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten            return true;
41833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        }
42833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    }
43833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    return false;
44833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten}
45833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten
46833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastennamespace android {
47833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten
4868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
4937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel TriviMediaPlayerNotificationClient::MediaPlayerNotificationClient(GenericMediaPlayer* gmp) :
5037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    mGenericMediaPlayer(gmp),
5149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    mPlayerPrepared(PREPARE_NOT_STARTED)
5268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi{
53b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::MediaPlayerNotificationClient()");
5468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
5568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
5668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviMediaPlayerNotificationClient::~MediaPlayerNotificationClient() {
57b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::~MediaPlayerNotificationClient()");
58b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten}
5968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
60b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten// Map a MEDIA_* enum to a string
61b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kastenstatic const char *media_to_string(int msg)
62b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten{
63b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    switch (msg) {
64b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten#define _(x) case MEDIA_##x: return "MEDIA_" #x;
65b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(PREPARED)
66b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(SET_VIDEO_SIZE)
67b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(SEEK_COMPLETE)
68b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(PLAYBACK_COMPLETE)
69b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(BUFFERING_UPDATE)
70b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(ERROR)
71b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(NOP)
72b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(TIMED_TEXT)
73b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten      _(INFO)
74b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten#undef _
75b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    default:
76b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        return NULL;
77b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    }
7868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
7968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
8068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
8168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi// IMediaPlayerClient implementation
822f6d462d89356cdaa77299ca27b60c5cca198d98Gloria Wangvoid MediaPlayerNotificationClient::notify(int msg, int ext1, int ext2, const Parcel *obj) {
83b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::notify(msg=%s (%d), ext1=%d, ext2=%d)",
84b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten            media_to_string(msg), msg, ext1, ext2);
8568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
8691ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    sp<GenericMediaPlayer> genericMediaPlayer(mGenericMediaPlayer.promote());
8791ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    if (genericMediaPlayer == NULL) {
8891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        SL_LOGW("MediaPlayerNotificationClient::notify after GenericMediaPlayer destroyed");
8991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        return;
9091ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    }
9191ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten
9237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    switch (msg) {
9337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      case MEDIA_PREPARED:
9491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        {
9591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        Mutex::Autolock _l(mLock);
960d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
970d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_SUCCESSFULLY;
980d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPreparedCondition.signal();
990d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        } else {
1000d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            SL_LOGE("Unexpected MEDIA_PREPARED");
1010d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        }
10291ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
10337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
10437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
10537dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      case MEDIA_SET_VIDEO_SIZE:
1064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // only send video size updates if the player was flagged as having video, to avoid
1074ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // sending video size updates of (0,0)
10891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // We're running on a different thread than genericMediaPlayer's ALooper thread,
10991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // so it would normally be racy to access fields within genericMediaPlayer.
11091ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // But in this case mHasVideo is const, so it is safe to access.
11191ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // Or alternatively, we could notify unconditionally and let it decide whether to handle.
11291ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        if (genericMediaPlayer->mHasVideo) {
11391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_VIDEO_SIZE_UPDATE,
1144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    (int32_t)ext1, (int32_t)ext2, true /*async*/);
1154ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
1164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1184ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_SEEK_COMPLETE:
11991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->seekComplete();
1204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_PLAYBACK_COMPLETE:
12391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
1244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_BUFFERING_UPDATE:
1274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // values received from Android framework for buffer fill level use percent,
1284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   while SL/XA use permille, so does GenericPlayer
12991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->bufferingUpdate(ext1 * 10 /*fillLevelPerMille*/);
13037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
13137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
13281e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_ERROR:
13391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        {
13491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        Mutex::Autolock _l(mLock);
1350d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
1360d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_UNSUCCESSFULLY;
1370d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPreparedCondition.signal();
1380d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        } else {
1395e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            // inform client of errors after preparation
1405e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_ERRORAFTERPREPARE, ext1, true /*async*/);
1410d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        }
14291ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
14349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        break;
14449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
14581e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_NOP:
14681e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_TIMED_TEXT:
14781e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_INFO:
14881e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten        break;
14981e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
15037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      default: { }
15168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
15281e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
15368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
15468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
15568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
15649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenvoid MediaPlayerNotificationClient::beforePrepare()
15749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten{
15849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    Mutex::Autolock _l(mLock);
15949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_NOT_STARTED);
16049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    mPlayerPrepared = PREPARE_IN_PROGRESS;
16149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten}
16249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
16349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten//--------------------------------------------------
16449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenbool MediaPlayerNotificationClient::blockUntilPlayerPrepared() {
16568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mLock);
16649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared != PREPARE_NOT_STARTED);
16749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    while (mPlayerPrepared == PREPARE_IN_PROGRESS) {
16868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayerPreparedCondition.wait(mLock);
16968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
17049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY ||
17149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten            mPlayerPrepared == PREPARE_COMPLETED_UNSUCCESSFULLY);
17249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    return mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY;
17368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
17468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
17568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
17668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::GenericMediaPlayer(const AudioPlayback_Parameters* params, bool hasVideo) :
17768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    GenericPlayer(params),
17868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mHasVideo(hasVideo),
1797ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    mSeekTimeMsec(0),
18068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mVideoSurface(0),
181ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture(0),
18268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mPlayer(0),
18391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    mPlayerClient(new MediaPlayerNotificationClient(this))
18468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi{
185e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::GenericMediaPlayer()");
18668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
18768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
18868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
18968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::~GenericMediaPlayer() {
190e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::~GenericMediaPlayer()");
1914b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
1924b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi
1934b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::preDestroy() {
194a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    // FIXME can't access mPlayer from outside the looper (no mutex!) so using mPreparedPlayer
195a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    sp<IMediaPlayer> player;
196a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
197a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    if (player != NULL) {
198a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->stop();
199a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // causes CHECK failure in Nuplayer, but commented out in the subclass preDestroy
2007c40d3b78c609b2a84acd0dd6e874ab24a73f8d7Glenn Kasten        // randomly causes a NPE in StagefrightPlayer, heap corruption, or app hang
2017c40d3b78c609b2a84acd0dd6e874ab24a73f8d7Glenn Kasten        //player->setDataSource(NULL);
202a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->setVideoSurface(NULL);
203a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->disconnect();
204a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // release all references to the IMediaPlayer
205a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // FIXME illegal if not on looper
206a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        //mPlayer.clear();
207a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        {
208a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            Mutex::Autolock _l(mPreparedPlayerLock);
209a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            mPreparedPlayer.clear();
210a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        }
211485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten    }
2124b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    GenericPlayer::preDestroy();
2134b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
21468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2154b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//--------------------------------------------------
2164b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// overridden from GenericPlayer
2174b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// pre-condition:
2184b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//   msec != NULL
2194b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// post-condition
2205933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//   *msec ==
2214b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//                  ANDROID_UNKNOWN_TIME if position is unknown at time of query,
2224b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//               or the current MediaPlayer position
2234b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::getPositionMsec(int* msec) {
2244b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::getPositionMsec()");
2255933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    sp<IMediaPlayer> player;
226a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
2275933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // To avoid deadlock, directly call the MediaPlayer object
2285933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (player == 0 || player->getCurrentPosition(msec) != NO_ERROR) {
2295933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        *msec = ANDROID_UNKNOWN_TIME;
2304b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    }
23168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
23268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
23368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
234ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenvoid GenericMediaPlayer::setVideoSurface(const sp<Surface> &surface) {
235b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurface()");
23635ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    // FIXME bug - race condition, should do in looper
23735ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if (mVideoSurface.get() == surface.get()) {
23835ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        return;
23935ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
24035ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
24135ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        mPlayer->setVideoSurface(surface);
24235ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
243ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurface = surface;
24435ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    mVideoSurfaceTexture = NULL;
245ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten}
246ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten
247ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenvoid GenericMediaPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
248b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurfaceTexture()");
24935ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    // FIXME bug - race condition, should do in looper
25035ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if (mVideoSurfaceTexture.get() == surfaceTexture.get()) {
25135ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        return;
25235ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
25335ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
25435ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        mPlayer->setVideoSurfaceTexture(surfaceTexture);
25535ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
256ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture = surfaceTexture;
25735ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    mVideoSurface = NULL;
25868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
25968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
26070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
26168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
26268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi// Event handlers
2634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
26485edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten// blocks until mPlayer is prepared
26568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPrepare() {
266e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare()");
26749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    // Attempt to prepare at most once, and only if there is a MediaPlayer
26849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    if (!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully)) && (mPlayer != 0)) {
269ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten        if (mHasVideo) {
270ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            if (mVideoSurface != 0) {
271ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten                mPlayer->setVideoSurface(mVideoSurface);
272ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            } else if (mVideoSurfaceTexture != 0) {
273ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten                mPlayer->setVideoSurfaceTexture(mVideoSurfaceTexture);
274ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            }
27568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        }
27668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->setAudioStreamType(mPlaybackParams.streamType);
27749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerClient->beforePrepare();
27868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->prepareAsync();
27906059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        if (mPlayerClient->blockUntilPlayerPrepared()) {
28006059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPrepared;
28106059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            afterMediaPlayerPreparedSuccessfully();
28206059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        } else {
28306059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPreparedUnsuccessfully;
28406059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        }
28568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
28685edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten    GenericPlayer::onPrepare();
287e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
28868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
28968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
29168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPlay() {
292e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPlay()");
2935933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (((mStateFlags & (kFlagPrepared | kFlagPlaying)) == kFlagPrepared) && (mPlayer != 0)) {
29468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->start();
29568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
2965933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPlay();
29768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
29868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2994ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
30068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPause() {
301e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPause()");
3025933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (!(~mStateFlags & (kFlagPrepared | kFlagPlaying)) && (mPlayer != 0)) {
30368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->pause();
30468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
3055933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPause();
30637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi}
30737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
308f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
309f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kastenvoid GenericMediaPlayer::onSeekComplete() {
310f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    SL_LOGV("GenericMediaPlayer::onSeekComplete()");
311f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    // did we initiate the seek?
312f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    if (!(mStateFlags & kFlagSeeking)) {
313f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, are we looping?
314f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        if (mStateFlags & kFlagLooping) {
315f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // yes, per OpenSL ES 1.0.1 and 1.1 do NOT report it to client
316f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
317f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, well that's surprising, but it's probably just a benign race condition
318f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        } else {
319f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            SL_LOGW("Unexpected seek complete event ignored");
320f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        }
321f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    }
322f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    GenericPlayer::onSeekComplete();
323f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten}
324f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
325f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
3267ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi/**
3277ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi * pre-condition: WHATPARAM_SEEK_SEEKTIME_MS parameter value >= 0
3287ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi */
3294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onSeek(const sp<AMessage> &msg) {
3304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onSeek");
3317ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    int64_t timeMsec = ANDROID_UNKNOWN_TIME;
3327ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    if (!msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec)) {
3337ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        // invalid command, drop it
3347ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
3357ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    }
336a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten    if ((mStateFlags & kFlagSeeking) && (timeMsec == mSeekTimeMsec) &&
337a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            (timeMsec != ANDROID_UNKNOWN_TIME)) {
338a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten        // already seeking to the same non-unknown time, cancel this command
3397ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
34049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    } else if (mStateFlags & kFlagPreparedUnsuccessfully) {
34149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        // discard seeks after unsuccessful prepare
3427ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    } else if (!(mStateFlags & kFlagPrepared)) {
3434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // we are not ready to accept a seek command at this time, retry later
3444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        msg->post(DEFAULT_COMMAND_DELAY_FOR_REPOST_US);
3454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
346c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten        if (mPlayer != 0) {
3477ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mStateFlags |= kFlagSeeking;
3487ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mSeekTimeMsec = (int32_t)timeMsec;
349a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            // seek to unknown time is used by StreamPlayer after discontinuity
350a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            if (timeMsec == ANDROID_UNKNOWN_TIME) {
351a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // FIXME simulate a MEDIA_SEEK_COMPLETE event in 250 ms;
352a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // this is a terrible hack to make up for mediaserver not sending one
353a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                (new AMessage(kWhatSeekComplete, id()))->post(250000);
354a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            } else if (OK != mPlayer->seekTo(timeMsec)) {
3557ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mStateFlags &= ~kFlagSeeking;
3567ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mSeekTimeMsec = ANDROID_UNKNOWN_TIME;
357e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten                // don't call updateOneShot because seek not yet done
3584ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
3594ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
3604ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
3614ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3624ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onLoop(const sp<AMessage> &msg) {
3654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onLoop");
3664ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t loop = 0;
3674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop)) {
3689f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (loop) {
3699f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags |= kFlagLooping;
3709f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        } else {
3719f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags &= ~kFlagLooping;
3729f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        }
3739f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        // if we have a MediaPlayer then tell it now, otherwise we'll tell it after it's created
3749f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (mPlayer != 0) {
3759f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            (void) mPlayer->setLooping(loop);
3764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
3774ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
3784ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3794ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
38137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivivoid GenericMediaPlayer::onVolumeUpdate() {
3824ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onVolumeUpdate()");
3834ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (mPlayer != 0) {
384e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        // use settings lock to read the volume settings
385e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        Mutex::Autolock _l(mSettingsLock);
386fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        mPlayer->setVolume(mAndroidAudioLevels.mFinalVolume[0],
387fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                mAndroidAudioLevels.mFinalVolume[1]);
38837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    }
3894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3914ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3923610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
3933610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onAttachAuxEffect()");
3943610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    int32_t effectId = 0;
3953610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findInt32(WHATPARAM_ATTACHAUXEFFECT, &effectId)) {
3963610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
3973610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
3983610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->attachAuxEffect(effectId);
3993610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // attachAuxEffect returns a status but we have no way to report it back to app
4003610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
4013610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
4023610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
4033610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
4043610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4053610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4063610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
4073610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onSetAuxEffectSendLevel()");
4083610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    float level = 0.0f;
4093610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, &level)) {
4103610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
4113610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
4123610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->setAuxEffectSendLevel(level);
4133610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // setAuxEffectSendLevel returns a status but we have no way to report it back to app
4143610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
4153610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
4163610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
4173610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
4183610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4193610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
4214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t fillLevel = 0;
4224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_BUFFERING_UPDATE, &fillLevel)) {
4234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("GenericMediaPlayer::onBufferingUpdate(fillLevel=%d)", fillLevel);
42468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
4254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        Mutex::Autolock _l(mSettingsLock);
4264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        mCacheFill = fillLevel;
4274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle cache fill update
4284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (mCacheFill - mLastNotifiedCacheFill >= mCacheFillNotifThreshold) {
4294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
4304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4314ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle prefetch status update
4324ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   compute how much time ahead of position is buffered
4334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int durationMsec, positionMsec = -1;
4344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)
4354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                && (OK == mPlayer->getDuration(&durationMsec))
4364ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                        && (OK == mPlayer->getCurrentPosition(&positionMsec))) {
4374ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            if ((-1 != durationMsec) && (-1 != positionMsec)) {
4384ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                // evaluate prefetch status based on buffer time thresholds
4394ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                int64_t bufferedDurationMsec = (durationMsec * fillLevel / 100) - positionMsec;
4404ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                CacheStatus_t newCacheStatus = mCacheStatus;
4414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (bufferedDurationMsec > DURATION_CACHED_HIGH_MS) {
4424ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusHigh;
4434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_MED_MS) {
4444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEnough;
4454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_LOW_MS) {
4464ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusIntermediate;
4474ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec == 0) {
4484ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEmpty;
4494ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else {
4504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusLow;
4514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
4524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (newCacheStatus != mCacheStatus) {
4544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    mCacheStatus = newCacheStatus;
4554ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    notifyStatus();
4564ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
4574ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
4584ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
459b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    } else {
460b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        SL_LOGV("GenericMediaPlayer::onBufferingUpdate(fillLevel=unknown)");
4614ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
4624ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
4634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi//--------------------------------------------------
4664ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi/**
46706059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten * called from GenericMediaPlayer::onPrepare after the MediaPlayer mPlayer is prepared successfully
468fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten * pre-conditions:
469fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten *  mPlayer != 0
47006059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten *  mPlayer is prepared successfully
4714ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi */
47206059e5ee1eaf907589c7f8d1320253f92211348Glenn Kastenvoid GenericMediaPlayer::afterMediaPlayerPreparedSuccessfully() {
47306059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    SL_LOGV("GenericMediaPlayer::afterMediaPlayerPrepared()");
474fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(mPlayer != 0);
47506059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    assert(mStateFlags & kFlagPrepared);
4765933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // Mark this player as prepared successfully, so safe to directly call getCurrentPosition
4775933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    {
478a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        Mutex::Autolock _l(mPreparedPlayerLock);
479a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        assert(mPreparedPlayer == 0);
480a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        mPreparedPlayer = mPlayer;
4815933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    }
482fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve channel count
483b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten    int32_t channelCount;
484fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    Parcel *reply = new Parcel();
485fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    status_t status = mPlayer->getParameter(KEY_PARAMETER_AUDIO_CHANNEL_COUNT, reply);
486fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (status == NO_ERROR) {
487b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        channelCount = reply->readInt32();
48899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
48999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // FIXME MPEG-2 TS doesn't yet implement this key, so default to stereo
490b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        channelCount = 2;
49199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
492b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten    if (UNKNOWN_NUMCHANNELS != channelCount) {
49399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // now that we know the channel count, re-calculate the volumes
494b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        notify(PLAYEREVENT_CHANNEL_COUNT, channelCount, true /*async*/);
49599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
49699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        LOGW("channel count is still unknown after prepare");
497fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
498fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    delete reply;
499fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve duration
5004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    {
5014ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int msec = 0;
5024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (OK == mPlayer->getDuration(&msec)) {
5031fa5c3206d06bbebdea2dc92f378ce6b8a211e23Glenn Kasten            Mutex::Autolock _l(mSettingsLock);
5044ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mDurationMsec = msec;
5054ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
5064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5079f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    // now that we have a MediaPlayer, set the looping flag
5089f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    if (mStateFlags & kFlagLooping) {
5099f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        (void) mPlayer->setLooping(1);
5109f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    }
5114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // when the MediaPlayer mPlayer is prepared, there is "sufficient data" in the playback buffers
5124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // if the data source was local, and the buffers are considered full so we need to notify that
5134ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    bool isLocalSource = true;
5144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (kDataLocatorUri == mDataLocatorType) {
515833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        isLocalSource = !isDistantProtocol(mDataLocator.uriRef);
5164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (isLocalSource) {
5184ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on local source");
5194ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        {
5204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            Mutex::Autolock _l(mSettingsLock);
5214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheStatus = kStatusHigh;
5224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheFill = 1000;
5234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyStatus();
5244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
5254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
5264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
5274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on non-local source");
5284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
52968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
53068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
5315933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
5325933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//--------------------------------------------------
5335933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten// If player is prepared successfully, set output parameter to that reference, otherwise NULL
534a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kastenvoid GenericMediaPlayer::getPreparedPlayer(sp<IMediaPlayer> &preparedPlayer)
5355933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten{
536a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    Mutex::Autolock _l(mPreparedPlayerLock);
537a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    preparedPlayer = mPreparedPlayer;
5385933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten}
5395933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
54068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi} // namespace android
541