GenericSource.cpp revision 1d883b2bedfb60f4f0406b3775fcd6fb890baf2d
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2012 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "GenericSource"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "GenericSource.h"
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "AnotherPacketSource.h"
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/IMediaHTTPService.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/DataSource.h>
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/FileSource.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaBuffer.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/MediaExtractor.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaSource.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/MetaData.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h>
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include "../../libstagefright/include/DRMExtractor.h"
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include "../../libstagefright/include/NuCachedSource2.h"
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "../../libstagefright/include/WVMExtractor.h"
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "../../libstagefright/include/HTTPBase.h"
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubernamespace android {
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int64_t kHighWaterMarkRebufferUs = 15000000ll;  // 15secs
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const ssize_t kLowWaterMarkBytes = 40000;
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic const ssize_t kHighWaterMarkBytes = 200000;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::GenericSource::GenericSource(
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &notify,
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool uidValid,
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uid_t uid)
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : Source(notify),
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAudioTimeUs(0),
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAudioLastDequeueTimeUs(0),
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoTimeUs(0),
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoLastDequeueTimeUs(0),
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFetchSubtitleDataGeneration(0),
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFetchTimedTextDataGeneration(0),
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mDurationUs(-1ll),
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAudioIsVorbis(false),
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mIsWidevine(false),
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mIsSecure(false),
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mIsStreaming(false),
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mUIDValid(uidValid),
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mUID(uid),
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFd(-1),
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mDrmManagerClient(NULL),
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mBitrate(-1ll),
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mPendingReadBufferTypes(0) {
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBufferingMonitor = new BufferingMonitor(notify);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resetDataSource();
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DataSource::RegisterDefaultSniffers();
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::resetDataSource() {
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHTTPService.clear();
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHttpSource.clear();
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUri.clear();
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUriHeaders.clear();
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFd >= 0) {
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        close(mFd);
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFd = -1;
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOffset = 0;
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLength = 0;
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDecryptHandle = NULL;
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDrmManagerClient = NULL;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mStarted = false;
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mStopRead = true;
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mBufferingMonitorLooper != NULL) {
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBufferingMonitorLooper->unregisterHandler(mBufferingMonitor->id());
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBufferingMonitorLooper->stop();
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBufferingMonitorLooper = NULL;
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBufferingMonitor->stop();
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::setDataSource(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<IMediaHTTPService> &httpService,
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *url,
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const KeyedVector<String8, String8> *headers) {
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resetDataSource();
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHTTPService = httpService;
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUri = url;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (headers) {
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mUriHeaders = *headers;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // delay data source creation to prepareAsync() to avoid blocking
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // the calling thread in setDataSource for any significant time.
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::setDataSource(
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int fd, int64_t offset, int64_t length) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resetDataSource();
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFd = dup(fd);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOffset = offset;
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLength = length;
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // delay data source creation to prepareAsync() to avoid blocking
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // the calling thread in setDataSource for any significant time.
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::setDataSource(const sp<DataSource>& source) {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resetDataSource();
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDataSource = source;
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mFileMeta;
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::initFromDataSource() {
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IMediaExtractor> extractor;
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    String8 mimeType;
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    float confidence;
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> dummy;
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool isWidevineStreaming = false;
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDataSource != NULL);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mIsWidevine) {
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isWidevineStreaming = SniffWVM(
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDataSource, &mimeType, &confidence, &dummy);
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!isWidevineStreaming ||
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strcasecmp(
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("unsupported widevine mime: %s", mimeType.string());
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return UNKNOWN_ERROR;
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (mIsStreaming) {
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!mDataSource->sniff(&mimeType, &confidence, &dummy)) {
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return UNKNOWN_ERROR;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isWidevineStreaming = !strcasecmp(
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM);
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (isWidevineStreaming) {
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // we don't want cached source for widevine streaming.
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCachedSource.clear();
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDataSource = mHttpSource;
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mWVMExtractor = new WVMExtractor(mDataSource);
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mWVMExtractor->setAdaptiveStreamingMode(true);
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        if (mUIDValid) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mWVMExtractor->setUID(mUID);
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        extractor = mWVMExtractor;
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    } else {
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        extractor = MediaExtractor::Create(mDataSource,
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber                mimeType.isEmpty() ? NULL : mimeType.string());
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (extractor == NULL) {
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return UNKNOWN_ERROR;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (extractor->getDrmFlag()) {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        checkDrmStatus(mDataSource);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFileMeta = extractor->getMetaData();
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mFileMeta != NULL) {
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t duration;
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDurationUs = duration;
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        if (!mIsWidevine) {
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            // Check mime to see if we actually have a widevine source.
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // If the data source is not URL-type (eg. file source), we
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // won't be able to tell until now.
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const char *fileMime;
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mFileMeta->findCString(kKeyMIMEType, &fileMime)
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && !strncasecmp(fileMime, "video/wvm", 9)) {
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                mIsWidevine = true;
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    int32_t totalBitrate = 0;
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    size_t numtracks = extractor->countTracks();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (numtracks == 0) {
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return UNKNOWN_ERROR;
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    for (size_t i = 0; i < numtracks; ++i) {
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        sp<IMediaSource> track = extractor->getTrack(i);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        if (track == NULL) {
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            continue;
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        if (meta == NULL) {
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("no metadata for track %zu", i);
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return UNKNOWN_ERROR;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Do the string compare immediately with "mime",
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // we can't assume "mime" would stay valid after another
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // extractor operation, some extractors might modify meta
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // during getTrack() and make it invalid.
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strncasecmp(mime, "audio/", 6)) {
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mAudioTrack.mSource == NULL) {
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAudioTrack.mIndex = i;
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAudioTrack.mSource = track;
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAudioTrack.mPackets =
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AnotherPacketSource(mAudioTrack.mSource->getFormat());
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioIsVorbis = true;
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioIsVorbis = false;
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else if (!strncasecmp(mime, "video/", 6)) {
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mVideoTrack.mSource == NULL) {
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mVideoTrack.mIndex = i;
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mVideoTrack.mSource = track;
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mVideoTrack.mPackets =
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AnotherPacketSource(mVideoTrack.mSource->getFormat());
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // check if the source requires secure buffers
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t secure;
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        && secure) {
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mIsSecure = true;
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (mUIDValid) {
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        extractor->setUID(mUID);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mSources.push(track);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t durationUs;
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (meta->findInt64(kKeyDuration, &durationUs)) {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (durationUs > mDurationUs) {
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDurationUs = durationUs;
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t bitrate;
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            totalBitrate += bitrate;
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            totalBitrate = -1;
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mSources.size() == 0) {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("b/23705695");
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBitrate = totalBitrate;
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::startSources() {
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Start the selected A/V tracks now before we start buffering.
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Widevine sources might re-initialize crypto when starting, if we delay
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // this to start(), all data buffered during prepare would be wasted.
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // (We don't actually start reading until start().)
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioTrack.mSource != NULL && mAudioTrack.mSource->start() != OK) {
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("failed to start audio track!");
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoTrack.mSource != NULL && mVideoTrack.mSource->start() != OK) {
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("failed to start video track!");
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mDecryptHandle != NULL) {
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(mDrmManagerClient);
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> msg = dupNotify();
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("what", kWhatDrmNoLicense);
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->post();
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint64_t NuPlayer::GenericSource::getLastReadPosition() {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioTrack.mSource != NULL) {
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mAudioTimeUs;
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (mVideoTrack.mSource != NULL) {
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mVideoTimeUs;
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return 0;
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::setBuffers(
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool audio, Vector<MediaBuffer *> &buffers) {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mIsSecure && !audio && mVideoTrack.mSource != NULL) {
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mVideoTrack.mSource->setBuffers(buffers);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return INVALID_OPERATION;
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::GenericSource::isStreaming() const {
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mIsStreaming;
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::setOffloadAudio(bool offload) {
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBufferingMonitor->setOffloadAudio(offload);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::GenericSource::~GenericSource() {
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mLooper != NULL) {
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->unregisterHandler(id());
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->stop();
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resetDataSource();
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::prepareAsync() {
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mLooper == NULL) {
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mLooper = new ALooper;
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mLooper->setName("generic");
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->start();
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mLooper->registerHandler(this);
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber    msg->post();
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid NuPlayer::GenericSource::onPrepareAsync() {
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    // delayed data source creation
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (mDataSource == NULL) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // set to false first, if the extractor
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        // comes back as secure, set it to true then.
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mIsSecure = false;
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!mUri.empty()) {
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const char* uri = mUri.c_str();
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            String8 contentType;
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!strncasecmp("http://", uri, 7)
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || !strncasecmp("https://", uri, 8)
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || mIsWidevine) {
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mHttpSource == NULL) {
388dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    ALOGE("Failed to create http source!");
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    return;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDataSource = DataSource::CreateFromURI(
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                   mHTTPService, uri, &mUriHeaders, &contentType,
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                   static_cast<HTTPBase *>(mHttpSource.get()));
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mIsWidevine = false;
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mDataSource = new FileSource(mFd, mOffset, mLength);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFd = -1;
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mDataSource == NULL) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Failed to create data source!");
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            notifyPreparedAndCleanup(UNKNOWN_ERROR);
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return;
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // For widevine or other cached streaming cases, we need to wait for
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // enough buffering before reporting prepared.
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Note that even when URL doesn't start with widevine://, mIsWidevine
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // could still be set to true later, if the streaming or file source
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // is sniffed to be widevine. We don't want to buffer for file source
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // in that case, so must check the flag now.
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsStreaming = (mIsWidevine || mCachedSource != NULL);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // init extractor from data source
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = initFromDataSource();
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err != OK) {
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("Failed to init from data source!");
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notifyPreparedAndCleanup(err);
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        return;
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mVideoTrack.mSource != NULL) {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> msg = new AMessage;
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = convertMetaDataToMessage(meta, &msg);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if(err != OK) {
4377a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            notifyPreparedAndCleanup(err);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notifyVideoSizeChanged(msg);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notifyFlagsChanged(
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            (mIsSecure ? FLAG_SECURE : 0)
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            | FLAG_CAN_PAUSE
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            | FLAG_CAN_SEEK_BACKWARD
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            | FLAG_CAN_SEEK_FORWARD
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            | FLAG_CAN_SEEK);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (mIsSecure) {
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        // secure decoders must be instantiated before starting widevine source
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, this);
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        notifyInstantiateSecureDecoders(reply);
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        finishPrepareAsync();
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) {
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Failed to instantiate secure decoders!");
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        notifyPreparedAndCleanup(err);
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return;
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    finishPrepareAsync();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::finishPrepareAsync() {
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = startSources();
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Failed to init start data source!");
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notifyPreparedAndCleanup(err);
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return;
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mIsStreaming) {
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mBufferingMonitorLooper == NULL) {
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mBufferingMonitor->prepare(mCachedSource, mWVMExtractor, mDurationUs, mBitrate,
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mIsStreaming);
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mBufferingMonitorLooper = new ALooper;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mBufferingMonitorLooper->setName("GSBMonitor");
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mBufferingMonitorLooper->start();
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mBufferingMonitorLooper->registerHandler(mBufferingMonitor);
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBufferingMonitor->ensureCacheIsFetching();
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mBufferingMonitor->restartPollBuffering();
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    } else {
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notifyPrepared();
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    }
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber}
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Hubervoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
4961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    if (err != OK) {
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        {
498308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            sp<DataSource> dataSource = mDataSource;
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            sp<NuCachedSource2> cachedSource = mCachedSource;
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            sp<DataSource> httpSource = mHttpSource;
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            {
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                Mutex::Autolock _l(mDisconnectLock);
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                mDataSource.clear();
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                mDecryptHandle = NULL;
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                mDrmManagerClient = NULL;
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mCachedSource.clear();
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mHttpSource.clear();
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mBitrate = -1;
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mBufferingMonitor->cancelPollBuffering();
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    notifyPrepared(err);
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubervoid NuPlayer::GenericSource::start() {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ALOGI("start");
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    mStopRead = false;
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mAudioTrack.mSource != NULL) {
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
5231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoTrack.mSource != NULL) {
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mStarted = true;
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, this))->post();
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid NuPlayer::GenericSource::stop() {
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    // nothing to do, just account for DRM playback status
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mStarted = false;
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mIsWidevine || mIsSecure) {
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        // For widevine or secure sources we need to prevent any further reads.
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = new AMessage(kWhatStopWidevine, this);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> response;
543eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        (void) msg->postAndAwaitResponse(&response);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::pause() {
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // nothing to do, just account for DRM playback status
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStarted = false;
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::resume() {
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // nothing to do, just account for DRM playback status
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mStarted = true;
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, this))->post();
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::disconnect() {
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<DataSource> dataSource, httpSource;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    {
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Mutex::Autolock _l(mDisconnectLock);
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        dataSource = mDataSource;
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        httpSource = mHttpSource;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (dataSource != NULL) {
57029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        // disconnect data source
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (dataSource->flags() & DataSource::kIsCachingDataSource) {
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (httpSource != NULL) {
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        static_cast<HTTPBase *>(httpSource.get())->disconnect();
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis}
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Blockvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (mDecryptHandle != NULL) {
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() {
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    return OK;
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubervoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    switch (msg->what()) {
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      case kWhatPrepareAsync:
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      {
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber          onPrepareAsync();
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber          break;
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      }
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      case kWhatFetchSubtitleData:
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      {
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber          break;
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      }
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      case kWhatFetchTimedTextData:
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber      {
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
6093c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis          break;
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block      case kWhatSendSubtitleData:
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      {
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
616054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          break;
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      }
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      case kWhatSendGlobalTimedTextData:
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      {
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          sendGlobalTextData(kWhatTimedTextData, mFetchTimedTextDataGeneration, msg);
62229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block          break;
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      }
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      case kWhatSendTimedTextData:
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      {
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          break;
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      }
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      case kWhatChangeAVSource:
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis      {
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          int32_t trackIndex;
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          CHECK(msg->findInt32("trackIndex", &trackIndex));
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          const sp<IMediaSource> source = mSources.itemAt(trackIndex);
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block          Track* track;
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          const char *mime;
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          media_track_type trackType, counterpartType;
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          sp<MetaData> meta = source->getFormat();
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          meta->findCString(kKeyMIMEType, &mime);
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis          if (!strncasecmp(mime, "audio/", 6)) {
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              track = &mAudioTrack;
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              trackType = MEDIA_TRACK_TYPE_AUDIO;
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          } else {
64729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block              CHECK(!strncasecmp(mime, "video/", 6));
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              track = &mVideoTrack;
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              trackType = MEDIA_TRACK_TYPE_VIDEO;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          }
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          if (track->mSource != NULL) {
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar              track->mSource->stop();
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          }
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          track->mSource = source;
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          track->mSource->start();
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          track->mIndex = trackIndex;
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          int64_t timeUs, actualTimeUs;
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          const bool formatChange = true;
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
6643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block              timeUs = mAudioLastDequeueTimeUs;
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          } else {
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar              timeUs = mVideoLastDequeueTimeUs;
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          }
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          readBuffer(counterpartType, -1, NULL, !formatChange);
6708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev          ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
6711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
67329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block      }
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatStart:
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatResume:
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      {
67874006804065941841883c4b46ee785070164023fJamie Gennis          mBufferingMonitor->restartPollBuffering();
67974006804065941841883c4b46ee785070164023fJamie Gennis          break;
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      }
68174006804065941841883c4b46ee785070164023fJamie Gennis
68274006804065941841883c4b46ee785070164023fJamie Gennis      case kWhatGetFormat:
68374006804065941841883c4b46ee785070164023fJamie Gennis      {
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onGetFormatMeta(msg);
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block      case kWhatGetSelectedTrack:
68974006804065941841883c4b46ee785070164023fJamie Gennis      {
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onGetSelectedTrack(msg);
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
69374006804065941841883c4b46ee785070164023fJamie Gennis
69474006804065941841883c4b46ee785070164023fJamie Gennis      case kWhatSelectTrack:
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block      {
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onSelectTrack(msg);
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatSeek:
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onSeek(msg);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatReadBuffer:
70774006804065941841883c4b46ee785070164023fJamie Gennis      {
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onReadBuffer(msg);
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          break;
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      }
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatSecureDecodersInstantiated:
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      {
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          int32_t err;
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          CHECK(msg->findInt32("err", &err));
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          onSecureDecodersInstantiated(err);
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          break;
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      }
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      case kWhatStopWidevine:
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      {
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          // mStopRead is only used for Widevine to prevent the video source
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          // from being read while the associated video decoder is shutting down.
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mStopRead = true;
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          if (mVideoTrack.mSource != NULL) {
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar              mVideoTrack.mPackets->clear();
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          }
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          sp<AMessage> response = new AMessage;
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          sp<AReplyToken> replyID;
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          CHECK(msg->senderAwaitsResponse(&replyID));
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          response->postReply(replyID);
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          break;
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      }
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      default:
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          Source::onMessageReceived(msg);
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          break;
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid NuPlayer::GenericSource::fetchTextData(
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        uint32_t sendWhat,
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        media_track_type type,
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        int32_t curGen,
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AnotherPacketSource> packets,
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AMessage> msg) {
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t msgGeneration;
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(msg->findInt32("generation", &msgGeneration));
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (msgGeneration != curGen) {
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // stale
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return;
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t avail;
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (packets->hasBufferAvailable(&avail)) {
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return;
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int64_t timeUs;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(msg->findInt64("timeUs", &timeUs));
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int64_t subTimeUs;
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    readBuffer(type, timeUs, &subTimeUs);
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int64_t delayUs = subTimeUs - timeUs;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (msg->what() == kWhatFetchSubtitleData) {
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        const int64_t oneSecUs = 1000000ll;
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        delayUs -= oneSecUs;
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<AMessage> msg2 = new AMessage(sendWhat, this);
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    msg2->setInt32("generation", msgGeneration);
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    msg2->post(delayUs < 0 ? 0 : delayUs);
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid NuPlayer::GenericSource::sendTextData(
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        uint32_t what,
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        media_track_type type,
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        int32_t curGen,
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AnotherPacketSource> packets,
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AMessage> msg) {
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t msgGeneration;
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("generation", &msgGeneration));
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msgGeneration != curGen) {
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // stale
7843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        return;
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t subTimeUs;
7881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (packets->nextBufferTime(&subTimeUs) != OK) {
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t nextSubTimeUs;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    readBuffer(type, -1, &nextSubTimeUs);
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> buffer;
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (dequeueStatus == OK) {
7988ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        sp<AMessage> notify = dupNotify();
7991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        notify->setInt32("what", what);
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        notify->setBuffer("buffer", buffer);
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        notify->post();
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        const int64_t delayUs = nextSubTimeUs - subTimeUs;
804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        msg->post(delayUs < 0 ? 0 : delayUs);
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::sendGlobalTextData(
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t what,
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t curGen,
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AMessage> msg) {
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t msgGeneration;
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("generation", &msgGeneration));
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msgGeneration != curGen) {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // stale
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    uint32_t textType;
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    const void *data;
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t size = 0;
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mTimedTextTrack.mSource->getFormat()->findData(
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    kKeyTextFormatData, &textType, &data, &size)) {
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mGlobalTimedText = new ABuffer(size);
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mGlobalTimedText->data()) {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            memcpy(mGlobalTimedText->data(), data, size);
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            sp<AMessage> globalMeta = mGlobalTimedText->meta();
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            globalMeta->setInt64("timeUs", 0);
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            globalMeta->setString("mime", MEDIA_MIMETYPE_TEXT_3GPP);
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            globalMeta->setInt32("global", 1);
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            sp<AMessage> notify = dupNotify();
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            notify->setInt32("what", what);
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            notify->setBuffer("buffer", mGlobalTimedText);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            notify->post();
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
837d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar}
838d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarsp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetFormat, this);
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    msg->setInt32("audio", audio);
842d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    sp<AMessage> response;
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    sp<RefBase> format;
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    if (err == OK && response != NULL) {
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(response->findObject("format", &format));
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return static_cast<MetaData*>(format.get());
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    } else {
850d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        return NULL;
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t audio;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("audio", &audio));
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> response = new AMessage;
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MetaData> format = doGetFormatMeta(audio);
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    response->setObject("format", format);
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AReplyToken> replyID;
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->senderAwaitsResponse(&replyID));
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    response->postReply(replyID);
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IMediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (source == NULL) {
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return NULL;
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return source->getFormat();
8752ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar}
8762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnarstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        bool audio, sp<ABuffer> *accessUnit) {
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio && !mStarted) {
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (track->mSource == NULL) {
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mIsWidevine && !audio) {
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // try to read a buffer as we may not have been able to the last time
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t finalResult;
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (finalResult == OK) {
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postReadBuffer(
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return -EWOULDBLOCK;
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return finalResult;
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // start pulling in more buffers if we only have one (or no) buffer left
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // so that decoder has less chance of being starved
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (result != OK) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mSubtitleTrack.mSource != NULL) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mSubtitleTrack.mPackets->clear();
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFetchSubtitleDataGeneration++;
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mTimedTextTrack.mSource != NULL) {
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mTimedTextTrack.mPackets->clear();
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFetchTimedTextDataGeneration++;
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return result;
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t timeUs;
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t eosResult; // ignored
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioLastDequeueTimeUs = timeUs;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBufferingMonitor->updateDequeuedBufferTime(timeUs);
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoLastDequeueTimeUs = timeUs;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mSubtitleTrack.mSource != NULL
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
9362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
9372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        msg->setInt64("timeUs", timeUs);
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        msg->setInt32("generation", mFetchSubtitleDataGeneration);
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        msg->post();
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mTimedTextTrack.mSource != NULL
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt64("timeUs", timeUs);
946729de186450f78c099637e1fce743fe531862c52Andreas Huber        msg->setInt32("generation", mFetchTimedTextDataGeneration);
947729de186450f78c099637e1fce743fe531862c52Andreas Huber        msg->post();
948c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber    }
949c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber    return result;
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber}
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    *durationUs = mDurationUs;
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
95894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuangsize_t NuPlayer::GenericSource::getTrackCount() const {
95994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    return mSources.size();
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang}
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang
962ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Hubersp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
963ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    size_t trackCount = mSources.size();
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (trackIndex >= trackCount) {
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        return NULL;
966ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    }
967ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> format = new AMessage();
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (meta == NULL) {
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("no metadata for track %zu", trackIndex);
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return NULL;
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *mime;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format->setString("mime", mime);
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t trackType;
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strncasecmp(mime, "video/", 6)) {
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        trackType = MEDIA_TRACK_TYPE_VIDEO;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strncasecmp(mime, "audio/", 6)) {
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        trackType = MEDIA_TRACK_TYPE_AUDIO;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format->setInt32("type", trackType);
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *lang;
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        lang = "und";
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format->setString("language", lang);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->findInt32(kKeyTrackIsDefault, &isDefault);
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->findInt32(kKeyTrackIsForced, &isForced);
10025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format->setInt32("auto", !!isAutoselect);
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format->setInt32("default", !!isDefault);
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format->setInt32("forced", !!isForced);
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return format;
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huberssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("type", type);
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t index;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(&response);
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err == OK && response != NULL) {
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(response->findInt32("index", &index));
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return index;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -1;
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmpType;
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    CHECK(msg->findInt32("type", &tmpType));
10292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    media_track_type type = (media_track_type)tmpType;
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = doGetSelectedTrack(type);
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setInt32("index", index);
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AReplyToken> replyID;
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(msg->senderAwaitsResponse(&replyID));
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    response->postReply(replyID);
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
1041308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    const Track *track = NULL;
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    switch (type) {
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    case MEDIA_TRACK_TYPE_VIDEO:
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        track = &mVideoTrack;
1045308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        break;
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    case MEDIA_TRACK_TYPE_AUDIO:
1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        track = &mAudioTrack;
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        break;
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    case MEDIA_TRACK_TYPE_TIMEDTEXT:
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        track = &mTimedTextTrack;
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        break;
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    case MEDIA_TRACK_TYPE_SUBTITLE:
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        track = &mSubtitleTrack;
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        break;
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    default:
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        break;
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (track != NULL && track->mSource != NULL) {
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        return track->mIndex;
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    return -1;
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber}
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huberstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    msg->setInt32("trackIndex", trackIndex);
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    msg->setInt32("select", select);
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    msg->setInt64("timeUs", timeUs);
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    sp<AMessage> response;
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    status_t err = msg->postAndAwaitResponse(&response);
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (err == OK && response != NULL) {
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        CHECK(response->findInt32("err", &err));
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    return err;
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t trackIndex, select;
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int64_t timeUs;
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(msg->findInt32("trackIndex", &trackIndex));
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(msg->findInt32("select", &select));
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(msg->findInt64("timeUs", &timeUs));
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    sp<AMessage> response = new AMessage;
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    status_t err = doSelectTrack(trackIndex, select, timeUs);
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    response->setInt32("err", err);
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    sp<AReplyToken> replyID;
1094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    CHECK(msg->senderAwaitsResponse(&replyID));
1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    response->postReply(replyID);
1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber}
1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huberstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (trackIndex >= mSources.size()) {
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        return BAD_INDEX;
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!select) {
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        Track* track = NULL;
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            track = &mSubtitleTrack;
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mFetchSubtitleDataGeneration++;
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            track = &mTimedTextTrack;
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mFetchTimedTextDataGeneration++;
1111fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1112fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (track == NULL) {
1113fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            return INVALID_OPERATION;
1114fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1115fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mSource->stop();
1116fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mSource = NULL;
1117fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mPackets->clear();
1118fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        return OK;
1119fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    }
1120fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1121fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    const sp<IMediaSource> source = mSources.itemAt(trackIndex);
1122fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    sp<MetaData> meta = source->getFormat();
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    const char *mime;
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    CHECK(meta->findCString(kKeyMIMEType, &mime));
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    if (!strncasecmp(mime, "text/", 5)) {
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (track->mSource != NULL && track->mIndex == trackIndex) {
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            return OK;
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mIndex = trackIndex;
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (track->mSource != NULL) {
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            track->mSource->stop();
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mSource = mSources.itemAt(trackIndex);
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        track->mSource->start();
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (track->mPackets == NULL) {
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        } else {
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            track->mPackets->clear();
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            track->mPackets->setFormat(track->mSource->getFormat());
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (isSubtitle) {
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            mFetchSubtitleDataGeneration++;
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        } else {
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            mFetchTimedTextDataGeneration++;
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        status_t eosResult; // ignored
1152054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mSubtitleTrack.mSource != NULL
1153054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
1155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            msg->setInt64("timeUs", timeUs);
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            msg->setInt32("generation", mFetchSubtitleDataGeneration);
11570167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            msg->post();
11580167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
11590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        sp<AMessage> msg2 = new AMessage(kWhatSendGlobalTimedTextData, this);
11610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        msg2->setInt32("generation", mFetchTimedTextDataGeneration);
11620167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        msg2->post();
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mTimedTextTrack.mSource != NULL
1165308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->setInt64("timeUs", timeUs);
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->setInt32("generation", mFetchTimedTextDataGeneration);
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool audio = !strncasecmp(mime, "audio/", 6);
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Track *track = audio ? &mAudioTrack : &mVideoTrack;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (track->mSource != NULL && track->mIndex == trackIndex) {
117742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            return OK;
117842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
117942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber
118042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
118142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        msg->setInt32("trackIndex", trackIndex);
118242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        msg->post();
118342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        return OK;
118442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    }
118542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber
118642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    return INVALID_OPERATION;
118742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber}
118842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatSeek, this);
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt64("seekTimeUs", seekTimeUs);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(&response);
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err == OK && response != NULL) {
1196aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        CHECK(response->findInt32("err", &err));
1197ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1198ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return err;
1200aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
1201aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
1202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkevoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
1203ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    int64_t seekTimeUs;
1204ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
12054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    sp<AMessage> response = new AMessage;
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = doSeek(seekTimeUs);
1208729de186450f78c099637e1fce743fe531862c52Andreas Huber    response->setInt32("err", err);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1210729de186450f78c099637e1fce743fe531862c52Andreas Huber    sp<AReplyToken> replyID;
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->senderAwaitsResponse(&replyID));
1212729de186450f78c099637e1fce743fe531862c52Andreas Huber    response->postReply(replyID);
1213729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1214729de186450f78c099637e1fce743fe531862c52Andreas Huber
1215729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber    mBufferingMonitor->updateDequeuedBufferTime(-1ll);
1217729de186450f78c099637e1fce743fe531862c52Andreas Huber
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // If the Widevine source is stopped, do not attempt to read any
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // more buffers.
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mStopRead) {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mVideoTrack.mSource != NULL) {
12242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int64_t actualTimeUs;
12252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
12262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        seekTimeUs = actualTimeUs;
12282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mVideoLastDequeueTimeUs = seekTimeUs;
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mAudioTrack.mSource != NULL) {
1232516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
1233516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        mAudioLastDequeueTimeUs = seekTimeUs;
12342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1236516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
1237516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    if (!mStarted) {
1238516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
12392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1241516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    // If currently buffering, post kWhatBufferingEnd first, so that
1242516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    // NuPlayer resumes. Otherwise, if cache hits high watermark
1243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    // before new polling happens, no one will resume the playback.
12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    mBufferingMonitor->stopBufferingIfNecessary();
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    mBufferingMonitor->restartPollBuffering();
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1247516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    return OK;
1248516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber}
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1250ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Hubersp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
1251ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        MediaBuffer* mb,
1252ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        media_track_type trackType,
1253ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int64_t /* seekTimeUs */,
1254ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int64_t *actualTimeUs) {
1255ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
1256ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    size_t outLength = mb->range_length();
1257ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
1258ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    if (audio && mAudioIsVorbis) {
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        outLength += sizeof(int32_t);
1260729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
12614471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12624471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    sp<ABuffer> ab;
12634471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (mIsSecure && !audio) {
12644471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        // data is already provided in the buffer
12658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        ab = new ABuffer(NULL, mb->range_length());
12668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mb->add_ref();
12678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        ab->setMediaBufferBase(mb);
12689806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        ab = new ABuffer(outLength);
12708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        memcpy(ab->data(),
12718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen               (const uint8_t *)mb->data() + mb->range_offset(),
12728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen               mb->range_length());
12739806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12749806555d3930be43e11106281dee354820ac1c88Andreas Huber
12759806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (audio && mAudioIsVorbis) {
12769806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t numPageSamples;
12779806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
12789806555d3930be43e11106281dee354820ac1c88Andreas Huber            numPageSamples = -1;
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint8_t* abEnd = ab->data() + mb->range_length();
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> meta = ab->meta();
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t timeUs;
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    meta->setInt64("timeUs", timeUs);
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Temporarily disable pre-roll till we have a full solution to handle
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // both single seek and continous seek gracefully.
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (seekTimeUs > timeUs) {
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> extra = new AMessage;
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->setMessage("extra", extra);
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t layerId;
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mb->meta_data()->findInt32(kKeyTemporalLayerId, &layerId)) {
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            meta->setInt32("temporal-layer-id", layerId);
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(mTimedTextTrack.mSource != NULL
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->setString("mime", mime);
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t durationUs;
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->setInt64("durationUs", durationUs);
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    uint32_t dataType; // unused
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const void *seiData;
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t seiLength;
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mb->meta_data()->findData(kKeySEI, &dataType, &seiData, &seiLength)) {
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        meta->setBuffer("sei", sei);
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const void *mpegUserDataPointer;
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t mpegUserDataLength;
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mb->meta_data()->findData(
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        meta->setBuffer("mpegUserData", mpegUserData);
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (actualTimeUs) {
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *actualTimeUs = timeUs;
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mb->release();
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mb = NULL;
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ab;
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13505778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Mutex::Autolock _l(mReadBufferLock);
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1353aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
1354aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mPendingReadBufferTypes |= (1 << trackType);
1355ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
1356ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        msg->setInt32("trackType", trackType);
1357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        msg->post();
1358ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmpType;
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("trackType", &tmpType));
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    media_track_type trackType = (media_track_type)tmpType;
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    readBuffer(trackType);
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // only protect the variable change, as readBuffer may
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // take considerable time.
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Mutex::Autolock _l(mReadBufferLock);
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mPendingReadBufferTypes &= ~(1 << trackType);
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13745778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::readBuffer(
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Do not read data if Widevine source is stopped
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mStopRead) {
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return;
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Track *track;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t maxBuffers = 1;
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (trackType) {
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MEDIA_TRACK_TYPE_VIDEO:
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track = &mVideoTrack;
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mIsWidevine) {
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                maxBuffers = 2;
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                maxBuffers = 8;  // too large of a number may influence seeks
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MEDIA_TRACK_TYPE_AUDIO:
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track = &mAudioTrack;
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mIsWidevine) {
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                maxBuffers = 8;
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                maxBuffers = 64;
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MEDIA_TRACK_TYPE_SUBTITLE:
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track = &mSubtitleTrack;
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MEDIA_TRACK_TYPE_TIMEDTEXT:
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track = &mTimedTextTrack;
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (track->mSource == NULL) {
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (actualTimeUs) {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *actualTimeUs = seekTimeUs;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    MediaSource::ReadOptions options;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1419aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    bool seeking = false;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (seekTimeUs >= 0) {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        seeking = true;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const bool couldReadMultiple = (!mIsWidevine && track->mSource->supportReadMultiple());
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mIsWidevine || couldReadMultiple) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        options.setNonBlocking();
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        Vector<MediaBuffer *> mediaBuffers;
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = NO_ERROR;
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (couldReadMultiple) {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = track->mSource->readMultiple(
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    &mediaBuffers, maxBuffers - numBuffers, &options);
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            MediaBuffer *mbuf = NULL;
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            err = track->mSource->read(&mbuf, &options);
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (err == OK && mbuf != NULL) {
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mediaBuffers.push_back(mbuf);
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1445ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        options.clearNonPersistent();
1447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        size_t id = 0;
1449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        size_t count = mediaBuffers.size();
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (; id < count; ++id) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeUs;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            MediaBuffer *mbuf = mediaBuffers[id];
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) {
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mbuf->meta_data()->dumpToLog();
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                track->mPackets->signalEOS(ERROR_MALFORMED);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mAudioTimeUs = timeUs;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBufferingMonitor->updateQueuedTime(true /* isAudio */, timeUs);
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mVideoTimeUs = timeUs;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBufferingMonitor->updateQueuedTime(false /* isAudio */, timeUs);
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<ABuffer> buffer = mediaBufferToABuffer(
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mbuf, trackType, seekTimeUs,
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    numBuffers == 0 ? actualTimeUs : NULL);
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track->mPackets->queueAccessUnit(buffer);
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            formatChange = false;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            seeking = false;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ++numBuffers;
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (id < count) {
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // Error, some mediaBuffer doesn't have kKeyTime.
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (; id < count; ++id) {
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mediaBuffers[id]->release();
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == WOULD_BLOCK) {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (err == INFO_FORMAT_CHANGED) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber#if 0
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track->mPackets->queueDiscontinuity(
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ATSParser::DISCONTINUITY_FORMATCHANGE,
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    NULL,
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    false /* discard */);
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber#endif
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (err != OK) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            track->mPackets->signalEOS(err);
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1501729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::queueDiscontinuityIfNeeded(
1502729de186450f78c099637e1fce743fe531862c52Andreas Huber        bool seeking, bool formatChange, media_track_type trackType, Track *track) {
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // formatChange && seeking: track whose source is changed during selection
1504729de186450f78c099637e1fce743fe531862c52Andreas Huber    // formatChange && !seeking: track whose source is not changed during selection
1505729de186450f78c099637e1fce743fe531862c52Andreas Huber    // !formatChange: normal seek
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber    if ((seeking || formatChange)
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber            && (trackType == MEDIA_TRACK_TYPE_AUDIO
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber            || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber        ATSParser::DiscontinuityType type = (formatChange && seeking)
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber                ? ATSParser::DISCONTINUITY_FORMATCHANGE
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber                : ATSParser::DISCONTINUITY_NONE;
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber        track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */);
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15165778822d86b0337407514b9372562b86edfa91cdAndreas HuberNuPlayer::GenericSource::BufferingMonitor::BufferingMonitor(const sp<AMessage> &notify)
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber    : mNotify(notify),
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDurationUs(-1ll),
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mBitrate(-1ll),
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mIsStreaming(false),
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber      mAudioTimeUs(0),
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mVideoTimeUs(0),
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mPollBufferingGeneration(0),
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mPrepareBuffering(false),
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mBuffering(false),
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber      mPrevBufferPercentage(-1),
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber      mOffloadAudio(false),
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFirstDequeuedBufferRealUs(-1ll),
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFirstDequeuedBufferMediaUs(-1ll),
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mlastDequeuedBufferMediaUs(-1ll) {
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber
1533729de186450f78c099637e1fce743fe531862c52Andreas HuberNuPlayer::GenericSource::BufferingMonitor::~BufferingMonitor() {
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber}
15352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid NuPlayer::GenericSource::BufferingMonitor::prepare(
15372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        const sp<NuCachedSource2> &cachedSource,
15382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        const sp<WVMExtractor> &wvmExtractor,
15392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int64_t durationUs,
15402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int64_t bitrate,
15412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool isStreaming) {
15422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    Mutex::Autolock _l(mLock);
15432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    prepare_l(cachedSource, wvmExtractor, durationUs, bitrate, isStreaming);
15442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid NuPlayer::GenericSource::BufferingMonitor::stop() {
15472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    Mutex::Autolock _l(mLock);
15482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    prepare_l(NULL /* cachedSource */, NULL /* wvmExtractor */, -1 /* durationUs */,
15492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            -1 /* bitrate */, false /* isStreaming */);
15502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid NuPlayer::GenericSource::BufferingMonitor::cancelPollBuffering() {
15532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    Mutex::Autolock _l(mLock);
15542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    cancelPollBuffering_l();
15552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivivoid NuPlayer::GenericSource::BufferingMonitor::restartPollBuffering() {
15582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    Mutex::Autolock _l(mLock);
15592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mIsStreaming) {
15602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        cancelPollBuffering_l();
15612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        onPollBuffering_l();
15622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
1563729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1564729de186450f78c099637e1fce743fe531862c52Andreas Huber
1565729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary() {
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber    Mutex::Autolock _l(mLock);
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    stopBufferingIfNecessary_l();
1568729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber
1570729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::ensureCacheIsFetching() {
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber    Mutex::Autolock _l(mLock);
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber    ensureCacheIsFetching_l();
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber
1575729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::updateQueuedTime(bool isAudio, int64_t timeUs) {
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    Mutex::Autolock _l(mLock);
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (isAudio) {
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber        mAudioTimeUs = timeUs;
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else {
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber        mVideoTimeUs = timeUs;
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber
1584729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::setOffloadAudio(bool offload) {
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber    Mutex::Autolock _l(mLock);
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber    mOffloadAudio = offload;
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber
1589729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::updateDequeuedBufferTime(int64_t mediaUs) {
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber    Mutex::Autolock _l(mLock);
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (mediaUs < 0) {
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber        mFirstDequeuedBufferRealUs = -1ll;
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber        mFirstDequeuedBufferMediaUs = -1ll;
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (mFirstDequeuedBufferRealUs < 0) {
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber        mFirstDequeuedBufferRealUs = ALooper::GetNowUs();
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber        mFirstDequeuedBufferMediaUs = mediaUs;
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    mlastDequeuedBufferMediaUs = mediaUs;
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1600729de186450f78c099637e1fce743fe531862c52Andreas Huber
1601729de186450f78c099637e1fce743fe531862c52Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::prepare_l(
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber        const sp<NuCachedSource2> &cachedSource,
1603c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        const sp<WVMExtractor> &wvmExtractor,
1604c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        int64_t durationUs,
1605729de186450f78c099637e1fce743fe531862c52Andreas Huber        int64_t bitrate,
1606729de186450f78c099637e1fce743fe531862c52Andreas Huber        bool isStreaming) {
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGW_IF(wvmExtractor != NULL && cachedSource != NULL,
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber            "WVMExtractor and NuCachedSource are both present when "
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber            "BufferingMonitor::prepare_l is called, ignore NuCachedSource");
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCachedSource = cachedSource;
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWVMExtractor = wvmExtractor;
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDurationUs = durationUs;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBitrate = bitrate;
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIsStreaming = isStreaming;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mAudioTimeUs = 0;
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mVideoTimeUs = 0;
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPrepareBuffering = (cachedSource != NULL || wvmExtractor != NULL);
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    cancelPollBuffering_l();
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOffloadAudio = false;
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFirstDequeuedBufferRealUs = -1ll;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFirstDequeuedBufferMediaUs = -1ll;
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mlastDequeuedBufferMediaUs = -1ll;
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::cancelPollBuffering_l() {
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffering = false;
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ++mPollBufferingGeneration;
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPrevBufferPercentage = -1;
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::notifyBufferingUpdate_l(int32_t percentage) {
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Buffering percent could go backward as it's estimated from remaining
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // data and last access time. This could cause the buffering position
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // drawn on media control to jitter slightly. Remember previously reported
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // percentage and don't allow it to go backward.
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (percentage < mPrevBufferPercentage) {
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        percentage = mPrevBufferPercentage;
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (percentage > 100) {
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        percentage = 100;
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPrevBufferPercentage = percentage;
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("notifyBufferingUpdate_l: buffering %d%%", percentage);
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = mNotify->dup();
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("what", kWhatBufferingUpdate);
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("percentage", percentage);
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::startBufferingIfNecessary_l() {
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mPrepareBuffering) {
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!mBuffering) {
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGD("startBufferingIfNecessary_l");
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBuffering = true;
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ensureCacheIsFetching_l();
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sendCacheStats_l();
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mNotify->dup();
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", kWhatPauseOnBufferingStart);
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary_l() {
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mPrepareBuffering) {
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGD("stopBufferingIfNecessary_l, mBuffering=%d", mBuffering);
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mPrepareBuffering = false;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mNotify->dup();
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", kWhatPrepared);
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("err", OK);
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mBuffering) {
1687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        ALOGD("stopBufferingIfNecessary_l");
1688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mBuffering = false;
1689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        sendCacheStats_l();
1691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        sp<AMessage> notify = mNotify->dup();
1693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        notify->setInt32("what", kWhatResumeOnBufferingEnd);
1694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        notify->post();
169594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    }
169694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang}
1697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::sendCacheStats_l() {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t kbps = 0;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = UNKNOWN_ERROR;
1701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (mWVMExtractor != NULL) {
1703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps);
1704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else if (mCachedSource != NULL) {
1705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
1706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err == OK) {
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mNotify->dup();
1710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        notify->setInt32("what", kWhatCacheStats);
1711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        notify->setInt32("bandwidth", kbps);
1712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        notify->post();
1713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::ensureCacheIsFetching_l() {
1717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (mCachedSource != NULL) {
1718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mCachedSource->resumeFetchingIfNecessary();
1719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::schedulePollBuffering_l() {
1723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
1724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    msg->setInt32("generation", mPollBufferingGeneration);
1725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    // Enquires buffering status every second.
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    msg->post(1000000ll);
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huberint64_t NuPlayer::GenericSource::BufferingMonitor::getLastReadPosition_l() {
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mAudioTimeUs > 0) {
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return mAudioTimeUs;
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mVideoTimeUs > 0) {
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return mVideoTimeUs;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17395778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::onPollBuffering_l() {
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t finalStatus = UNKNOWN_ERROR;
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t cachedDurationUs = -1ll;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t cachedDataRemaining = -1;
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mWVMExtractor != NULL) {
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cachedDurationUs =
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mWVMExtractor->getCachedDurationUs(&finalStatus);
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (mCachedSource != NULL) {
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cachedDataRemaining =
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCachedSource->approxDataRemaining(&finalStatus);
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (finalStatus == OK) {
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            off64_t size;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t bitrate = 0ll;
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // |bitrate| uses bits/second unit, while size is number of bytes.
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                bitrate = size * 8000000ll / mDurationUs;
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (mBitrate > 0) {
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                bitrate = mBitrate;
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (bitrate > 0) {
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (finalStatus != OK) {
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGV("onPollBuffering_l: EOS (finalStatus = %d)", finalStatus);
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (finalStatus == ERROR_END_OF_STREAM) {
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notifyBufferingUpdate_l(100);
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stopBufferingIfNecessary_l();
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (cachedDurationUs >= 0ll) {
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mDurationUs > 0ll) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t cachedPosUs = getLastReadPosition_l() + cachedDurationUs;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int percentage = 100.0 * cachedPosUs / mDurationUs;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (percentage > 100) {
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                percentage = 100;
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notifyBufferingUpdate_l(percentage);
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("onPollBuffering_l: cachedDurationUs %.1f sec",
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                cachedDurationUs / 1000000.0f);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (cachedDurationUs < kLowWaterMarkUs) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // Take into account the data cached in downstream components to try to avoid
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            // unnecessary pause.
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mOffloadAudio && mFirstDequeuedBufferRealUs >= 0) {
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                int64_t downStreamCacheUs = mlastDequeuedBufferMediaUs - mFirstDequeuedBufferMediaUs
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        - (ALooper::GetNowUs() - mFirstDequeuedBufferRealUs);
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (downStreamCacheUs > 0) {
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    cachedDurationUs += downStreamCacheUs;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (cachedDurationUs < kLowWaterMarkUs) {
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                startBufferingIfNecessary_l();
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t highWaterMark = mPrepareBuffering ? kHighWaterMarkUs : kHighWaterMarkRebufferUs;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (cachedDurationUs > highWaterMark) {
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                stopBufferingIfNecessary_l();
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (cachedDataRemaining >= 0) {
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("onPollBuffering_l: cachedDataRemaining %zd bytes",
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                cachedDataRemaining);
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (cachedDataRemaining < kLowWaterMarkBytes) {
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            startBufferingIfNecessary_l();
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (cachedDataRemaining > kHighWaterMarkBytes) {
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            stopBufferingIfNecessary_l();
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    schedulePollBuffering_l();
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18235778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid NuPlayer::GenericSource::BufferingMonitor::onMessageReceived(const sp<AMessage> &msg) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber      case kWhatPollBuffering:
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber      {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber          int32_t generation;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber          CHECK(msg->findInt32("generation", &generation));
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber          Mutex::Autolock _l(mLock);
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber          if (generation == mPollBufferingGeneration) {
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber              onPollBuffering_l();
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber          }
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber          break;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber      }
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber      default:
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber          TRESPASS();
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber          break;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber