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