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
265efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Start the selected A/V tracks now before we start buffering.
266efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // Widevine sources might re-initialize crypto when starting, if we delay
267efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // this to start(), all data buffered during prepare would be wasted.
268efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // (We don't actually start reading until start().)
269efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) {
270efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start audio track!");
271efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
272efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
273efbb61950db36a5eb789be83f077246172507c67Chong Zhang
274efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) {
275efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGE("failed to start video track!");
276efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return UNKNOWN_ERROR;
277efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
278efbb61950db36a5eb789be83f077246172507c67Chong Zhang
2792a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    mBitrate = totalBitrate;
2802a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
2813de157dd8f9cd45bf9b0406268f5830887105ae1Chong Zhang    return OK;
282afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
283afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
284802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
285802768790c131f8237364906fd13981a6bb91193Ronghua Wu    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
286802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
287802768790c131f8237364906fd13981a6bb91193Ronghua Wu        CHECK(mDrmManagerClient);
288802768790c131f8237364906fd13981a6bb91193Ronghua Wu        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
289802768790c131f8237364906fd13981a6bb91193Ronghua Wu            sp<AMessage> msg = dupNotify();
290802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->setInt32("what", kWhatDrmNoLicense);
291802768790c131f8237364906fd13981a6bb91193Ronghua Wu            msg->post();
292802768790c131f8237364906fd13981a6bb91193Ronghua Wu        }
293802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
294802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
295802768790c131f8237364906fd13981a6bb91193Ronghua Wu
296802768790c131f8237364906fd13981a6bb91193Ronghua Wuint64_t NuPlayer::GenericSource::getLastReadPosition() {
297802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mAudioTrack.mSource != NULL) {
298802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mAudioTimeUs;
299802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else if (mVideoTrack.mSource != NULL) {
300802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return mVideoTimeUs;
301802768790c131f8237364906fd13981a6bb91193Ronghua Wu    } else {
302802768790c131f8237364906fd13981a6bb91193Ronghua Wu        return 0;
303802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
304802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
305802768790c131f8237364906fd13981a6bb91193Ronghua Wu
306a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhangstatus_t NuPlayer::GenericSource::setBuffers(
307a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        bool audio, Vector<MediaBuffer *> &buffers) {
30842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsSecure && !audio) {
309cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        return mVideoTrack.mSource->setBuffers(buffers);
310cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
311cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    return INVALID_OPERATION;
312cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar}
313cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
314afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::~GenericSource() {
3151228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper != NULL) {
3161228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
3171228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->stop();
3181228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
319a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang    resetDataSource();
320afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
321afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
3229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::GenericSource::prepareAsync() {
3231228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    if (mLooper == NULL) {
3241228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper = new ALooper;
3251228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->setName("generic");
3261228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->start();
3271228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3281228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
3291228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    }
3301228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3311228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
3321228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang    msg->post();
3331228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang}
3341228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang
3351228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhangvoid NuPlayer::GenericSource::onPrepareAsync() {
336a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    // delayed data source creation
337d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mDataSource == NULL) {
33842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // set to false first, if the extractor
33942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // comes back as secure, set it to true then.
34042e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        mIsSecure = false;
34142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang
342d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (!mUri.empty()) {
343360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            const char* uri = mUri.c_str();
344360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
345360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih
346360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            if (!strncasecmp("http://", uri, 7)
347360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || !strncasecmp("https://", uri, 8)
348360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    || mIsWidevine) {
349360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
350360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                if (mHttpSource == NULL) {
351360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    ALOGE("Failed to create http source!");
352360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
353360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                    return;
354360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                }
355360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih            }
356d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
357d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = DataSource::CreateFromURI(
358360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                   mHTTPService, uri, &mUriHeaders, &mContentType,
359360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih                   static_cast<HTTPBase *>(mHttpSource.get()));
360d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        } else {
361d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mIsWidevine = false;
362d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
363d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mDataSource = new FileSource(mFd, mOffset, mLength);
364a6bf21f2a7cdd33c78464019dc1105ef01248b51Chong Zhang            mFd = -1;
365d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
366a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
367d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mDataSource == NULL) {
368d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("Failed to create data source!");
369d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            notifyPreparedAndCleanup(UNKNOWN_ERROR);
370d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return;
371d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
372a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
373d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
374d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
375d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
3762a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
377efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // For widevine or other cached streaming cases, we need to wait for
378efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // enough buffering before reporting prepared.
379efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // Note that even when URL doesn't start with widevine://, mIsWidevine
380efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // could still be set to true later, if the streaming or file source
381efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // is sniffed to be widevine. We don't want to buffer for file source
382efbb61950db36a5eb789be83f077246172507c67Chong Zhang        // in that case, so must check the flag now.
383efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mIsStreaming = (mIsWidevine || mCachedSource != NULL);
384a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
385a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
386d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // check initial caching status
387d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    status_t err = prefillCacheIfNecessary();
388d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (err != OK) {
389d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (err == -EAGAIN) {
390d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            (new AMessage(kWhatPrepareAsync, id()))->post(200000);
391d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        } else {
392d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("Failed to prefill data cache!");
393d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            notifyPreparedAndCleanup(UNKNOWN_ERROR);
394d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
395a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        return;
396a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
397a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
398d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // init extrator from data source
399d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    err = initFromDataSource();
400a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
401a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    if (err != OK) {
402a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        ALOGE("Failed to init from data source!");
403d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        notifyPreparedAndCleanup(err);
404a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang        return;
405a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang    }
406a19f33e4e50cda5d5953fa0cc662502262ac9dfdChong Zhang
4079575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    if (mVideoTrack.mSource != NULL) {
40817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
40917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        sp<AMessage> msg = new AMessage;
41017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        err = convertMetaDataToMessage(meta, &msg);
41117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        if(err != OK) {
41217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            notifyPreparedAndCleanup(err);
41317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih            return;
41417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        }
41517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        notifyVideoSizeChanged(msg);
4169575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
4179575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
4189575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notifyFlagsChanged(
41942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            (mIsSecure ? FLAG_SECURE : 0)
4201713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
421cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            | FLAG_CAN_PAUSE
4229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_BACKWARD
4239575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_FORWARD
4249575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK);
4259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
426efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mIsStreaming) {
427efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mPrepareBuffering = true;
428efbb61950db36a5eb789be83f077246172507c67Chong Zhang
429efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ensureCacheIsFetching();
430efbb61950db36a5eb789be83f077246172507c67Chong Zhang        restartPollBuffering();
431efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else {
432efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notifyPrepared();
433efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
4349575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
4359575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
436d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangvoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
437d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (err != OK) {
438d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mMetaDataSize = -1ll;
439d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mContentType = "";
440d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mSniffedMIME = "";
441d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mDataSource.clear();
442d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mCachedSource.clear();
443360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih        mHttpSource.clear();
4442a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
4452a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        cancelPollBuffering();
446d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
447d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    notifyPrepared(err);
448d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang}
449d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
450d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhangstatus_t NuPlayer::GenericSource::prefillCacheIfNecessary() {
451d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    CHECK(mDataSource != NULL);
452d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
453d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mCachedSource == NULL) {
454d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // no prefill if the data source is not cached
455d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
456d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
457d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
458d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // We're not doing this for streams that appear to be audio-only
459d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // streams to ensure that even low bandwidth streams start
460d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // playing back fairly instantly.
461d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (!strncasecmp(mContentType.string(), "audio/", 6)) {
462d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
463d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
464d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
465d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // We're going to prefill the cache before trying to instantiate
466d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // the extractor below, as the latter is an operation that otherwise
467d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // could block on the datasource for a significant amount of time.
468d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // During that time we'd be unable to abort the preparation phase
469d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // without this prefill.
470d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
471d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // Initially make sure we have at least 192 KB for the sniff
472d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    // to complete without blocking.
473d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    static const size_t kMinBytesForSniffing = 192 * 1024;
474d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    static const size_t kDefaultMetaSize = 200000;
475d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
476d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    status_t finalStatus;
477d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
478d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    size_t cachedDataRemaining =
479d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mCachedSource->approxDataRemaining(&finalStatus);
480d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
481d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (finalStatus != OK || (mMetaDataSize >= 0
482d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            && (off64_t)cachedDataRemaining >= mMetaDataSize)) {
483d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        ALOGV("stop caching, status %d, "
484d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                "metaDataSize %lld, cachedDataRemaining %zu",
485d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                finalStatus, mMetaDataSize, cachedDataRemaining);
486d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        return OK;
487d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
488d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
489d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    ALOGV("now cached %zu bytes of data", cachedDataRemaining);
490d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
491d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    if (mMetaDataSize < 0
492d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            && cachedDataRemaining >= kMinBytesForSniffing) {
493d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        String8 tmp;
494d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        float confidence;
495d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        sp<AMessage> meta;
496d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (!mCachedSource->sniff(&tmp, &confidence, &meta)) {
497d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return UNKNOWN_ERROR;
498d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
499d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
500d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // We successfully identified the file's extractor to
501d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // be, remember this mime type so we don't have to
502d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        // sniff it again when we call MediaExtractor::Create()
503d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        mSniffedMIME = tmp.string();
504d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
505d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (meta == NULL
506d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                || !meta->findInt64("meta-data-size",
507d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang                        reinterpret_cast<int64_t*>(&mMetaDataSize))) {
508d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            mMetaDataSize = kDefaultMetaSize;
509d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
510d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
511d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        if (mMetaDataSize < 0ll) {
512d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            ALOGE("invalid metaDataSize = %lld bytes", mMetaDataSize);
513d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang            return UNKNOWN_ERROR;
514d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang        }
515d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    }
516d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
517d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang    return -EAGAIN;
518d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang}
519d354d8d1b09503c0166c1f3e626cda72a3eeb83cChong Zhang
520afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::start() {
521afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    ALOGI("start");
522afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
5232abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    mStopRead = false;
524afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
52517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
526afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
527afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
528afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
52917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
530afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
531802768790c131f8237364906fd13981a6bb91193Ronghua Wu
532802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
533802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
534efbb61950db36a5eb789be83f077246172507c67Chong Zhang
535efbb61950db36a5eb789be83f077246172507c67Chong Zhang    (new AMessage(kWhatStart, id()))->post();
536802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
537802768790c131f8237364906fd13981a6bb91193Ronghua Wu
538802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::stop() {
539802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
540802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
541802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
54242e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine || mIsSecure) {
54342e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // For widevine or secure sources we need to prevent any further reads.
5442abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());
5452abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        sp<AMessage> response;
5462abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        (void) msg->postAndAwaitResponse(&response);
5472abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
548802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
549802768790c131f8237364906fd13981a6bb91193Ronghua Wu
550802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::pause() {
551802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
552802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
553802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = false;
554802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
555802768790c131f8237364906fd13981a6bb91193Ronghua Wu
556802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::resume() {
557802768790c131f8237364906fd13981a6bb91193Ronghua Wu    // nothing to do, just account for DRM playback status
558802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
559802768790c131f8237364906fd13981a6bb91193Ronghua Wu    mStarted = true;
560efbb61950db36a5eb789be83f077246172507c67Chong Zhang
561efbb61950db36a5eb789be83f077246172507c67Chong Zhang    (new AMessage(kWhatResume, id()))->post();
562802768790c131f8237364906fd13981a6bb91193Ronghua Wu}
563802768790c131f8237364906fd13981a6bb91193Ronghua Wu
56448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhangvoid NuPlayer::GenericSource::disconnect() {
56548296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    if (mDataSource != NULL) {
56648296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        // disconnect data source
56748296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
56848296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
56948296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang        }
570360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih    } else if (mHttpSource != NULL) {
571360d6d0924f99b82ebacb5cfb6f7bca95e11b4eeRobert Shih        static_cast<HTTPBase *>(mHttpSource.get())->disconnect();
57248296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang    }
57348296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang}
57448296b792a8d68358de74141fa80bd5bd84d0307Chong Zhang
575802768790c131f8237364906fd13981a6bb91193Ronghua Wuvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
576802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (mDecryptHandle != NULL) {
577802768790c131f8237364906fd13981a6bb91193Ronghua Wu        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
578802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
57917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
58017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
581afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
582afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
583afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() {
584afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
585afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
586afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
5872a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::schedulePollBuffering() {
5882a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    sp<AMessage> msg = new AMessage(kWhatPollBuffering, id());
5892a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("generation", mPollBufferingGeneration);
5902a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->post(1000000ll);
5912a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
5922a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
5932a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::cancelPollBuffering() {
594efbb61950db36a5eb789be83f077246172507c67Chong Zhang    mBuffering = false;
5952a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    ++mPollBufferingGeneration;
5962a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
5972a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
598efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::restartPollBuffering() {
599efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mIsStreaming) {
600efbb61950db36a5eb789be83f077246172507c67Chong Zhang        cancelPollBuffering();
601efbb61950db36a5eb789be83f077246172507c67Chong Zhang        onPollBuffering();
602efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
603efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
604efbb61950db36a5eb789be83f077246172507c67Chong Zhang
6052a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) {
606efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("notifyBufferingUpdate: buffering %d%%", percentage);
607efbb61950db36a5eb789be83f077246172507c67Chong Zhang
6082a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    sp<AMessage> msg = dupNotify();
6092a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("what", kWhatBufferingUpdate);
6102a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->setInt32("percentage", percentage);
6112a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    msg->post();
6122a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
6132a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
614efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::startBufferingIfNecessary() {
615efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("startBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d",
616efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPrepareBuffering, mBuffering);
617efbb61950db36a5eb789be83f077246172507c67Chong Zhang
618efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mPrepareBuffering) {
619efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
620efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
621efbb61950db36a5eb789be83f077246172507c67Chong Zhang
622efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (!mBuffering) {
623efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mBuffering = true;
624efbb61950db36a5eb789be83f077246172507c67Chong Zhang
625efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ensureCacheIsFetching();
626efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sendCacheStats();
627efbb61950db36a5eb789be83f077246172507c67Chong Zhang
628efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
629efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatPauseOnBufferingStart);
630efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
631efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
632efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
633efbb61950db36a5eb789be83f077246172507c67Chong Zhang
634efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::stopBufferingIfNecessary() {
635efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ALOGV("stopBufferingIfNecessary: mPrepareBuffering=%d, mBuffering=%d",
636efbb61950db36a5eb789be83f077246172507c67Chong Zhang            mPrepareBuffering, mBuffering);
637efbb61950db36a5eb789be83f077246172507c67Chong Zhang
638efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mPrepareBuffering) {
639efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mPrepareBuffering = false;
640efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notifyPrepared();
641efbb61950db36a5eb789be83f077246172507c67Chong Zhang        return;
642efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
643efbb61950db36a5eb789be83f077246172507c67Chong Zhang
644efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mBuffering) {
645efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mBuffering = false;
646efbb61950db36a5eb789be83f077246172507c67Chong Zhang
647efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sendCacheStats();
648efbb61950db36a5eb789be83f077246172507c67Chong Zhang
649efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
650efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatResumeOnBufferingEnd);
651efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
652efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
653efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
654efbb61950db36a5eb789be83f077246172507c67Chong Zhang
655efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::sendCacheStats() {
656efbb61950db36a5eb789be83f077246172507c67Chong Zhang    int32_t kbps = 0;
657efbb61950db36a5eb789be83f077246172507c67Chong Zhang    status_t err = UNKNOWN_ERROR;
658efbb61950db36a5eb789be83f077246172507c67Chong Zhang
659efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mCachedSource != NULL) {
660efbb61950db36a5eb789be83f077246172507c67Chong Zhang        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
661efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (mWVMExtractor != NULL) {
662efbb61950db36a5eb789be83f077246172507c67Chong Zhang        err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps);
663efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
664efbb61950db36a5eb789be83f077246172507c67Chong Zhang
665efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (err == OK) {
666efbb61950db36a5eb789be83f077246172507c67Chong Zhang        sp<AMessage> notify = dupNotify();
667efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("what", kWhatCacheStats);
668efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->setInt32("bandwidth", kbps);
669efbb61950db36a5eb789be83f077246172507c67Chong Zhang        notify->post();
670efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
671efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
672efbb61950db36a5eb789be83f077246172507c67Chong Zhang
673efbb61950db36a5eb789be83f077246172507c67Chong Zhangvoid NuPlayer::GenericSource::ensureCacheIsFetching() {
674efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (mCachedSource != NULL) {
675efbb61950db36a5eb789be83f077246172507c67Chong Zhang        mCachedSource->resumeFetchingIfNecessary();
676efbb61950db36a5eb789be83f077246172507c67Chong Zhang    }
677efbb61950db36a5eb789be83f077246172507c67Chong Zhang}
678efbb61950db36a5eb789be83f077246172507c67Chong Zhang
6792a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhangvoid NuPlayer::GenericSource::onPollBuffering() {
6802a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    status_t finalStatus = UNKNOWN_ERROR;
681efbb61950db36a5eb789be83f077246172507c67Chong Zhang    int64_t cachedDurationUs = -1ll;
682efbb61950db36a5eb789be83f077246172507c67Chong Zhang    ssize_t cachedDataRemaining = -1;
6832a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
6842a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    if (mCachedSource != NULL) {
685efbb61950db36a5eb789be83f077246172507c67Chong Zhang        cachedDataRemaining =
6862a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                mCachedSource->approxDataRemaining(&finalStatus);
6872a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
6882a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        if (finalStatus == OK) {
6892a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            off64_t size;
6902a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            int64_t bitrate = 0ll;
6912a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
6922a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                bitrate = size * 8000000ll / mDurationUs;
6932a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            } else if (mBitrate > 0) {
6942a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                bitrate = mBitrate;
6952a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            }
6962a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            if (bitrate > 0) {
6972a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
6982a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            }
6992a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        }
7002a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    } else if (mWVMExtractor != NULL) {
7012a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        cachedDurationUs
7022a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang            = mWVMExtractor->getCachedDurationUs(&finalStatus);
7032a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    }
7042a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
705efbb61950db36a5eb789be83f077246172507c67Chong Zhang    if (finalStatus != OK) {
706efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus);
707efbb61950db36a5eb789be83f077246172507c67Chong Zhang
708efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (finalStatus == ERROR_END_OF_STREAM) {
709efbb61950db36a5eb789be83f077246172507c67Chong Zhang            notifyBufferingUpdate(100);
710efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
711efbb61950db36a5eb789be83f077246172507c67Chong Zhang
712efbb61950db36a5eb789be83f077246172507c67Chong Zhang        stopBufferingIfNecessary();
7132a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        return;
714efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (cachedDurationUs >= 0ll) {
715efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (mDurationUs > 0ll) {
716efbb61950db36a5eb789be83f077246172507c67Chong Zhang            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
717efbb61950db36a5eb789be83f077246172507c67Chong Zhang            int percentage = 100.0 * cachedPosUs / mDurationUs;
718efbb61950db36a5eb789be83f077246172507c67Chong Zhang            if (percentage > 100) {
719efbb61950db36a5eb789be83f077246172507c67Chong Zhang                percentage = 100;
720efbb61950db36a5eb789be83f077246172507c67Chong Zhang            }
721efbb61950db36a5eb789be83f077246172507c67Chong Zhang
722efbb61950db36a5eb789be83f077246172507c67Chong Zhang            notifyBufferingUpdate(percentage);
7232a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang        }
7242a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
725efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: cachedDurationUs %.1f sec",
726efbb61950db36a5eb789be83f077246172507c67Chong Zhang                cachedDurationUs / 1000000.0f);
727efbb61950db36a5eb789be83f077246172507c67Chong Zhang
728efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (cachedDurationUs < kLowWaterMarkUs) {
729efbb61950db36a5eb789be83f077246172507c67Chong Zhang            startBufferingIfNecessary();
730efbb61950db36a5eb789be83f077246172507c67Chong Zhang        } else if (cachedDurationUs > kHighWaterMarkUs) {
731efbb61950db36a5eb789be83f077246172507c67Chong Zhang            stopBufferingIfNecessary();
732efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
733efbb61950db36a5eb789be83f077246172507c67Chong Zhang    } else if (cachedDataRemaining >= 0) {
734efbb61950db36a5eb789be83f077246172507c67Chong Zhang        ALOGV("onPollBuffering: cachedDataRemaining %d bytes",
735efbb61950db36a5eb789be83f077246172507c67Chong Zhang                cachedDataRemaining);
736efbb61950db36a5eb789be83f077246172507c67Chong Zhang
737efbb61950db36a5eb789be83f077246172507c67Chong Zhang        if (cachedDataRemaining < kLowWaterMarkBytes) {
738efbb61950db36a5eb789be83f077246172507c67Chong Zhang            startBufferingIfNecessary();
739efbb61950db36a5eb789be83f077246172507c67Chong Zhang        } else if (cachedDataRemaining > kHighWaterMarkBytes) {
740efbb61950db36a5eb789be83f077246172507c67Chong Zhang            stopBufferingIfNecessary();
741efbb61950db36a5eb789be83f077246172507c67Chong Zhang        }
7422a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    }
7432a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7442a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang    schedulePollBuffering();
7452a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang}
7462a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang
7473423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihvoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
7483423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (msg->what()) {
7491228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      case kWhatPrepareAsync:
7501228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      {
7511228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          onPrepareAsync();
7521228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang          break;
7531228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang      }
7543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatFetchSubtitleData:
7553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
756e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
757e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
758e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
759e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
7603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
761e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatFetchTimedTextData:
762e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
763e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
764e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
7653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
7663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
7673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
7683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatSendSubtitleData:
7693423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
770e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
771e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
772e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          break;
773e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      }
7743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
775e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      case kWhatSendTimedTextData:
776e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar      {
777e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
778e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
7793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
7803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
7813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
7823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      case kWhatChangeAVSource:
7833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      {
7843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int32_t trackIndex;
7853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          CHECK(msg->findInt32("trackIndex", &trackIndex));
7863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const sp<MediaSource> source = mSources.itemAt(trackIndex);
7873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
7883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Track* track;
7893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const char *mime;
7903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          media_track_type trackType, counterpartType;
7913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          sp<MetaData> meta = source->getFormat();
7923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          meta->findCString(kKeyMIMEType, &mime);
7933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (!strncasecmp(mime, "audio/", 6)) {
7943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mAudioTrack;
7953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_AUDIO;
7963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
7973423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          } else {
7983423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              CHECK(!strncasecmp(mime, "video/", 6));
7993423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track = &mVideoTrack;
8003423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              trackType = MEDIA_TRACK_TYPE_VIDEO;
8013423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
8023423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
8033423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8043423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8053423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          if (track->mSource != NULL) {
8063423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih              track->mSource->stop();
8073423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          }
8083423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource = source;
8093423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mSource->start();
8103423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          track->mIndex = trackIndex;
8113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          int64_t timeUs, actualTimeUs;
8133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          const bool formatChange = true;
8145c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
8155c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mAudioLastDequeueTimeUs;
8165c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          } else {
8175c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih              timeUs = mVideoLastDequeueTimeUs;
8185c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih          }
8193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
8203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          readBuffer(counterpartType, -1, NULL, formatChange);
8213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);
8223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
8233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
8243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      }
825efbb61950db36a5eb789be83f077246172507c67Chong Zhang
826efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatStart:
827efbb61950db36a5eb789be83f077246172507c67Chong Zhang      case kWhatResume:
828efbb61950db36a5eb789be83f077246172507c67Chong Zhang      {
829efbb61950db36a5eb789be83f077246172507c67Chong Zhang          restartPollBuffering();
830efbb61950db36a5eb789be83f077246172507c67Chong Zhang          break;
831efbb61950db36a5eb789be83f077246172507c67Chong Zhang      }
832efbb61950db36a5eb789be83f077246172507c67Chong Zhang
8332a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      case kWhatPollBuffering:
8342a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      {
8352a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          int32_t generation;
8362a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          CHECK(msg->findInt32("generation", &generation));
8372a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          if (generation == mPollBufferingGeneration) {
8382a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang              onPollBuffering();
8392a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          }
8402a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang          break;
8412a3cc9a64330dd36e466fe5e1b634146f2d641c1Chong Zhang      }
84217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
84317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetFormat:
84417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
84517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetFormatMeta(msg);
84617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
84717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
84817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
84917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatGetSelectedTrack:
85017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
85117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onGetSelectedTrack(msg);
85217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
85317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
85417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
85517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSelectTrack:
85617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
85717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSelectTrack(msg);
85817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
85917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
86017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
86117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatSeek:
86217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
86317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onSeek(msg);
86417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
86517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
86617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
86717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      case kWhatReadBuffer:
86817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      {
86917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          onReadBuffer(msg);
87017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih          break;
87117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih      }
87217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
8732abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      case kWhatStopWidevine:
8742abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      {
8752abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // mStopRead is only used for Widevine to prevent the video source
8762abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          // from being read while the associated video decoder is shutting down.
8772abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          mStopRead = true;
8782abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          if (mVideoTrack.mSource != NULL) {
8792abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung              mVideoTrack.mPackets->clear();
8802abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          }
8812abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          sp<AMessage> response = new AMessage;
8822abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          uint32_t replyID;
8832abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          CHECK(msg->senderAwaitsResponse(&replyID));
8842abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          response->postReply(replyID);
8852abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung          break;
8862abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung      }
8873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih      default:
8883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          Source::onMessageReceived(msg);
8893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih          break;
8903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
8913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
8923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
893e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::fetchTextData(
894e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t sendWhat,
895e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
896e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
897e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
898e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
899e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
900e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
901e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
902e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
903e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
904e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
905e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
906e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t avail;
907e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->hasBufferAvailable(&avail)) {
908e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
909e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
910e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
911e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t timeUs;
912e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt64("timeUs", &timeUs));
913e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
914e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
915e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, timeUs, &subTimeUs);
916e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
917e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t delayUs = subTimeUs - timeUs;
918e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msg->what() == kWhatFetchSubtitleData) {
919e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t oneSecUs = 1000000ll;
920e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        delayUs -= oneSecUs;
921e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
922e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<AMessage> msg2 = new AMessage(sendWhat, id());
923e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->setInt32("generation", msgGeneration);
924e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    msg2->post(delayUs < 0 ? 0 : delayUs);
925e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
926e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
927e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarvoid NuPlayer::GenericSource::sendTextData(
928e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        uint32_t what,
929e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        media_track_type type,
930e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        int32_t curGen,
931e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AnotherPacketSource> packets,
932e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg) {
933e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int32_t msgGeneration;
934e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
935e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (msgGeneration != curGen) {
936e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        // stale
937e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
938e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
939e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
940e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t subTimeUs;
941e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (packets->nextBufferTime(&subTimeUs) != OK) {
942e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return;
943e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
944e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
945e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    int64_t nextSubTimeUs;
946e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    readBuffer(type, -1, &nextSubTimeUs);
947e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
948e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<ABuffer> buffer;
949e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
950e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (dequeueStatus == OK) {
951e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> notify = dupNotify();
952e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setInt32("what", what);
953e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->setBuffer("buffer", buffer);
954e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        notify->post();
955e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
956e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const int64_t delayUs = nextSubTimeUs - subTimeUs;
957e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post(delayUs < 0 ? 0 : delayUs);
958e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
959e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
960e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
961840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
96217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
96317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("audio", audio);
96417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
96517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
96617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    void *format;
96717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
96817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
96917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findPointer("format", &format));
97017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return (MetaData *)format;
97117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
97217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return NULL;
97317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
97417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
97517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
97617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
97717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t audio;
97817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("audio", &audio));
97917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
98017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
98117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<MetaData> format = doGetFormatMeta(audio);
98217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setPointer("format", format.get());
98317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
98417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
98517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
98617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
98717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
98817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
98917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihsp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
990afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
991afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
992afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (source == NULL) {
993afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return NULL;
994afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
995afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
996afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return source->getFormat();
997afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
998afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
999afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
1000afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
1001afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
1002afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1003afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (track->mSource == NULL) {
1004afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return -EWOULDBLOCK;
1005afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1006afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1007cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    if (mIsWidevine && !audio) {
1008cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        // try to read a buffer as we may not have been able to the last time
100917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
1010cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
1011cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
1012afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t finalResult;
1013afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
101442e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        if (finalResult == OK) {
101542e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            postReadBuffer(
101642e8153cf7271b572e4a94ade332b68521977f36Chong Zhang                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
101742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang            return -EWOULDBLOCK;
101842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        }
101942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        return finalResult;
1020afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1021afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1022afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
1023afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
10243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
102517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
1026e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1027e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
10283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (result != OK) {
1029e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL) {
1030e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mSubtitleTrack.mPackets->clear();
1031e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1032e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1033e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mTimedTextTrack.mSource != NULL) {
1034e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mTimedTextTrack.mPackets->clear();
1035e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1036e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
10373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return result;
10383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
10393423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
10403423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
10413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    status_t eosResult; // ignored
10423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
10435c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    if (audio) {
10445c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = timeUs;
10455c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    } else {
10465c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = timeUs;
10475c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih    }
1048e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1049e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mSubtitleTrack.mSource != NULL
1050e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
10513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
10523423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt64("timeUs", timeUs);
10533423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("generation", mFetchSubtitleDataGeneration);
10543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
10553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
1056eb1735e343a93830df259ae8882160bb0d79dcb5Robert Shih
1057e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (mTimedTextTrack.mSource != NULL
1058e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
1059e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
1060e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt64("timeUs", timeUs);
1061e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->setInt32("generation", mFetchTimedTextDataGeneration);
1062e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        msg->post();
1063e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1064e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1065afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return result;
1066afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1067afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1068afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
1069afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    *durationUs = mDurationUs;
1070afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
1071afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1072afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1073dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsize_t NuPlayer::GenericSource::getTrackCount() const {
1074dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return mSources.size();
1075dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
1076dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1077dd235727a1b4e283deeb581559f99c2c8889da07Robert Shihsp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
1078dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    size_t trackCount = mSources.size();
1079dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackIndex >= trackCount) {
1080dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        return NULL;
1081dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1082dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1083dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<AMessage> format = new AMessage();
1084dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
1085dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1086dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *mime;
1087dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
1088dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1089dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    int32_t trackType;
1090dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!strncasecmp(mime, "video/", 6)) {
1091dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_VIDEO;
1092dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strncasecmp(mime, "audio/", 6)) {
1093dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_AUDIO;
1094dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
1095dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
1096dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    } else {
1097dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
1098dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1099dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setInt32("type", trackType);
1100dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1101dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    const char *lang;
1102dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
1103dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        lang = "und";
1104dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1105dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    format->setString("language", lang);
1106dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1107dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
1108dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setString("mime", mime);
1109dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1110dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
1111dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
1112dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsDefault, &isDefault);
1113dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        meta->findInt32(kKeyTrackIsForced, &isForced);
1114dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1115dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("auto", !!isAutoselect);
1116dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("default", !!isDefault);
1117dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih        format->setInt32("forced", !!isForced);
1118dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    }
1119dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1120dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih    return format;
1121dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih}
1122dd235727a1b4e283deeb581559f99c2c8889da07Robert Shih
1123e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnarssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
112417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
112517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("type", type);
112617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
112717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
112817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t index;
112917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
113017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
113117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("index", &index));
113217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return index;
113317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    } else {
113417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        return -1;
113517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
113617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
113717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
113817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
113917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
114017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("type", &tmpType));
114117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type type = (media_track_type)tmpType;
114217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
114317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
114417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    ssize_t index = doGetSelectedTrack(type);
114517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("index", index);
114617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
114717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
114817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
114917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
115017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
115117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
115217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
1153e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    const Track *track = NULL;
1154e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    switch (type) {
1155e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_VIDEO:
1156e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mVideoTrack;
1157e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1158e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_AUDIO:
1159e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mAudioTrack;
1160e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1161e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_TIMEDTEXT:
1162e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mTimedTextTrack;
1163e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1164e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    case MEDIA_TRACK_TYPE_SUBTITLE:
1165e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track = &mSubtitleTrack;
1166e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1167e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    default:
1168e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        break;
1169e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1170e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1171e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (track != NULL && track->mSource != NULL) {
1172e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        return track->mIndex;
1173e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1174e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1175e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    return -1;
1176e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar}
1177e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
11786ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1179e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
118017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
118117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt32("trackIndex", trackIndex);
1182da23ab9b0dfa780175651daf057a02b0aa106dc8Robert Shih    msg->setInt32("select", select);
11836ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    msg->setInt64("timeUs", timeUs);
118417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
118517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
118617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
118717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
118817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
118917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
119017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
119117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
119217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
119317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
119417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
119517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t trackIndex, select;
11966ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    int64_t timeUs;
119717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackIndex", &trackIndex));
119817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("select", &select));
11996ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    CHECK(msg->findInt64("timeUs", &timeUs));
120017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
120117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
12026ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih    status_t err = doSelectTrack(trackIndex, select, timeUs);
120317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
120417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
120517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
120617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
120717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
120817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
120917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
12106ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shihstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) {
12113423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackIndex >= mSources.size()) {
12123423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return BAD_INDEX;
12133423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!select) {
1216e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track* track = NULL;
1217e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
1218e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mSubtitleTrack;
1219e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1220e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
1221e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1222e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1223e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1224e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track == NULL) {
12253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return INVALID_OPERATION;
12263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1227e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->stop();
1228e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = NULL;
1229e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mPackets->clear();
12303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
12313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12333423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    const sp<MediaSource> source = mSources.itemAt(trackIndex);
12343423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<MetaData> meta = source->getFormat();
12353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    const char *mime;
12363423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(meta->findCString(kKeyMIMEType, &mime));
12373423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (!strncasecmp(mime, "text/", 5)) {
1238e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
1239e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
1240e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL && track->mIndex == trackIndex) {
12413423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
12423423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1243e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mIndex = trackIndex;
1244e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mSource != NULL) {
1245e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mSource->stop();
12463423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1247e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource = mSources.itemAt(trackIndex);
1248e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        track->mSource->start();
1249e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (track->mPackets == NULL) {
1250e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
12513423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        } else {
1252e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->clear();
1253e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track->mPackets->setFormat(track->mSource->getFormat());
12543423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12553423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
1256e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
1257e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        if (isSubtitle) {
1258e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchSubtitleDataGeneration++;
1259e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        } else {
1260e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            mFetchTimedTextDataGeneration++;
1261e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        }
1262e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
12636ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        status_t eosResult; // ignored
12646ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mSubtitleTrack.mSource != NULL
12656ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
12666ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
12676ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
12686ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchSubtitleDataGeneration);
12696ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
12706ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
12716ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
12726ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        if (mTimedTextTrack.mSource != NULL
12736ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
12746ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
12756ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt64("timeUs", timeUs);
12766ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->setInt32("generation", mFetchTimedTextDataGeneration);
12776ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih            msg->post();
12786ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih        }
12796ffb1fd67eb8f00f130a6db914ba42a8432aec70Robert Shih
12803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
12813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
12823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        bool audio = !strncasecmp(mime, "audio/", 6);
12833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        Track *track = audio ? &mAudioTrack : &mVideoTrack;
12843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (track->mSource != NULL && track->mIndex == trackIndex) {
12853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            return OK;
12863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
12873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
12893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->setInt32("trackIndex", trackIndex);
12903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        msg->post();
12913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return OK;
12923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
12933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
12943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return INVALID_OPERATION;
12953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
12963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1297afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
129817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> msg = new AMessage(kWhatSeek, id());
129917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    msg->setInt64("seekTimeUs", seekTimeUs);
130017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
130117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response;
130217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
130317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    if (err == OK && response != NULL) {
130417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih        CHECK(response->findInt32("err", &err));
130517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    }
130617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
130717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    return err;
130817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
130917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
131017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
131117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int64_t seekTimeUs;
131217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
131317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
131417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    sp<AMessage> response = new AMessage;
131517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    status_t err = doSeek(seekTimeUs);
131617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->setInt32("err", err);
131717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
131817f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    uint32_t replyID;
131917f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->senderAwaitsResponse(&replyID));
132017f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    response->postReply(replyID);
132117f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
132217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
132317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
13242abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // If the Widevine source is stopped, do not attempt to read any
13252abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // more buffers.
13262abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
13272abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return INVALID_OPERATION;
13282abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
1329afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
1330afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        int64_t actualTimeUs;
13313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
1332afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1333afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seekTimeUs = actualTimeUs;
13345c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mVideoLastDequeueTimeUs = seekTimeUs;
1335afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1336afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1337afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
13383423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
13395c67ddcf987b1f07c9abc1d051a0c051e7c73ff7Robert Shih        mAudioLastDequeueTimeUs = seekTimeUs;
1340afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1341afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1342802768790c131f8237364906fd13981a6bb91193Ronghua Wu    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
1343802768790c131f8237364906fd13981a6bb91193Ronghua Wu    if (!mStarted) {
1344802768790c131f8237364906fd13981a6bb91193Ronghua Wu        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
1345802768790c131f8237364906fd13981a6bb91193Ronghua Wu    }
1346efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1347efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // If currently buffering, post kWhatBufferingEnd first, so that
1348efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // NuPlayer resumes. Otherwise, if cache hits high watermark
1349efbb61950db36a5eb789be83f077246172507c67Chong Zhang    // before new polling happens, no one will resume the playback.
1350efbb61950db36a5eb789be83f077246172507c67Chong Zhang    stopBufferingIfNecessary();
1351efbb61950db36a5eb789be83f077246172507c67Chong Zhang    restartPollBuffering();
1352efbb61950db36a5eb789be83f077246172507c67Chong Zhang
1353afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
1354afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1355afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
13563423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shihsp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
13573423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        MediaBuffer* mb,
13583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType,
1359474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        int64_t /* seekTimeUs */,
13603423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int64_t *actualTimeUs) {
13613423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
13623423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    size_t outLength = mb->range_length();
13633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13643423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
13653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        outLength += sizeof(int32_t);
13663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13683423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    sp<ABuffer> ab;
136942e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsSecure && !audio) {
13703423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        // data is already provided in the buffer
13713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(NULL, mb->range_length());
13723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        mb->add_ref();
137396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia        ab->setMediaBufferBase(mb);
13743423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    } else {
13753423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        ab = new ABuffer(outLength);
13763423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(ab->data(),
13773423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               (const uint8_t *)mb->data() + mb->range_offset(),
13783423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih               mb->range_length());
13793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (audio && mAudioIsVorbis) {
13823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        int32_t numPageSamples;
13833423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
13843423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            numPageSamples = -1;
13853423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        }
13863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
13873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        uint8_t* abEnd = ab->data() + mb->range_length();
13883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
13893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
13903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1391e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    sp<AMessage> meta = ab->meta();
1392e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
13933423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t timeUs;
13943423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
13953423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    meta->setInt64("timeUs", timeUs);
13963423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
1397474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#if 0
1398474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // Temporarily disable pre-roll till we have a full solution to handle
1399474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    // both single seek and continous seek gracefully.
1400474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    if (seekTimeUs > timeUs) {
1401474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        sp<AMessage> extra = new AMessage;
1402474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
1403474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia        meta->setMessage("extra", extra);
1404474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia    }
1405474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia#endif
1406474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia
1407e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
1408e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        const char *mime;
1409e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        CHECK(mTimedTextTrack.mSource != NULL
1410e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
1411e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        meta->setString("mime", mime);
1412e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar    }
1413e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar
14143423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    int64_t durationUs;
14153423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
14163423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt64("durationUs", durationUs);
14173423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14183423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14193423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
14203423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
14213423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14223423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14233423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (actualTimeUs) {
14243423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        *actualTimeUs = timeUs;
14253423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb->release();
14283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    mb = NULL;
14293423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14303423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    return ab;
14313423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih}
14323423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
143317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
143484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    Mutex::Autolock _l(mReadBufferLock);
143584f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar
143684f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
143784f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes |= (1 << trackType);
143884f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        sp<AMessage> msg = new AMessage(kWhatReadBuffer, id());
143984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->setInt32("trackType", trackType);
144084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        msg->post();
144184f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
144217f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
144317f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
144417f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shihvoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
144517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    int32_t tmpType;
144617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    CHECK(msg->findInt32("trackType", &tmpType));
144717f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih    media_track_type trackType = (media_track_type)tmpType;
144842e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    readBuffer(trackType);
144984f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    {
145084f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        // only protect the variable change, as readBuffer may
145142e8153cf7271b572e4a94ade332b68521977f36Chong Zhang        // take considerable time.
145284f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        Mutex::Autolock _l(mReadBufferLock);
145384f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar        mPendingReadBufferTypes &= ~(1 << trackType);
145484f5278a36f2816cc38f64307b4a1ad8a6818507Lajos Molnar    }
145517f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih}
145617f6dd64cd749f4e38e12b672b551047f4cbe9b4Robert Shih
1457afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::readBuffer(
14583423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
14592abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    // Do not read data if Widevine source is stopped
14602abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    if (mStopRead) {
14612abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung        return;
14622abde2c118a94f843a7450818c925d3f0b673cd3Andy Hung    }
14633423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    Track *track;
1464c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    size_t maxBuffers = 1;
14653423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    switch (trackType) {
14663423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_VIDEO:
14673423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mVideoTrack;
1468a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1469a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 2;
1470a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
14713423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
14723423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_AUDIO:
14733423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mAudioTrack;
1474a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            if (mIsWidevine) {
1475a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 8;
1476a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            } else {
1477a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker                maxBuffers = 64;
1478a28785aa9ce323494a6971a38ce1d4d29bf710e4Jeff Tinker            }
14793423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
14803423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        case MEDIA_TRACK_TYPE_SUBTITLE:
14813423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            track = &mSubtitleTrack;
14823423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            break;
1483e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar        case MEDIA_TRACK_TYPE_TIMEDTEXT:
1484e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            track = &mTimedTextTrack;
1485e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            break;
14863423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        default:
14873423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            TRESPASS();
14883423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
14893423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih
14903423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    if (track->mSource == NULL) {
14913423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        return;
14923423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih    }
1493afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1494afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (actualTimeUs) {
1495afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        *actualTimeUs = seekTimeUs;
1496afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1497afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1498afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    MediaSource::ReadOptions options;
1499afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1500afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    bool seeking = false;
1501afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1502afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (seekTimeUs >= 0) {
15033423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1504afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seeking = true;
1505afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1506afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
150742e8153cf7271b572e4a94ade332b68521977f36Chong Zhang    if (mIsWidevine) {
1508cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        options.setNonBlocking();
1509cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar    }
1510cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar
1511c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
1512afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        MediaBuffer *mbuf;
1513afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        status_t err = track->mSource->read(&mbuf, &options);
1514afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1515afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        options.clearSeekTo();
1516afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1517afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (err == OK) {
1518802768790c131f8237364906fd13981a6bb91193Ronghua Wu            int64_t timeUs;
1519802768790c131f8237364906fd13981a6bb91193Ronghua Wu            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
1520802768790c131f8237364906fd13981a6bb91193Ronghua Wu            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
1521802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mAudioTimeUs = timeUs;
1522802768790c131f8237364906fd13981a6bb91193Ronghua Wu            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
1523802768790c131f8237364906fd13981a6bb91193Ronghua Wu                mVideoTimeUs = timeUs;
1524802768790c131f8237364906fd13981a6bb91193Ronghua Wu            }
1525802768790c131f8237364906fd13981a6bb91193Ronghua Wu
15263423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // formatChange && seeking: track whose source is changed during selection
15273423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // formatChange && !seeking: track whose source is not changed during selection
15283423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih            // !formatChange: normal seek
1529e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar            if ((seeking || formatChange)
1530e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
1531e26940f11c3f2040bced09f06a8f374b50c985fbLajos Molnar                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
1532fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                ATSParser::DiscontinuityType type = (formatChange && seeking)
1533fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ? ATSParser::DISCONTINUITY_FORMATCHANGE
1534fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        : ATSParser::DISCONTINUITY_NONE;
15353423bbdb05f843a64356fa24e8657f03ecbb7d65Robert Shih                track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
1536afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
1537afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1538474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia            sp<ABuffer> buffer = mediaBufferToABuffer(
1539474d7c778b63aa33dcf25a92e23a52c1c47f0ac1Wei Jia                    mbuf, trackType, seekTimeUs, actualTimeUs);
1540afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueAccessUnit(buffer);
1541317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            formatChange = false;
1542317a49a4c4bf02944d1e01941c6b9f86179044bbMarco Nelissen            seeking = false;
1543c5cc2e21602182c7ab4df1d7eba40f18037c1818Phil Burk            ++numBuffers;
1544cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar        } else if (err == WOULD_BLOCK) {
1545cc227036b05f7c2f960a89c567a61f9decefe742Lajos Molnar            break;
1546afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (err == INFO_FORMAT_CHANGED) {
1547afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#if 0
1548afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueDiscontinuity(
1549632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    ATSParser::DISCONTINUITY_FORMATCHANGE,
1550632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    NULL,
1551632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                    false /* discard */);
1552afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#endif
1553afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else {
1554afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->signalEOS(err);
1555afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            break;
1556afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
1557afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
1558afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
1559afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1560afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}  // namespace android
1561