android_GenericMediaPlayer.cpp revision a0fa47f72f47fffb80ab2ae791739ce73de1e8f4
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);
9649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerPrepared = PREPARE_COMPLETED_SUCCESSFULLY;
9768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayerPreparedCondition.signal();
9891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
9937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
10037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
10137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      case MEDIA_SET_VIDEO_SIZE:
1024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // only send video size updates if the player was flagged as having video, to avoid
1034ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // sending video size updates of (0,0)
10491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // We're running on a different thread than genericMediaPlayer's ALooper thread,
10591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // so it would normally be racy to access fields within genericMediaPlayer.
10691ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // But in this case mHasVideo is const, so it is safe to access.
10791ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // Or alternatively, we could notify unconditionally and let it decide whether to handle.
10891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        if (genericMediaPlayer->mHasVideo) {
10991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_VIDEO_SIZE_UPDATE,
1104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    (int32_t)ext1, (int32_t)ext2, true /*async*/);
1114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
1124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1134ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_SEEK_COMPLETE:
11591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->seekComplete();
1164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1184ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_PLAYBACK_COMPLETE:
11991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
1204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_BUFFERING_UPDATE:
1234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // values received from Android framework for buffer fill level use percent,
1244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   while SL/XA use permille, so does GenericPlayer
12591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->bufferingUpdate(ext1 * 10 /*fillLevelPerMille*/);
12637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
12737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
12881e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_ERROR:
12991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        {
13091ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        Mutex::Autolock _l(mLock);
13149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerPrepared = PREPARE_COMPLETED_UNSUCCESSFULLY;
13249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerPreparedCondition.signal();
13391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
13449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        break;
13549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
13681e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_NOP:
13781e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_TIMED_TEXT:
13881e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_INFO:
13981e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten        break;
14081e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
14137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      default: { }
14268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
14381e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
14468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
14568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
14668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
14749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenvoid MediaPlayerNotificationClient::beforePrepare()
14849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten{
14949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    Mutex::Autolock _l(mLock);
15049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_NOT_STARTED);
15149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    mPlayerPrepared = PREPARE_IN_PROGRESS;
15249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten}
15349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
15449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten//--------------------------------------------------
15549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenbool MediaPlayerNotificationClient::blockUntilPlayerPrepared() {
15668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mLock);
15749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared != PREPARE_NOT_STARTED);
15849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    while (mPlayerPrepared == PREPARE_IN_PROGRESS) {
15968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayerPreparedCondition.wait(mLock);
16068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
16149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY ||
16249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten            mPlayerPrepared == PREPARE_COMPLETED_UNSUCCESSFULLY);
16349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    return mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY;
16468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
16568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
16668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
16768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::GenericMediaPlayer(const AudioPlayback_Parameters* params, bool hasVideo) :
16868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    GenericPlayer(params),
16968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mHasVideo(hasVideo),
1707ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    mSeekTimeMsec(0),
17168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mVideoSurface(0),
172ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture(0),
17368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mPlayer(0),
17491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    mPlayerClient(new MediaPlayerNotificationClient(this))
17568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi{
176e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::GenericMediaPlayer()");
17768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
17868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
17968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
18068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::~GenericMediaPlayer() {
181e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::~GenericMediaPlayer()");
1824b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
1834b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi
1844b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::preDestroy() {
185a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    // FIXME can't access mPlayer from outside the looper (no mutex!) so using mPreparedPlayer
186a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    sp<IMediaPlayer> player;
187a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
188a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    if (player != NULL) {
189a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->stop();
190a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // causes CHECK failure in Nuplayer, but commented out in the subclass preDestroy
191a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->setDataSource(NULL);
192a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->setVideoSurface(NULL);
193a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->disconnect();
194a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // release all references to the IMediaPlayer
195a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // FIXME illegal if not on looper
196a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        //mPlayer.clear();
197a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        {
198a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            Mutex::Autolock _l(mPreparedPlayerLock);
199a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            mPreparedPlayer.clear();
200a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        }
201485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten    }
2024b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    GenericPlayer::preDestroy();
2034b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
20468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2054b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//--------------------------------------------------
2064b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// overridden from GenericPlayer
2074b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// pre-condition:
2084b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//   msec != NULL
2094b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// post-condition
2105933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//   *msec ==
2114b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//                  ANDROID_UNKNOWN_TIME if position is unknown at time of query,
2124b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//               or the current MediaPlayer position
2134b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::getPositionMsec(int* msec) {
2144b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::getPositionMsec()");
2155933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    sp<IMediaPlayer> player;
216a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
2175933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // To avoid deadlock, directly call the MediaPlayer object
2185933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (player == 0 || player->getCurrentPosition(msec) != NO_ERROR) {
2195933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        *msec = ANDROID_UNKNOWN_TIME;
2204b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    }
22168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
22268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
22368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
224ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenvoid GenericMediaPlayer::setVideoSurface(const sp<Surface> &surface) {
225b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurface()");
22635ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    // FIXME bug - race condition, should do in looper
22735ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if (mVideoSurface.get() == surface.get()) {
22835ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        return;
22935ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
23035ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
23135ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        mPlayer->setVideoSurface(surface);
23235ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
233ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurface = surface;
23435ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    mVideoSurfaceTexture = NULL;
235ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten}
236ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten
237ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenvoid GenericMediaPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
238b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurfaceTexture()");
23935ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    // FIXME bug - race condition, should do in looper
24035ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if (mVideoSurfaceTexture.get() == surfaceTexture.get()) {
24135ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        return;
24235ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
24335ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
24435ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        mPlayer->setVideoSurfaceTexture(surfaceTexture);
24535ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
246ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture = surfaceTexture;
24735ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    mVideoSurface = NULL;
24868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
24968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
25070c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
25168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
25268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi// Event handlers
2534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
25485edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten// blocks until mPlayer is prepared
25568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPrepare() {
256e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare()");
25749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    // Attempt to prepare at most once, and only if there is a MediaPlayer
25849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    if (!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully)) && (mPlayer != 0)) {
259ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten        if (mHasVideo) {
260ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            if (mVideoSurface != 0) {
261ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten                mPlayer->setVideoSurface(mVideoSurface);
262ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            } else if (mVideoSurfaceTexture != 0) {
263ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten                mPlayer->setVideoSurfaceTexture(mVideoSurfaceTexture);
264ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            }
26568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        }
26668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->setAudioStreamType(mPlaybackParams.streamType);
26749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerClient->beforePrepare();
26868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->prepareAsync();
26906059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        if (mPlayerClient->blockUntilPlayerPrepared()) {
27006059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPrepared;
27106059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            afterMediaPlayerPreparedSuccessfully();
27206059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        } else {
27306059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPreparedUnsuccessfully;
27406059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        }
27568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
27685edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten    GenericPlayer::onPrepare();
277e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
27868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
27968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
28168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPlay() {
282e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPlay()");
2835933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (((mStateFlags & (kFlagPrepared | kFlagPlaying)) == kFlagPrepared) && (mPlayer != 0)) {
28468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->start();
28568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
2865933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPlay();
28768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
28868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
29068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPause() {
291e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPause()");
2925933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (!(~mStateFlags & (kFlagPrepared | kFlagPlaying)) && (mPlayer != 0)) {
29368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->pause();
29468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
2955933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPause();
29637dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi}
29737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
298f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
299f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kastenvoid GenericMediaPlayer::onSeekComplete() {
300f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    SL_LOGV("GenericMediaPlayer::onSeekComplete()");
301f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    // did we initiate the seek?
302f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    if (!(mStateFlags & kFlagSeeking)) {
303f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, are we looping?
304f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        if (mStateFlags & kFlagLooping) {
305f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // yes, per OpenSL ES 1.0.1 and 1.1 do NOT report it to client
306f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
307f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, well that's surprising, but it's probably just a benign race condition
308f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        } else {
309f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            SL_LOGW("Unexpected seek complete event ignored");
310f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        }
311f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    }
312f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    GenericPlayer::onSeekComplete();
313f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten}
314f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
315f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
3167ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi/**
3177ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi * pre-condition: WHATPARAM_SEEK_SEEKTIME_MS parameter value >= 0
3187ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi */
3194ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onSeek(const sp<AMessage> &msg) {
3204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onSeek");
3217ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    int64_t timeMsec = ANDROID_UNKNOWN_TIME;
3227ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    if (!msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec)) {
3237ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        // invalid command, drop it
3247ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
3257ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    }
326a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten    if ((mStateFlags & kFlagSeeking) && (timeMsec == mSeekTimeMsec) &&
327a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            (timeMsec != ANDROID_UNKNOWN_TIME)) {
328a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten        // already seeking to the same non-unknown time, cancel this command
3297ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
33049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    } else if (mStateFlags & kFlagPreparedUnsuccessfully) {
33149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        // discard seeks after unsuccessful prepare
3327ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    } else if (!(mStateFlags & kFlagPrepared)) {
3334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // we are not ready to accept a seek command at this time, retry later
3344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        msg->post(DEFAULT_COMMAND_DELAY_FOR_REPOST_US);
3354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
336c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten        if (mPlayer != 0) {
3377ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mStateFlags |= kFlagSeeking;
3387ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mSeekTimeMsec = (int32_t)timeMsec;
339a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            // seek to unknown time is used by StreamPlayer after discontinuity
340a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            if (timeMsec == ANDROID_UNKNOWN_TIME) {
341a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // FIXME simulate a MEDIA_SEEK_COMPLETE event in 250 ms;
342a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // this is a terrible hack to make up for mediaserver not sending one
343a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                (new AMessage(kWhatSeekComplete, id()))->post(250000);
344a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            } else if (OK != mPlayer->seekTo(timeMsec)) {
3457ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mStateFlags &= ~kFlagSeeking;
3467ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mSeekTimeMsec = ANDROID_UNKNOWN_TIME;
3474ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
3484ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
3494ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
3504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onLoop(const sp<AMessage> &msg) {
3544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onLoop");
3554ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t loop = 0;
3564ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop)) {
3579f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (loop) {
3589f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags |= kFlagLooping;
3599f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        } else {
3609f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags &= ~kFlagLooping;
3619f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        }
3629f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        // if we have a MediaPlayer then tell it now, otherwise we'll tell it after it's created
3639f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (mPlayer != 0) {
3649f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            (void) mPlayer->setLooping(loop);
3654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
3664ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
3674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3684ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
37037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivivoid GenericMediaPlayer::onVolumeUpdate() {
3714ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onVolumeUpdate()");
37237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    // use settings lock to read the volume settings
37337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    Mutex::Autolock _l(mSettingsLock);
3744ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (mPlayer != 0) {
375fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        mPlayer->setVolume(mAndroidAudioLevels.mFinalVolume[0],
376fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                mAndroidAudioLevels.mFinalVolume[1]);
37737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    }
3784ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
3794ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
3813610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
3823610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onAttachAuxEffect()");
3833610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    int32_t effectId = 0;
3843610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findInt32(WHATPARAM_ATTACHAUXEFFECT, &effectId)) {
3853610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
3863610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
3873610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->attachAuxEffect(effectId);
3883610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // attachAuxEffect returns a status but we have no way to report it back to app
3893610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
3903610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
3913610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
3923610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
3933610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
3943610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
3953610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
3963610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onSetAuxEffectSendLevel()");
3973610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    float level = 0.0f;
3983610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, &level)) {
3993610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
4003610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
4013610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->setAuxEffectSendLevel(level);
4023610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // setAuxEffectSendLevel returns a status but we have no way to report it back to app
4033610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
4043610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
4053610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
4063610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
4073610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4083610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4094ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
4104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t fillLevel = 0;
4114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_BUFFERING_UPDATE, &fillLevel)) {
4124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("GenericMediaPlayer::onBufferingUpdate(fillLevel=%d)", fillLevel);
41368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
4144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        Mutex::Autolock _l(mSettingsLock);
4154ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        mCacheFill = fillLevel;
4164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle cache fill update
4174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (mCacheFill - mLastNotifiedCacheFill >= mCacheFillNotifThreshold) {
4184ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
4194ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle prefetch status update
4214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   compute how much time ahead of position is buffered
4224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int durationMsec, positionMsec = -1;
4234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)
4244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                && (OK == mPlayer->getDuration(&durationMsec))
4254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                        && (OK == mPlayer->getCurrentPosition(&positionMsec))) {
4264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            if ((-1 != durationMsec) && (-1 != positionMsec)) {
4274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                // evaluate prefetch status based on buffer time thresholds
4284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                int64_t bufferedDurationMsec = (durationMsec * fillLevel / 100) - positionMsec;
4294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                CacheStatus_t newCacheStatus = mCacheStatus;
4304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (bufferedDurationMsec > DURATION_CACHED_HIGH_MS) {
4314ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusHigh;
4324ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_MED_MS) {
4334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEnough;
4344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_LOW_MS) {
4354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusIntermediate;
4364ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec == 0) {
4374ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEmpty;
4384ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else {
4394ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusLow;
4404ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
4414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4424ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (newCacheStatus != mCacheStatus) {
4434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    mCacheStatus = newCacheStatus;
4444ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    notifyStatus();
4454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
4464ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
4474ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
448b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    } else {
449b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        SL_LOGV("GenericMediaPlayer::onBufferingUpdate(fillLevel=unknown)");
4504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
4514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
4524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi//--------------------------------------------------
4554ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi/**
45606059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten * called from GenericMediaPlayer::onPrepare after the MediaPlayer mPlayer is prepared successfully
457fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten * pre-conditions:
458fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten *  mPlayer != 0
45906059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten *  mPlayer is prepared successfully
4604ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi */
46106059e5ee1eaf907589c7f8d1320253f92211348Glenn Kastenvoid GenericMediaPlayer::afterMediaPlayerPreparedSuccessfully() {
46206059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    SL_LOGV("GenericMediaPlayer::afterMediaPlayerPrepared()");
463fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(mPlayer != 0);
46406059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    assert(mStateFlags & kFlagPrepared);
4655933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // Mark this player as prepared successfully, so safe to directly call getCurrentPosition
4665933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    {
467a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        Mutex::Autolock _l(mPreparedPlayerLock);
468a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        assert(mPreparedPlayer == 0);
469a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        mPreparedPlayer = mPlayer;
4705933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    }
471fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve channel count
472fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(UNKNOWN_NUMCHANNELS == mChannelCount);
473fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    Parcel *reply = new Parcel();
474fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    status_t status = mPlayer->getParameter(KEY_PARAMETER_AUDIO_CHANNEL_COUNT, reply);
475fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (status == NO_ERROR) {
476fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        mChannelCount = reply->readInt32();
47799b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
47899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // FIXME MPEG-2 TS doesn't yet implement this key, so default to stereo
47999b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        mChannelCount = 2;
48099b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
48199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    if (UNKNOWN_NUMCHANNELS != mChannelCount) {
48299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // now that we know the channel count, re-calculate the volumes
48399b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        notify(PLAYEREVENT_CHANNEL_COUNT, mChannelCount, true /*async*/);
48499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
48599b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        LOGW("channel count is still unknown after prepare");
486fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
487fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    delete reply;
488fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve duration
4894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    {
4904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        Mutex::Autolock _l(mSettingsLock);
4914ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int msec = 0;
4924ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (OK == mPlayer->getDuration(&msec)) {
4934ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mDurationMsec = msec;
4944ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4954ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
4969f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    // now that we have a MediaPlayer, set the looping flag
4979f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    if (mStateFlags & kFlagLooping) {
4989f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        (void) mPlayer->setLooping(1);
4999f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    }
5004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // when the MediaPlayer mPlayer is prepared, there is "sufficient data" in the playback buffers
5014ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // if the data source was local, and the buffers are considered full so we need to notify that
5024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    bool isLocalSource = true;
5034ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (kDataLocatorUri == mDataLocatorType) {
504833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        isLocalSource = !isDistantProtocol(mDataLocator.uriRef);
5054ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (isLocalSource) {
5074ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on local source");
5084ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        {
5094ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            Mutex::Autolock _l(mSettingsLock);
5104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheStatus = kStatusHigh;
5114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheFill = 1000;
5124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyStatus();
5134ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
5144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
5154ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
5164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on non-local source");
5174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
51868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
51968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
5205933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
5215933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//--------------------------------------------------
5225933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten// If player is prepared successfully, set output parameter to that reference, otherwise NULL
523a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kastenvoid GenericMediaPlayer::getPreparedPlayer(sp<IMediaPlayer> &preparedPlayer)
5245933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten{
525a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    Mutex::Autolock _l(mPreparedPlayerLock);
526a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    preparedPlayer = mPreparedPlayer;
5275933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten}
5285933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
52968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi} // namespace android
530