168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi/*
268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * you may not use this file except in compliance with the License.
668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * You may obtain a copy of the License at
768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi *
1068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * See the License for the specific language governing permissions and
1468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi * limitations under the License.
1568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi */
1668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
17de015407a89018f9422254624e1b75703f38defdGlenn Kasten//#define USE_LOG SLAndroidLogLevel_Verbose
1868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
1968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include "sles_allinclusive.h"
204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "android_GenericMediaPlayer.h"
214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
2201e4a8ff63523bba5c8f919a72e0adb66daf4b98Mathias Agopian#include <system/window.h>
2301e4a8ff63523bba5c8f919a72e0adb66daf4b98Mathias Agopian
2468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi#include <media/IMediaPlayerService.h>
254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include <media/stagefright/foundation/ADebug.h>
260384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#include <media/mediaplayer.h>  // media_event_type media_error_type media_info_type
2768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi// default delay in Us used when reposting an event when the player is not ready to accept
294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi// the command yet. This is for instance used when seeking on a MediaPlayer that's still preparing
304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#define DEFAULT_COMMAND_DELAY_FOR_REPOST_US (100*1000) // 100ms
314ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
32833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten// table of prefixes for known distant protocols; these are immediately dispatched to mediaserver
33833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastenstatic const char* const kDistantProtocolPrefix[] = { "http://", "https://", "rtsp://"};
344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#define NB_DISTANT_PROTOCOLS (sizeof(kDistantProtocolPrefix)/sizeof(kDistantProtocolPrefix[0]))
354ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
36833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten// is the specified URI a known distant protocol?
37833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastenbool isDistantProtocol(const char *uri)
38833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten{
39833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    for (unsigned int i = 0; i < NB_DISTANT_PROTOCOLS; i++) {
40833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        if (!strncasecmp(uri, kDistantProtocolPrefix[i], strlen(kDistantProtocolPrefix[i]))) {
41833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten            return true;
42833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        }
43833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    }
44833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten    return false;
45833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten}
46833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten
47833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kastennamespace android {
48833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten
4968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
5037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel TriviMediaPlayerNotificationClient::MediaPlayerNotificationClient(GenericMediaPlayer* gmp) :
5137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    mGenericMediaPlayer(gmp),
5249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    mPlayerPrepared(PREPARE_NOT_STARTED)
5368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi{
54b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::MediaPlayerNotificationClient()");
5568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
5668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
5768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviMediaPlayerNotificationClient::~MediaPlayerNotificationClient() {
58b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::~MediaPlayerNotificationClient()");
59b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten}
6068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
610384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten// Map a media_event_type enum (the msg of an IMediaPlayerClient::notify) to a string or NULL
620384250ce4221e4a6a16db2725e1232c71a60965Glenn Kastenstatic const char *media_event_type_to_string(media_event_type msg)
63b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten{
64b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    switch (msg) {
650384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#define _(code) case code: return #code;
660384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_NOP)
670384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_PREPARED)
680384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_PLAYBACK_COMPLETE)
690384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_BUFFERING_UPDATE)
700384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_SEEK_COMPLETE)
710384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_SET_VIDEO_SIZE)
720384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_TIMED_TEXT)
730384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_ERROR)
740384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO)
750384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#undef _
760384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    default:
770384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        return NULL;
780384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    }
790384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten}
800384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten
810384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten// Map a media_error_type enum (the ext1 of a MEDIA_ERROR event) to a string or NULL
820384250ce4221e4a6a16db2725e1232c71a60965Glenn Kastenstatic const char *media_error_type_to_string(media_error_type err)
830384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten{
840384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    switch (err) {
850384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#define _(code, msg) case code: return msg;
860384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_ERROR_UNKNOWN,                              "Unknown media error")
870384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_ERROR_SERVER_DIED,                          "Server died")
880384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK,   "Not valid for progressive playback")
890384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#undef _
900384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    default:
910384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        return NULL;
920384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    }
930384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten}
940384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten
950384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten// Map a media_info_type enum (the ext1 of a MEDIA_INFO event) to a string or NULL
960384250ce4221e4a6a16db2725e1232c71a60965Glenn Kastenstatic const char *media_info_type_to_string(media_info_type info)
970384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten{
980384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    switch (info) {
990384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten#define _(code, msg) case code: return msg;
1000384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_UNKNOWN,             "Unknown info")
1010384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_VIDEO_TRACK_LAGGING, "Video track lagging")
1020384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_BUFFERING_START,     "Buffering start")
1030384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_BUFFERING_END,       "Buffering end")
1040384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_NETWORK_BANDWIDTH,   "Network bandwidth")
1050384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_BAD_INTERLEAVING,    "Bad interleaving")
1060384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_NOT_SEEKABLE,        "Not seekable")
1070384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    _(MEDIA_INFO_METADATA_UPDATE,     "Metadata update")
108b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten#undef _
109b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    default:
110b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        return NULL;
111b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    }
11268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
11368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
11468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
11568d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi// IMediaPlayerClient implementation
1162f6d462d89356cdaa77299ca27b60c5cca198d98Gloria Wangvoid MediaPlayerNotificationClient::notify(int msg, int ext1, int ext2, const Parcel *obj) {
117b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("MediaPlayerNotificationClient::notify(msg=%s (%d), ext1=%d, ext2=%d)",
1180384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            media_event_type_to_string((enum media_event_type) msg), msg, ext1, ext2);
11968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
12091ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    sp<GenericMediaPlayer> genericMediaPlayer(mGenericMediaPlayer.promote());
12191ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    if (genericMediaPlayer == NULL) {
12291ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        SL_LOGW("MediaPlayerNotificationClient::notify after GenericMediaPlayer destroyed");
12391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        return;
12491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten    }
12591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten
1260384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten    switch ((media_event_type) msg) {
12737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      case MEDIA_PREPARED:
12891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        {
12991ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        Mutex::Autolock _l(mLock);
1300d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
1310d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_SUCCESSFULLY;
1320d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPreparedCondition.signal();
1330d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        } else {
1340d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            SL_LOGE("Unexpected MEDIA_PREPARED");
1350d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        }
13691ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
13737dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
13837dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
13937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi      case MEDIA_SET_VIDEO_SIZE:
1404ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // only send video size updates if the player was flagged as having video, to avoid
1414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // sending video size updates of (0,0)
14291ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // We're running on a different thread than genericMediaPlayer's ALooper thread,
14391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // so it would normally be racy to access fields within genericMediaPlayer.
14491ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // But in this case mHasVideo is const, so it is safe to access.
14591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        // Or alternatively, we could notify unconditionally and let it decide whether to handle.
1460384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        if (genericMediaPlayer->mHasVideo && (ext1 != 0 || ext2 != 0)) {
14791ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_VIDEO_SIZE_UPDATE,
1480384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten                    (int32_t)ext1 /*width*/, (int32_t)ext2 /*height*/, true /*async*/);
1494ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
1504ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1514ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_SEEK_COMPLETE:
15391ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->seekComplete();
1544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1554ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1564ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_PLAYBACK_COMPLETE:
15791ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
1584ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        break;
1594ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
1604ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi      case MEDIA_BUFFERING_UPDATE:
1610384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        // if we receive any out-of-range data, then clamp it to reduce further harm
1620384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        if (ext1 < 0) {
1630384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            SL_LOGE("MEDIA_BUFFERING_UPDATE %d%% < 0", ext1);
1640384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            ext1 = 0;
1650384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        } else if (ext1 > 100) {
1660384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            SL_LOGE("MEDIA_BUFFERING_UPDATE %d%% > 100", ext1);
1670384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            ext1 = 100;
1680384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        }
1694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // values received from Android framework for buffer fill level use percent,
1704ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   while SL/XA use permille, so does GenericPlayer
17191ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        genericMediaPlayer->bufferingUpdate(ext1 * 10 /*fillLevelPerMille*/);
17237dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi        break;
17337dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
17481e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_ERROR:
17591ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        {
1760384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        SL_LOGV("MediaPlayerNotificationClient::notify(msg=MEDIA_ERROR, ext1=%s (%d), ext2=%d)",
1770384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten                media_error_type_to_string((media_error_type) ext1), ext1, ext2);
17891ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        Mutex::Autolock _l(mLock);
1790d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        if (PREPARE_IN_PROGRESS == mPlayerPrepared) {
1800d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPrepared = PREPARE_COMPLETED_UNSUCCESSFULLY;
1810d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten            mPlayerPreparedCondition.signal();
1820d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        } else {
1835e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            // inform client of errors after preparation
1845e4d65e369f28746767aba11b618dee314bb8197Glenn Kasten            genericMediaPlayer->notify(PLAYEREVENT_ERRORAFTERPREPARE, ext1, true /*async*/);
1850d1c7e2ccd98bf7e2285c3db98ea263c79b24978Glenn Kasten        }
18691ff087fb814063f9faa23ab37a61e8fe4e38f45Glenn Kasten        }
18749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        break;
18849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
18981e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_NOP:
19081e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_TIMED_TEXT:
1910384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        break;
1920384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten
19381e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten      case MEDIA_INFO:
1940384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        SL_LOGV("MediaPlayerNotificationClient::notify(msg=MEDIA_INFO, ext1=%s (%d), ext2=%d)",
1950384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten                media_info_type_to_string((media_info_type) ext1), ext1, ext2);
1960384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        switch (ext1) {
1970384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_VIDEO_TRACK_LAGGING:
1980384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            SL_LOGV("MEDIA_INFO_VIDEO_TRACK_LAGGING by %d ms", ext1);
1990384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            break;
2000384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_NETWORK_BANDWIDTH:
2010384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            SL_LOGV("MEDIA_INFO_NETWORK_BANDWIDTH %d kbps", ext2);
2020384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            break;
2030384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_UNKNOWN:
2040384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_BUFFERING_START:
2050384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_BUFFERING_END:
2060384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_BAD_INTERLEAVING:
2070384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_NOT_SEEKABLE:
2080384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        case MEDIA_INFO_METADATA_UPDATE:
2090384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        default:
2100384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten            break;
2110384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        }
21281e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten        break;
21381e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
2140384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten      default:
2150384250ce4221e4a6a16db2725e1232c71a60965Glenn Kasten        break;
21668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
21781e917a2605e14901b8f5e6cac7eafb5667aad0dGlenn Kasten
21868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
21968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
22068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
22149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenvoid MediaPlayerNotificationClient::beforePrepare()
22249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten{
22349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    Mutex::Autolock _l(mLock);
22449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_NOT_STARTED);
22549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    mPlayerPrepared = PREPARE_IN_PROGRESS;
22649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten}
22749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten
22849935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten//--------------------------------------------------
22949935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kastenbool MediaPlayerNotificationClient::blockUntilPlayerPrepared() {
23068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    Mutex::Autolock _l(mLock);
23149935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared != PREPARE_NOT_STARTED);
23249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    while (mPlayerPrepared == PREPARE_IN_PROGRESS) {
23368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayerPreparedCondition.wait(mLock);
23468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
23549935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    assert(mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY ||
23649935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten            mPlayerPrepared == PREPARE_COMPLETED_UNSUCCESSFULLY);
23749935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    return mPlayerPrepared == PREPARE_COMPLETED_SUCCESSFULLY;
23868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
23968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
24068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------------------------------------------------------
24168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::GenericMediaPlayer(const AudioPlayback_Parameters* params, bool hasVideo) :
24268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    GenericPlayer(params),
24368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mHasVideo(hasVideo),
2447ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    mSeekTimeMsec(0),
245ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture(0),
24668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    mPlayer(0),
247513222822545c3e954176476b263df52a47f43a4Glenn Kasten    mPlayerClient(new MediaPlayerNotificationClient(this)),
248513222822545c3e954176476b263df52a47f43a4Glenn Kasten    mPlayerDeathNotifier(new MediaPlayerDeathNotifier(mPlayerClient))
24968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi{
250e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::GenericMediaPlayer()");
25168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
25268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
25368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
25468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel TriviGenericMediaPlayer::~GenericMediaPlayer() {
255e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::~GenericMediaPlayer()");
2564b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
2574b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi
2584b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::preDestroy() {
259a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    // FIXME can't access mPlayer from outside the looper (no mutex!) so using mPreparedPlayer
260a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    sp<IMediaPlayer> player;
261a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
262a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    if (player != NULL) {
263a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->stop();
264a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // causes CHECK failure in Nuplayer, but commented out in the subclass preDestroy
2657c40d3b78c609b2a84acd0dd6e874ab24a73f8d7Glenn Kasten        // randomly causes a NPE in StagefrightPlayer, heap corruption, or app hang
2667c40d3b78c609b2a84acd0dd6e874ab24a73f8d7Glenn Kasten        //player->setDataSource(NULL);
267241b9c06493479dc632a8851097c193b724a2b41Andreas Huber        player->setVideoSurfaceTexture(NULL);
268a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        player->disconnect();
269a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // release all references to the IMediaPlayer
270a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        // FIXME illegal if not on looper
271a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        //mPlayer.clear();
272a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        {
273a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            Mutex::Autolock _l(mPreparedPlayerLock);
274a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten            mPreparedPlayer.clear();
275a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        }
276485a038f9f0f898227b8ab4218e94c5d56b6ed0bGlenn Kasten    }
2774b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    GenericPlayer::preDestroy();
2784b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi}
27968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
2804b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//--------------------------------------------------
2814b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// overridden from GenericPlayer
2824b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// pre-condition:
2834b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//   msec != NULL
2844b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi// post-condition
2855933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//   *msec ==
2864b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//                  ANDROID_UNKNOWN_TIME if position is unknown at time of query,
2874b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi//               or the current MediaPlayer position
2884b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivivoid GenericMediaPlayer::getPositionMsec(int* msec) {
2894b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::getPositionMsec()");
2905933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    sp<IMediaPlayer> player;
291a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    getPreparedPlayer(player);
2925933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // To avoid deadlock, directly call the MediaPlayer object
2935933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (player == 0 || player->getCurrentPosition(msec) != NO_ERROR) {
2945933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten        *msec = ANDROID_UNKNOWN_TIME;
2954b0e0b2860ffd5e246b42c8a434833cca2f068b3Jean-Michel Trivi    }
29668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
29768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
29868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
299ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kastenvoid GenericMediaPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
300b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    SL_LOGV("GenericMediaPlayer::setVideoSurfaceTexture()");
30135ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    // FIXME bug - race condition, should do in looper
30235ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if (mVideoSurfaceTexture.get() == surfaceTexture.get()) {
30335ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        return;
30435ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
30535ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)) {
30635ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten        mPlayer->setVideoSurfaceTexture(surfaceTexture);
30735ac702ee1ad91e5c8748c12450222d50b366a52Glenn Kasten    }
308ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten    mVideoSurfaceTexture = surfaceTexture;
30968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
31068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
31191145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi//--------------------------------------------------
31291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivivoid GenericMediaPlayer::setPlaybackRate(int32_t ratePermille) {
31391145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    SL_LOGV("GenericMediaPlayer::setPlaybackRate(%d)", ratePermille);
31491145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    GenericPlayer::setPlaybackRate(ratePermille);
31591145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    sp<IMediaPlayer> player;
31691145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    getPreparedPlayer(player);
31791145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    if (player != 0) {
31891145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        Parcel rateParcel;
31991145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        if (rateParcel.writeInt32(ratePermille) == OK) {
32091145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi            player->setParameter(KEY_PARAMETER_PLAYBACK_RATE_PERMILLE, rateParcel);
32191145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        }
32291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    }
32391145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi}
32491145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi
32570c49ae2867094072a4365423417ea452bf82231Jean-Michel Trivi
32668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi//--------------------------------------------------
32768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi// Event handlers
3284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
32985edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten// blocks until mPlayer is prepared
33068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPrepare() {
331e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare()");
33249935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    // Attempt to prepare at most once, and only if there is a MediaPlayer
33349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    if (!(mStateFlags & (kFlagPrepared | kFlagPreparedUnsuccessfully)) && (mPlayer != 0)) {
334ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten        if (mHasVideo) {
335241b9c06493479dc632a8851097c193b724a2b41Andreas Huber            if (mVideoSurfaceTexture != 0) {
336ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten                mPlayer->setVideoSurfaceTexture(mVideoSurfaceTexture);
337ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8Glenn Kasten            }
33868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        }
33968d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->setAudioStreamType(mPlaybackParams.streamType);
34049935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        mPlayerClient->beforePrepare();
34168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->prepareAsync();
34206059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        if (mPlayerClient->blockUntilPlayerPrepared()) {
34306059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPrepared;
34406059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            afterMediaPlayerPreparedSuccessfully();
34506059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        } else {
34606059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten            mStateFlags |= kFlagPreparedUnsuccessfully;
34706059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten        }
34868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
34985edd878a30caa535b0267d8d6e61b4ccc0d5fd0Glenn Kasten    GenericPlayer::onPrepare();
350e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPrepare() done, mStateFlags=0x%x", mStateFlags);
35168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
35268d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
3534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
35468d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPlay() {
355e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPlay()");
3565933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (((mStateFlags & (kFlagPrepared | kFlagPlaying)) == kFlagPrepared) && (mPlayer != 0)) {
35768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->start();
35868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
3595933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPlay();
36068d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
36168d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
3624ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
36368d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivivoid GenericMediaPlayer::onPause() {
364e9236d046fdb5cac0696c42e03443a2439188146Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onPause()");
3655933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    if (!(~mStateFlags & (kFlagPrepared | kFlagPlaying)) && (mPlayer != 0)) {
36668d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi        mPlayer->pause();
36768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi    }
3685933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    GenericPlayer::onPause();
36937dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi}
37037dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi
371f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
372f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kastenvoid GenericMediaPlayer::onSeekComplete() {
373f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    SL_LOGV("GenericMediaPlayer::onSeekComplete()");
374f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    // did we initiate the seek?
375f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    if (!(mStateFlags & kFlagSeeking)) {
376f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, are we looping?
377f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        if (mStateFlags & kFlagLooping) {
378f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // yes, per OpenSL ES 1.0.1 and 1.1 do NOT report it to client
379f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            // notify(PLAYEREVENT_ENDOFSTREAM, 1, true /*async*/);
380f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        // no, well that's surprising, but it's probably just a benign race condition
381f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        } else {
382f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten            SL_LOGW("Unexpected seek complete event ignored");
383f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten        }
384f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    }
385f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten    GenericPlayer::onSeekComplete();
386f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten}
387f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
388f6445d330c05ccc57d1adcc6ee05735a33f78881Glenn Kasten
3897ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi/**
3907ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi * pre-condition: WHATPARAM_SEEK_SEEKTIME_MS parameter value >= 0
3917ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi */
3924ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onSeek(const sp<AMessage> &msg) {
3934ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onSeek");
3947ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    int64_t timeMsec = ANDROID_UNKNOWN_TIME;
3957ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    if (!msg->findInt64(WHATPARAM_SEEK_SEEKTIME_MS, &timeMsec)) {
3967ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        // invalid command, drop it
3977ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
3987ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    }
399a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten    if ((mStateFlags & kFlagSeeking) && (timeMsec == mSeekTimeMsec) &&
400a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            (timeMsec != ANDROID_UNKNOWN_TIME)) {
401a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten        // already seeking to the same non-unknown time, cancel this command
4027ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi        return;
40349935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten    } else if (mStateFlags & kFlagPreparedUnsuccessfully) {
40449935c51fddcd0caa0030e2aac0c3a7ba3339e3dGlenn Kasten        // discard seeks after unsuccessful prepare
4057ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi    } else if (!(mStateFlags & kFlagPrepared)) {
4064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // we are not ready to accept a seek command at this time, retry later
4074ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        msg->post(DEFAULT_COMMAND_DELAY_FOR_REPOST_US);
4084ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
409c0a40f3efef1706f861777ff68003fe344730055Glenn Kasten        if (mPlayer != 0) {
4107ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mStateFlags |= kFlagSeeking;
4117ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi            mSeekTimeMsec = (int32_t)timeMsec;
412a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            // seek to unknown time is used by StreamPlayer after discontinuity
413a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            if (timeMsec == ANDROID_UNKNOWN_TIME) {
414a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // FIXME simulate a MEDIA_SEEK_COMPLETE event in 250 ms;
415a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                // this is a terrible hack to make up for mediaserver not sending one
416a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten                (new AMessage(kWhatSeekComplete, id()))->post(250000);
417a9f22e6f5f53e90daa779e38b22f88e4faa35c95Glenn Kasten            } else if (OK != mPlayer->seekTo(timeMsec)) {
4187ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mStateFlags &= ~kFlagSeeking;
4197ef5526a7bd12eccfa777cc8bc167794634f405aJean-Michel Trivi                mSeekTimeMsec = ANDROID_UNKNOWN_TIME;
420e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten                // don't call updateOneShot because seek not yet done
4214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
4224ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
4244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
4254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onLoop(const sp<AMessage> &msg) {
4284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGV("GenericMediaPlayer::onLoop");
4294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t loop = 0;
4304ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_LOOP_LOOPING, &loop)) {
4319f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (loop) {
4329f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags |= kFlagLooping;
4339f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        } else {
4349f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            mStateFlags &= ~kFlagLooping;
4359f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        }
4369f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        // if we have a MediaPlayer then tell it now, otherwise we'll tell it after it's created
4379f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        if (mPlayer != 0) {
4389f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten            (void) mPlayer->setLooping(loop);
4394ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4404ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
4414ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
4424ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4434ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
44437dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivivoid GenericMediaPlayer::onVolumeUpdate() {
4454ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    SL_LOGD("GenericMediaPlayer::onVolumeUpdate()");
4464ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (mPlayer != 0) {
447e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        // use settings lock to read the volume settings
448e2e8fa36bd7448b59fbcdf141e0b6d21e5401d91Glenn Kasten        Mutex::Autolock _l(mSettingsLock);
449fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten        mPlayer->setVolume(mAndroidAudioLevels.mFinalVolume[0],
450fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten                mAndroidAudioLevels.mFinalVolume[1]);
45137dc2fccf3f122b79ebd554de209d0a3c94ae161Jean-Michel Trivi    }
4524ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
4534ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4544ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
4553610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onAttachAuxEffect(const sp<AMessage> &msg) {
4563610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onAttachAuxEffect()");
4573610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    int32_t effectId = 0;
4583610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findInt32(WHATPARAM_ATTACHAUXEFFECT, &effectId)) {
4593610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
4603610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
4613610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->attachAuxEffect(effectId);
4623610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // attachAuxEffect returns a status but we have no way to report it back to app
4633610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
4643610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
4653610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
4663610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
4673610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4683610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4693610785fa93586ce84a27a27530feb77b8035229Glenn Kastenvoid GenericMediaPlayer::onSetAuxEffectSendLevel(const sp<AMessage> &msg) {
4703610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    SL_LOGD("GenericMediaPlayer::onSetAuxEffectSendLevel()");
4713610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    float level = 0.0f;
4723610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    if (msg->findFloat(WHATPARAM_SETAUXEFFECTSENDLEVEL, &level)) {
4733610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        if (mPlayer != 0) {
4743610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status_t status;
4753610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            status = mPlayer->setAuxEffectSendLevel(level);
4763610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            // setAuxEffectSendLevel returns a status but we have no way to report it back to app
4773610785fa93586ce84a27a27530feb77b8035229Glenn Kasten            (void) status;
4783610785fa93586ce84a27a27530feb77b8035229Glenn Kasten        }
4793610785fa93586ce84a27a27530feb77b8035229Glenn Kasten    }
4803610785fa93586ce84a27a27530feb77b8035229Glenn Kasten}
4813610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4823610785fa93586ce84a27a27530feb77b8035229Glenn Kasten
4834ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivivoid GenericMediaPlayer::onBufferingUpdate(const sp<AMessage> &msg) {
4844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    int32_t fillLevel = 0;
4854ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (msg->findInt32(WHATPARAM_BUFFERING_UPDATE, &fillLevel)) {
4864ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("GenericMediaPlayer::onBufferingUpdate(fillLevel=%d)", fillLevel);
48768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
4884ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        Mutex::Autolock _l(mSettingsLock);
4894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        mCacheFill = fillLevel;
4904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle cache fill update
4914ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (mCacheFill - mLastNotifiedCacheFill >= mCacheFillNotifThreshold) {
4924ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
4934ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
4944ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        // handle prefetch status update
4954ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        //   compute how much time ahead of position is buffered
4964ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int durationMsec, positionMsec = -1;
4974ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if ((mStateFlags & kFlagPrepared) && (mPlayer != 0)
4984ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                && (OK == mPlayer->getDuration(&durationMsec))
4994ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                        && (OK == mPlayer->getCurrentPosition(&positionMsec))) {
5004ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            if ((-1 != durationMsec) && (-1 != positionMsec)) {
5014ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                // evaluate prefetch status based on buffer time thresholds
5024ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                int64_t bufferedDurationMsec = (durationMsec * fillLevel / 100) - positionMsec;
5034ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                CacheStatus_t newCacheStatus = mCacheStatus;
5044ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (bufferedDurationMsec > DURATION_CACHED_HIGH_MS) {
5054ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusHigh;
5064ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_MED_MS) {
5074ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEnough;
5084ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec > DURATION_CACHED_LOW_MS) {
5094ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusIntermediate;
5104ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else if (bufferedDurationMsec == 0) {
5114ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusEmpty;
5124ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                } else {
5134ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    newCacheStatus = kStatusLow;
5144ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
5154ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
5164ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                if (newCacheStatus != mCacheStatus) {
5174ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    mCacheStatus = newCacheStatus;
5184ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                    notifyStatus();
5194ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                }
5204ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            }
5214ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
522b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten    } else {
523b2549c73290f1955f3a7731bf98446a45f295dfaGlenn Kasten        SL_LOGV("GenericMediaPlayer::onBufferingUpdate(fillLevel=unknown)");
5244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi}
5264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
5274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi
5284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi//--------------------------------------------------
5294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi/**
53006059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten * called from GenericMediaPlayer::onPrepare after the MediaPlayer mPlayer is prepared successfully
531fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten * pre-conditions:
532fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten *  mPlayer != 0
53306059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten *  mPlayer is prepared successfully
5344ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi */
53506059e5ee1eaf907589c7f8d1320253f92211348Glenn Kastenvoid GenericMediaPlayer::afterMediaPlayerPreparedSuccessfully() {
53606059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    SL_LOGV("GenericMediaPlayer::afterMediaPlayerPrepared()");
537fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    assert(mPlayer != 0);
53806059e5ee1eaf907589c7f8d1320253f92211348Glenn Kasten    assert(mStateFlags & kFlagPrepared);
5395933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    // Mark this player as prepared successfully, so safe to directly call getCurrentPosition
5405933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    {
541a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        Mutex::Autolock _l(mPreparedPlayerLock);
542a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        assert(mPreparedPlayer == 0);
543a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten        mPreparedPlayer = mPlayer;
5445933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten    }
545fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve channel count
546b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten    int32_t channelCount;
547fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    Parcel *reply = new Parcel();
548fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    status_t status = mPlayer->getParameter(KEY_PARAMETER_AUDIO_CHANNEL_COUNT, reply);
549fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    if (status == NO_ERROR) {
550b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        channelCount = reply->readInt32();
55199b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
55299b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // FIXME MPEG-2 TS doesn't yet implement this key, so default to stereo
553b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        channelCount = 2;
55499b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    }
555b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten    if (UNKNOWN_NUMCHANNELS != channelCount) {
55699b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten        // now that we know the channel count, re-calculate the volumes
557b4393ef4ef3edb785746c37fd7b68950e85283aeGlenn Kasten        notify(PLAYEREVENT_CHANNEL_COUNT, channelCount, true /*async*/);
55899b927751677abfb60a388d65dfeed1fed1db12cGlenn Kasten    } else {
559a6c69c7e1665b38da8d6784e65210acbe501b92cSteve Block        ALOGW("channel count is still unknown after prepare");
560fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    }
561fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    delete reply;
562fa2bd93c3a9852a1f879663eeff598d13cf8fa81Glenn Kasten    // retrieve duration
5634ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    {
5644ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        int msec = 0;
5654ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        if (OK == mPlayer->getDuration(&msec)) {
5661fa5c3206d06bbebdea2dc92f378ce6b8a211e23Glenn Kasten            Mutex::Autolock _l(mSettingsLock);
5674ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mDurationMsec = msec;
5684ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
5694ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5709f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    // now that we have a MediaPlayer, set the looping flag
5719f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    if (mStateFlags & kFlagLooping) {
5729f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten        (void) mPlayer->setLooping(1);
5739f07ea788f57654acf29d1321b40162e41eb122bGlenn Kasten    }
5744ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // when the MediaPlayer mPlayer is prepared, there is "sufficient data" in the playback buffers
5754ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    // if the data source was local, and the buffers are considered full so we need to notify that
5764ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    bool isLocalSource = true;
5774ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (kDataLocatorUri == mDataLocatorType) {
578833251ab9e5e59a6ea5ac325122cf3abdf7cd944Glenn Kasten        isLocalSource = !isDistantProtocol(mDataLocator.uriRef);
5794ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
5804ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    if (isLocalSource) {
5814ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on local source");
5824ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        {
5834ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            Mutex::Autolock _l(mSettingsLock);
5844ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheStatus = kStatusHigh;
5854ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            mCacheFill = 1000;
5864ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyStatus();
5874ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi            notifyCacheFill();
5884ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        }
5894ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    } else {
5904ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi        SL_LOGD("media player prepared on non-local source");
5914ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi    }
59291145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    // when the MediaPlayer mPlayer is prepared, apply the playback rate
59391145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    Parcel rateParcel;
59491145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    if (rateParcel.writeInt32((int32_t)mPlaybackRatePermille) == OK) {
59591145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi        mPlayer->setParameter(KEY_PARAMETER_PLAYBACK_RATE_PERMILLE, rateParcel);
59691145ef159d3e165a461cbd76341ff8ed3d72baeJean-Michel Trivi    }
59768d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi}
59868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi
5995933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
6005933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten//--------------------------------------------------
6015933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten// If player is prepared successfully, set output parameter to that reference, otherwise NULL
602a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kastenvoid GenericMediaPlayer::getPreparedPlayer(sp<IMediaPlayer> &preparedPlayer)
6035933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten{
604a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    Mutex::Autolock _l(mPreparedPlayerLock);
605a0fa47f72f47fffb80ab2ae791739ce73de1e8f4Glenn Kasten    preparedPlayer = mPreparedPlayer;
6065933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten}
6075933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten
60868d56b8ebaf60184a3aef988e3d2b09ed8b88c05Jean-Michel Trivi} // namespace android
609