GenericSource.cpp revision 5e5a6e100920679f20b4d7fae0d8866ec5053f7e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2012 The Android Open Source Project
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * limitations under the License.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//#define LOG_NDEBUG 0
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_TAG "GenericSource"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "GenericSource.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "AnotherPacketSource.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/IMediaHTTPService.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/foundation/ABuffer.h>
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/foundation/ADebug.h>
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/foundation/AMessage.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/DataSource.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/FileSource.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <media/stagefright/MediaBuffer.h>
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/MediaDefs.h>
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/MediaExtractor.h>
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/MediaSource.h>
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/MetaData.h>
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <media/stagefright/Utils.h>
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "../../libstagefright/include/DRMExtractor.h"
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "../../libstagefright/include/NuCachedSource2.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "../../libstagefright/include/WVMExtractor.h"
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace android {
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NuPlayer::GenericSource::GenericSource(
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        const sp<AMessage> &notify,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool uidValid,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uid_t uid)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Source(notify),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mFetchSubtitleDataGeneration(0),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mFetchTimedTextDataGeneration(0),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mDurationUs(0ll),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mAudioIsVorbis(false),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mIsWidevine(false),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mUIDValid(uidValid),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mUID(uid),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mDrmManagerClient(NULL),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mMetaDataSize(-1ll),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mBitrate(-1ll),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mPollBufferingGeneration(0),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mPendingReadBufferTypes(0) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resetDataSource();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DataSource::RegisterDefaultSniffers();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::resetDataSource() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mAudioTimeUs = 0;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mVideoTimeUs = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mHTTPService.clear();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mUri.clear();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mUriHeaders.clear();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mFd = -1;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mOffset = 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mLength = 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mDecryptHandle = NULL;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mDrmManagerClient = NULL;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mStarted = false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t NuPlayer::GenericSource::setDataSource(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const sp<IMediaHTTPService> &httpService,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const char *url,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const KeyedVector<String8, String8> *headers) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resetDataSource();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mHTTPService = httpService;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mUri = url;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (headers) {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mUriHeaders = *headers;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // delay data source creation to prepareAsync() to avoid blocking
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the calling thread in setDataSource for any significant time.
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return OK;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)status_t NuPlayer::GenericSource::setDataSource(
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        int fd, int64_t offset, int64_t length) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resetDataSource();
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mFd = dup(fd);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mOffset = offset;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mLength = length;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // delay data source creation to prepareAsync() to avoid blocking
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the calling thread in setDataSource for any significant time.
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return mFileMeta;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)status_t NuPlayer::GenericSource::initFromDataSource() {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sp<MediaExtractor> extractor;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(mDataSource != NULL);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mIsWidevine) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        String8 mimeType;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        float confidence;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> dummy;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bool success;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        success = SniffWVM(mDataSource, &mimeType, &confidence, &dummy);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (!success
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                || strcasecmp(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ALOGE("unsupported widevine mime: %s", mimeType.string());
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return UNKNOWN_ERROR;
130a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        }
131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mWVMExtractor = new WVMExtractor(mDataSource);
133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mWVMExtractor->setAdaptiveStreamingMode(true);
134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        if (mUIDValid) {
135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            mWVMExtractor->setUID(mUID);
136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        }
137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        extractor = mWVMExtractor;
138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    } else {
139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        extractor = MediaExtractor::Create(mDataSource,
140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str());
141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (extractor == NULL) {
144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return UNKNOWN_ERROR;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extractor->getDrmFlag()) {
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        checkDrmStatus(mDataSource);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mFileMeta = extractor->getMetaData();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mFileMeta != NULL) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int64_t duration;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mDurationUs = duration;
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int32_t totalBitrate = 0;
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < extractor->countTracks(); ++i) {
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<MediaSource> track = extractor->getTrack(i);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<MetaData> meta = extractor->getTrackMetaData(i);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const char *mime;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK(meta->findCString(kKeyMIMEType, &mime));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Do the string compare immediately with "mime",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // we can't assume "mime" would stay valid after another
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // extractor operation, some extractors might modify meta
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // during getTrack() and make it invalid.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!strncasecmp(mime, "audio/", 6)) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (mAudioTrack.mSource == NULL) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mAudioTrack.mIndex = i;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mAudioTrack.mSource = track;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mAudioTrack.mPackets =
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    new AnotherPacketSource(mAudioTrack.mSource->getFormat());
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    mAudioIsVorbis = true;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                } else {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    mAudioIsVorbis = false;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                }
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else if (!strncasecmp(mime, "video/", 6)) {
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            if (mVideoTrack.mSource == NULL) {
188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                mVideoTrack.mIndex = i;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mVideoTrack.mSource = track;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mVideoTrack.mPackets =
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    new AnotherPacketSource(mVideoTrack.mSource->getFormat());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // check if the source requires secure buffers
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int32_t secure;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        && secure) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    mIsWidevine = true;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (mUIDValid) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        extractor->setUID(mUID);
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    }
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (track != NULL) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mSources.push(track);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int64_t durationUs;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (meta->findInt64(kKeyDuration, &durationUs)) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (durationUs > mDurationUs) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    mDurationUs = durationUs;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int32_t bitrate;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                totalBitrate += bitrate;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                totalBitrate = -1;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mBitrate = totalBitrate;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mDecryptHandle != NULL) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK(mDrmManagerClient);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sp<AMessage> msg = dupNotify();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            msg->setInt32("what", kWhatDrmNoLicense);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            msg->post();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64_t NuPlayer::GenericSource::getLastReadPosition() {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mAudioTrack.mSource != NULL) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mAudioTimeUs;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (mVideoTrack.mSource != NULL) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mVideoTimeUs;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t NuPlayer::GenericSource::setBuffers(
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bool audio, Vector<MediaBuffer *> &buffers) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mIsWidevine && !audio) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mVideoTrack.mSource->setBuffers(buffers);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return INVALID_OPERATION;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NuPlayer::GenericSource::~GenericSource() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mLooper != NULL) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper->unregisterHandler(id());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper->stop();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::prepareAsync() {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mLooper == NULL) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper = new ALooper;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper->setName("generic");
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper->start();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mLooper->registerHandler(this);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->post();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::onPrepareAsync() {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // delayed data source creation
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mDataSource == NULL) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!mUri.empty()) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mIsWidevine = !strncasecmp(mUri.c_str(), "widevine://", 11);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mDataSource = DataSource::CreateFromURI(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   mHTTPService, mUri.c_str(), &mUriHeaders, &mContentType);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // set to false first, if the extractor
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // comes back as secure, set it to true then.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mIsWidevine = false;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mDataSource = new FileSource(mFd, mOffset, mLength);
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mDataSource == NULL) {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ALOGE("Failed to create data source!");
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            notifyPreparedAndCleanup(UNKNOWN_ERROR);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (mIsWidevine || mCachedSource != NULL) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            schedulePollBuffering();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // check initial caching status
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = prefillCacheIfNecessary();
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (err != OK) {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (err == -EAGAIN) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            (new AMessage(kWhatPrepareAsync, id()))->post(200000);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ALOGE("Failed to prefill data cache!");
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            notifyPreparedAndCleanup(UNKNOWN_ERROR);
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // init extrator from data source
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    err = initFromDataSource();
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (err != OK) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ALOGE("Failed to init from data source!");
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        notifyPreparedAndCleanup(err);
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mVideoTrack.mSource != NULL) {
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> msg = new AMessage;
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        err = convertMetaDataToMessage(meta, &msg);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(err != OK) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            notifyPreparedAndCleanup(err);
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return;
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        notifyVideoSizeChanged(msg);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notifyFlagsChanged(
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            (mIsWidevine ? FLAG_SECURE : 0)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            | FLAG_CAN_PAUSE
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            | FLAG_CAN_SEEK_BACKWARD
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            | FLAG_CAN_SEEK_FORWARD
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            | FLAG_CAN_SEEK);
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notifyPrepared();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (err != OK) {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mMetaDataSize = -1ll;
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mContentType = "";
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mSniffedMIME = "";
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDataSource.clear();
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        mCachedSource.clear();
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        cancelPollBuffering();
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    notifyPrepared(err);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)status_t NuPlayer::GenericSource::prefillCacheIfNecessary() {
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(mDataSource != NULL);
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mCachedSource == NULL) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // no prefill if the data source is not cached
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return OK;
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We're not doing this for streams that appear to be audio-only
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // streams to ensure that even low bandwidth streams start
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // playing back fairly instantly.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!strncasecmp(mContentType.string(), "audio/", 6)) {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return OK;
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We're going to prefill the cache before trying to instantiate
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the extractor below, as the latter is an operation that otherwise
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // could block on the datasource for a significant amount of time.
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // During that time we'd be unable to abort the preparation phase
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // without this prefill.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Initially make sure we have at least 192 KB for the sniff
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to complete without blocking.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const size_t kMinBytesForSniffing = 192 * 1024;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static const size_t kDefaultMetaSize = 200000;
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t finalStatus;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t cachedDataRemaining =
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mCachedSource->approxDataRemaining(&finalStatus);
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (finalStatus != OK || (mMetaDataSize >= 0
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            && (off64_t)cachedDataRemaining >= mMetaDataSize)) {
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ALOGV("stop caching, status %d, "
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "metaDataSize %lld, cachedDataRemaining %zu",
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                finalStatus, mMetaDataSize, cachedDataRemaining);
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return OK;
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ALOGV("now cached %zu bytes of data", cachedDataRemaining);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mMetaDataSize < 0
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            && cachedDataRemaining >= kMinBytesForSniffing) {
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        String8 tmp;
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        float confidence;
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> meta;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!mCachedSource->sniff(&tmp, &confidence, &meta)) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return UNKNOWN_ERROR;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // We successfully identified the file's extractor to
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // be, remember this mime type so we don't have to
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // sniff it again when we call MediaExtractor::Create()
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mSniffedMIME = tmp.string();
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (meta == NULL
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                || !meta->findInt64("meta-data-size",
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        reinterpret_cast<int64_t*>(&mMetaDataSize))) {
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            mMetaDataSize = kDefaultMetaSize;
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        }
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (mMetaDataSize < 0ll) {
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            ALOGE("invalid metaDataSize = %lld bytes", mMetaDataSize);
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            return UNKNOWN_ERROR;
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        }
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return -EAGAIN;
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::start() {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ALOGI("start");
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mAudioTrack.mSource != NULL) {
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mVideoTrack.mSource != NULL) {
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mStarted = true;
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NuPlayer::GenericSource::stop() {
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // nothing to do, just account for DRM playback status
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mStarted = false;
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::pause() {
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // nothing to do, just account for DRM playback status
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mStarted = false;
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::resume() {
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // nothing to do, just account for DRM playback status
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mStarted = true;
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::disconnect() {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mDataSource != NULL) {
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // disconnect data source
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mDecryptHandle != NULL) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)status_t NuPlayer::GenericSource::feedMoreTSData() {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return OK;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::schedulePollBuffering() {
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatPollBuffering, id());
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    msg->setInt32("generation", mPollBufferingGeneration);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    msg->post(1000000ll);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::cancelPollBuffering() {
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++mPollBufferingGeneration;
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) {
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = dupNotify();
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt32("what", kWhatBufferingUpdate);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt32("percentage", percentage);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    msg->post();
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NuPlayer::GenericSource::onPollBuffering() {
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t finalStatus = UNKNOWN_ERROR;
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t cachedDurationUs = 0ll;
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mCachedSource != NULL) {
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        size_t cachedDataRemaining =
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                mCachedSource->approxDataRemaining(&finalStatus);
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (finalStatus == OK) {
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            off64_t size;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            int64_t bitrate = 0ll;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                bitrate = size * 8000000ll / mDurationUs;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            } else if (mBitrate > 0) {
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                bitrate = mBitrate;
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (bitrate > 0) {
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (mWVMExtractor != NULL) {
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        cachedDurationUs
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            = mWVMExtractor->getCachedDurationUs(&finalStatus);
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (finalStatus == ERROR_END_OF_STREAM) {
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        notifyBufferingUpdate(100);
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        cancelPollBuffering();
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (cachedDurationUs > 0ll && mDurationUs > 0ll) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int percentage = 100.0 * cachedDurationUs / mDurationUs;
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (percentage > 100) {
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            percentage = 100;
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        notifyBufferingUpdate(percentage);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    schedulePollBuffering();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (msg->what()) {
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatPrepareAsync:
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          onPrepareAsync();
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatFetchSubtitleData:
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kWhatFetchTimedTextData:
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
572ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case kWhatSendSubtitleData:
573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      {
574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
576ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          break;
577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatSendTimedTextData:
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatChangeAVSource:
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int32_t trackIndex;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          CHECK(msg->findInt32("trackIndex", &trackIndex));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const sp<MediaSource> source = mSources.itemAt(trackIndex);
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
5920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          Track* track;
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          const char *mime;
5940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          media_track_type trackType, counterpartType;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sp<MetaData> meta = source->getFormat();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          meta->findCString(kKeyMIMEType, &mime);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!strncasecmp(mime, "audio/", 6)) {
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              track = &mAudioTrack;
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              trackType = MEDIA_TRACK_TYPE_AUDIO;
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          } else {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              CHECK(!strncasecmp(mime, "video/", 6));
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              track = &mVideoTrack;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              trackType = MEDIA_TRACK_TYPE_VIDEO;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (track->mSource != NULL) {
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              track->mSource->stop();
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          track->mSource = source;
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          track->mSource->start();
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          track->mIndex = trackIndex;
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          status_t avail;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!track->mPackets->hasBufferAvailable(&avail)) {
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              // sync from other source
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              TRESPASS();
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              break;
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          }
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          int64_t timeUs, actualTimeUs;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const bool formatChange = true;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sp<AMessage> latestMeta = track->mPackets->getLatestEnqueuedMeta();
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CHECK(latestMeta != NULL && latestMeta->findInt64("timeUs", &timeUs));
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          readBuffer(counterpartType, -1, NULL, formatChange);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatPollBuffering:
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int32_t generation;
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CHECK(msg->findInt32("generation", &generation));
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if (generation == mPollBufferingGeneration) {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              onPollBuffering();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatGetFormat:
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          onGetFormatMeta(msg);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatGetSelectedTrack:
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          onGetSelectedTrack(msg);
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case kWhatSelectTrack:
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          onSelectTrack(msg);
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case kWhatSeek:
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          onSeek(msg);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kWhatReadBuffer:
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          onReadBuffer(msg);
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      default:
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          Source::onMessageReceived(msg);
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          break;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::fetchTextData(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32_t sendWhat,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        media_track_type type,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int32_t curGen,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sp<AnotherPacketSource> packets,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sp<AMessage> msg) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t msgGeneration;
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt32("generation", &msgGeneration));
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (msgGeneration != curGen) {
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // stale
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t avail;
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (packets->hasBufferAvailable(&avail)) {
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t timeUs;
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt64("timeUs", &timeUs));
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t subTimeUs;
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    readBuffer(type, timeUs, &subTimeUs);
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_t delayUs = subTimeUs - timeUs;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (msg->what() == kWhatFetchSubtitleData) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const int64_t oneSecUs = 1000000ll;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delayUs -= oneSecUs;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> msg2 = new AMessage(sendWhat, id());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg2->setInt32("generation", msgGeneration);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg2->post(delayUs < 0 ? 0 : delayUs);
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::sendTextData(
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        uint32_t what,
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        media_track_type type,
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int32_t curGen,
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sp<AnotherPacketSource> packets,
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> msg) {
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int32_t msgGeneration;
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt32("generation", &msgGeneration));
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (msgGeneration != curGen) {
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // stale
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_t subTimeUs;
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (packets->nextBufferTime(&subTimeUs) != OK) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t nextSubTimeUs;
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    readBuffer(type, -1, &nextSubTimeUs);
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<ABuffer> buffer;
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dequeueStatus == OK) {
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> notify = dupNotify();
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        notify->setInt32("what", what);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notify->setBuffer("buffer", buffer);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        notify->post();
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const int64_t delayUs = nextSubTimeUs - subTimeUs;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->post(delayUs < 0 ? 0 : delayUs);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt32("audio", audio);
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> response;
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    void *format;
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = msg->postAndAwaitResponse(&response);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (err == OK && response != NULL) {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK(response->findPointer("format", &format));
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return (MetaData *)format;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int32_t audio;
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt32("audio", &audio));
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> response = new AMessage;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<MetaData> format = doGetFormatMeta(audio);
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response->setPointer("format", format.get());
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint32_t replyID;
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->senderAwaitsResponse(&replyID));
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response->postReply(replyID);
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)sp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (source == NULL) {
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return NULL;
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return source->getFormat();
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t NuPlayer::GenericSource::dequeueAccessUnit(
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bool audio, sp<ABuffer> *accessUnit) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Track *track = audio ? &mAudioTrack : &mVideoTrack;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (track->mSource == NULL) {
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return -EWOULDBLOCK;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mIsWidevine && !audio) {
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // try to read a buffer as we may not have been able to the last time
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_t finalResult;
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return (finalResult == OK ? -EWOULDBLOCK : finalResult);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result != OK) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (mSubtitleTrack.mSource != NULL) {
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mSubtitleTrack.mPackets->clear();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mFetchSubtitleDataGeneration++;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mTimedTextTrack.mSource != NULL) {
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mTimedTextTrack.mPackets->clear();
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mFetchTimedTextDataGeneration++;
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return result;
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64_t timeUs;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_t eosResult; // ignored
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mSubtitleTrack.mSource != NULL
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        msg->setInt64("timeUs", timeUs);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->setInt32("generation", mFetchSubtitleDataGeneration);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->post();
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mTimedTextTrack.mSource != NULL
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->setInt64("timeUs", timeUs);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->setInt32("generation", mFetchTimedTextDataGeneration);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        msg->post();
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *durationUs = mDurationUs;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t NuPlayer::GenericSource::getTrackCount() const {
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return mSources.size();
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t trackCount = mSources.size();
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (trackIndex >= trackCount) {
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return NULL;
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> format = new AMessage();
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char *mime;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(meta->findCString(kKeyMIMEType, &mime));
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int32_t trackType;
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!strncasecmp(mime, "video/", 6)) {
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trackType = MEDIA_TRACK_TYPE_VIDEO;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (!strncasecmp(mime, "audio/", 6)) {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trackType = MEDIA_TRACK_TYPE_AUDIO;
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    format->setInt32("type", trackType);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *lang;
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        lang = "und";
880cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
881cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    format->setString("language", lang);
882cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
883cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        format->setString("mime", mime);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
887cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        meta->findInt32(kKeyTrackIsDefault, &isDefault);
889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        meta->findInt32(kKeyTrackIsForced, &isForced);
890cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        format->setInt32("auto", !!isAutoselect);
892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        format->setInt32("default", !!isDefault);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        format->setInt32("forced", !!isForced);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return format;
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt32("type", type);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> response;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t index;
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = msg->postAndAwaitResponse(&response);
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (err == OK && response != NULL) {
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CHECK(response->findInt32("index", &index));
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return index;
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return -1;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int32_t tmpType;
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt32("type", &tmpType));
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media_track_type type = (media_track_type)tmpType;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> response = new AMessage;
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ssize_t index = doGetSelectedTrack(type);
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response->setInt32("index", index);
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint32_t replyID;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(msg->senderAwaitsResponse(&replyID));
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response->postReply(replyID);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Track *track = NULL;
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (type) {
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case MEDIA_TRACK_TYPE_VIDEO:
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        track = &mVideoTrack;
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MEDIA_TRACK_TYPE_AUDIO:
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        track = &mAudioTrack;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case MEDIA_TRACK_TYPE_TIMEDTEXT:
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        track = &mTimedTextTrack;
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MEDIA_TRACK_TYPE_SUBTITLE:
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        track = &mSubtitleTrack;
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (track != NULL && track->mSource != NULL) {
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return track->mIndex;
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return -1;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msg->setInt32("trackIndex", trackIndex);
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt32("select", select);
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sp<AMessage> response;
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = msg->postAndAwaitResponse(&response);
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (err == OK && response != NULL) {
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CHECK(response->findInt32("err", &err));
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return err;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32_t trackIndex, select;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(msg->findInt32("trackIndex", &trackIndex));
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(msg->findInt32("select", &select));
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> response = new AMessage;
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = doSelectTrack(trackIndex, select);
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    response->setInt32("err", err);
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t replyID;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(msg->senderAwaitsResponse(&replyID));
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response->postReply(replyID);
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)status_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) {
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (trackIndex >= mSources.size()) {
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return BAD_INDEX;
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!select) {
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Track* track = NULL;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            track = &mSubtitleTrack;
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mFetchSubtitleDataGeneration++;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track = &mTimedTextTrack;
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mFetchTimedTextDataGeneration++;
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (track == NULL) {
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return INVALID_OPERATION;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        track->mSource->stop();
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        track->mSource = NULL;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        track->mPackets->clear();
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return OK;
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const sp<MediaSource> source = mSources.itemAt(trackIndex);
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<MetaData> meta = source->getFormat();
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char *mime;
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(meta->findCString(kKeyMIMEType, &mime));
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!strncasecmp(mime, "text/", 5)) {
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (track->mSource != NULL && track->mIndex == trackIndex) {
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return OK;
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        track->mIndex = trackIndex;
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (track->mSource != NULL) {
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track->mSource->stop();
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        track->mSource = mSources.itemAt(trackIndex);
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        track->mSource->start();
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (track->mPackets == NULL) {
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track->mPackets->clear();
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track->mPackets->setFormat(track->mSource->getFormat());
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (isSubtitle) {
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mFetchSubtitleDataGeneration++;
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } else {
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            mFetchTimedTextDataGeneration++;
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return OK;
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bool audio = !strncasecmp(mime, "audio/", 6);
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        Track *track = audio ? &mAudioTrack : &mVideoTrack;
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (track->mSource != NULL && track->mIndex == trackIndex) {
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return OK;
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        msg->setInt32("trackIndex", trackIndex);
1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        msg->post();
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return OK;
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return INVALID_OPERATION;
1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> msg = new AMessage(kWhatSeek, id());
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    msg->setInt64("seekTimeUs", seekTimeUs);
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sp<AMessage> response;
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = msg->postAndAwaitResponse(&response);
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (err == OK && response != NULL) {
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CHECK(response->findInt32("err", &err));
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return err;
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int64_t seekTimeUs;
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1069a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1070a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    sp<AMessage> response = new AMessage;
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_t err = doSeek(seekTimeUs);
1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    response->setInt32("err", err);
1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32_t replyID;
1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CHECK(msg->senderAwaitsResponse(&replyID));
1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    response->postReply(replyID);
1077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
1080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (mVideoTrack.mSource != NULL) {
1081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        int64_t actualTimeUs;
1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
1083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        seekTimeUs = actualTimeUs;
10852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
10862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
10872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (mAudioTrack.mSource != NULL) {
1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!mStarted) {
1093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
1094868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1095868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return OK;
1096868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1098868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
1099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        MediaBuffer* mb,
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        media_track_type trackType,
1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        int64_t *actualTimeUs) {
1102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
1103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t outLength = mb->range_length();
1104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (audio && mAudioIsVorbis) {
1106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        outLength += sizeof(int32_t);
1107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    sp<ABuffer> ab;
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (mIsWidevine && !audio) {
1111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        // data is already provided in the buffer
1112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        ab = new ABuffer(NULL, mb->range_length());
1113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        ab->meta()->setPointer("mediaBuffer", mb);
1114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mb->add_ref();
1115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    } else {
1116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        ab = new ABuffer(outLength);
1117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        memcpy(ab->data(),
1118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)               (const uint8_t *)mb->data() + mb->range_offset(),
1119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)               mb->range_length());
1120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (audio && mAudioIsVorbis) {
1123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        int32_t numPageSamples;
1124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
1125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            numPageSamples = -1;
1126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        }
1127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        uint8_t* abEnd = ab->data() + mb->range_length();
1129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
1130a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    sp<AMessage> meta = ab->meta();
1133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int64_t timeUs;
1135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
1136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    meta->setInt64("timeUs", timeUs);
1137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
1139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        const char *mime;
1140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        CHECK(mTimedTextTrack.mSource != NULL
1141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
1142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        meta->setString("mime", mime);
1143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int64_t durationUs;
1146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
1147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        meta->setInt64("durationUs", durationUs);
1148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
1151a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
1152a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1153a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1154a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (actualTimeUs) {
1155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        *actualTimeUs = timeUs;
1156a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1158a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    mb->release();
1159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    mb = NULL;
1160a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1161a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return ab;
1162a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1163a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Mutex::Autolock _l(mReadBufferLock);
1166a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
1168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mPendingReadBufferTypes |= (1 << trackType);
1169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        sp<AMessage> msg = new AMessage(kWhatReadBuffer, id());
1170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        msg->setInt32("trackType", trackType);
1171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        msg->post();
1172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1175a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
1176a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int32_t tmpType;
1177a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CHECK(msg->findInt32("trackType", &tmpType));
1178a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    media_track_type trackType = (media_track_type)tmpType;
1179a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    {
1180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        // only protect the variable change, as readBuffer may
1181a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        // take considerable time.  This may result in one extra
1182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        // read being processed, but that is benign.
1183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        Mutex::Autolock _l(mReadBufferLock);
1184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        mPendingReadBufferTypes &= ~(1 << trackType);
1185a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1186a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    readBuffer(trackType);
1187a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1189a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NuPlayer::GenericSource::readBuffer(
1190a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
1191a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    Track *track;
1192a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    size_t maxBuffers = 1;
1193a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    switch (trackType) {
1194a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        case MEDIA_TRACK_TYPE_VIDEO:
1195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            track = &mVideoTrack;
1196a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            break;
1197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        case MEDIA_TRACK_TYPE_AUDIO:
1198a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            track = &mAudioTrack;
1199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            maxBuffers = 64;
1200a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            break;
1201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        case MEDIA_TRACK_TYPE_SUBTITLE:
1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            track = &mSubtitleTrack;
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            break;
1204a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        case MEDIA_TRACK_TYPE_TIMEDTEXT:
1205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            track = &mTimedTextTrack;
1206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            break;
1207a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        default:
1208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            TRESPASS();
1209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (track->mSource == NULL) {
1212a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return;
1213a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (actualTimeUs) {
1216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        *actualTimeUs = seekTimeUs;
1217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MediaSource::ReadOptions options;
1220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    bool seeking = false;
1222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (seekTimeUs >= 0) {
1224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        seeking = true;
1226a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) {
1229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        options.setNonBlocking();
1230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
1233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        MediaBuffer *mbuf;
1234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        status_t err = track->mSource->read(&mbuf, &options);
1235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        options.clearSeekTo();
1237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1238a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        if (err == OK) {
1239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            int64_t timeUs;
1240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
1241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
1242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                mAudioTimeUs = timeUs;
1243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
1244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                mVideoTimeUs = timeUs;
1245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            }
1246a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            // formatChange && seeking: track whose source is changed during selection
1248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            // formatChange && !seeking: track whose source is not changed during selection
1249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            // !formatChange: normal seek
1250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            if ((seeking || formatChange)
1251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
1252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
1253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                ATSParser::DiscontinuityType type = formatChange
1254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                        ? (seeking
1255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                ? ATSParser::DISCONTINUITY_FORMATCHANGE
1256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                : ATSParser::DISCONTINUITY_NONE)
1257a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                        : ATSParser::DISCONTINUITY_SEEK;
1258a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
1259a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            }
1260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs);
1262a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            track->mPackets->queueAccessUnit(buffer);
1263a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            ++numBuffers;
1264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        } else if (err == WOULD_BLOCK) {
1265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            break;
1266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        } else if (err == INFO_FORMAT_CHANGED) {
1267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if 0
1268a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            track->mPackets->queueDiscontinuity(
1269a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    ATSParser::DISCONTINUITY_FORMATCHANGE,
1270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    NULL,
1271a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                    false /* discard */);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            track->mPackets->signalEOS(err);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace android
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)