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
45efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kLowWaterMarkBytes = 40000;
46efbb61950db36a5eb789be83f077246172507c67Chong Zhangstatic const ssize_t kHighWaterMarkBytes = 200000;
47efbb61950db36a5eb789be83f077246172507c67Chong Zhang
48afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::GenericSource(
49b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        const sp<AMessage> &notify,
50cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        bool uidValid,
51cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        uid_t uid)
52b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    : Source(notify),
535c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mAudioTimeUs(0),
545c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mAudioLastDequeueTimeUs(0),
555c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mVideoTimeUs(0),
565c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih      mVideoLastDequeueTimeUs(0),
573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      mFetchSubtitleDataGeneration(0),
58e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      mFetchTimedTextDataGeneration(0),
59b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber      mDurationUs(0ll),
60cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar      mAudioIsVorbis(false),
613de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang      mIsWidevine(false),
6242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang      mIsSecure(false),
63efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mIsStreaming(false),
64cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar      mUIDValid(uidValid),
65d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang      mUID(uid),
66a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang      mFd(-1),
67802768790c131f8237364906fd13981a6bb91193Ronghua Wu      mDrmManagerClient(NULL),
682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      mMetaDataSize(-1ll),
692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      mBitrate(-1ll),
7084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar      mPollBufferingGeneration(0),
71efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mPendingReadBufferTypes(0),
72efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mBuffering(false),
73efbb61950db36a5eb789be83f077246172507c67Chong Zhang      mPrepareBuffering(false) {
74a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
75afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    DataSource::RegisterDefaultSniffers();
763de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang}
773de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
78a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangvoid NuPlayer::GenericSource::resetDataSource() {
79a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mHTTPService.clear();
80360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih    mHttpSource.clear();
81a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUri.clear();
82a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUriHeaders.clear();
83a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    if (mFd >= 0) {
84a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang        close(mFd);
85a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang        mFd = -1;
86a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    }
87a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mOffset = 0;
88a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mLength = 0;
89802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
90802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mDecryptHandle = NULL;
91802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mDrmManagerClient = NULL;
92802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
932abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    mStopRead = true;
94a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang}
95a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
96a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource(
973de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const sp<IMediaHTTPService> &httpService,
983de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const char *url,
993de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        const KeyedVector<String8, String8> *headers) {
100a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
102a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mHTTPService = httpService;
103a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mUri = url;
104afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
105a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    if (headers) {
106a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        mUriHeaders = *headers;
1073de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
109a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delay data source creation to prepareAsync() to avoid blocking
110a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // the calling thread in setDataSource for any significant time.
111a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    return OK;
1123de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang}
113afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
114a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setDataSource(
1153de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        int fd, int64_t offset, int64_t length) {
116a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    resetDataSource();
117a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
118a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mFd = dup(fd);
119a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mOffset = offset;
120a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    mLength = length;
121afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
122a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delay data source creation to prepareAsync() to avoid blocking
123a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // the calling thread in setDataSource for any significant time.
124a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    return OK;
125afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
126afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
127f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissensp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
128f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    return mFileMeta;
129f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen}
130f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen
131d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangstatus_t NuPlayer::GenericSource::initFromDataSource() {
132cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    sp<MediaExtractor> extractor;
133cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
134d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    CHECK(mDataSource != NULL);
135d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
136cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    if (mIsWidevine) {
137cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        String8 mimeType;
138cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        float confidence;
139cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        sp<AMessage> dummy;
140cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        bool success;
141cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
142d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        success = SniffWVM(mDataSource, &mimeType, &confidence, &dummy);
143cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        if (!success
144cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar                || strcasecmp(
145cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
146cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            ALOGE("unsupported widevine mime: %s", mimeType.string());
1473de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang            return UNKNOWN_ERROR;
148cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        }
149cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
1502a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        mWVMExtractor = new WVMExtractor(mDataSource);
1512a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        mWVMExtractor->setAdaptiveStreamingMode(true);
152cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        if (mUIDValid) {
1532a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            mWVMExtractor->setUID(mUID);
154cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        }
1552a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        extractor = mWVMExtractor;
156cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    } else {
157d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        extractor = MediaExtractor::Create(mDataSource,
158d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str());
159cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
160afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1613de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    if (extractor == NULL) {
1623de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang        return UNKNOWN_ERROR;
1633de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    }
164afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
165802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (extractor->getDrmFlag()) {
166802768790c131f8237364906fd13981a6bb91193Ronghua Wu        checkDrmStatus(mDataSource);
167802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
168802768790c131f8237364906fd13981a6bb91193Ronghua Wu
169f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    mFileMeta = extractor->getMetaData();
170f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen    if (mFileMeta != NULL) {
171c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        int64_t duration;
172f0b72b509ab1147a2a0925aced970dd68fd7fa4fMarco Nelissen        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
173c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen            mDurationUs = duration;
174c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen        }
17542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang
17642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        if (!mIsWidevine) {
17742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // Check mime to see if we actually have a widevine source.
17842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // If the data source is not URL-type (eg. file source), we
17942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            // won't be able to tell until now.
18042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            const char *fileMime;
18142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            if (mFileMeta->findCString(kKeyMIMEType, &fileMime)
18242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    && !strncasecmp(fileMime, "video/wvm", 9)) {
18342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                mIsWidevine = true;
184661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                if (!mUri.empty()) {
185661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                  // streaming, but the app forgot to specify widevine:// url
186661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                  mWVMExtractor = static_cast<WVMExtractor *>(extractor.get());
187661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                  mWVMExtractor->setAdaptiveStreamingMode(true);
188661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                  if (mUIDValid) {
189661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                    mWVMExtractor->setUID(mUID);
190661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                  }
191661a5270303392bbf22eaa459961e6ab7b26b529Jeff Tinker                }
19242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            }
19342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        }
194c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen    }
195c1f4b2b73fe9432cb75ce1dd368475a2867e70edMarco Nelissen
1962a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    int32_t totalBitrate = 0;
1972a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
198705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    size_t numtracks = extractor->countTracks();
199705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    if (numtracks == 0) {
200705d3290102875409e334e2a80e64221714aa37cMarco Nelissen        return UNKNOWN_ERROR;
201705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    }
202705d3290102875409e334e2a80e64221714aa37cMarco Nelissen
203705d3290102875409e334e2a80e64221714aa37cMarco Nelissen    for (size_t i = 0; i < numtracks; ++i) {
204afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        sp<MediaSource> track = extractor->getTrack(i);
205afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang
206afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
207afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
208afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const char *mime;
209afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
210afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
211afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // Do the string compare immediately with "mime",
212afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // we can't assume "mime" would stay valid after another
213afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // extractor operation, some extractors might modify meta
214afc0a87cc92a474bb14fb2a4093c74d04e4efd1bChong Zhang        // during getTrack() and make it invalid.
215afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (!strncasecmp(mime, "audio/", 6)) {
216afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mAudioTrack.mSource == NULL) {
217dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mAudioTrack.mIndex = i;
218dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mAudioTrack.mSource = track;
219af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                mAudioTrack.mPackets =
220af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                    new AnotherPacketSource(mAudioTrack.mSource->getFormat());
221afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
222afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
223afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = true;
224afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                } else {
225afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = false;
226afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
227afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
228afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (!strncasecmp(mime, "video/", 6)) {
229afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mVideoTrack.mSource == NULL) {
230dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mVideoTrack.mIndex = i;
231dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih                mVideoTrack.mSource = track;
232af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                mVideoTrack.mPackets =
233af52c1a1ccab588ae4ed94521f202ed9474eccecRobert Shih                    new AnotherPacketSource(mVideoTrack.mSource->getFormat());
2347e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang
2357e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                // check if the source requires secure buffers
2367e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                int32_t secure;
237a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
238a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang                        && secure) {
23942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    mIsSecure = true;
2403de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    if (mUIDValid) {
2413de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                        extractor->setUID(mUID);
2423de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang                    }
2437e892180f3992c088dc0d44f0b0e54ace4dabe3cChong Zhang                }
244afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
245afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
246afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
247afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (track != NULL) {
248dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih            mSources.push(track);
249afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            int64_t durationUs;
250afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (meta->findInt64(kKeyDuration, &durationUs)) {
251afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (durationUs > mDurationUs) {
252afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mDurationUs = durationUs;
253afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
254afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
2552a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
2562a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            int32_t bitrate;
2572a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
2582a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                totalBitrate += bitrate;
2592a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            } else {
2602a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                totalBitrate = -1;
2612a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            }
262afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
263afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
2643de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang
26522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    mBitrate = totalBitrate;
26622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
26722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    return OK;
26822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar}
26922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
27022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarstatus_t NuPlayer::GenericSource::startSources() {
271efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Start the selected A/V tracks now before we start buffering.
272efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Widevine sources might re-initialize crypto when starting, if we delay
273efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // this to start(), all data buffered during prepare would be wasted.
274efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // (We don't actually start reading until start().)
275efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) {
276efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start audio track!");
277efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
278efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
279efbb61950db36a5eb789be83f077246172507c67Chong Zhang
280efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) {
281efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start video track!");
282efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
283efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
284efbb61950db36a5eb789be83f077246172507c67Chong Zhang
2853de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    return OK;
286afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
287afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
288802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
289802768790c131f8237364906fd13981a6bb91193Ronghua Wu    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
290802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
291802768790c131f8237364906fd13981a6bb91193Ronghua Wu        CHECK(mDrmManagerClient);
292802768790c131f8237364906fd13981a6bb91193Ronghua Wu        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
293802768790c131f8237364906fd13981a6bb91193Ronghua Wu            sp<AMessage> msg = dupNotify();
294802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->setInt32("what", kWhatDrmNoLicense);
295802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->post();
296802768790c131f8237364906fd13981a6bb91193Ronghua Wu        }
297802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
298802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
299802768790c131f8237364906fd13981a6bb91193Ronghua Wu
300802768790c131f8237364906fd13981a6bb91193Ronghua Wuint64_t NuPlayer::GenericSource::getLastReadPosition() {
301802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mAudioTrack.mSource != NULL) {
302802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mAudioTimeUs;
303802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else if (mVideoTrack.mSource != NULL) {
304802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mVideoTimeUs;
305802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else {
306802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return 0;
307802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
308802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
309802768790c131f8237364906fd13981a6bb91193Ronghua Wu
310a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setBuffers(
311a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        bool audio, Vector<MediaBuffer *> &buffers) {
31242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsSecure && !audio) {
313cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        return mVideoTrack.mSource->setBuffers(buffers);
314cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
315cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    return INVALID_OPERATION;
316cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar}
317cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
318afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::~GenericSource() {
3191228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper != NULL) {
3201228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
3211228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->stop();
3221228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
323a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    resetDataSource();
324afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
325afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
3269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::GenericSource::prepareAsync() {
3271228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper == NULL) {
3281228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper = new ALooper;
3291228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->setName("generic");
3301228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->start();
3311228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3321228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
3331228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
3341228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3351228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
3361228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    msg->post();
3371228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang}
3381228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3391228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhangvoid NuPlayer::GenericSource::onPrepareAsync() {
340a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delayed data source creation
341d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mDataSource == NULL) {
34242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // set to false first, if the extractor
34342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // comes back as secure, set it to true then.
34442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        mIsSecure = false;
34542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang
346d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (!mUri.empty()) {
347360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            const char* uri = mUri.c_str();
348360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
349360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih
350360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            if (!strncasecmp("http://", uri, 7)
351360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || !strncasecmp("https://", uri, 8)
352360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || mIsWidevine) {
353360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
354360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                if (mHttpSource == NULL) {
355360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    ALOGE("Failed to create http source!");
356360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
357360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    return;
358360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                }
359360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            }
360d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
361d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = DataSource::CreateFromURI(
362360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                   mHTTPService, uri, &mUriHeaders, &mContentType,
363360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                   static_cast<HTTPBase *>(mHttpSource.get()));
364d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        } else {
365d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mIsWidevine = false;
366d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
367d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = new FileSource(mFd, mOffset, mLength);
368a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang            mFd = -1;
369d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
370a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
371d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mDataSource == NULL) {
372d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("Failed to create data source!");
373d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            notifyPreparedAndCleanup(UNKNOWN_ERROR);
374d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return;
375d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
376a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
377d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
378d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
379d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
3802a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
381efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // For widevine or other cached streaming cases, we need to wait for
382efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // enough buffering before reporting prepared.
383efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // Note that even when URL doesn't start with widevine://, mIsWidevine
384efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // could still be set to true later, if the streaming or file source
385efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // is sniffed to be widevine. We don't want to buffer for file source
386efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // in that case, so must check the flag now.
387efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mIsStreaming = (mIsWidevine || mCachedSource != NULL);
388a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
389a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
390d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // check initial caching status
391d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    status_t err = prefillCacheIfNecessary();
392d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (err != OK) {
393d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (err == -EAGAIN) {
394d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            (new AMessage(kWhatPrepareAsync, id()))->post(200000);
395d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        } else {
396d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("Failed to prefill data cache!");
397d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            notifyPreparedAndCleanup(UNKNOWN_ERROR);
398d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
399a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        return;
400a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
401a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
402d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // init extrator from data source
403d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    err = initFromDataSource();
404a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
405a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    if (err != OK) {
406a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        ALOGE("Failed to init from data source!");
407d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        notifyPreparedAndCleanup(err);
408a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        return;
409a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
410a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
4119575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    if (mVideoTrack.mSource != NULL) {
41217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
41317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<AMessage> msg = new AMessage;
41417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        err = convertMetaDataToMessage(meta, &msg);
41517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        if(err != OK) {
41617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            notifyPreparedAndCleanup(err);
41717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            return;
41817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        }
41917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        notifyVideoSizeChanged(msg);
4209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
4219575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
4229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notifyFlagsChanged(
42342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            (mIsSecure ? FLAG_SECURE : 0)
4241713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
425cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            | FLAG_CAN_PAUSE
4269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_BACKWARD
4279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_FORWARD
4289575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK);
4299575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
43022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (mIsSecure) {
43122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        // secure decoders must be instantiated before starting widevine source
43222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, id());
43322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        notifyInstantiateSecureDecoders(reply);
43422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    } else {
43522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        finishPrepareAsync();
43622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
43722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar}
43822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
43922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarvoid NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) {
44022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (err != OK) {
44122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        ALOGE("Failed to instantiate secure decoders!");
44222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        notifyPreparedAndCleanup(err);
44322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        return;
44422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
44522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    finishPrepareAsync();
44622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar}
44722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
44822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnarvoid NuPlayer::GenericSource::finishPrepareAsync() {
44922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    status_t err = startSources();
45022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    if (err != OK) {
45122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        ALOGE("Failed to init start data source!");
45222412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        notifyPreparedAndCleanup(err);
45322412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        return;
45422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar    }
45522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
456efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mIsStreaming) {
457efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mPrepareBuffering = true;
458efbb61950db36a5eb789be83f077246172507c67Chong Zhang
459efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ensureCacheIsFetching();
460efbb61950db36a5eb789be83f077246172507c67Chong Zhang        restartPollBuffering();
461efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else {
462efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notifyPrepared();
463efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
4649575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
4659575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
466d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangvoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
467d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (err != OK) {
468d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mMetaDataSize = -1ll;
469d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mContentType = "";
470d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mSniffedMIME = "";
471d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mDataSource.clear();
472d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mCachedSource.clear();
473360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih        mHttpSource.clear();
47422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar        mBitrate = -1;
4752a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
4762a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        cancelPollBuffering();
477d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
478d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    notifyPrepared(err);
479d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang}
480d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
481d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangstatus_t NuPlayer::GenericSource::prefillCacheIfNecessary() {
482d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    CHECK(mDataSource != NULL);
483d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
484d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mCachedSource == NULL) {
485d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // no prefill if the data source is not cached
486d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
487d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
488d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
489d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // We're not doing this for streams that appear to be audio-only
490d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // streams to ensure that even low bandwidth streams start
491d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // playing back fairly instantly.
492d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (!strncasecmp(mContentType.string(), "audio/", 6)) {
493d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
494d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
495d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
496d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // We're going to prefill the cache before trying to instantiate
497d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // the extractor below, as the latter is an operation that otherwise
498d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // could block on the datasource for a significant amount of time.
499d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // During that time we'd be unable to abort the preparation phase
500d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // without this prefill.
501d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
502d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // Initially make sure we have at least 192 KB for the sniff
503d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // to complete without blocking.
504d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    static const size_t kMinBytesForSniffing = 192 * 1024;
505d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    static const size_t kDefaultMetaSize = 200000;
506d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
507d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    status_t finalStatus;
508d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
509d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    size_t cachedDataRemaining =
510d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mCachedSource->approxDataRemaining(&finalStatus);
511d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
512d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (finalStatus != OK || (mMetaDataSize >= 0
513d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            && (off64_t)cachedDataRemaining >= mMetaDataSize)) {
514d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        ALOGV("stop caching, status %d, "
515d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                "metaDataSize %lld, cachedDataRemaining %zu",
516d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                finalStatus, mMetaDataSize, cachedDataRemaining);
517d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
518d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
519d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
520d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    ALOGV("now cached %zu bytes of data", cachedDataRemaining);
521d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
522d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mMetaDataSize < 0
523d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            && cachedDataRemaining >= kMinBytesForSniffing) {
524d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        String8 tmp;
525d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        float confidence;
526d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        sp<AMessage> meta;
527d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (!mCachedSource->sniff(&tmp, &confidence, &meta)) {
528d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return UNKNOWN_ERROR;
529d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
530d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
531d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // We successfully identified the file's extractor to
532d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // be, remember this mime type so we don't have to
533d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // sniff it again when we call MediaExtractor::Create()
534d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mSniffedMIME = tmp.string();
535d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
536d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (meta == NULL
537d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                || !meta->findInt64("meta-data-size",
538d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                        reinterpret_cast<int64_t*>(&mMetaDataSize))) {
539d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mMetaDataSize = kDefaultMetaSize;
540d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
541d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
542d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mMetaDataSize < 0ll) {
543d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("invalid metaDataSize = %lld bytes", mMetaDataSize);
544d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return UNKNOWN_ERROR;
545d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
546d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
547d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
548d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    return -EAGAIN;
549d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang}
550d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
551afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::start() {
552afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    ALOGI("start");
553afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
5542abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    mStopRead = false;
555afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
55617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
557afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
558afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
559afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
56017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
561afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
562802768790c131f8237364906fd13981a6bb91193Ronghua Wu
563802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
564802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
565efbb61950db36a5eb789be83f077246172507c67Chong Zhang
566efbb61950db36a5eb789be83f077246172507c67Chong Zhang    (new AMessage(kWhatStart, id()))->post();
567802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
568802768790c131f8237364906fd13981a6bb91193Ronghua Wu
569802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::stop() {
570802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
571802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
572802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
57342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine || mIsSecure) {
57442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // For widevine or secure sources we need to prevent any further reads.
5752abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());
5762abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        sp<AMessage> response;
5772abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        (void) msg->postAndAwaitResponse(&response);
5782abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
579802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
580802768790c131f8237364906fd13981a6bb91193Ronghua Wu
581802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::pause() {
582802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
583802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
584802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
585802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
586802768790c131f8237364906fd13981a6bb91193Ronghua Wu
587802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::resume() {
588802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
589802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
590802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
591efbb61950db36a5eb789be83f077246172507c67Chong Zhang
592efbb61950db36a5eb789be83f077246172507c67Chong Zhang    (new AMessage(kWhatResume, id()))->post();
593802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
594802768790c131f8237364906fd13981a6bb91193Ronghua Wu
59548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhangvoid NuPlayer::GenericSource::disconnect() {
59648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    if (mDataSource != NULL) {
59748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // disconnect data source
59848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
59948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
60048296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        }
601360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih    } else if (mHttpSource != NULL) {
602360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih        static_cast<HTTPBase *>(mHttpSource.get())->disconnect();
60348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    }
60448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang}
60548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang
606802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
607802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
608802768790c131f8237364906fd13981a6bb91193Ronghua Wu        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
609802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
61017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
61117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
612afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
613afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
614afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() {
615afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
616afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
617afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
6182a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::schedulePollBuffering() {
6192a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    sp<AMessage> msg = new AMessage(kWhatPollBuffering, id());
6202a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("generation", mPollBufferingGeneration);
6212a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->post(1000000ll);
6222a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
6232a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
6242a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::cancelPollBuffering() {
625efbb61950db36a5eb789be83f077246172507c67Chong Zhang    mBuffering = false;
6262a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    ++mPollBufferingGeneration;
6272a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
6282a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
629efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::restartPollBuffering() {
630efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mIsStreaming) {
631efbb61950db36a5eb789be83f077246172507c67Chong Zhang        cancelPollBuffering();
632efbb61950db36a5eb789be83f077246172507c67Chong Zhang        onPollBuffering();
633efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
634efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
635efbb61950db36a5eb789be83f077246172507c67Chong Zhang
6362a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) {
637efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("notifyBufferingUpdate: buffering %d%%", percentage);
638efbb61950db36a5eb789be83f077246172507c67Chong Zhang
6392a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    sp<AMessage> msg = dupNotify();
6402a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("what", kWhatBufferingUpdate);
6412a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("percentage", percentage);
6422a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->post();
6432a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
6442a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
645efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::startBufferingIfNecessary() {
646efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("startBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d",
647efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPrepareBuffering, mBuffering);
648efbb61950db36a5eb789be83f077246172507c67Chong Zhang
649efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mPrepareBuffering) {
650efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
651efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
652efbb61950db36a5eb789be83f077246172507c67Chong Zhang
653efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (!mBuffering) {
654efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mBuffering = true;
655efbb61950db36a5eb789be83f077246172507c67Chong Zhang
656efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ensureCacheIsFetching();
657efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sendCacheStats();
658efbb61950db36a5eb789be83f077246172507c67Chong Zhang
659efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
660efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatPauseOnBufferingStart);
661efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
662efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
663efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
664efbb61950db36a5eb789be83f077246172507c67Chong Zhang
665efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::stopBufferingIfNecessary() {
666efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("stopBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d",
667efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPrepareBuffering, mBuffering);
668efbb61950db36a5eb789be83f077246172507c67Chong Zhang
669efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mPrepareBuffering) {
670efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mPrepareBuffering = false;
671efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notifyPrepared();
672efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
673efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
674efbb61950db36a5eb789be83f077246172507c67Chong Zhang
675efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mBuffering) {
676efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mBuffering = false;
677efbb61950db36a5eb789be83f077246172507c67Chong Zhang
678efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sendCacheStats();
679efbb61950db36a5eb789be83f077246172507c67Chong Zhang
680efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
681efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatResumeOnBufferingEnd);
682efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
683efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
684efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
685efbb61950db36a5eb789be83f077246172507c67Chong Zhang
686efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::sendCacheStats() {
687efbb61950db36a5eb789be83f077246172507c67Chong Zhang    int32_t kbps = 0;
688efbb61950db36a5eb789be83f077246172507c67Chong Zhang    status_t err = UNKNOWN_ERROR;
689efbb61950db36a5eb789be83f077246172507c67Chong Zhang
690efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mCachedSource != NULL) {
691efbb61950db36a5eb789be83f077246172507c67Chong Zhang        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
692efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (mWVMExtractor != NULL) {
693efbb61950db36a5eb789be83f077246172507c67Chong Zhang        err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps);
694efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
695efbb61950db36a5eb789be83f077246172507c67Chong Zhang
696efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (err == OK) {
697efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
698efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatCacheStats);
699efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("bandwidth", kbps);
700efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
701efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
702efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
703efbb61950db36a5eb789be83f077246172507c67Chong Zhang
704efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::ensureCacheIsFetching() {
705efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mCachedSource != NULL) {
706efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mCachedSource->resumeFetchingIfNecessary();
707efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
708efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
709efbb61950db36a5eb789be83f077246172507c67Chong Zhang
7102a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::onPollBuffering() {
7112a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    status_t finalStatus = UNKNOWN_ERROR;
712efbb61950db36a5eb789be83f077246172507c67Chong Zhang    int64_t cachedDurationUs = -1ll;
713efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ssize_t cachedDataRemaining = -1;
7142a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7152a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    if (mCachedSource != NULL) {
716efbb61950db36a5eb789be83f077246172507c67Chong Zhang        cachedDataRemaining =
7172a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                mCachedSource->approxDataRemaining(&finalStatus);
7182a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7192a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        if (finalStatus == OK) {
7202a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            off64_t size;
7212a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            int64_t bitrate = 0ll;
7222a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
7232a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                bitrate = size * 8000000ll / mDurationUs;
7242a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            } else if (mBitrate > 0) {
7252a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                bitrate = mBitrate;
7262a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            }
7272a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            if (bitrate > 0) {
7282a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
7292a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            }
7302a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        }
7312a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    } else if (mWVMExtractor != NULL) {
7322a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        cachedDurationUs
7332a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            = mWVMExtractor->getCachedDurationUs(&finalStatus);
7342a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    }
7352a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
736efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (finalStatus != OK) {
737efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus);
738efbb61950db36a5eb789be83f077246172507c67Chong Zhang
739efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (finalStatus == ERROR_END_OF_STREAM) {
740efbb61950db36a5eb789be83f077246172507c67Chong Zhang            notifyBufferingUpdate(100);
741efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
742efbb61950db36a5eb789be83f077246172507c67Chong Zhang
743efbb61950db36a5eb789be83f077246172507c67Chong Zhang        stopBufferingIfNecessary();
7442a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        return;
745efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (cachedDurationUs >= 0ll) {
746efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (mDurationUs > 0ll) {
747efbb61950db36a5eb789be83f077246172507c67Chong Zhang            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
748efbb61950db36a5eb789be83f077246172507c67Chong Zhang            int percentage = 100.0 * cachedPosUs / mDurationUs;
749efbb61950db36a5eb789be83f077246172507c67Chong Zhang            if (percentage > 100) {
750efbb61950db36a5eb789be83f077246172507c67Chong Zhang                percentage = 100;
751efbb61950db36a5eb789be83f077246172507c67Chong Zhang            }
752efbb61950db36a5eb789be83f077246172507c67Chong Zhang
753efbb61950db36a5eb789be83f077246172507c67Chong Zhang            notifyBufferingUpdate(percentage);
7542a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        }
7552a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
756efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: cachedDurationUs %.1f sec",
757efbb61950db36a5eb789be83f077246172507c67Chong Zhang                cachedDurationUs / 1000000.0f);
758efbb61950db36a5eb789be83f077246172507c67Chong Zhang
759efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (cachedDurationUs < kLowWaterMarkUs) {
760efbb61950db36a5eb789be83f077246172507c67Chong Zhang            startBufferingIfNecessary();
761efbb61950db36a5eb789be83f077246172507c67Chong Zhang        } else if (cachedDurationUs > kHighWaterMarkUs) {
762efbb61950db36a5eb789be83f077246172507c67Chong Zhang            stopBufferingIfNecessary();
763efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
764efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (cachedDataRemaining >= 0) {
765efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: cachedDataRemaining %d bytes",
766efbb61950db36a5eb789be83f077246172507c67Chong Zhang                cachedDataRemaining);
767efbb61950db36a5eb789be83f077246172507c67Chong Zhang
768efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (cachedDataRemaining < kLowWaterMarkBytes) {
769efbb61950db36a5eb789be83f077246172507c67Chong Zhang            startBufferingIfNecessary();
770efbb61950db36a5eb789be83f077246172507c67Chong Zhang        } else if (cachedDataRemaining > kHighWaterMarkBytes) {
771efbb61950db36a5eb789be83f077246172507c67Chong Zhang            stopBufferingIfNecessary();
772efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
7732a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    }
7742a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7752a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    schedulePollBuffering();
7762a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
7772a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihvoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
7793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (msg->what()) {
7801228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      case kWhatPrepareAsync:
7811228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      {
7821228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          onPrepareAsync();
7831228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          break;
7841228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      }
7853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatFetchSubtitleData:
7863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
787e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
788e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
789e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
790e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
7913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
792e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatFetchTimedTextData:
793e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
794e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
795e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
7963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
7973423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
7983423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
7993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatSendSubtitleData:
8003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
801e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
802e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
803e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
804e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
8053423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
806e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatSendTimedTextData:
807e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
808e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
809e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
8103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
8113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
8123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatChangeAVSource:
8143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
8153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int32_t trackIndex;
8163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          CHECK(msg->findInt32("trackIndex", &trackIndex));
8173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const sp<MediaSource> source = mSources.itemAt(trackIndex);
8183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Track* track;
8203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const char *mime;
8213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          media_track_type trackType, counterpartType;
8223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          sp<MetaData> meta = source->getFormat();
8233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          meta->findCString(kKeyMIMEType, &mime);
8243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (!strncasecmp(mime, "audio/", 6)) {
8253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mAudioTrack;
8263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_AUDIO;
8273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
8283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          } else {
8293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              CHECK(!strncasecmp(mime, "video/", 6));
8303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mVideoTrack;
8313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_VIDEO;
8323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
8333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
8343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (track->mSource != NULL) {
8373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track->mSource->stop();
8383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
8393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource = source;
8403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource->start();
8413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mIndex = trackIndex;
8423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8433423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int64_t timeUs, actualTimeUs;
8443423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const bool formatChange = true;
8455c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
8465c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mAudioLastDequeueTimeUs;
8475c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          } else {
8485c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mVideoLastDequeueTimeUs;
8495c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          }
8503423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
8513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(counterpartType, -1, NULL, formatChange);
8523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);
8533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
8553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
856efbb61950db36a5eb789be83f077246172507c67Chong Zhang
857efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatStart:
858efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatResume:
859efbb61950db36a5eb789be83f077246172507c67Chong Zhang      {
860efbb61950db36a5eb789be83f077246172507c67Chong Zhang          restartPollBuffering();
861efbb61950db36a5eb789be83f077246172507c67Chong Zhang          break;
862efbb61950db36a5eb789be83f077246172507c67Chong Zhang      }
863efbb61950db36a5eb789be83f077246172507c67Chong Zhang
8642a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      case kWhatPollBuffering:
8652a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      {
8662a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          int32_t generation;
8672a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          CHECK(msg->findInt32("generation", &generation));
8682a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          if (generation == mPollBufferingGeneration) {
8692a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang              onPollBuffering();
8702a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          }
8712a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          break;
8722a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      }
87317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
87417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetFormat:
87517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
87617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetFormatMeta(msg);
87717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
87817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
87917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
88017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetSelectedTrack:
88117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
88217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetSelectedTrack(msg);
88317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
88417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
88517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
88617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSelectTrack:
88717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
88817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSelectTrack(msg);
88917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
89017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
89117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
89217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSeek:
89317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
89417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSeek(msg);
89517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
89617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
89717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
89817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatReadBuffer:
89917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
90017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onReadBuffer(msg);
90117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
90217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
90317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
90422412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar      case kWhatSecureDecodersInstantiated:
90522412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar      {
90622412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar          int32_t err;
90722412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar          CHECK(msg->findInt32("err", &err));
90822412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar          onSecureDecodersInstantiated(err);
90922412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar          break;
91022412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar      }
91122412164dee9f658272a25833aebe83d05dfe4ffLajos Molnar
9122abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      case kWhatStopWidevine:
9132abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      {
9142abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // mStopRead is only used for Widevine to prevent the video source
9152abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // from being read while the associated video decoder is shutting down.
9162abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          mStopRead = true;
9172abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          if (mVideoTrack.mSource != NULL) {
9182abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung              mVideoTrack.mPackets->clear();
9192abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          }
9202abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          sp<AMessage> response = new AMessage;
9212abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          uint32_t replyID;
9222abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          CHECK(msg->senderAwaitsResponse(&replyID));
9232abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          response->postReply(replyID);
9242abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          break;
9252abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      }
9263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      default:
9273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Source::onMessageReceived(msg);
9283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
9293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
9303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
9313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
932e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::fetchTextData(
933e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t sendWhat,
934e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
935e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
936e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
937e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
938e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
939e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
940e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
941e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
942e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
943e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
944e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
945e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t avail;
946e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->hasBufferAvailable(&avail)) {
947e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
948e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
949e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
950e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t timeUs;
951e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt64("timeUs", &timeUs));
952e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
953e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
954e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, timeUs, &subTimeUs);
955e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
956e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t delayUs = subTimeUs - timeUs;
957e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msg->what() == kWhatFetchSubtitleData) {
958e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t oneSecUs = 1000000ll;
959e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        delayUs -= oneSecUs;
960e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
961e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<AMessage> msg2 = new AMessage(sendWhat, id());
962e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->setInt32("generation", msgGeneration);
963e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->post(delayUs < 0 ? 0 : delayUs);
964e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
965e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
966e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::sendTextData(
967e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t what,
968e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
969e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
970e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
971e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
972e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
973e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
974e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
975e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
976e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
977e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
978e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
979e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
980e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->nextBufferTime(&subTimeUs) != OK) {
981e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
982e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
983e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
984e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t nextSubTimeUs;
985e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, -1, &nextSubTimeUs);
986e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
987e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<ABuffer> buffer;
988e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
989e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (dequeueStatus == OK) {
990e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> notify = dupNotify();
991e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setInt32("what", what);
992e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setBuffer("buffer", buffer);
993e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->post();
994e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
995e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t delayUs = nextSubTimeUs - subTimeUs;
996e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post(delayUs < 0 ? 0 : delayUs);
997e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
998e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
999e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1000840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
100117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
100217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("audio", audio);
100317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
100417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
100517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    void *format;
100617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
100717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
100817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findPointer("format", &format));
100917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return (MetaData *)format;
101017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
101117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return NULL;
101217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
101317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
101417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
101517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
101617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t audio;
101717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("audio", &audio));
101817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
101917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
102017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<MetaData> format = doGetFormatMeta(audio);
102117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setPointer("format", format.get());
102217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
102317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
102417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
102517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
102617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
102717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
102817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihsp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
1029afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
1030afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1031afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (source == NULL) {
1032afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return NULL;
1033afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1034afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1035afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return source->getFormat();
1036afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1037afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1038afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
1039afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
1040afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
1041afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1042afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (track->mSource == NULL) {
1043afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return -EWOULDBLOCK;
1044afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1045afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1046cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    if (mIsWidevine && !audio) {
1047cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        // try to read a buffer as we may not have been able to the last time
104817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
1049cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
1050cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
1051afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t finalResult;
1052afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
105342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        if (finalResult == OK) {
105442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            postReadBuffer(
105542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
105642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            return -EWOULDBLOCK;
105742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        }
105842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        return finalResult;
1059afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1060afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1061afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
1062afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
10633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
106417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
1065e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1066e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
10673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (result != OK) {
1068e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL) {
1069e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mSubtitleTrack.mPackets->clear();
1070e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1071e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1072e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mTimedTextTrack.mSource != NULL) {
1073e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mTimedTextTrack.mPackets->clear();
1074e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1075e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
10763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return result;
10773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
10783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
10793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
10803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    status_t eosResult; // ignored
10813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
10825c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    if (audio) {
10835c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = timeUs;
10845c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    } else {
10855c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = timeUs;
10865c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    }
1087e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1088e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mSubtitleTrack.mSource != NULL
1089e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
10903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
10913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt64("timeUs", timeUs);
10923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("generation", mFetchSubtitleDataGeneration);
10933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
10943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
1095eb1735e343a93830df259ae8882160bb0d79dcb5Robert Shih
1096e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mTimedTextTrack.mSource != NULL
1097e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
1098e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
1099e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt64("timeUs", timeUs);
1100e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt32("generation", mFetchTimedTextDataGeneration);
1101e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post();
1102e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1103e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1104afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return result;
1105afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1106afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1107afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
1108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    *durationUs = mDurationUs;
1109afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
1110afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1111afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1112dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsize_t NuPlayer::GenericSource::getTrackCount() const {
1113dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return mSources.size();
1114dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
1115dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1116dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
1117dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    size_t trackCount = mSources.size();
1118dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackIndex >= trackCount) {
1119dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        return NULL;
1120dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1121dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1122dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<AMessage> format = new AMessage();
1123dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
1124dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1125dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *mime;
1126dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
1127dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1128dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    int32_t trackType;
1129dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!strncasecmp(mime, "video/", 6)) {
1130dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_VIDEO;
1131dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strncasecmp(mime, "audio/", 6)) {
1132dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_AUDIO;
1133dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
1134dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
1135dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else {
1136dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
1137dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1138dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setInt32("type", trackType);
1139dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1140dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *lang;
1141dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
1142dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        lang = "und";
1143dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1144dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setString("language", lang);
1145dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1146dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
1147dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setString("mime", mime);
1148dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1149dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
1150dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
1151dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsDefault, &isDefault);
1152dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsForced, &isForced);
1153dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1154dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("auto", !!isAutoselect);
1155dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("default", !!isDefault);
1156dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("forced", !!isForced);
1157dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1158dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1159dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return format;
1160dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
1161dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1162e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
116317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
116417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("type", type);
116517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
116617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
116717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t index;
116817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
116917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
117017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("index", &index));
117117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return index;
117217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
117317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return -1;
117417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
117517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
117617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
117717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
117817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
117917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("type", &tmpType));
118017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type type = (media_track_type)tmpType;
118117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
118217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
118317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    ssize_t index = doGetSelectedTrack(type);
118417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("index", index);
118517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
118617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
118717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
118817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
118917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
119017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
119117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
1192e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    const Track *track = NULL;
1193e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    switch (type) {
1194e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_VIDEO:
1195e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mVideoTrack;
1196e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1197e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_AUDIO:
1198e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mAudioTrack;
1199e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1200e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_TIMEDTEXT:
1201e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mTimedTextTrack;
1202e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1203e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_SUBTITLE:
1204e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mSubtitleTrack;
1205e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1206e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    default:
1207e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1208e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1209e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1210e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (track != NULL && track->mSource != NULL) {
1211e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return track->mIndex;
1212e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1213e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1214e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    return -1;
1215e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
1216e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
12176ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1218e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
121917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
122017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("trackIndex", trackIndex);
1221da23ab9b0dfa780175651daf057a02b0aa106dc8Robert Shih    msg->setInt32("select", select);
12226ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    msg->setInt64("timeUs", timeUs);
122317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
122417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
122517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
122617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
122717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
122817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
122917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
123017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
123117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
123217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
123317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
123417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t trackIndex, select;
12356ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    int64_t timeUs;
123617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackIndex", &trackIndex));
123717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("select", &select));
12386ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    CHECK(msg->findInt64("timeUs", &timeUs));
123917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
124017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
12416ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    status_t err = doSelectTrack(trackIndex, select, timeUs);
124217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
124317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
124417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
124517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
124617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
124717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
124817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
12496ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) {
12503423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackIndex >= mSources.size()) {
12513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return BAD_INDEX;
12523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!select) {
1255e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track* track = NULL;
1256e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
1257e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mSubtitleTrack;
1258e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1259e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
1260e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1261e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1262e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1263e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track == NULL) {
12643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return INVALID_OPERATION;
12653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1266e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->stop();
1267e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = NULL;
1268e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mPackets->clear();
12693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
12703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    const sp<MediaSource> source = mSources.itemAt(trackIndex);
12733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<MetaData> meta = source->getFormat();
12743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    const char *mime;
12753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
12763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!strncasecmp(mime, "text/", 5)) {
1277e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
1278e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
1279e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL && track->mIndex == trackIndex) {
12803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
12813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1282e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mIndex = trackIndex;
1283e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL) {
1284e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mSource->stop();
12853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1286e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = mSources.itemAt(trackIndex);
1287e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->start();
1288e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mPackets == NULL) {
1289e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
12903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        } else {
1291e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->clear();
1292e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->setFormat(track->mSource->getFormat());
12933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1295e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1296e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (isSubtitle) {
1297e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1298e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else {
1299e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1300e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1301e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
13026ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        status_t eosResult; // ignored
13036ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mSubtitleTrack.mSource != NULL
13046ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
13056ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
13066ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
13076ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchSubtitleDataGeneration);
13086ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
13096ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
13106ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
13116ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mTimedTextTrack.mSource != NULL
13126ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
13136ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
13146ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
13156ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchTimedTextDataGeneration);
13166ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
13176ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
13186ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
13193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
13203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
13213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        bool audio = !strncasecmp(mime, "audio/", 6);
13223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        Track *track = audio ? &mAudioTrack : &mVideoTrack;
13233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (track->mSource != NULL && track->mIndex == trackIndex) {
13243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
13253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
13263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
13283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("trackIndex", trackIndex);
13293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
13303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
13313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return INVALID_OPERATION;
13343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
13353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1336afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
133717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatSeek, id());
133817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt64("seekTimeUs", seekTimeUs);
133917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
134017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
134117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
134217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
134317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
134417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
134517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
134617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
134717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
134817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
134917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
135017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int64_t seekTimeUs;
135117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
135217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
135317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
135417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = doSeek(seekTimeUs);
135517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
135617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
135717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
135817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
135917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
136017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
136117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
136217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
13632abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // If the Widevine source is stopped, do not attempt to read any
13642abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // more buffers.
13652abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
13662abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return INVALID_OPERATION;
13672abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
1368afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
1369afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        int64_t actualTimeUs;
13703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
1371afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1372afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seekTimeUs = actualTimeUs;
13735c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = seekTimeUs;
1374afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1375afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1376afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
13773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
13785c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = seekTimeUs;
1379afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1380afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1381802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
1382802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (!mStarted) {
1383802768790c131f8237364906fd13981a6bb91193Ronghua Wu        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
1384802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
1385efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1386efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // If currently buffering, post kWhatBufferingEnd first, so that
1387efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // NuPlayer resumes. Otherwise, if cache hits high watermark
1388efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // before new polling happens, no one will resume the playback.
1389efbb61950db36a5eb789be83f077246172507c67Chong Zhang    stopBufferingIfNecessary();
1390efbb61950db36a5eb789be83f077246172507c67Chong Zhang    restartPollBuffering();
1391efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1392afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
1393afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1394afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
13953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihsp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
13963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        MediaBuffer* mb,
13973423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType,
1398474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        int64_t /* seekTimeUs */,
13993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int64_t *actualTimeUs) {
14003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
14013423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    size_t outLength = mb->range_length();
14023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14033423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
14043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        outLength += sizeof(int32_t);
14053423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14063423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14073423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<ABuffer> ab;
140842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsSecure && !audio) {
14093423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        // data is already provided in the buffer
14103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(NULL, mb->range_length());
14113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        mb->add_ref();
141296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia        ab->setMediaBufferBase(mb);
14133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else {
14143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(outLength);
14153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(ab->data(),
14163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               (const uint8_t *)mb->data() + mb->range_offset(),
14173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               mb->range_length());
14183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
14213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int32_t numPageSamples;
14223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
14233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            numPageSamples = -1;
14243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
14253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        uint8_t* abEnd = ab->data() + mb->range_length();
14273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
14283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1430e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<AMessage> meta = ab->meta();
1431e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
14323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
14333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
14343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    meta->setInt64("timeUs", timeUs);
14353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1436474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#if 0
1437474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // Temporarily disable pre-roll till we have a full solution to handle
1438474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // both single seek and continous seek gracefully.
1439474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    if (seekTimeUs > timeUs) {
1440474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        sp<AMessage> extra = new AMessage;
1441474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
1442474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        meta->setMessage("extra", extra);
1443474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    }
1444474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#endif
1445474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia
1446e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
1447e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const char *mime;
1448e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        CHECK(mTimedTextTrack.mSource != NULL
1449e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
1450e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        meta->setString("mime", mime);
1451e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1452e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
14533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t durationUs;
14543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
14553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt64("durationUs", durationUs);
14563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
14593423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
14603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (actualTimeUs) {
14633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        *actualTimeUs = timeUs;
14643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb->release();
14673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb = NULL;
14683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return ab;
14703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
14713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
147217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
147384f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    Mutex::Autolock _l(mReadBufferLock);
147484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar
147584f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
147684f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes |= (1 << trackType);
147784f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatReadBuffer, id());
147884f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->setInt32("trackType", trackType);
147984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->post();
148084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
148117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
148217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
148317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
148417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
148517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackType", &tmpType));
148617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type trackType = (media_track_type)tmpType;
148742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    readBuffer(trackType);
148884f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    {
148984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        // only protect the variable change, as readBuffer may
149042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // take considerable time.
149184f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        Mutex::Autolock _l(mReadBufferLock);
149284f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes &= ~(1 << trackType);
149384f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
149417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
149517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
1496afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::readBuffer(
14973423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
14982abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // Do not read data if Widevine source is stopped
14992abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
15002abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return;
15012abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
15023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    Track *track;
1503c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    size_t maxBuffers = 1;
15043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (trackType) {
15053423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_VIDEO:
15063423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mVideoTrack;
1507a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1508a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 2;
1509a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
15103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
15113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_AUDIO:
15123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mAudioTrack;
1513a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1514a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 8;
1515a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            } else {
1516a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 64;
1517a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
15183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
15193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_SUBTITLE:
15203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mSubtitleTrack;
15213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
1522e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        case MEDIA_TRACK_TYPE_TIMEDTEXT:
1523e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1524e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            break;
15253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        default:
15263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            TRESPASS();
15273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
15283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
15293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (track->mSource == NULL) {
15303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return;
15313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
1532afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1533afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (actualTimeUs) {
1534afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        *actualTimeUs = seekTimeUs;
1535afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1536afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1537afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    MediaSource::ReadOptions options;
1538afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1539afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    bool seeking = false;
1540afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1541afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (seekTimeUs >= 0) {
15423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1543afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seeking = true;
1544afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1545afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
154642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine) {
1547cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        options.setNonBlocking();
1548cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
1549cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
1550c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
1551afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        MediaBuffer *mbuf;
1552afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        status_t err = track->mSource->read(&mbuf, &options);
1553afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1554afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        options.clearSeekTo();
1555afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1556afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (err == OK) {
1557802768790c131f8237364906fd13981a6bb91193Ronghua Wu            int64_t timeUs;
1558802768790c131f8237364906fd13981a6bb91193Ronghua Wu            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
1559802768790c131f8237364906fd13981a6bb91193Ronghua Wu            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
1560802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mAudioTimeUs = timeUs;
1561802768790c131f8237364906fd13981a6bb91193Ronghua Wu            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
1562802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mVideoTimeUs = timeUs;
1563802768790c131f8237364906fd13981a6bb91193Ronghua Wu            }
1564802768790c131f8237364906fd13981a6bb91193Ronghua Wu
15653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // formatChange && seeking: track whose source is changed during selection
15663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // formatChange && !seeking: track whose source is not changed during selection
15673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // !formatChange: normal seek
1568e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            if ((seeking || formatChange)
1569e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
1570e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
1571fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                ATSParser::DiscontinuityType type = (formatChange && seeking)
1572fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ? ATSParser::DISCONTINUITY_FORMATCHANGE
1573fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        : ATSParser::DISCONTINUITY_NONE;
15743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih                track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
1575afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
1576afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1577474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia            sp<ABuffer> buffer = mediaBufferToABuffer(
1578474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia                    mbuf, trackType, seekTimeUs, actualTimeUs);
1579afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueAccessUnit(buffer);
1580317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            formatChange = false;
1581317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            seeking = false;
1582c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk            ++numBuffers;
1583cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        } else if (err == WOULD_BLOCK) {
1584cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            break;
1585afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (err == INFO_FORMAT_CHANGED) {
1586afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#if 0
1587afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueDiscontinuity(
1588632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    ATSParser::DISCONTINUITY_FORMATCHANGE,
1589632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    NULL,
1590632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    false /* discard */);
1591afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#endif
1592afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else {
1593afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->signalEOS(err);
1594afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            break;
1595afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
1596afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1597afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1598afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1599afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}  // namespace android
1600