1afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber/*
2afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Copyright (C) 2012 The Android Open Source Project
3afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
4afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * you may not use this file except in compliance with the License.
6afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * You may obtain a copy of the License at
7afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
8afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
10afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Unless required by applicable law or agreed to in writing, software
11afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * See the License for the specific language governing permissions and
14afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * limitations under the License.
15afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber */
16afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
177e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang//#define LOG_NDEBUG 0
187e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang#define LOG_TAG "GenericSource"
197e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang
20afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h"
21afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
22afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "AnotherPacketSource.h"
23afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
24a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang#include <media/IMediaHTTPService.h>
25afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
26afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ADebug.h>
27afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/AMessage.h>
28afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/DataSource.h>
29afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/FileSource.h>
30afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaBuffer.h>
31afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaDefs.h>
32afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaExtractor.h>
33afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaSource.h>
34afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MetaData.h>
3517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih#include <media/stagefright/Utils.h>
36802768790c131f8237364906fd13981a6bb91193Ronghua Wu#include "../../libstagefright/include/DRMExtractor.h"
37d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang#include "../../libstagefright/include/NuCachedSource2.h"
38cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar#include "../../libstagefright/include/WVMExtractor.h"
39360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih#include "../../libstagefright/include/HTTPBase.h"
40afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
41afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubernamespace android {
42afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
43efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
44efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
4514532f2383c3849d0db59a607ed0bd802f57155cWei Jiastatic int64_t kHighWaterMarkRebufferUs = 15000000ll;  // 15secs
46efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kLowWaterMarkBytes = 40000;
47efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kHighWaterMarkBytes = 200000;
48efbb61950db36a5eb789be83f077246172507c67Chong Zhang
49afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::GenericSource(
50b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        const sp<AMessage> &notify,
51cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        bool uidValid,
52cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        uid_t uid)
53b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    : Source(notify),
545c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mAudioTimeUs(0),
555c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mAudioLastDequeueTimeUs(0),
565c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mVideoTimeUs(0),
575c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mVideoLastDequeueTimeUs(0),
583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      mFetchSubtitleDataGeneration(0),
59e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      mFetchTimedTextDataGeneration(0),
6002fc5e3f8af41052dcb961f85e34fe109d38a3bbMarco Nelissen      mDurationUs(-1ll),
61cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar      mAudioIsVorbis(false),
623de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang      mIsWidevine(false),
6342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang      mIsSecure(false),
64efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mIsStreaming(false),
65cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar      mUIDValid(uidValid),
66d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang      mUID(uid),
67a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang      mFd(-1),
68802768790c131f8237364906fd13981a6bb91193Ronghua Wu      mDrmManagerClient(NULL),
692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      mBitrate(-1ll),
7014532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mPendingReadBufferTypes(0) {
7114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor = new BufferingMonitor(notify);
72a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
73afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    DataSource::RegisterDefaultSniffers();
743de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang}
753de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
76a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangvoid NuPlayer::GenericSource::resetDataSource() {
77a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mHTTPService.clear();
78360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih    mHttpSource.clear();
79a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUri.clear();
80a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUriHeaders.clear();
81a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    if (mFd >= 0) {
82a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang        close(mFd);
83a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang        mFd = -1;
84a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    }
85a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mOffset = 0;
86a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mLength = 0;
87802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
88802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mDecryptHandle = NULL;
89802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mDrmManagerClient = NULL;
90802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
912abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    mStopRead = true;
9214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
9314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mBufferingMonitorLooper != NULL) {
9414532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitorLooper->unregisterHandler(mBufferingMonitor->id());
9514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitorLooper->stop();
9614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitorLooper = NULL;
9714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
9814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor->stop();
99a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang}
100a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
101a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource(
1023de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const sp<IMediaHTTPService> &httpService,
1033de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const char *url,
1043de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const KeyedVector<String8, String8> *headers) {
105a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
106afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
107a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mHTTPService = httpService;
108a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUri = url;
109afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
110a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    if (headers) {
111a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        mUriHeaders = *headers;
1123de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
113afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
114a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delay data source creation to prepareAsync() to avoid blocking
115a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // the calling thread in setDataSource for any significant time.
116a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    return OK;
1173de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang}
118afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
119a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource(
1203de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        int fd, int64_t offset, int64_t length) {
121a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
122a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
123a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mFd = dup(fd);
124a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mOffset = offset;
125a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mLength = length;
126afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
127a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delay data source creation to prepareAsync() to avoid blocking
128a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // the calling thread in setDataSource for any significant time.
129a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    return OK;
130afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
131afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
13299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkinsstatus_t NuPlayer::GenericSource::setDataSource(const sp<DataSource>& source) {
13399f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    resetDataSource();
13499f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    mDataSource = source;
13599f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    return OK;
13699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins}
13799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins
138f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissensp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
139f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    return mFileMeta;
140f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen}
141f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen
142d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangstatus_t NuPlayer::GenericSource::initFromDataSource() {
143b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<IMediaExtractor> extractor;
144fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    String8 mimeType;
145fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    float confidence;
146fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    sp<AMessage> dummy;
147fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    bool isWidevineStreaming = false;
148cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
149d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    CHECK(mDataSource != NULL);
150d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
151cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    if (mIsWidevine) {
152fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        isWidevineStreaming = SniffWVM(
153fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang                mDataSource, &mimeType, &confidence, &dummy);
154fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        if (!isWidevineStreaming ||
155fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang                strcasecmp(
156cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
157cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            ALOGE("unsupported widevine mime: %s", mimeType.string());
1583de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            return UNKNOWN_ERROR;
159cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        }
160fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    } else if (mIsStreaming) {
161c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang        if (!mDataSource->sniff(&mimeType, &confidence, &dummy)) {
162c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang            return UNKNOWN_ERROR;
163fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        }
164fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        isWidevineStreaming = !strcasecmp(
165c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang                mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM);
166fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    }
167cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
168fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang    if (isWidevineStreaming) {
169fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        // we don't want cached source for widevine streaming.
170fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        mCachedSource.clear();
171fc6cfd8343ae8919e85ec22efed9df626fe8854bChong Zhang        mDataSource = mHttpSource;
1722a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        mWVMExtractor = new WVMExtractor(mDataSource);
1732a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        mWVMExtractor->setAdaptiveStreamingMode(true);
174cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        if (mUIDValid) {
1752a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            mWVMExtractor->setUID(mUID);
176cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        }
1772a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        extractor = mWVMExtractor;
178cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    } else {
179d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        extractor = MediaExtractor::Create(mDataSource,
180c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang                mimeType.isEmpty() ? NULL : mimeType.string());
181cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
182afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1833de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    if (extractor == NULL) {
1843de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        return UNKNOWN_ERROR;
1853de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
186afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
187802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (extractor->getDrmFlag()) {
188802768790c131f8237364906fd13981a6bb91193Ronghua Wu        checkDrmStatus(mDataSource);
189802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
190802768790c131f8237364906fd13981a6bb91193Ronghua Wu
191f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    mFileMeta = extractor->getMetaData();
192f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    if (mFileMeta != NULL) {
193c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        int64_t duration;
194f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
195c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mDurationUs = duration;
196c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
19742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang
19842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        if (!mIsWidevine) {
19942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // Check mime to see if we actually have a widevine source.
20042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // If the data source is not URL-type (eg. file source), we
20142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // won't be able to tell until now.
20242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            const char *fileMime;
20342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            if (mFileMeta->findCString(kKeyMIMEType, &fileMime)
20442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    && !strncasecmp(fileMime, "video/wvm", 9)) {
20542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                mIsWidevine = true;
20642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            }
20742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        }
208c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    }
209c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
2102a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    int32_t totalBitrate = 0;
2112a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
212705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    size_t numtracks = extractor->countTracks();
213705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    if (numtracks == 0) {
214705d3290102875409e334e2a80e64221714aa37cMarco Nelissen        return UNKNOWN_ERROR;
215705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    }
216705d3290102875409e334e2a80e64221714aa37cMarco Nelissen
217705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    for (size_t i = 0; i < numtracks; ++i) {
218b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        sp<IMediaSource> track = extractor->getTrack(i);
2190386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        if (track == NULL) {
2200386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia            continue;
2210386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        }
222afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang
223afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
224c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen        if (meta == NULL) {
225c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen            ALOGE("no metadata for track %zu", i);
226c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen            return UNKNOWN_ERROR;
227c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen        }
228afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
229afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const char *mime;
230afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
231afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
232afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // Do the string compare immediately with "mime",
233afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // we can't assume "mime" would stay valid after another
234afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // extractor operation, some extractors might modify meta
235afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // during getTrack() and make it invalid.
236afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (!strncasecmp(mime, "audio/", 6)) {
237afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mAudioTrack.mSource == NULL) {
238dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mAudioTrack.mIndex = i;
239dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mAudioTrack.mSource = track;
240af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                mAudioTrack.mPackets =
241af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                    new AnotherPacketSource(mAudioTrack.mSource->getFormat());
242afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
243afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
244afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = true;
245afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                } else {
246afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = false;
247afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
248afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
249afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (!strncasecmp(mime, "video/", 6)) {
250afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mVideoTrack.mSource == NULL) {
251dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mVideoTrack.mIndex = i;
252dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mVideoTrack.mSource = track;
253af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                mVideoTrack.mPackets =
254af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                    new AnotherPacketSource(mVideoTrack.mSource->getFormat());
2557e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang
2567e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                // check if the source requires secure buffers
2577e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                int32_t secure;
258a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
259a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang                        && secure) {
26042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    mIsSecure = true;
2613de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    if (mUIDValid) {
2623de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        extractor->setUID(mUID);
2633de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    }
2647e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                }
265afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
266afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
267afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
2680386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        mSources.push(track);
2690386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        int64_t durationUs;
2700386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        if (meta->findInt64(kKeyDuration, &durationUs)) {
2710386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia            if (durationUs > mDurationUs) {
2720386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia                mDurationUs = durationUs;
273afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
2740386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        }
2752a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
2760386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        int32_t bitrate;
2770386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
2780386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia            totalBitrate += bitrate;
2790386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        } else {
2800386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia            totalBitrate = -1;
281afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
282afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
2833de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
2840386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    if (mSources.size() == 0) {
2850386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        ALOGE("b/23705695");
2860386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        return UNKNOWN_ERROR;
2870386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    }
2880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia
289fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    mBitrate = totalBitrate;
290fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
291fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    return OK;
292fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar}
293fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
294fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarstatus_t NuPlayer::GenericSource::startSources() {
295efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Start the selected A/V tracks now before we start buffering.
296efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Widevine sources might re-initialize crypto when starting, if we delay
297efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // this to start(), all data buffered during prepare would be wasted.
298efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // (We don't actually start reading until start().)
299efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) {
300efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start audio track!");
301efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
302efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
303efbb61950db36a5eb789be83f077246172507c67Chong Zhang
304efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) {
305efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start video track!");
306efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
307efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
308efbb61950db36a5eb789be83f077246172507c67Chong Zhang
3093de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    return OK;
310afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
311afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
312802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
313802768790c131f8237364906fd13981a6bb91193Ronghua Wu    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
314802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
315802768790c131f8237364906fd13981a6bb91193Ronghua Wu        CHECK(mDrmManagerClient);
316802768790c131f8237364906fd13981a6bb91193Ronghua Wu        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
317802768790c131f8237364906fd13981a6bb91193Ronghua Wu            sp<AMessage> msg = dupNotify();
318802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->setInt32("what", kWhatDrmNoLicense);
319802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->post();
320802768790c131f8237364906fd13981a6bb91193Ronghua Wu        }
321802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
322802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
323802768790c131f8237364906fd13981a6bb91193Ronghua Wu
324802768790c131f8237364906fd13981a6bb91193Ronghua Wuint64_t NuPlayer::GenericSource::getLastReadPosition() {
325802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mAudioTrack.mSource != NULL) {
326802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mAudioTimeUs;
327802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else if (mVideoTrack.mSource != NULL) {
328802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mVideoTimeUs;
329802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else {
330802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return 0;
331802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
332802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
333802768790c131f8237364906fd13981a6bb91193Ronghua Wu
334a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setBuffers(
335a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        bool audio, Vector<MediaBuffer *> &buffers) {
3360386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    if (mIsSecure && !audio && mVideoTrack.mSource != NULL) {
337cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        return mVideoTrack.mSource->setBuffers(buffers);
338cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
339cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    return INVALID_OPERATION;
340cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar}
341cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
34202cb98d726b97d8e6dbb9c6c60d32a3cedc7f82dRonghua Wubool NuPlayer::GenericSource::isStreaming() const {
34302cb98d726b97d8e6dbb9c6c60d32a3cedc7f82dRonghua Wu    return mIsStreaming;
34402cb98d726b97d8e6dbb9c6c60d32a3cedc7f82dRonghua Wu}
34502cb98d726b97d8e6dbb9c6c60d32a3cedc7f82dRonghua Wu
34614532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::setOffloadAudio(bool offload) {
34714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor->setOffloadAudio(offload);
34814532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
34914532f2383c3849d0db59a607ed0bd802f57155cWei Jia
350afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::~GenericSource() {
3511228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper != NULL) {
3521228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
3531228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->stop();
3541228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
355a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    resetDataSource();
356afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
357afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
3589575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::GenericSource::prepareAsync() {
3591228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper == NULL) {
3601228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper = new ALooper;
3611228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->setName("generic");
3621228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->start();
3631228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3641228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
3651228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
3661228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
3681228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    msg->post();
3691228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang}
3701228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3711228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhangvoid NuPlayer::GenericSource::onPrepareAsync() {
372a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delayed data source creation
373d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mDataSource == NULL) {
37442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // set to false first, if the extractor
37542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // comes back as secure, set it to true then.
37642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        mIsSecure = false;
37742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang
378d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (!mUri.empty()) {
379360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            const char* uri = mUri.c_str();
380c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang            String8 contentType;
381360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
382360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih
383360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            if (!strncasecmp("http://", uri, 7)
384360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || !strncasecmp("https://", uri, 8)
385360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || mIsWidevine) {
386360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
387360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                if (mHttpSource == NULL) {
388360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    ALOGE("Failed to create http source!");
389360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
390360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    return;
391360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                }
392360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            }
393d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
394d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = DataSource::CreateFromURI(
395c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang                   mHTTPService, uri, &mUriHeaders, &contentType,
396360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                   static_cast<HTTPBase *>(mHttpSource.get()));
397d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        } else {
398d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mIsWidevine = false;
399d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
400d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = new FileSource(mFd, mOffset, mLength);
401a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang            mFd = -1;
402d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
403a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
404d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mDataSource == NULL) {
405d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("Failed to create data source!");
406d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            notifyPreparedAndCleanup(UNKNOWN_ERROR);
407d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return;
408d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
40999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    }
410a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
41199f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
41299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins        mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
413a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
414a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
41599f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // For widevine or other cached streaming cases, we need to wait for
41699f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // enough buffering before reporting prepared.
41799f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // Note that even when URL doesn't start with widevine://, mIsWidevine
41899f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // could still be set to true later, if the streaming or file source
41999f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // is sniffed to be widevine. We don't want to buffer for file source
42099f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    // in that case, so must check the flag now.
42199f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins    mIsStreaming = (mIsWidevine || mCachedSource != NULL);
42299f31604136d66ae10e20669fb6b5716f342bde0Chris Watkins
423c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang    // init extractor from data source
424c287cad65bd0c7a79e43f4decc5e04593027a7c8Chong Zhang    status_t err = initFromDataSource();
425a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
426a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    if (err != OK) {
427a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        ALOGE("Failed to init from data source!");
428d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        notifyPreparedAndCleanup(err);
429a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        return;
430a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
431a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
4329575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    if (mVideoTrack.mSource != NULL) {
43317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
43417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<AMessage> msg = new AMessage;
43517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        err = convertMetaDataToMessage(meta, &msg);
43617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        if(err != OK) {
43717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            notifyPreparedAndCleanup(err);
43817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            return;
43917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        }
44017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        notifyVideoSizeChanged(msg);
4419575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
4429575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
4439575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notifyFlagsChanged(
44442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            (mIsSecure ? FLAG_SECURE : 0)
4451713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
446cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            | FLAG_CAN_PAUSE
4479575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_BACKWARD
4489575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_FORWARD
4499575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK);
4509575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
451fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    if (mIsSecure) {
452fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        // secure decoders must be instantiated before starting widevine source
453fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, this);
454fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        notifyInstantiateSecureDecoders(reply);
455fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    } else {
456fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        finishPrepareAsync();
457fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    }
458fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar}
459fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
460fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarvoid NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) {
461fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    if (err != OK) {
462fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        ALOGE("Failed to instantiate secure decoders!");
463fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        notifyPreparedAndCleanup(err);
464fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        return;
465fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    }
466fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    finishPrepareAsync();
467fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar}
468fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
469fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnarvoid NuPlayer::GenericSource::finishPrepareAsync() {
470fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    status_t err = startSources();
471fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    if (err != OK) {
472fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        ALOGE("Failed to init start data source!");
473fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        notifyPreparedAndCleanup(err);
474fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        return;
475fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar    }
476fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
477efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mIsStreaming) {
47814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (mBufferingMonitorLooper == NULL) {
47914532f2383c3849d0db59a607ed0bd802f57155cWei Jia            mBufferingMonitor->prepare(mCachedSource, mWVMExtractor, mDurationUs, mBitrate,
48014532f2383c3849d0db59a607ed0bd802f57155cWei Jia                    mIsStreaming);
48114532f2383c3849d0db59a607ed0bd802f57155cWei Jia
48214532f2383c3849d0db59a607ed0bd802f57155cWei Jia            mBufferingMonitorLooper = new ALooper;
48314532f2383c3849d0db59a607ed0bd802f57155cWei Jia            mBufferingMonitorLooper->setName("GSBMonitor");
48414532f2383c3849d0db59a607ed0bd802f57155cWei Jia            mBufferingMonitorLooper->start();
48514532f2383c3849d0db59a607ed0bd802f57155cWei Jia            mBufferingMonitorLooper->registerHandler(mBufferingMonitor);
48614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
487efbb61950db36a5eb789be83f077246172507c67Chong Zhang
48814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitor->ensureCacheIsFetching();
48914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitor->restartPollBuffering();
490efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else {
491efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notifyPrepared();
492efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
4939575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
4949575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
495d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangvoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
496d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (err != OK) {
497ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        {
498ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            sp<DataSource> dataSource = mDataSource;
499ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            sp<NuCachedSource2> cachedSource = mCachedSource;
500ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            sp<DataSource> httpSource = mHttpSource;
501ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            {
502ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih                Mutex::Autolock _l(mDisconnectLock);
503ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih                mDataSource.clear();
504cdc9cf656a8e43875234cb021fffeb4792d7c74eWei Jia                mDecryptHandle = NULL;
505b41fd0d4929f0a89811bafcc4fd944b128f00ce2Wei Jia                mDrmManagerClient = NULL;
506ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih                mCachedSource.clear();
507ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih                mHttpSource.clear();
508ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            }
509ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        }
510fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar        mBitrate = -1;
5112a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
51214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitor->cancelPollBuffering();
513d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
514d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    notifyPrepared(err);
515d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang}
516d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
517afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::start() {
518afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    ALOGI("start");
519afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
5202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    mStopRead = false;
521afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
52217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
523afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
524afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
525afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
52617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
527afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
528802768790c131f8237364906fd13981a6bb91193Ronghua Wu
529802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
530802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
531efbb61950db36a5eb789be83f077246172507c67Chong Zhang
5321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
533802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
534802768790c131f8237364906fd13981a6bb91193Ronghua Wu
535802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::stop() {
536802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
537802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
538802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
53942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine || mIsSecure) {
54042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // For widevine or secure sources we need to prevent any further reads.
5411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatStopWidevine, this);
5422abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        sp<AMessage> response;
5432abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        (void) msg->postAndAwaitResponse(&response);
5442abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
545802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
546802768790c131f8237364906fd13981a6bb91193Ronghua Wu
547802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::pause() {
548802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
549802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
550802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
551802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
552802768790c131f8237364906fd13981a6bb91193Ronghua Wu
553802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::resume() {
554802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
555802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
556802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
557efbb61950db36a5eb789be83f077246172507c67Chong Zhang
5581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
559802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
560802768790c131f8237364906fd13981a6bb91193Ronghua Wu
56148296b792a8d68358de74141fa80bd5bd84d0307Chong Zhangvoid NuPlayer::GenericSource::disconnect() {
562ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih    sp<DataSource> dataSource, httpSource;
563ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih    {
564ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        Mutex::Autolock _l(mDisconnectLock);
565ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        dataSource = mDataSource;
566ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        httpSource = mHttpSource;
567ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih    }
568ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih
569ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih    if (dataSource != NULL) {
57048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // disconnect data source
571ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        if (dataSource->flags() & DataSource::kIsCachingDataSource) {
572ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih            static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
57348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        }
574ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih    } else if (httpSource != NULL) {
575ebc2712d5e8a66f8d6652e7cc7fb14cdbec7f235Robert Shih        static_cast<HTTPBase *>(httpSource.get())->disconnect();
57648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    }
57748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang}
57848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang
579802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
580802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
581802768790c131f8237364906fd13981a6bb91193Ronghua Wu        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
582802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
58317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
58417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
585afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
586afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
587afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() {
588afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
589afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
590afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
5913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihvoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
5923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (msg->what()) {
5931228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      case kWhatPrepareAsync:
5941228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      {
5951228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          onPrepareAsync();
5961228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          break;
5971228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      }
5983423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatFetchSubtitleData:
5993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
600e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
601e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
602e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
603e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
6043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
605e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatFetchTimedTextData:
606e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
607e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
608e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
6093423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
6103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
6113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatSendSubtitleData:
6133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
614e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
615e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
616e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
617e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
6183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
61955e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen      case kWhatSendGlobalTimedTextData:
62055e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen      {
62155e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen          sendGlobalTextData(kWhatTimedTextData, mFetchTimedTextDataGeneration, msg);
62255e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen          break;
62355e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen      }
624e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatSendTimedTextData:
625e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
626e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
627e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
6283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
6293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
6303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatChangeAVSource:
6323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
6333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int32_t trackIndex;
6343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          CHECK(msg->findInt32("trackIndex", &trackIndex));
635b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen          const sp<IMediaSource> source = mSources.itemAt(trackIndex);
6363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Track* track;
6383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const char *mime;
6393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          media_track_type trackType, counterpartType;
6403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          sp<MetaData> meta = source->getFormat();
6413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          meta->findCString(kKeyMIMEType, &mime);
6423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (!strncasecmp(mime, "audio/", 6)) {
6433423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mAudioTrack;
6443423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_AUDIO;
6453423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
6463423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          } else {
6473423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              CHECK(!strncasecmp(mime, "video/", 6));
6483423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mVideoTrack;
6493423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_VIDEO;
6503423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
6513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
6523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (track->mSource != NULL) {
6553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track->mSource->stop();
6563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
6573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource = source;
6583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource->start();
6593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mIndex = trackIndex;
6603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int64_t timeUs, actualTimeUs;
6623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const bool formatChange = true;
6635c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
6645c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mAudioLastDequeueTimeUs;
6655c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          } else {
6665c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mVideoLastDequeueTimeUs;
6675c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          }
6683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
6693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(counterpartType, -1, NULL, formatChange);
6706d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar          ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
6713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
6723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
6733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
674efbb61950db36a5eb789be83f077246172507c67Chong Zhang
675efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatStart:
676efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatResume:
677efbb61950db36a5eb789be83f077246172507c67Chong Zhang      {
67814532f2383c3849d0db59a607ed0bd802f57155cWei Jia          mBufferingMonitor->restartPollBuffering();
6792a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          break;
6802a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      }
68117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
68217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetFormat:
68317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
68417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetFormatMeta(msg);
68517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
68617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
68717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
68817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetSelectedTrack:
68917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
69017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetSelectedTrack(msg);
69117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
69217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
69317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
69417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSelectTrack:
69517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
69617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSelectTrack(msg);
69717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
69817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
69917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
70017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSeek:
70117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
70217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSeek(msg);
70317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
70417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
70517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
70617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatReadBuffer:
70717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
70817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onReadBuffer(msg);
70917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
71017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
71117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
712fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar      case kWhatSecureDecodersInstantiated:
713fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar      {
714fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar          int32_t err;
715fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar          CHECK(msg->findInt32("err", &err));
716fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar          onSecureDecodersInstantiated(err);
717fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar          break;
718fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar      }
719fcd3e94c075e964670d946f6ec5d82d059bf9e09Lajos Molnar
7202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      case kWhatStopWidevine:
7212abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      {
7222abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // mStopRead is only used for Widevine to prevent the video source
7232abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // from being read while the associated video decoder is shutting down.
7242abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          mStopRead = true;
7252abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          if (mVideoTrack.mSource != NULL) {
7262abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung              mVideoTrack.mPackets->clear();
7272abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          }
7282abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          sp<AMessage> response = new AMessage;
7293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar          sp<AReplyToken> replyID;
7302abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          CHECK(msg->senderAwaitsResponse(&replyID));
7312abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          response->postReply(replyID);
7322abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          break;
7332abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      }
7343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      default:
7353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Source::onMessageReceived(msg);
7363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
7373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
7383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
7393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
740e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::fetchTextData(
741e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t sendWhat,
742e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
743e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
744e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
745e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
746e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
747e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
748e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
749e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
750e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
751e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
752e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
753e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t avail;
754e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->hasBufferAvailable(&avail)) {
755e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
756e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
757e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
758e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t timeUs;
759e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt64("timeUs", &timeUs));
760e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
761e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
762e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, timeUs, &subTimeUs);
763e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
764e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t delayUs = subTimeUs - timeUs;
765e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msg->what() == kWhatFetchSubtitleData) {
766e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t oneSecUs = 1000000ll;
767e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        delayUs -= oneSecUs;
768e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
7691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg2 = new AMessage(sendWhat, this);
770e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->setInt32("generation", msgGeneration);
771e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->post(delayUs < 0 ? 0 : delayUs);
772e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
773e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
774e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::sendTextData(
775e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t what,
776e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
777e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
778e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
779e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
780e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
781e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
782e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
783e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
784e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
785e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
786e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
787e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
788e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->nextBufferTime(&subTimeUs) != OK) {
789e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
790e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
791e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
792e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t nextSubTimeUs;
793e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, -1, &nextSubTimeUs);
794e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
795e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<ABuffer> buffer;
796e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
797e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (dequeueStatus == OK) {
798e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> notify = dupNotify();
799e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setInt32("what", what);
800e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setBuffer("buffer", buffer);
801e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->post();
802e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
803e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t delayUs = nextSubTimeUs - subTimeUs;
804e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post(delayUs < 0 ? 0 : delayUs);
805e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
806e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
807e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
80855e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissenvoid NuPlayer::GenericSource::sendGlobalTextData(
80955e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        uint32_t what,
81055e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        int32_t curGen,
81155e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        sp<AMessage> msg) {
81255e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    int32_t msgGeneration;
81355e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    CHECK(msg->findInt32("generation", &msgGeneration));
81455e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    if (msgGeneration != curGen) {
81555e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        // stale
81655e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        return;
81755e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    }
81855e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen
81955e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    uint32_t textType;
82055e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    const void *data;
82155e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    size_t size = 0;
82255e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    if (mTimedTextTrack.mSource->getFormat()->findData(
82355e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen                    kKeyTextFormatData, &textType, &data, &size)) {
82455e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        mGlobalTimedText = new ABuffer(size);
82555e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        if (mGlobalTimedText->data()) {
82655e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            memcpy(mGlobalTimedText->data(), data, size);
82755e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            sp<AMessage> globalMeta = mGlobalTimedText->meta();
82855e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            globalMeta->setInt64("timeUs", 0);
82955e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            globalMeta->setString("mime", MEDIA_MIMETYPE_TEXT_3GPP);
83055e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            globalMeta->setInt32("global", 1);
83155e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            sp<AMessage> notify = dupNotify();
83255e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            notify->setInt32("what", what);
83355e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            notify->setBuffer("buffer", mGlobalTimedText);
83455e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen            notify->post();
83555e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        }
83655e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen    }
83755e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen}
83855e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen
839840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
8401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetFormat, this);
84117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("audio", audio);
84217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
84317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
84410a121b2a3ea3334e1e3a2722b2a03833fb9a897Marco Nelissen    sp<RefBase> format;
84517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
84617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
84710a121b2a3ea3334e1e3a2722b2a03833fb9a897Marco Nelissen        CHECK(response->findObject("format", &format));
84810a121b2a3ea3334e1e3a2722b2a03833fb9a897Marco Nelissen        return static_cast<MetaData*>(format.get());
84917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
85017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return NULL;
85117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
85217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
85317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
85417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
85517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t audio;
85617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("audio", &audio));
85717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
85817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
85917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<MetaData> format = doGetFormatMeta(audio);
86010a121b2a3ea3334e1e3a2722b2a03833fb9a897Marco Nelissen    response->setObject("format", format);
86117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
8623f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    sp<AReplyToken> replyID;
86317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
86417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
86517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
86617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
86717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihsp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
868b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<IMediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
869afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
870afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (source == NULL) {
871afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return NULL;
872afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
873afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
874afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return source->getFormat();
875afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
876afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
877afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
878afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
879ff486640ca9794a4c328bb1b7ccf4ab5d36d1331Wei Jia    if (audio && !mStarted) {
88014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return -EWOULDBLOCK;
88114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
88214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
883afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
884afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
885afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (track->mSource == NULL) {
886afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return -EWOULDBLOCK;
887afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
888afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
889cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    if (mIsWidevine && !audio) {
890cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        // try to read a buffer as we may not have been able to the last time
89117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
892cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
893cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
894afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t finalResult;
895afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
89642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        if (finalResult == OK) {
89742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            postReadBuffer(
89842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
89942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            return -EWOULDBLOCK;
90042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        }
90142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        return finalResult;
902afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
903afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
904afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
905afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
906fcf044a9c5624395d24eb6181e67163ce169458bChong Zhang    // start pulling in more buffers if we only have one (or no) buffer left
907fcf044a9c5624395d24eb6181e67163ce169458bChong Zhang    // so that decoder has less chance of being starved
908fcf044a9c5624395d24eb6181e67163ce169458bChong Zhang    if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
90917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
910e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
911e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
9123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (result != OK) {
913e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL) {
914e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mSubtitleTrack.mPackets->clear();
915e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
916e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
917e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mTimedTextTrack.mSource != NULL) {
918e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mTimedTextTrack.mPackets->clear();
919e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
920e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
9213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return result;
9223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
9233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
9243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
9253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    status_t eosResult; // ignored
9263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
9275c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    if (audio) {
9285c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = timeUs;
92914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBufferingMonitor->updateDequeuedBufferTime(timeUs);
9305c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    } else {
9315c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = timeUs;
9325c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    }
933e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
934e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mSubtitleTrack.mSource != NULL
935e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
9361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
9373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt64("timeUs", timeUs);
9383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("generation", mFetchSubtitleDataGeneration);
9393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
9403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
941eb1735e343a93830df259ae8882160bb0d79dcb5Robert Shih
942e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mTimedTextTrack.mSource != NULL
943e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
9441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
945e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt64("timeUs", timeUs);
946e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt32("generation", mFetchTimedTextDataGeneration);
947e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post();
948e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
949e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
950afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return result;
951afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
952afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
953afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
954afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    *durationUs = mDurationUs;
955afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
956afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
957afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
958dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsize_t NuPlayer::GenericSource::getTrackCount() const {
959dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return mSources.size();
960dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
961dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
962dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
963dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    size_t trackCount = mSources.size();
964dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackIndex >= trackCount) {
965dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        return NULL;
966dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
967dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
968dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<AMessage> format = new AMessage();
969dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
970c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen    if (meta == NULL) {
971c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen        ALOGE("no metadata for track %zu", trackIndex);
972c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen        return NULL;
973c367ca1762278277fb7a7d1156ce6e193ab524a3Marco Nelissen    }
974dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
975dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *mime;
976dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
977755106eb9cff51dc4eda45d8cefc4306df308845Robert Shih    format->setString("mime", mime);
978dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
979dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    int32_t trackType;
980dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!strncasecmp(mime, "video/", 6)) {
981dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_VIDEO;
982dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strncasecmp(mime, "audio/", 6)) {
983dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_AUDIO;
984dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
985dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
986dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else {
987dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
988dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
989dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setInt32("type", trackType);
990dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
991dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *lang;
992dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
993dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        lang = "und";
994dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
995dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setString("language", lang);
996dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
997dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
998dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
999dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
1000dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsDefault, &isDefault);
1001dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsForced, &isForced);
1002dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1003dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("auto", !!isAutoselect);
1004dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("default", !!isDefault);
1005dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("forced", !!isForced);
1006dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1007dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1008dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return format;
1009dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
1010dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1011e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
10121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
101317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("type", type);
101417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
101517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
101617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t index;
101717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
101817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
101917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("index", &index));
102017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return index;
102117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
102217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return -1;
102317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
102417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
102517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
102617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
102717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
102817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("type", &tmpType));
102917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type type = (media_track_type)tmpType;
103017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
103117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
103217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    ssize_t index = doGetSelectedTrack(type);
103317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("index", index);
103417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
10353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    sp<AReplyToken> replyID;
103617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
103717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
103817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
103917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
104017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
1041e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    const Track *track = NULL;
1042e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    switch (type) {
1043e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_VIDEO:
1044e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mVideoTrack;
1045e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1046e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_AUDIO:
1047e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mAudioTrack;
1048e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1049e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_TIMEDTEXT:
1050e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mTimedTextTrack;
1051e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1052e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_SUBTITLE:
1053e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mSubtitleTrack;
1054e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1055e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    default:
1056e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1057e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1058e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1059e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (track != NULL && track->mSource != NULL) {
1060e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return track->mIndex;
1061e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1062e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1063e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    return -1;
1064e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
1065e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
10666ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1067e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
10681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
106917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("trackIndex", trackIndex);
1070da23ab9b0dfa780175651daf057a02b0aa106dc8Robert Shih    msg->setInt32("select", select);
10716ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    msg->setInt64("timeUs", timeUs);
107217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
107317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
107417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
107517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
107617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
107717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
107817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
107917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
108017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
108117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
108217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
108317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t trackIndex, select;
10846ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    int64_t timeUs;
108517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackIndex", &trackIndex));
108617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("select", &select));
10876ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    CHECK(msg->findInt64("timeUs", &timeUs));
108817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
108917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
10906ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    status_t err = doSelectTrack(trackIndex, select, timeUs);
109117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
109217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
10933f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    sp<AReplyToken> replyID;
109417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
109517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
109617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
109717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
10986ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) {
10993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackIndex >= mSources.size()) {
11003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return BAD_INDEX;
11013423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
11023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
11033423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!select) {
1104e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track* track = NULL;
1105e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
1106e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mSubtitleTrack;
1107e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1108e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
1109e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1110e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1111e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1112e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track == NULL) {
11133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return INVALID_OPERATION;
11143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1115e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->stop();
1116e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = NULL;
1117e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mPackets->clear();
11183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
11193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
11203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    const sp<IMediaSource> source = mSources.itemAt(trackIndex);
11223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<MetaData> meta = source->getFormat();
11233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    const char *mime;
11243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
11253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!strncasecmp(mime, "text/", 5)) {
1126e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
1127e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
1128e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL && track->mIndex == trackIndex) {
11293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
11303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1131e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mIndex = trackIndex;
1132e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL) {
1133e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mSource->stop();
11343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1135e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = mSources.itemAt(trackIndex);
1136e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->start();
1137e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mPackets == NULL) {
1138e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
11393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        } else {
1140e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->clear();
1141e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->setFormat(track->mSource->getFormat());
11423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
11433423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1144e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1145e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (isSubtitle) {
1146e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1147e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else {
1148e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1149e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1150e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
11516ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        status_t eosResult; // ignored
11526ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mSubtitleTrack.mSource != NULL
11536ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
11541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
11556ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
11566ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchSubtitleDataGeneration);
11576ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
11586ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
11596ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
116055e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        sp<AMessage> msg2 = new AMessage(kWhatSendGlobalTimedTextData, this);
116155e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        msg2->setInt32("generation", mFetchTimedTextDataGeneration);
116255e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen        msg2->post();
116355e2f4ca5bb23ce32fbdd627b0f648c27106b98eMarco Nelissen
11646ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mTimedTextTrack.mSource != NULL
11656ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
11661d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
11676ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
11686ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchTimedTextDataGeneration);
11696ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
11706ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
11716ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
11723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
11733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
11743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        bool audio = !strncasecmp(mime, "audio/", 6);
11753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        Track *track = audio ? &mAudioTrack : &mVideoTrack;
11763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (track->mSource != NULL && track->mIndex == trackIndex) {
11773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
11783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
11793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
11801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
11813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("trackIndex", trackIndex);
11823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
11833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
11843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
11853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
11863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return INVALID_OPERATION;
11873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
11883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1189afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
11901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSeek, this);
119117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt64("seekTimeUs", seekTimeUs);
119217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
119317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
119417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
119517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
119617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
119717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
119817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
119917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
120017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
120117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
120217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
120317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int64_t seekTimeUs;
120417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
120517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
120617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
120717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = doSeek(seekTimeUs);
120817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
120917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
12103f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    sp<AReplyToken> replyID;
121117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
121217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
121317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
121417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
121517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
121614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor->updateDequeuedBufferTime(-1ll);
121714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
12182abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // If the Widevine source is stopped, do not attempt to read any
12192abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // more buffers.
12202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
12212abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return INVALID_OPERATION;
12222abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
1223afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
1224afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        int64_t actualTimeUs;
12253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
1226afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1227afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seekTimeUs = actualTimeUs;
12285c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = seekTimeUs;
1229afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1230afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1231afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
12323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
12335c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = seekTimeUs;
1234afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1235afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1236802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
1237802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (!mStarted) {
1238802768790c131f8237364906fd13981a6bb91193Ronghua Wu        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
1239802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
1240efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1241efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // If currently buffering, post kWhatBufferingEnd first, so that
1242efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // NuPlayer resumes. Otherwise, if cache hits high watermark
1243efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // before new polling happens, no one will resume the playback.
124414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor->stopBufferingIfNecessary();
124514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBufferingMonitor->restartPollBuffering();
1246efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1247afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
1248afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1249afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
12503423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihsp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
12513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        MediaBuffer* mb,
12523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType,
1253474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        int64_t /* seekTimeUs */,
12543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int64_t *actualTimeUs) {
12553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
12563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    size_t outLength = mb->range_length();
12573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
12593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        outLength += sizeof(int32_t);
12603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<ABuffer> ab;
126342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsSecure && !audio) {
12643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        // data is already provided in the buffer
12653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(NULL, mb->range_length());
12663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        mb->add_ref();
126796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia        ab->setMediaBufferBase(mb);
12683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else {
12693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(outLength);
12703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(ab->data(),
12713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               (const uint8_t *)mb->data() + mb->range_offset(),
12723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               mb->range_length());
12733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
12763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int32_t numPageSamples;
12773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
12783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            numPageSamples = -1;
12793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
12803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        uint8_t* abEnd = ab->data() + mb->range_length();
12823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
12833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1285e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<AMessage> meta = ab->meta();
1286e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
12873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
12883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
12893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    meta->setInt64("timeUs", timeUs);
12903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1291474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#if 0
1292474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // Temporarily disable pre-roll till we have a full solution to handle
1293474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // both single seek and continous seek gracefully.
1294474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    if (seekTimeUs > timeUs) {
1295474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        sp<AMessage> extra = new AMessage;
1296474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
1297474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        meta->setMessage("extra", extra);
1298474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    }
1299474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#endif
1300474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia
1301e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
1302e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const char *mime;
1303e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        CHECK(mTimedTextTrack.mSource != NULL
1304e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
1305e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        meta->setString("mime", mime);
1306e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1307e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
13083423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t durationUs;
13093423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
13103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt64("durationUs", durationUs);
13113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
13143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
13153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1317f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih    uint32_t dataType; // unused
1318f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih    const void *seiData;
1319f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih    size_t seiLength;
1320f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih    if (mb->meta_data()->findData(kKeySEI, &dataType, &seiData, &seiLength)) {
1321f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih        sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
1322f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih        meta->setBuffer("sei", sei);
1323f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih    }
1324f8bd851cc652501239a8e3759b21890dfa2afdeaRobert Shih
13253694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung    const void *mpegUserDataPointer;
13263694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung    size_t mpegUserDataLength;
13273694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung    if (mb->meta_data()->findData(
13283694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung            kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
13293694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung        sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
13303694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung        meta->setBuffer("mpegUserData", mpegUserData);
13313694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung    }
13323694d7cf40d1645bf05246cf38595eed606bb650Jaesung Chung
13333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (actualTimeUs) {
13343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        *actualTimeUs = timeUs;
13353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb->release();
13383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb = NULL;
13393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return ab;
13413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
13423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
134317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
134484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    Mutex::Autolock _l(mReadBufferLock);
134584f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar
134684f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
134784f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes |= (1 << trackType);
13481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
134984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->setInt32("trackType", trackType);
135084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->post();
135184f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
135217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
135317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
135417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
135517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
135617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackType", &tmpType));
135717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type trackType = (media_track_type)tmpType;
135842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    readBuffer(trackType);
135984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    {
136084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        // only protect the variable change, as readBuffer may
136142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // take considerable time.
136284f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        Mutex::Autolock _l(mReadBufferLock);
136384f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes &= ~(1 << trackType);
136484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
136517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
136617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
1367afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::readBuffer(
13683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
13692abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // Do not read data if Widevine source is stopped
13702abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
13712abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return;
13722abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
13733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    Track *track;
1374c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    size_t maxBuffers = 1;
13753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (trackType) {
13763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_VIDEO:
13773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mVideoTrack;
1378a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1379a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 2;
1380fcf044a9c5624395d24eb6181e67163ce169458bChong Zhang            } else {
1381fcf044a9c5624395d24eb6181e67163ce169458bChong Zhang                maxBuffers = 4;
1382a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
13833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
13843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_AUDIO:
13853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mAudioTrack;
1386a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1387a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 8;
1388a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            } else {
1389a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 64;
1390a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
13913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
13923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_SUBTITLE:
13933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mSubtitleTrack;
13943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
1395e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        case MEDIA_TRACK_TYPE_TIMEDTEXT:
1396e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1397e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            break;
13983423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        default:
13993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            TRESPASS();
14003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14013423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (track->mSource == NULL) {
14033423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return;
14043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
1405afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1406afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (actualTimeUs) {
1407afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        *actualTimeUs = seekTimeUs;
1408afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1409afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1410afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    MediaSource::ReadOptions options;
1411afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1412afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    bool seeking = false;
1413afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1414afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (seekTimeUs >= 0) {
14153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1416afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seeking = true;
1417afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1418afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
141942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine) {
1420cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        options.setNonBlocking();
1421cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
1422cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
14231f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia    bool couldReadMultiple = (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO);
1424c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
14251f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        Vector<MediaBuffer *> mediaBuffers;
14261f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        status_t err = NO_ERROR;
14271f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia
14281f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        if (!seeking && couldReadMultiple) {
14291f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            err = track->mSource->readMultiple(&mediaBuffers, (maxBuffers - numBuffers));
14301f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        } else {
14311f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            MediaBuffer *mbuf = NULL;
14321f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            err = track->mSource->read(&mbuf, &options);
14331f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            if (err == OK && mbuf != NULL) {
14341f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia                mediaBuffers.push_back(mbuf);
14351f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            }
14361f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        }
1437afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1438afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        options.clearSeekTo();
1439afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
14401f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        size_t id = 0;
14411f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        size_t count = mediaBuffers.size();
14421f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        for (; id < count; ++id) {
1443802768790c131f8237364906fd13981a6bb91193Ronghua Wu            int64_t timeUs;
14441f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            MediaBuffer *mbuf = mediaBuffers[id];
14453b9912bcd428fcaeead1faf9297aee11b7fd1888Robert Shih            if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) {
14463b9912bcd428fcaeead1faf9297aee11b7fd1888Robert Shih                mbuf->meta_data()->dumpToLog();
14473b9912bcd428fcaeead1faf9297aee11b7fd1888Robert Shih                track->mPackets->signalEOS(ERROR_MALFORMED);
14483b9912bcd428fcaeead1faf9297aee11b7fd1888Robert Shih                break;
14493b9912bcd428fcaeead1faf9297aee11b7fd1888Robert Shih            }
1450802768790c131f8237364906fd13981a6bb91193Ronghua Wu            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
1451802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mAudioTimeUs = timeUs;
145214532f2383c3849d0db59a607ed0bd802f57155cWei Jia                mBufferingMonitor->updateQueuedTime(true /* isAudio */, timeUs);
1453802768790c131f8237364906fd13981a6bb91193Ronghua Wu            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
1454802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mVideoTimeUs = timeUs;
145514532f2383c3849d0db59a607ed0bd802f57155cWei Jia                mBufferingMonitor->updateQueuedTime(false /* isAudio */, timeUs);
1456802768790c131f8237364906fd13981a6bb91193Ronghua Wu            }
1457802768790c131f8237364906fd13981a6bb91193Ronghua Wu
14588f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
1459afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1460474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia            sp<ABuffer> buffer = mediaBufferToABuffer(
146198e7ece3fcea7d95620049a69df08140f59ba3b8Shivaprasad Hongal                    mbuf, trackType, seekTimeUs,
146298e7ece3fcea7d95620049a69df08140f59ba3b8Shivaprasad Hongal                    numBuffers == 0 ? actualTimeUs : NULL);
1463afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueAccessUnit(buffer);
1464317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            formatChange = false;
1465317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            seeking = false;
1466c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk            ++numBuffers;
14671f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        }
14681f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        if (id < count) {
14691f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            // Error, some mediaBuffer doesn't have kKeyTime.
14701f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            for (; id < count; ++id) {
14711f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia                mediaBuffers[id]->release();
14721f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            }
14731f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia            break;
14741f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        }
14751f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia
14761f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        if (err == WOULD_BLOCK) {
1477cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            break;
1478afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (err == INFO_FORMAT_CHANGED) {
1479afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#if 0
1480afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueDiscontinuity(
1481632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    ATSParser::DISCONTINUITY_FORMATCHANGE,
1482632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    NULL,
1483632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    false /* discard */);
1484afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#endif
14851f1fc459ddb67d1162f2dbb10d14e57f42841da2Wei Jia        } else if (err != OK) {
14868f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
1487afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->signalEOS(err);
1488afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            break;
1489afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
1490afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1491afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1492afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
14938f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wuvoid NuPlayer::GenericSource::queueDiscontinuityIfNeeded(
14948f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu        bool seeking, bool formatChange, media_track_type trackType, Track *track) {
14958f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu    // formatChange && seeking: track whose source is changed during selection
14968f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu    // formatChange && !seeking: track whose source is not changed during selection
14978f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu    // !formatChange: normal seek
14988f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu    if ((seeking || formatChange)
14998f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu            && (trackType == MEDIA_TRACK_TYPE_AUDIO
15008f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu            || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
15018f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu        ATSParser::DiscontinuityType type = (formatChange && seeking)
15028f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu                ? ATSParser::DISCONTINUITY_FORMATCHANGE
15038f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu                : ATSParser::DISCONTINUITY_NONE;
15048f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu        track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */);
15058f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu    }
15068f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu}
15078f291bc99e92015ebb959654a73c87e98bd46958Ronghua Wu
150814532f2383c3849d0db59a607ed0bd802f57155cWei JiaNuPlayer::GenericSource::BufferingMonitor::BufferingMonitor(const sp<AMessage> &notify)
150914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    : mNotify(notify),
151014532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mDurationUs(-1ll),
151114532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mBitrate(-1ll),
151214532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mIsStreaming(false),
151314532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mAudioTimeUs(0),
151414532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mVideoTimeUs(0),
151514532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mPollBufferingGeneration(0),
151614532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mPrepareBuffering(false),
151714532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mBuffering(false),
151814532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mPrevBufferPercentage(-1),
151914532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mOffloadAudio(false),
152014532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mFirstDequeuedBufferRealUs(-1ll),
152114532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mFirstDequeuedBufferMediaUs(-1ll),
152214532f2383c3849d0db59a607ed0bd802f57155cWei Jia      mlastDequeuedBufferMediaUs(-1ll) {
152314532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
152414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
152514532f2383c3849d0db59a607ed0bd802f57155cWei JiaNuPlayer::GenericSource::BufferingMonitor::~BufferingMonitor() {
152614532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
152714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
152814532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::prepare(
152914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        const sp<NuCachedSource2> &cachedSource,
153014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        const sp<WVMExtractor> &wvmExtractor,
153114532f2383c3849d0db59a607ed0bd802f57155cWei Jia        int64_t durationUs,
153214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        int64_t bitrate,
153314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        bool isStreaming) {
153414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
153514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    prepare_l(cachedSource, wvmExtractor, durationUs, bitrate, isStreaming);
153614532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
153714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
153814532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::stop() {
153914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
154014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    prepare_l(NULL /* cachedSource */, NULL /* wvmExtractor */, -1 /* durationUs */,
154114532f2383c3849d0db59a607ed0bd802f57155cWei Jia            -1 /* bitrate */, false /* isStreaming */);
154214532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
154314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
154414532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::cancelPollBuffering() {
154514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
154614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    cancelPollBuffering_l();
154714532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
154814532f2383c3849d0db59a607ed0bd802f57155cWei Jia
154914532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::restartPollBuffering() {
155014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
155114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mIsStreaming) {
155214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        cancelPollBuffering_l();
155314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        onPollBuffering_l();
155414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
155514532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
155614532f2383c3849d0db59a607ed0bd802f57155cWei Jia
155714532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary() {
155814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
155914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    stopBufferingIfNecessary_l();
156014532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
156114532f2383c3849d0db59a607ed0bd802f57155cWei Jia
156214532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::ensureCacheIsFetching() {
156314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
156414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    ensureCacheIsFetching_l();
156514532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
156614532f2383c3849d0db59a607ed0bd802f57155cWei Jia
156714532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::updateQueuedTime(bool isAudio, int64_t timeUs) {
156814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
156914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (isAudio) {
157014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mAudioTimeUs = timeUs;
157114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else {
157214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mVideoTimeUs = timeUs;
157314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
157414532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
157514532f2383c3849d0db59a607ed0bd802f57155cWei Jia
157614532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::setOffloadAudio(bool offload) {
157714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
157814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mOffloadAudio = offload;
157914532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
158014532f2383c3849d0db59a607ed0bd802f57155cWei Jia
158114532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::updateDequeuedBufferTime(int64_t mediaUs) {
158214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    Mutex::Autolock _l(mLock);
158314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mediaUs < 0) {
158414532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mFirstDequeuedBufferRealUs = -1ll;
158514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mFirstDequeuedBufferMediaUs = -1ll;
158614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (mFirstDequeuedBufferRealUs < 0) {
158714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mFirstDequeuedBufferRealUs = ALooper::GetNowUs();
158814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mFirstDequeuedBufferMediaUs = mediaUs;
158914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
159014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mlastDequeuedBufferMediaUs = mediaUs;
159114532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
159214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
159314532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::prepare_l(
159414532f2383c3849d0db59a607ed0bd802f57155cWei Jia        const sp<NuCachedSource2> &cachedSource,
159514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        const sp<WVMExtractor> &wvmExtractor,
159614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        int64_t durationUs,
159714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        int64_t bitrate,
159814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        bool isStreaming) {
159914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    ALOGW_IF(wvmExtractor != NULL && cachedSource != NULL,
160014532f2383c3849d0db59a607ed0bd802f57155cWei Jia            "WVMExtractor and NuCachedSource are both present when "
160114532f2383c3849d0db59a607ed0bd802f57155cWei Jia            "BufferingMonitor::prepare_l is called, ignore NuCachedSource");
160214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
160314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mCachedSource = cachedSource;
160414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mWVMExtractor = wvmExtractor;
160514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mDurationUs = durationUs;
160614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBitrate = bitrate;
160714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mIsStreaming = isStreaming;
160814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mAudioTimeUs = 0;
160914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mVideoTimeUs = 0;
16104def1cb3283df05929dbf81f9ca68803b519437fWei Jia    mPrepareBuffering = (cachedSource != NULL || wvmExtractor != NULL);
161114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    cancelPollBuffering_l();
161214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mOffloadAudio = false;
161314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mFirstDequeuedBufferRealUs = -1ll;
161414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mFirstDequeuedBufferMediaUs = -1ll;
161514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mlastDequeuedBufferMediaUs = -1ll;
161614532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
161714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
161814532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::cancelPollBuffering_l() {
161914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mBuffering = false;
162014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    ++mPollBufferingGeneration;
162114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mPrevBufferPercentage = -1;
162214532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
162314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
162414532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::notifyBufferingUpdate_l(int32_t percentage) {
162514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    // Buffering percent could go backward as it's estimated from remaining
162614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    // data and last access time. This could cause the buffering position
162714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    // drawn on media control to jitter slightly. Remember previously reported
162814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    // percentage and don't allow it to go backward.
162914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (percentage < mPrevBufferPercentage) {
163014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        percentage = mPrevBufferPercentage;
163114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (percentage > 100) {
163214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        percentage = 100;
163314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
163414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
163514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    mPrevBufferPercentage = percentage;
163614532f2383c3849d0db59a607ed0bd802f57155cWei Jia
163714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    ALOGV("notifyBufferingUpdate_l: buffering %d%%", percentage);
163814532f2383c3849d0db59a607ed0bd802f57155cWei Jia
163914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    sp<AMessage> msg = mNotify->dup();
164014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    msg->setInt32("what", kWhatBufferingUpdate);
164114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    msg->setInt32("percentage", percentage);
164214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    msg->post();
164314532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
164414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
164514532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::startBufferingIfNecessary_l() {
164614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mPrepareBuffering) {
164714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return;
164814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
164914532f2383c3849d0db59a607ed0bd802f57155cWei Jia
165014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (!mBuffering) {
16514d71c0224e48d87c81363ad061d58deaf991a323Wei Jia        ALOGD("startBufferingIfNecessary_l");
16524d71c0224e48d87c81363ad061d58deaf991a323Wei Jia
165314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBuffering = true;
165414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
165514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        ensureCacheIsFetching_l();
165614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sendCacheStats_l();
165714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
165814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sp<AMessage> notify = mNotify->dup();
165914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("what", kWhatPauseOnBufferingStart);
166014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->post();
166114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
166214532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
166314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
166414532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary_l() {
166514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mPrepareBuffering) {
16664d71c0224e48d87c81363ad061d58deaf991a323Wei Jia        ALOGD("stopBufferingIfNecessary_l, mBuffering=%d", mBuffering);
16674d71c0224e48d87c81363ad061d58deaf991a323Wei Jia
166814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mPrepareBuffering = false;
166914532f2383c3849d0db59a607ed0bd802f57155cWei Jia
167014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sp<AMessage> notify = mNotify->dup();
167114532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("what", kWhatPrepared);
167214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("err", OK);
167314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->post();
167414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
167514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return;
167614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
167714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
167814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mBuffering) {
16794d71c0224e48d87c81363ad061d58deaf991a323Wei Jia        ALOGD("stopBufferingIfNecessary_l");
168014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mBuffering = false;
168114532f2383c3849d0db59a607ed0bd802f57155cWei Jia
168214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sendCacheStats_l();
168314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
168414532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sp<AMessage> notify = mNotify->dup();
168514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("what", kWhatResumeOnBufferingEnd);
168614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->post();
168714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
168814532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
168914532f2383c3849d0db59a607ed0bd802f57155cWei Jia
169014532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::sendCacheStats_l() {
169114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    int32_t kbps = 0;
169214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    status_t err = UNKNOWN_ERROR;
169314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
169414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mWVMExtractor != NULL) {
169514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps);
169614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (mCachedSource != NULL) {
169714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
169814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
169914532f2383c3849d0db59a607ed0bd802f57155cWei Jia
170014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (err == OK) {
170114532f2383c3849d0db59a607ed0bd802f57155cWei Jia        sp<AMessage> notify = mNotify->dup();
170214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("what", kWhatCacheStats);
170314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->setInt32("bandwidth", kbps);
170414532f2383c3849d0db59a607ed0bd802f57155cWei Jia        notify->post();
170514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
170614532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
170714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
170814532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::ensureCacheIsFetching_l() {
170914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mCachedSource != NULL) {
171014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        mCachedSource->resumeFetchingIfNecessary();
171114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
171214532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
171314532f2383c3849d0db59a607ed0bd802f57155cWei Jia
171414532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::schedulePollBuffering_l() {
171514532f2383c3849d0db59a607ed0bd802f57155cWei Jia    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
171614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    msg->setInt32("generation", mPollBufferingGeneration);
171714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    // Enquires buffering status every second.
171814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    msg->post(1000000ll);
171914532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
172014532f2383c3849d0db59a607ed0bd802f57155cWei Jia
172114532f2383c3849d0db59a607ed0bd802f57155cWei Jiaint64_t NuPlayer::GenericSource::BufferingMonitor::getLastReadPosition_l() {
172214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mAudioTimeUs > 0) {
172314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return mAudioTimeUs;
172414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (mVideoTimeUs > 0) {
172514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return mVideoTimeUs;
172614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else {
172714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return 0;
172814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
172914532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
173014532f2383c3849d0db59a607ed0bd802f57155cWei Jia
173114532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::onPollBuffering_l() {
173214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    status_t finalStatus = UNKNOWN_ERROR;
173314532f2383c3849d0db59a607ed0bd802f57155cWei Jia    int64_t cachedDurationUs = -1ll;
173414532f2383c3849d0db59a607ed0bd802f57155cWei Jia    ssize_t cachedDataRemaining = -1;
173514532f2383c3849d0db59a607ed0bd802f57155cWei Jia
173614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (mWVMExtractor != NULL) {
173714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        cachedDurationUs =
173814532f2383c3849d0db59a607ed0bd802f57155cWei Jia                mWVMExtractor->getCachedDurationUs(&finalStatus);
173914532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (mCachedSource != NULL) {
174014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        cachedDataRemaining =
174114532f2383c3849d0db59a607ed0bd802f57155cWei Jia                mCachedSource->approxDataRemaining(&finalStatus);
174214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
174314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (finalStatus == OK) {
174414532f2383c3849d0db59a607ed0bd802f57155cWei Jia            off64_t size;
174514532f2383c3849d0db59a607ed0bd802f57155cWei Jia            int64_t bitrate = 0ll;
174614532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
174714532f2383c3849d0db59a607ed0bd802f57155cWei Jia                // |bitrate| uses bits/second unit, while size is number of bytes.
174814532f2383c3849d0db59a607ed0bd802f57155cWei Jia                bitrate = size * 8000000ll / mDurationUs;
174914532f2383c3849d0db59a607ed0bd802f57155cWei Jia            } else if (mBitrate > 0) {
175014532f2383c3849d0db59a607ed0bd802f57155cWei Jia                bitrate = mBitrate;
175114532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
175214532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (bitrate > 0) {
175314532f2383c3849d0db59a607ed0bd802f57155cWei Jia                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
175414532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
175514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
175614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
175714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
175814532f2383c3849d0db59a607ed0bd802f57155cWei Jia    if (finalStatus != OK) {
175914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        ALOGV("onPollBuffering_l: EOS (finalStatus = %d)", finalStatus);
176014532f2383c3849d0db59a607ed0bd802f57155cWei Jia
176114532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (finalStatus == ERROR_END_OF_STREAM) {
176214532f2383c3849d0db59a607ed0bd802f57155cWei Jia            notifyBufferingUpdate_l(100);
176314532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
176414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
176514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        stopBufferingIfNecessary_l();
176614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        return;
176714532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (cachedDurationUs >= 0ll) {
176814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (mDurationUs > 0ll) {
176914532f2383c3849d0db59a607ed0bd802f57155cWei Jia            int64_t cachedPosUs = getLastReadPosition_l() + cachedDurationUs;
177014532f2383c3849d0db59a607ed0bd802f57155cWei Jia            int percentage = 100.0 * cachedPosUs / mDurationUs;
177114532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (percentage > 100) {
177214532f2383c3849d0db59a607ed0bd802f57155cWei Jia                percentage = 100;
177314532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
177414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
177514532f2383c3849d0db59a607ed0bd802f57155cWei Jia            notifyBufferingUpdate_l(percentage);
177614532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
177714532f2383c3849d0db59a607ed0bd802f57155cWei Jia
177814532f2383c3849d0db59a607ed0bd802f57155cWei Jia        ALOGV("onPollBuffering_l: cachedDurationUs %.1f sec",
177914532f2383c3849d0db59a607ed0bd802f57155cWei Jia                cachedDurationUs / 1000000.0f);
178014532f2383c3849d0db59a607ed0bd802f57155cWei Jia
178114532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (cachedDurationUs < kLowWaterMarkUs) {
178214532f2383c3849d0db59a607ed0bd802f57155cWei Jia            // Take into account the data cached in downstream components to try to avoid
178314532f2383c3849d0db59a607ed0bd802f57155cWei Jia            // unnecessary pause.
178414532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (mOffloadAudio && mFirstDequeuedBufferRealUs >= 0) {
178514532f2383c3849d0db59a607ed0bd802f57155cWei Jia                int64_t downStreamCacheUs = mlastDequeuedBufferMediaUs - mFirstDequeuedBufferMediaUs
178614532f2383c3849d0db59a607ed0bd802f57155cWei Jia                        - (ALooper::GetNowUs() - mFirstDequeuedBufferRealUs);
178714532f2383c3849d0db59a607ed0bd802f57155cWei Jia                if (downStreamCacheUs > 0) {
178814532f2383c3849d0db59a607ed0bd802f57155cWei Jia                    cachedDurationUs += downStreamCacheUs;
178914532f2383c3849d0db59a607ed0bd802f57155cWei Jia                }
179014532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
179114532f2383c3849d0db59a607ed0bd802f57155cWei Jia
179214532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (cachedDurationUs < kLowWaterMarkUs) {
179314532f2383c3849d0db59a607ed0bd802f57155cWei Jia                startBufferingIfNecessary_l();
179414532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
179514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        } else {
179614532f2383c3849d0db59a607ed0bd802f57155cWei Jia            int64_t highWaterMark = mPrepareBuffering ? kHighWaterMarkUs : kHighWaterMarkRebufferUs;
179714532f2383c3849d0db59a607ed0bd802f57155cWei Jia            if (cachedDurationUs > highWaterMark) {
179814532f2383c3849d0db59a607ed0bd802f57155cWei Jia                stopBufferingIfNecessary_l();
179914532f2383c3849d0db59a607ed0bd802f57155cWei Jia            }
180014532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
180114532f2383c3849d0db59a607ed0bd802f57155cWei Jia    } else if (cachedDataRemaining >= 0) {
180214532f2383c3849d0db59a607ed0bd802f57155cWei Jia        ALOGV("onPollBuffering_l: cachedDataRemaining %zd bytes",
180314532f2383c3849d0db59a607ed0bd802f57155cWei Jia                cachedDataRemaining);
180414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
180514532f2383c3849d0db59a607ed0bd802f57155cWei Jia        if (cachedDataRemaining < kLowWaterMarkBytes) {
180614532f2383c3849d0db59a607ed0bd802f57155cWei Jia            startBufferingIfNecessary_l();
180714532f2383c3849d0db59a607ed0bd802f57155cWei Jia        } else if (cachedDataRemaining > kHighWaterMarkBytes) {
180814532f2383c3849d0db59a607ed0bd802f57155cWei Jia            stopBufferingIfNecessary_l();
180914532f2383c3849d0db59a607ed0bd802f57155cWei Jia        }
181014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
181114532f2383c3849d0db59a607ed0bd802f57155cWei Jia
181214532f2383c3849d0db59a607ed0bd802f57155cWei Jia    schedulePollBuffering_l();
181314532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
181414532f2383c3849d0db59a607ed0bd802f57155cWei Jia
181514532f2383c3849d0db59a607ed0bd802f57155cWei Jiavoid NuPlayer::GenericSource::BufferingMonitor::onMessageReceived(const sp<AMessage> &msg) {
181614532f2383c3849d0db59a607ed0bd802f57155cWei Jia    switch (msg->what()) {
181714532f2383c3849d0db59a607ed0bd802f57155cWei Jia      case kWhatPollBuffering:
181814532f2383c3849d0db59a607ed0bd802f57155cWei Jia      {
181914532f2383c3849d0db59a607ed0bd802f57155cWei Jia          int32_t generation;
182014532f2383c3849d0db59a607ed0bd802f57155cWei Jia          CHECK(msg->findInt32("generation", &generation));
182114532f2383c3849d0db59a607ed0bd802f57155cWei Jia          Mutex::Autolock _l(mLock);
182214532f2383c3849d0db59a607ed0bd802f57155cWei Jia          if (generation == mPollBufferingGeneration) {
182314532f2383c3849d0db59a607ed0bd802f57155cWei Jia              onPollBuffering_l();
182414532f2383c3849d0db59a607ed0bd802f57155cWei Jia          }
182514532f2383c3849d0db59a607ed0bd802f57155cWei Jia          break;
182614532f2383c3849d0db59a607ed0bd802f57155cWei Jia      }
182714532f2383c3849d0db59a607ed0bd802f57155cWei Jia      default:
182814532f2383c3849d0db59a607ed0bd802f57155cWei Jia          TRESPASS();
182914532f2383c3849d0db59a607ed0bd802f57155cWei Jia          break;
183014532f2383c3849d0db59a607ed0bd802f57155cWei Jia    }
183114532f2383c3849d0db59a607ed0bd802f57155cWei Jia}
183214532f2383c3849d0db59a607ed0bd802f57155cWei Jia
1833afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}  // namespace android
1834