1e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi/*
2e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
3e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi *
4e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * you may not use this file except in compliance with the License.
6e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * You may obtain a copy of the License at
7e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi *
8e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi *
10e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * See the License for the specific language governing permissions and
14e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi * limitations under the License.
15e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi */
16e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
17bbaef0633cc7e9509e462c65d071d76e2857ffe9Glenn Kasten//#define USE_LOG SLAndroidLogLevel_Verbose
18e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
19e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi#include "sles_allinclusive.h"
208ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#include "android_GenericMediaPlayer.h"
218ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
22e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi#include <media/IMediaPlayerService.h>
23e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi#include <surfaceflinger/ISurfaceComposer.h>
24e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi#include <surfaceflinger/SurfaceComposerClient.h>
258ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#include <media/stagefright/foundation/ADebug.h>
26e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
278ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi// default delay in Us used when reposting an event when the player is not ready to accept
288ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi// the command yet. This is for instance used when seeking on a MediaPlayer that's still preparing
298ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#define DEFAULT_COMMAND_DELAY_FOR_REPOST_US (100*1000) // 100ms
308ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
31d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten// table of prefixes for known distant protocols; these are immediately dispatched to mediaserver
32d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kastenstatic const char* const kDistantProtocolPrefix[] = { "http://", "https://", "rtsp://"};
338ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi#define NB_DISTANT_PROTOCOLS (sizeof(kDistantProtocolPrefix)/sizeof(kDistantProtocolPrefix[0]))
348ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
35d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten// is the specified URI a known distant protocol?
36d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kastenbool isDistantProtocol(const char *uri)
37d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten{
38d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten    for (unsigned int i = 0; i < NB_DISTANT_PROTOCOLS; i++) {
39d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        if (!strncasecmp(uri, kDistantProtocolPrefix[i], strlen(kDistantProtocolPrefix[i]))) {
40d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten            return true;
41d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        }
42d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten    }
43d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten    return false;
44d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten}
45d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten
46d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kastennamespace android {
47d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten
48e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
49fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel TriviMediaPlayerNotificationClient::MediaPlayerNotificationClient(GenericMediaPlayer* gmp) :
50fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    mGenericMediaPlayer(gmp),
51e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    mPlayerPrepared(PREPARE_NOT_STARTED)
52e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi{
536e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    SL_LOGV("MediaPlayerNotificationClient::MediaPlayerNotificationClient()");
54e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
55e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
56e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel TriviMediaPlayerNotificationClient::~MediaPlayerNotificationClient() {
576e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    SL_LOGV("MediaPlayerNotificationClient::~MediaPlayerNotificationClient()");
586e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten}
59e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
606e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten// Map a MEDIA_* enum to a string
616e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kastenstatic const char *media_to_string(int msg)
626e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten{
636e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    switch (msg) {
646e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten#define _(x) case MEDIA_##x: return "MEDIA_" #x;
656e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(PREPARED)
666e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(SET_VIDEO_SIZE)
676e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(SEEK_COMPLETE)
686e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(PLAYBACK_COMPLETE)
696e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(BUFFERING_UPDATE)
706e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(ERROR)
716e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(NOP)
726e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(TIMED_TEXT)
736e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten      _(INFO)
746e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten#undef _
756e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    default:
766e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten        return NULL;
776e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    }
78e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
79e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
80e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------
81e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi// IMediaPlayerClient implementation
82cd422d88f508397adf8f6b492a82f0d9baee5b88Gloria Wangvoid MediaPlayerNotificationClient::notify(int msg, int ext1, int ext2, const Parcel *obj) {
836e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    SL_LOGV("MediaPlayerNotificationClient::notify(msg=%s (%d), ext1=%d, ext2=%d)",
846e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten            media_to_string(msg), msg, ext1, ext2);
85e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
8651627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten    sp<GenericMediaPlayer> genericMediaPlayer(mGenericMediaPlayer.promote());
8751627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten    if (genericMediaPlayer == NULL) {
8851627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        SL_LOGW("MediaPlayerNotificationClient::notify after GenericMediaPlayer destroyed");
8951627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        return;
9051627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten    }
9151627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten
92fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    switch (msg) {
93fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi      case MEDIA_PREPARED:
9451627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        {
9551627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        Mutex::Autolock _l(mLock);
965a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
975a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_SUCCESSFULLY;
985a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten            mPlayerPreparedCondition.signal();
995a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        } else {
1005a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten            SL_LOGE("Unexpected MEDIA_PREPARED");
1015a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        }
10251627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        }
103fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
104fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
105fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi      case MEDIA_SET_VIDEO_SIZE:
1068ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // only send video size updates if the player was flagged as having video, to avoid
1078ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // sending video size updates of (0,0)
10851627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        // We're running on a different thread than genericMediaPlayer's ALooper thread,
10951627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        // so it would normally be racy to access fields within genericMediaPlayer.
11051627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        // But in this case mHasVideo is const, so it is safe to access.
11151627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        // Or alternatively, we could notify unconditionally and let it decide whether to handle.
11251627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        if (genericMediaPlayer->mHasVideo) {
11351627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_VIDEO_SIZE_UPDATE,
1148ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    (int32_t)ext1, (int32_t)ext2, true /*async*/);
1158ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
1168ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        break;
1178ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
1188ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi      case MEDIA_SEEK_COMPLETE:
11951627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        genericMediaPlayer->seekComplete();
1208ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        break;
1218ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
1228ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi      case MEDIA_PLAYBACK_COMPLETE:
12351627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        genericMediaPlayer->notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
1248ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        break;
1258ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
1268ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi      case MEDIA_BUFFERING_UPDATE:
1278ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // values received from Android framework for buffer fill level use percent,
1288ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        //   while SL/XA use permille, so does GenericPlayer
12951627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        genericMediaPlayer->bufferingUpdate(ext1 * 10 /*fillLevelPerMille*/);
130fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi        break;
131fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
1325dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten      case MEDIA_ERROR:
13351627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        {
13451627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        Mutex::Autolock _l(mLock);
1355a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
1365a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_UNSUCCESSFULLY;
1375a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten            mPlayerPreparedCondition.signal();
1385a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        } else {
13931cc0d9597a502a2c81ff318556adde92d50590aGlenn Kasten            // inform client of errors after preparation
14031cc0d9597a502a2c81ff318556adde92d50590aGlenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_ERRORAFTERPREPARE, ext1, true /*async*/);
1415a7123b8f2a7c726ff5d5ef89952b213a4da8411Glenn Kasten        }
14251627b879ac8c1ef34028801d9d6b697f362c405Glenn Kasten        }
143e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten        break;
144e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten
1455dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten      case MEDIA_NOP:
1465dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten      case MEDIA_TIMED_TEXT:
1475dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten      case MEDIA_INFO:
1485dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten        break;
1495dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten
150fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi      default: { }
151e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    }
1525dc09fe1d61c11a91343237032d65163fe691297Glenn Kasten
153e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
154e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
155e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------
156e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kastenvoid MediaPlayerNotificationClient::beforePrepare()
157e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten{
158e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    Mutex::Autolock _l(mLock);
159e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    assert(mPlayerPrepared == PREPARE_NOT_STARTED);
160e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    mPlayerPrepared = PREPARE_IN_PROGRESS;
161e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten}
162e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten
163e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten//--------------------------------------------------
164e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kastenbool MediaPlayerNotificationClient::blockUntilPlayerPrepared() {
165e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    Mutex::Autolock _l(mLock);
166e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    assert(mPlayerPrepared != PREPARE_NOT_STARTED);
167e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    while (mPlayerPrepared == PREPARE_IN_PROGRESS) {
168e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        mPlayerPreparedCondition.wait(mLock);
169e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    }
170e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    assert(mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY ||
171e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten            mPlayerPrepared == PREPARE_COMPLETED_UNSUCCESSFULLY);
172e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    return mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY;
173e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
174e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
175e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
176e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel TriviGenericMediaPlayer::GenericMediaPlayer(const AudioPlayback_Parameters* params, bool hasVideo) :
177e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    GenericPlayer(params),
178e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    mHasVideo(hasVideo),
179f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi    mSeekTimeMsec(0),
18013a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    mVideoSurfaceTexture(0),
181e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    mPlayer(0),
18242d2daefb2508a4f8f05ce8fe4c6b7da9f3d896dGlenn Kasten    mPlayerClient(new MediaPlayerNotificationClient(this)),
18342d2daefb2508a4f8f05ce8fe4c6b7da9f3d896dGlenn Kasten    mPlayerDeathNotifier(new MediaPlayerDeathNotifier(mPlayerClient))
184e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi{
18530ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::GenericMediaPlayer()");
186e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
187e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
188e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
189e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel TriviGenericMediaPlayer::~GenericMediaPlayer() {
19030ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::~GenericMediaPlayer()");
1911b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi}
1921b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi
1931b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid GenericMediaPlayer::preDestroy() {
1943adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    // FIXME can't access mPlayer from outside the looper (no mutex!) so using mPreparedPlayer
1953adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    sp<IMediaPlayer> player;
1963adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    getPreparedPlayer(player);
1973adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    if (player != NULL) {
1983adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        player->stop();
1993adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        // causes CHECK failure in Nuplayer, but commented out in the subclass preDestroy
200ba6d04f523bf6c3c2d4ed6975109e72f328889b8Glenn Kasten        // randomly causes a NPE in StagefrightPlayer, heap corruption, or app hang
201ba6d04f523bf6c3c2d4ed6975109e72f328889b8Glenn Kasten        //player->setDataSource(NULL);
2028d7bd3c0c920ba70cbf3cc762411902c94c35253Andreas Huber        player->setVideoSurfaceTexture(NULL);
2033adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        player->disconnect();
2043adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        // release all references to the IMediaPlayer
2053adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        // FIXME illegal if not on looper
2063adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        //mPlayer.clear();
2073adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        {
2083adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten            Mutex::Autolock _l(mPreparedPlayerLock);
2093adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten            mPreparedPlayer.clear();
2103adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        }
211abf6db3696e93960f7bc943e8235ba31f73e5c3fGlenn Kasten    }
2121b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi    GenericPlayer::preDestroy();
2131b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi}
214e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
2151b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//--------------------------------------------------
2161b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi// overridden from GenericPlayer
2171b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi// pre-condition:
2181b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//   msec != NULL
2191b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi// post-condition
220a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten//   *msec ==
2211b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//                  ANDROID_UNKNOWN_TIME if position is unknown at time of query,
2221b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi//               or the current MediaPlayer position
2231b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivivoid GenericMediaPlayer::getPositionMsec(int* msec) {
2241b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::getPositionMsec()");
225a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    sp<IMediaPlayer> player;
2263adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    getPreparedPlayer(player);
227a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    // To avoid deadlock, directly call the MediaPlayer object
228a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    if (player == 0 || player->getCurrentPosition(msec) != NO_ERROR) {
229a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten        *msec = ANDROID_UNKNOWN_TIME;
2301b3d049fdaa0dfb601e5b7f482e04e84d38d2f93Jean-Michel Trivi    }
231e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
232e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
233e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------
23413a07de046bce3663b905a892dbaf770a54d982dGlenn Kastenvoid GenericMediaPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
2356e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurfaceTexture()");
23639671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten    // FIXME bug - race condition, should do in looper
23739671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten    if (mVideoSurfaceTexture.get() == surfaceTexture.get()) {
23839671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten        return;
23939671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten    }
24039671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
24139671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten        mPlayer->setVideoSurfaceTexture(surfaceTexture);
24239671763229bf1140c8e1c1b6cd4c072cbd4eb6cGlenn Kasten    }
24313a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten    mVideoSurfaceTexture = surfaceTexture;
244e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
245e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
2465b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi
247e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi//--------------------------------------------------
248e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi// Event handlers
2498ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
2506bd00f9169990c3b9e84b03ef1c5c27ed50a37d1Glenn Kasten// blocks until mPlayer is prepared
251e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivivoid GenericMediaPlayer::onPrepare() {
25230ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare()");
253e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    // Attempt to prepare at most once, and only if there is a MediaPlayer
254e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    if (!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully)) && (mPlayer != 0)) {
25513a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten        if (mHasVideo) {
2568d7bd3c0c920ba70cbf3cc762411902c94c35253Andreas Huber            if (mVideoSurfaceTexture != 0) {
25713a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten                mPlayer->setVideoSurfaceTexture(mVideoSurfaceTexture);
25813a07de046bce3663b905a892dbaf770a54d982dGlenn Kasten            }
259e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        }
260e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        mPlayer->setAudioStreamType(mPlaybackParams.streamType);
261e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten        mPlayerClient->beforePrepare();
262e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        mPlayer->prepareAsync();
263f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten        if (mPlayerClient->blockUntilPlayerPrepared()) {
264f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten            mStateFlags |= kFlagPrepared;
265f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten            afterMediaPlayerPreparedSuccessfully();
266f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten        } else {
267f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten            mStateFlags |= kFlagPreparedUnsuccessfully;
268f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten        }
269e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    }
2706bd00f9169990c3b9e84b03ef1c5c27ed50a37d1Glenn Kasten    GenericPlayer::onPrepare();
27130ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
272e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
273e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
2748ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
275e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivivoid GenericMediaPlayer::onPlay() {
27630ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPlay()");
277a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    if (((mStateFlags & (kFlagPrepared | kFlagPlaying)) == kFlagPrepared) && (mPlayer != 0)) {
278e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        mPlayer->start();
279e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    }
280a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    GenericPlayer::onPlay();
281e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
282e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
2838ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
284e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivivoid GenericMediaPlayer::onPause() {
28530ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPause()");
286a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    if (!(~mStateFlags & (kFlagPrepared | kFlagPlaying)) && (mPlayer != 0)) {
287e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi        mPlayer->pause();
288e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi    }
289a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    GenericPlayer::onPause();
290fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi}
291fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi
2920b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten
2930b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kastenvoid GenericMediaPlayer::onSeekComplete() {
2940b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten    SL_LOGV("GenericMediaPlayer::onSeekComplete()");
2950b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten    // did we initiate the seek?
2960b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten    if (!(mStateFlags & kFlagSeeking)) {
2970b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten        // no, are we looping?
2980b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten        if (mStateFlags & kFlagLooping) {
2990b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten            // yes, per OpenSL ES 1.0.1 and 1.1 do NOT report it to client
3000b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten            // notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
3010b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten        // no, well that's surprising, but it's probably just a benign race condition
3020b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten        } else {
3030b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten            SL_LOGW("Unexpected seek complete event ignored");
3040b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten        }
3050b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten    }
3060b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten    GenericPlayer::onSeekComplete();
3070b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten}
3080b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten
3090b02ad8c6715ac9d8526e4229a6030ef436704bcGlenn Kasten
310f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi/**
311f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi * pre-condition: WHATPARAM_SEEK_SEEKTIME_MS parameter value >= 0
312f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi */
3138ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivivoid GenericMediaPlayer::onSeek(const sp<AMessage> &msg) {
3148ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onSeek");
315f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi    int64_t timeMsec = ANDROID_UNKNOWN_TIME;
316f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi    if (!msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec)) {
317f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi        // invalid command, drop it
318f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi        return;
319f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi    }
32022c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten    if ((mStateFlags & kFlagSeeking) && (timeMsec == mSeekTimeMsec) &&
32122c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten            (timeMsec != ANDROID_UNKNOWN_TIME)) {
32222c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten        // already seeking to the same non-unknown time, cancel this command
323f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi        return;
324e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten    } else if (mStateFlags & kFlagPreparedUnsuccessfully) {
325e1c913c670ee6f38940555b4247bc4a572eaa798Glenn Kasten        // discard seeks after unsuccessful prepare
326f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi    } else if (!(mStateFlags & kFlagPrepared)) {
3278ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // we are not ready to accept a seek command at this time, retry later
3288ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        msg->post(DEFAULT_COMMAND_DELAY_FOR_REPOST_US);
3298ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    } else {
33029c0e5eb471b5d3f519887da6ee067da6f2fcd33Glenn Kasten        if (mPlayer != 0) {
331f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi            mStateFlags |= kFlagSeeking;
332f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi            mSeekTimeMsec = (int32_t)timeMsec;
33322c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten            // seek to unknown time is used by StreamPlayer after discontinuity
33422c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten            if (timeMsec == ANDROID_UNKNOWN_TIME) {
33522c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten                // FIXME simulate a MEDIA_SEEK_COMPLETE event in 250 ms;
33622c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten                // this is a terrible hack to make up for mediaserver not sending one
33722c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten                (new AMessage(kWhatSeekComplete, id()))->post(250000);
33822c4f2714b5a419ba350ba733a78d17e09fbd2c3Glenn Kasten            } else if (OK != mPlayer->seekTo(timeMsec)) {
339f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi                mStateFlags &= ~kFlagSeeking;
340f096e77e6cbfc60263f42b435cb34fbab7be2e45Jean-Michel Trivi                mSeekTimeMsec = ANDROID_UNKNOWN_TIME;
3418ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            }
3428ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
3438ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
3448ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi}
3458ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
3468ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
3478ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivivoid GenericMediaPlayer::onLoop(const sp<AMessage> &msg) {
3488ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onLoop");
3498ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    int32_t loop = 0;
3508ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop)) {
3515ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        if (loop) {
3525ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten            mStateFlags |= kFlagLooping;
3535ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        } else {
3545ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten            mStateFlags &= ~kFlagLooping;
3555ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        }
3565ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        // if we have a MediaPlayer then tell it now, otherwise we'll tell it after it's created
3575ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        if (mPlayer != 0) {
3585ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten            (void) mPlayer->setLooping(loop);
3598ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
3608ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
3618ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi}
3628ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
3638ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
364fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivivoid GenericMediaPlayer::onVolumeUpdate() {
3658ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onVolumeUpdate()");
366fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    // use settings lock to read the volume settings
367fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    Mutex::Autolock _l(mSettingsLock);
3688ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (mPlayer != 0) {
3697e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten        mPlayer->setVolume(mAndroidAudioLevels.mFinalVolume[0],
3707e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten                mAndroidAudioLevels.mFinalVolume[1]);
371fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    }
3728ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi}
3738ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
3748ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
37541562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kastenvoid GenericMediaPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
37641562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    SL_LOGD("GenericMediaPlayer::onAttachAuxEffect()");
37741562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    int32_t effectId = 0;
37841562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    if (msg->findInt32(WHATPARAM_ATTACHAUXEFFECT, &effectId)) {
37941562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten        if (mPlayer != 0) {
38041562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            status_t status;
38141562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            status = mPlayer->attachAuxEffect(effectId);
38241562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            // attachAuxEffect returns a status but we have no way to report it back to app
38341562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            (void) status;
38441562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten        }
38541562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    }
38641562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten}
38741562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten
38841562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten
38941562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kastenvoid GenericMediaPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
39041562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    SL_LOGD("GenericMediaPlayer::onSetAuxEffectSendLevel()");
39141562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    float level = 0.0f;
39241562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    if (msg->findFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, &level)) {
39341562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten        if (mPlayer != 0) {
39441562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            status_t status;
39541562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            status = mPlayer->setAuxEffectSendLevel(level);
39641562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            // setAuxEffectSendLevel returns a status but we have no way to report it back to app
39741562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten            (void) status;
39841562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten        }
39941562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten    }
40041562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten}
40141562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten
40241562990ca46e5d6c4aadde6c2469b8007bb980cGlenn Kasten
4038ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivivoid GenericMediaPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
4048ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    int32_t fillLevel = 0;
4058ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_BUFFERING_UPDATE, &fillLevel)) {
4068ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SL_LOGD("GenericMediaPlayer::onBufferingUpdate(fillLevel=%d)", fillLevel);
407e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
4088ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        Mutex::Autolock _l(mSettingsLock);
4098ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        mCacheFill = fillLevel;
4108ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // handle cache fill update
4118ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        if (mCacheFill - mLastNotifiedCacheFill >= mCacheFillNotifThreshold) {
4128ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            notifyCacheFill();
4138ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
4148ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        // handle prefetch status update
4158ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        //   compute how much time ahead of position is buffered
4168ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        int durationMsec, positionMsec = -1;
4178ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)
4188ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                && (OK == mPlayer->getDuration(&durationMsec))
4198ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                        && (OK == mPlayer->getCurrentPosition(&positionMsec))) {
4208ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            if ((-1 != durationMsec) && (-1 != positionMsec)) {
4218ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                // evaluate prefetch status based on buffer time thresholds
4228ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                int64_t bufferedDurationMsec = (durationMsec * fillLevel / 100) - positionMsec;
4238ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                CacheStatus_t newCacheStatus = mCacheStatus;
4248ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                if (bufferedDurationMsec > DURATION_CACHED_HIGH_MS) {
4258ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    newCacheStatus = kStatusHigh;
4268ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_MED_MS) {
4278ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    newCacheStatus = kStatusEnough;
4288ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_LOW_MS) {
4298ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    newCacheStatus = kStatusIntermediate;
4308ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                } else if (bufferedDurationMsec == 0) {
4318ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    newCacheStatus = kStatusEmpty;
4328ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                } else {
4338ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    newCacheStatus = kStatusLow;
4348ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                }
4358ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
4368ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                if (newCacheStatus != mCacheStatus) {
4378ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    mCacheStatus = newCacheStatus;
4388ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                    notifyStatus();
4398ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi                }
4408ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            }
4418ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
4426e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten    } else {
4436e00efb769f780bc46c2ccda92688ba890623fb4Glenn Kasten        SL_LOGV("GenericMediaPlayer::onBufferingUpdate(fillLevel=unknown)");
4448ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
4458ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi}
4468ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
4478ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi
4488ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi//--------------------------------------------------
4498ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi/**
450f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten * called from GenericMediaPlayer::onPrepare after the MediaPlayer mPlayer is prepared successfully
4517e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten * pre-conditions:
4527e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten *  mPlayer != 0
453f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten *  mPlayer is prepared successfully
4548ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi */
455f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kastenvoid GenericMediaPlayer::afterMediaPlayerPreparedSuccessfully() {
456f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten    SL_LOGV("GenericMediaPlayer::afterMediaPlayerPrepared()");
4577e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    assert(mPlayer != 0);
458f037e5965c0a0e6a918344753dc59bf4e8149d10Glenn Kasten    assert(mStateFlags & kFlagPrepared);
459a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    // Mark this player as prepared successfully, so safe to directly call getCurrentPosition
460a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    {
4613adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        Mutex::Autolock _l(mPreparedPlayerLock);
4623adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        assert(mPreparedPlayer == 0);
4633adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten        mPreparedPlayer = mPlayer;
464a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten    }
4657e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    // retrieve channel count
466e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    int32_t channelCount;
4677e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    Parcel *reply = new Parcel();
4687e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    status_t status = mPlayer->getParameter(KEY_PARAMETER_AUDIO_CHANNEL_COUNT, reply);
4697e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    if (status == NO_ERROR) {
470e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        channelCount = reply->readInt32();
4710afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten    } else {
4720afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten        // FIXME MPEG-2 TS doesn't yet implement this key, so default to stereo
473e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        channelCount = 2;
4740afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten    }
475e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten    if (UNKNOWN_NUMCHANNELS != channelCount) {
4760afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten        // now that we know the channel count, re-calculate the volumes
477e851581e7a62192f69626b9a0d2e5380a4d3979cGlenn Kasten        notify(PLAYEREVENT_CHANNEL_COUNT, channelCount, true /*async*/);
4780afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten    } else {
4790afa0fdcde5876941eaefaacc778984ec4efefa0Glenn Kasten        LOGW("channel count is still unknown after prepare");
4807e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    }
4817e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    delete reply;
4827e4729ac84d876de3ae439ae9cfef41701d6a2a2Glenn Kasten    // retrieve duration
4838ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    {
4848ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        int msec = 0;
4858ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        if (OK == mPlayer->getDuration(&msec)) {
486891673f650f233f17f60e2c663fa24279b8dc9afGlenn Kasten            Mutex::Autolock _l(mSettingsLock);
4878ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            mDurationMsec = msec;
4888ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
4898ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
4905ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten    // now that we have a MediaPlayer, set the looping flag
4915ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten    if (mStateFlags & kFlagLooping) {
4925ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten        (void) mPlayer->setLooping(1);
4935ec63c4998f9b1d8c30363f21cbecc7ffc5d152aGlenn Kasten    }
4948ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    // when the MediaPlayer mPlayer is prepared, there is "sufficient data" in the playback buffers
4958ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    // if the data source was local, and the buffers are considered full so we need to notify that
4968ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    bool isLocalSource = true;
4978ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (kDataLocatorUri == mDataLocatorType) {
498d62f504ebe6a3f9b15c6115f9add1c4fed87d847Glenn Kasten        isLocalSource = !isDistantProtocol(mDataLocator.uriRef);
4998ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
5008ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    if (isLocalSource) {
5018ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SL_LOGD("media player prepared on local source");
5028ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        {
5038ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            Mutex::Autolock _l(mSettingsLock);
5048ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            mCacheStatus = kStatusHigh;
5058ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            mCacheFill = 1000;
5068ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            notifyStatus();
5078ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi            notifyCacheFill();
5088ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        }
5098ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    } else {
5108ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi        SL_LOGD("media player prepared on non-local source");
5118ad101d5bcaca289da3d820e2b87b5da55e560f9Jean-Michel Trivi    }
512e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi}
513e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi
514a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten
515a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten//--------------------------------------------------
516a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten// If player is prepared successfully, set output parameter to that reference, otherwise NULL
5173adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kastenvoid GenericMediaPlayer::getPreparedPlayer(sp<IMediaPlayer> &preparedPlayer)
518a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten{
5193adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    Mutex::Autolock _l(mPreparedPlayerLock);
5203adea07faf6124cfbc68d2db80e05f4cced9dfa9Glenn Kasten    preparedPlayer = mPreparedPlayer;
521a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten}
522a81ac67d31590942f5a3a8233cf9759c20a494dcGlenn Kasten
523e8af8705a6eb3b8ebd239c379d9143dc69c363d4Jean-Michel Trivi} // namespace android
524