GenericSource.cpp revision a6bf21f2a7cdd33c78464019dc1105ef01248b51
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2012 The Android Open Source Project
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License.
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License.
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "GenericSource"
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "GenericSource.h"
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AnotherPacketSource.h"
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/IMediaHTTPService.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/ABuffer.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/foundation/ADebug.h>
279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <media/stagefright/foundation/AMessage.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/DataSource.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/FileSource.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaBuffer.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaDefs.h>
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaExtractor.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/MediaSource.h>
3438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <media/stagefright/MetaData.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/stagefright/Utils.h>
36fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include "../../libstagefright/include/DRMExtractor.h"
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "../../libstagefright/include/NuCachedSource2.h"
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "../../libstagefright/include/WVMExtractor.h"
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "../../libstagefright/include/HTTPBase.h"
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
419ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangnamespace android {
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianNuPlayer::GenericSource::GenericSource(
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<AMessage> &notify,
45fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        bool uidValid,
4664760240f931714858a59c1579f07264d7182ba2Dima Zavin        uid_t uid)
477394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin    : Source(notify),
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mAudioTimeUs(0),
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mAudioLastDequeueTimeUs(0),
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mVideoTimeUs(0),
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mVideoLastDequeueTimeUs(0),
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mFetchSubtitleDataGeneration(0),
536d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent      mFetchTimedTextDataGeneration(0),
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mDurationUs(0ll),
554d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten      mAudioIsVorbis(false),
56feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent      mIsWidevine(false),
574d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten      mUIDValid(uidValid),
584d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten      mUID(uid),
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mFd(-1),
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mDrmManagerClient(NULL),
61de070137f11d346fba77605bd76a44c040a618fcEric Laurent      mMetaDataSize(-1ll),
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mBitrate(-1ll),
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mPollBufferingGeneration(0),
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mPendingReadBufferTypes(0) {
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    resetDataSource();
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DataSource::RegisterDefaultSniffers();
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::resetDataSource() {
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHTTPService.clear();
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHttpSource.clear();
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mUri.clear();
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mUriHeaders.clear();
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mFd >= 0) {
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        close(mFd);
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mFd = -1;
7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mOffset = 0;
7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLength = 0;
8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mDecryptHandle = NULL;
8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mDrmManagerClient = NULL;
8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStarted = false;
8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStopRead = true;
857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::setDataSource(
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMediaHTTPService> &httpService,
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const char *url,
9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const KeyedVector<String8, String8> *headers) {
9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    resetDataSource();
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHTTPService = httpService;
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mUri = url;
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (headers) {
9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mUriHeaders = *headers;
9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // delay data source creation to prepareAsync() to avoid blocking
10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // the calling thread in setDataSource for any significant time.
10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
1049ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1059ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangstatus_t NuPlayer::GenericSource::setDataSource(
1069ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        int fd, int64_t offset, int64_t length) {
1079ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    resetDataSource();
1089ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1099ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    mFd = dup(fd);
1109ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    mOffset = offset;
1119ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    mLength = length;
1129ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1139ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // delay data source creation to prepareAsync() to avoid blocking
1149ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // the calling thread in setDataSource for any significant time.
1159ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    return OK;
1169ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang}
117799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
118799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinsp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
119799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return mFileMeta;
120799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
121799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
122799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinstatus_t NuPlayer::GenericSource::initFromDataSource() {
123799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    sp<MediaExtractor> extractor;
124799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
125799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    CHECK(mDataSource != NULL);
126799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
127799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (mIsWidevine) {
128799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        String8 mimeType;
129799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        float confidence;
130799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        sp<AMessage> dummy;
131799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        bool success;
132799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
133799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        success = SniffWVM(mDataSource, &mimeType, &confidence, &dummy);
134799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        if (!success
135799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                || strcasecmp(
136799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
137799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            ALOGE("unsupported widevine mime: %s", mimeType.string());
138799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            return UNKNOWN_ERROR;
139799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
140799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
141799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        mWVMExtractor = new WVMExtractor(mDataSource);
142799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        mWVMExtractor->setAdaptiveStreamingMode(true);
143799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        if (mUIDValid) {
144799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            mWVMExtractor->setUID(mUID);
145799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
146799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        extractor = mWVMExtractor;
14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        extractor = MediaExtractor::Create(mDataSource,
14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str());
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
151799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (extractor == NULL) {
1535a61d2f277af3098fc10b2881babca16391362daDima Zavin        return UNKNOWN_ERROR;
1545a61d2f277af3098fc10b2881babca16391362daDima Zavin    }
1555a61d2f277af3098fc10b2881babca16391362daDima Zavin
1565a61d2f277af3098fc10b2881babca16391362daDima Zavin    if (extractor->getDrmFlag()) {
157799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        checkDrmStatus(mDataSource);
158fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
159935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
160935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    mFileMeta = extractor->getMetaData();
161799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (mFileMeta != NULL) {
16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int64_t duration;
16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
164799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            mDurationUs = duration;
165799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
166799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
167fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
168799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int32_t totalBitrate = 0;
169799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
170799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    size_t numtracks = extractor->countTracks();
171799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (numtracks == 0) {
172799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return UNKNOWN_ERROR;
173799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
174799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
175799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    for (size_t i = 0; i < numtracks; ++i) {
176799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        sp<MediaSource> track = extractor->getTrack(i);
177799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
178799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        sp<MetaData> meta = extractor->getTrackMetaData(i);
1795a61d2f277af3098fc10b2881babca16391362daDima Zavin
180799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        const char *mime;
181799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        CHECK(meta->findCString(kKeyMIMEType, &mime));
18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Do the string compare immediately with "mime",
184fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        // we can't assume "mime" would stay valid after another
185799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // extractor operation, some extractors might modify meta
186799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // during getTrack() and make it invalid.
187799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        if (!strncasecmp(mime, "audio/", 6)) {
188799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            if (mAudioTrack.mSource == NULL) {
189799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mAudioTrack.mIndex = i;
190799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mAudioTrack.mSource = track;
191799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mAudioTrack.mPackets =
192799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                    new AnotherPacketSource(mAudioTrack.mSource->getFormat());
193799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
194799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
195799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                    mAudioIsVorbis = true;
196799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                } else {
197799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                    mAudioIsVorbis = false;
198799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                }
199799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            }
200799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        } else if (!strncasecmp(mime, "video/", 6)) {
201799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            if (mVideoTrack.mSource == NULL) {
202799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mVideoTrack.mIndex = i;
203799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mVideoTrack.mSource = track;
204799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                mVideoTrack.mPackets =
20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    new AnotherPacketSource(mVideoTrack.mSource->getFormat());
20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // check if the source requires secure buffers
2085a61d2f277af3098fc10b2881babca16391362daDima Zavin                int32_t secure;
2095a61d2f277af3098fc10b2881babca16391362daDima Zavin                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
2105a61d2f277af3098fc10b2881babca16391362daDima Zavin                        && secure) {
2115a61d2f277af3098fc10b2881babca16391362daDima Zavin                    mIsWidevine = true;
2125a61d2f277af3098fc10b2881babca16391362daDima Zavin                    if (mUIDValid) {
2135a61d2f277af3098fc10b2881babca16391362daDima Zavin                        extractor->setUID(mUID);
2145a61d2f277af3098fc10b2881babca16391362daDima Zavin                    }
2155a61d2f277af3098fc10b2881babca16391362daDima Zavin                }
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
218799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
219799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        if (track != NULL) {
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSources.push(track);
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int64_t durationUs;
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (meta->findInt64(kKeyDuration, &durationUs)) {
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (durationUs > mDurationUs) {
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mDurationUs = durationUs;
22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
228799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            int32_t bitrate;
229799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
230799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                totalBitrate += bitrate;
231799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            } else {
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                totalBitrate = -1;
233799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            }
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
236799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
237799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mBitrate = totalBitrate;
238799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
239799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return OK;
240799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
241799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
242799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinvoid NuPlayer::GenericSource::checkDrmStatus(const sp<DataSource>& dataSource) {
243799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
244799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (mDecryptHandle != NULL) {
245799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        CHECK(mDrmManagerClient);
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<AMessage> msg = dupNotify();
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            msg->setInt32("what", kWhatDrmNoLicense);
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            msg->post();
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint64_t NuPlayer::GenericSource::getLastReadPosition() {
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mAudioTrack.mSource != NULL) {
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return mAudioTimeUs;
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (mVideoTrack.mSource != NULL) {
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return mVideoTimeUs;
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::setBuffers(
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool audio, Vector<MediaBuffer *> &buffers) {
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mIsWidevine && !audio) {
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return mVideoTrack.mSource->setBuffers(buffers);
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return INVALID_OPERATION;
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianNuPlayer::GenericSource::~GenericSource() {
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mLooper != NULL) {
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper->unregisterHandler(id());
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper->stop();
27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    resetDataSource();
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::prepareAsync() {
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mLooper == NULL) {
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper = new ALooper;
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper->setName("generic");
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper->start();
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLooper->registerHandler(this);
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, id());
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->post();
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onPrepareAsync() {
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // delayed data source creation
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mDataSource == NULL) {
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!mUri.empty()) {
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const char* uri = mUri.c_str();
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mIsWidevine = !strncasecmp(uri, "widevine://", 11);
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!strncasecmp("http://", uri, 7)
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    || !strncasecmp("https://", uri, 8)
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    || mIsWidevine) {
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mHttpSource = DataSource::CreateMediaHTTP(mHTTPService);
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mHttpSource == NULL) {
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ALOGE("Failed to create http source!");
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return;
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDataSource = DataSource::CreateFromURI(
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                   mHTTPService, uri, &mUriHeaders, &mContentType,
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                   static_cast<HTTPBase *>(mHttpSource.get()));
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // set to false first, if the extractor
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // comes back as secure, set it to true then.
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mIsWidevine = false;
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDataSource = new FileSource(mFd, mOffset, mLength);
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFd = -1;
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mDataSource == NULL) {
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("Failed to create data source!");
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            notifyPreparedAndCleanup(UNKNOWN_ERROR);
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return;
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mIsWidevine || mCachedSource != NULL) {
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            schedulePollBuffering();
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check initial caching status
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = prefillCacheIfNecessary();
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == -EAGAIN) {
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (new AMessage(kWhatPrepareAsync, id()))->post(200000);
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
344799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            ALOGE("Failed to prefill data cache!");
345799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            notifyPreparedAndCleanup(UNKNOWN_ERROR);
346799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
347799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return;
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // init extrator from data source
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    err = initFromDataSource();
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGE("Failed to init from data source!");
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notifyPreparedAndCleanup(err);
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mVideoTrack.mSource != NULL) {
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<MetaData> meta = doGetFormatMeta(false /* audio */);
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = new AMessage;
3620d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        err = convertMetaDataToMessage(meta, &msg);
3630d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        if(err != OK) {
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            notifyPreparedAndCleanup(err);
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return;
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notifyVideoSizeChanged(msg);
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notifyFlagsChanged(
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (mIsWidevine ? FLAG_SECURE : 0)
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            | FLAG_CAN_PAUSE
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            | FLAG_CAN_SEEK_BACKWARD
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            | FLAG_CAN_SEEK_FORWARD
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            | FLAG_CAN_SEEK);
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notifyPrepared();
378fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err != OK) {
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMetaDataSize = -1ll;
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mContentType = "";
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mSniffedMIME = "";
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mDataSource.clear();
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCachedSource.clear();
38739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        mHttpSource.clear();
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        cancelPollBuffering();
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    notifyPrepared(err);
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::prefillCacheIfNecessary() {
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(mDataSource != NULL);
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCachedSource == NULL) {
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // no prefill if the data source is not cached
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OK;
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // We're not doing this for streams that appear to be audio-only
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // streams to ensure that even low bandwidth streams start
404fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // playing back fairly instantly.
405de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (!strncasecmp(mContentType.string(), "audio/", 6)) {
40639e94f8f723d445447fdee0822291e664b631f60Eric Laurent        return OK;
40739e94f8f723d445447fdee0822291e664b631f60Eric Laurent    }
40839e94f8f723d445447fdee0822291e664b631f60Eric Laurent
40939e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // We're going to prefill the cache before trying to instantiate
41039e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // the extractor below, as the latter is an operation that otherwise
41139e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // could block on the datasource for a significant amount of time.
41239e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // During that time we'd be unable to abort the preparation phase
41339e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // without this prefill.
41439e94f8f723d445447fdee0822291e664b631f60Eric Laurent
41539e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // Initially make sure we have at least 192 KB for the sniff
41639e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // to complete without blocking.
41739e94f8f723d445447fdee0822291e664b631f60Eric Laurent    static const size_t kMinBytesForSniffing = 192 * 1024;
418de070137f11d346fba77605bd76a44c040a618fcEric Laurent    static const size_t kDefaultMetaSize = 200000;
419de070137f11d346fba77605bd76a44c040a618fcEric Laurent
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t finalStatus;
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
422de070137f11d346fba77605bd76a44c040a618fcEric Laurent    size_t cachedDataRemaining =
4237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            mCachedSource->approxDataRemaining(&finalStatus);
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (finalStatus != OK || (mMetaDataSize >= 0
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            && (off64_t)cachedDataRemaining >= mMetaDataSize)) {
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ALOGV("stop caching, status %d, "
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "metaDataSize %lld, cachedDataRemaining %zu",
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                finalStatus, mMetaDataSize, cachedDataRemaining);
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OK;
4310d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    }
43239e94f8f723d445447fdee0822291e664b631f60Eric Laurent
43339e94f8f723d445447fdee0822291e664b631f60Eric Laurent    ALOGV("now cached %zu bytes of data", cachedDataRemaining);
43439e94f8f723d445447fdee0822291e664b631f60Eric Laurent
43539e94f8f723d445447fdee0822291e664b631f60Eric Laurent    if (mMetaDataSize < 0
43639e94f8f723d445447fdee0822291e664b631f60Eric Laurent            && cachedDataRemaining >= kMinBytesForSniffing) {
43739e94f8f723d445447fdee0822291e664b631f60Eric Laurent        String8 tmp;
43839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        float confidence;
43939e94f8f723d445447fdee0822291e664b631f60Eric Laurent        sp<AMessage> meta;
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!mCachedSource->sniff(&tmp, &confidence, &meta)) {
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return UNKNOWN_ERROR;
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // We successfully identified the file's extractor to
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // be, remember this mime type so we don't have to
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // sniff it again when we call MediaExtractor::Create()
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mSniffedMIME = tmp.string();
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (meta == NULL
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                || !meta->findInt64("meta-data-size",
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        reinterpret_cast<int64_t*>(&mMetaDataSize))) {
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mMetaDataSize = kDefaultMetaSize;
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mMetaDataSize < 0ll) {
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ALOGE("invalid metaDataSize = %lld bytes", mMetaDataSize);
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return UNKNOWN_ERROR;
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
45965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return -EAGAIN;
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::start() {
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGI("start");
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStopRead = false;
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mAudioTrack.mSource != NULL) {
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mVideoTrack.mSource != NULL) {
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4790d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStarted = true;
48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::stop() {
48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // nothing to do, just account for DRM playback status
48665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStarted = false;
48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mIsWidevine) {
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // For a widevine source we need to prevent any further reads.
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> response;
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        (void) msg->postAndAwaitResponse(&response);
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::pause() {
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // nothing to do, just account for DRM playback status
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStarted = false;
50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::resume() {
50365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // nothing to do, just account for DRM playback status
50465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::START, getLastReadPosition() / 1000);
50565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStarted = true;
50665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
50765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
50865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::disconnect() {
50965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mDataSource != NULL) {
51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // disconnect data source
51165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            static_cast<NuCachedSource2 *>(mDataSource.get())->disconnect();
51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
51465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (mHttpSource != NULL) {
51565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        static_cast<HTTPBase *>(mHttpSource.get())->disconnect();
51665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
51765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::setDrmPlaybackStatusIfNeeded(int playbackStatus, int64_t position) {
520935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    if (mDecryptHandle != NULL) {
521935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        mDrmManagerClient->setPlaybackStatus(mDecryptHandle, playbackStatus, position);
522935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    }
523799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mSubtitleTrack.mPackets = new AnotherPacketSource(NULL);
524935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    mTimedTextTrack.mPackets = new AnotherPacketSource(NULL);
525935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent}
526935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::feedMoreTSData() {
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
529935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent}
53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::schedulePollBuffering() {
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatPollBuffering, id());
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("generation", mPollBufferingGeneration);
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->post(1000000ll);
53565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::cancelPollBuffering() {
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ++mPollBufferingGeneration;
53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) {
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = dupNotify();
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("what", kWhatBufferingUpdate);
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("percentage", percentage);
545fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    msg->post();
54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onPollBuffering() {
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t finalStatus = UNKNOWN_ERROR;
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t cachedDurationUs = 0ll;
55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCachedSource != NULL) {
553799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        size_t cachedDataRemaining =
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCachedSource->approxDataRemaining(&finalStatus);
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (finalStatus == OK) {
55765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            off64_t size;
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int64_t bitrate = 0ll;
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                bitrate = size * 8000000ll / mDurationUs;
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (mBitrate > 0) {
56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                bitrate = mBitrate;
56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (bitrate > 0) {
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
56865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (mWVMExtractor != NULL) {
56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        cachedDurationUs
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            = mWVMExtractor->getCachedDurationUs(&finalStatus);
57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (finalStatus == ERROR_END_OF_STREAM) {
57465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notifyBufferingUpdate(100);
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        cancelPollBuffering();
576799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return;
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (cachedDurationUs > 0ll && mDurationUs > 0ll) {
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int percentage = 100.0 * cachedDurationUs / mDurationUs;
57965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (percentage > 100) {
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            percentage = 100;
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
583fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        notifyBufferingUpdate(percentage);
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
585799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    schedulePollBuffering();
58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (msg->what()) {
59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatPrepareAsync:
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onPrepareAsync();
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
597935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent      case kWhatFetchSubtitleData:
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatFetchTimedTextData:
60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatSendSubtitleData:
61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatSendTimedTextData:
61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
622fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin          break;
62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatChangeAVSource:
62665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          int32_t trackIndex;
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          CHECK(msg->findInt32("trackIndex", &trackIndex));
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          const sp<MediaSource> source = mSources.itemAt(trackIndex);
63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          Track* track;
63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          const char *mime;
63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          media_track_type trackType, counterpartType;
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          sp<MetaData> meta = source->getFormat();
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          meta->findCString(kKeyMIMEType, &mime);
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          if (!strncasecmp(mime, "audio/", 6)) {
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              track = &mAudioTrack;
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              trackType = MEDIA_TRACK_TYPE_AUDIO;
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          } else {
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              CHECK(!strncasecmp(mime, "video/", 6));
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              track = &mVideoTrack;
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              trackType = MEDIA_TRACK_TYPE_VIDEO;
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          }
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          if (track->mSource != NULL) {
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              track->mSource->stop();
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          }
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          track->mSource = source;
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          track->mSource->start();
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          track->mIndex = trackIndex;
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
655fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin          int64_t timeUs, actualTimeUs;
656fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin          const bool formatChange = true;
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              timeUs = mAudioLastDequeueTimeUs;
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          } else {
660935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent              timeUs = mVideoLastDequeueTimeUs;
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          }
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          readBuffer(counterpartType, -1, NULL, formatChange);
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatPollBuffering:
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
670fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin          int32_t generation;
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          CHECK(msg->findInt32("generation", &generation));
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          if (generation == mPollBufferingGeneration) {
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian              onPollBuffering();
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          }
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatGetFormat:
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onGetFormatMeta(msg);
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatGetSelectedTrack:
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onGetSelectedTrack(msg);
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatSelectTrack:
691fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin      {
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onSelectTrack(msg);
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatSeek:
69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onSeek(msg);
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatReadBuffer:
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          onReadBuffer(msg);
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      case kWhatStopWidevine:
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      {
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          // mStopRead is only used for Widevine to prevent the video source
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          // from being read while the associated video decoder is shutting down.
71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          mStopRead = true;
713799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          if (mVideoTrack.mSource != NULL) {
714799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin              mVideoTrack.mPackets->clear();
715799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          }
716799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          sp<AMessage> response = new AMessage;
717799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          uint32_t replyID;
718799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          CHECK(msg->senderAwaitsResponse(&replyID));
71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          response->postReply(replyID);
720799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin          break;
72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      }
72265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      default:
72365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          Source::onMessageReceived(msg);
72465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian          break;
72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
72665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::fetchTextData(
72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sendWhat,
73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        media_track_type type,
7317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        int32_t curGen,
7327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        sp<AnotherPacketSource> packets,
7337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        sp<AMessage> msg) {
7347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    int32_t msgGeneration;
7357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    CHECK(msg->findInt32("generation", &msgGeneration));
7367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (msgGeneration != curGen) {
7377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // stale
7387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return;
7397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t avail;
74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (packets->hasBufferAvailable(&avail)) {
74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t timeUs;
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt64("timeUs", &timeUs));
74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t subTimeUs;
75065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    readBuffer(type, timeUs, &subTimeUs);
75165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t delayUs = subTimeUs - timeUs;
75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (msg->what() == kWhatFetchSubtitleData) {
75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const int64_t oneSecUs = 1000000ll;
755fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        delayUs -= oneSecUs;
756fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
757799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    sp<AMessage> msg2 = new AMessage(sendWhat, id());
758799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    msg2->setInt32("generation", msgGeneration);
759799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    msg2->post(delayUs < 0 ? 0 : delayUs);
760799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
761799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
762799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinvoid NuPlayer::GenericSource::sendTextData(
763fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        uint32_t what,
76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        media_track_type type,
76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t curGen,
76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AnotherPacketSource> packets,
76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg) {
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t msgGeneration;
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("generation", &msgGeneration));
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (msgGeneration != curGen) {
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // stale
77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t subTimeUs;
77665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (packets->nextBufferTime(&subTimeUs) != OK) {
77765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
77865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
77965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t nextSubTimeUs;
781799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    readBuffer(type, -1, &nextSubTimeUs);
78265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ABuffer> buffer;
78465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
78565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (dequeueStatus == OK) {
78665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> notify = dupNotify();
78765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setInt32("what", what);
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->setBuffer("buffer", buffer);
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        notify->post();
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const int64_t delayUs = nextSubTimeUs - subTimeUs;
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->post(delayUs < 0 ? 0 : delayUs);
79365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("audio", audio);
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response;
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    void *format;
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = msg->postAndAwaitResponse(&response);
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK && response != NULL) {
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(response->findPointer("format", &format));
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return (MetaData *)format;
80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
808799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    }
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onGetFormatMeta(sp<AMessage> msg) const {
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t audio;
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("audio", &audio));
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response = new AMessage;
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MetaData> format = doGetFormatMeta(audio);
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->setPointer("format", format.get());
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t replyID;
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->senderAwaitsResponse(&replyID));
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->postReply(replyID);
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (source == NULL) {
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return source->getFormat();
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool audio, sp<ABuffer> *accessUnit) {
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Track *track = audio ? &mAudioTrack : &mVideoTrack;
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (track->mSource == NULL) {
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return -EWOULDBLOCK;
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mIsWidevine && !audio) {
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // try to read a buffer as we may not have been able to the last time
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t finalResult;
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return (finalResult == OK ? -EWOULDBLOCK : finalResult);
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != OK) {
85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSubtitleTrack.mSource != NULL) {
86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSubtitleTrack.mPackets->clear();
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFetchSubtitleDataGeneration++;
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mTimedTextTrack.mSource != NULL) {
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mTimedTextTrack.mPackets->clear();
86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFetchTimedTextDataGeneration++;
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return result;
86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t timeUs;
87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t eosResult; // ignored
87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (audio) {
87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioLastDequeueTimeUs = timeUs;
87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mVideoLastDequeueTimeUs = timeUs;
87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSubtitleTrack.mSource != NULL
88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->setInt64("timeUs", timeUs);
88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->setInt32("generation", mFetchSubtitleDataGeneration);
88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->post();
88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mTimedTextTrack.mSource != NULL
8887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
88965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
89065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->setInt64("timeUs", timeUs);
891feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        msg->setInt32("generation", mFetchTimedTextDataGeneration);
892feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        msg->post();
89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
894feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *durationUs = mDurationUs;
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
901feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
902feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansize_t NuPlayer::GenericSource::getTrackCount() const {
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mSources.size();
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t trackCount = mSources.size();
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (trackIndex >= trackCount) {
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> format = new AMessage();
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const char *mime;
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(meta->findCString(kKeyMIMEType, &mime));
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t trackType;
92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!strncasecmp(mime, "video/", 6)) {
92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackType = MEDIA_TRACK_TYPE_VIDEO;
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strncasecmp(mime, "audio/", 6)) {
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackType = MEDIA_TRACK_TYPE_AUDIO;
92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    format->setInt32("type", trackType);
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9310d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    const char *lang;
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!meta->findCString(kKeyMediaLanguage, &lang)) {
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lang = "und";
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    format->setString("language", lang);
93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        format->setString("mime", mime);
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->findInt32(kKeyTrackIsDefault, &isDefault);
94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->findInt32(kKeyTrackIsForced, &isForced);
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        format->setInt32("auto", !!isAutoselect);
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        format->setInt32("default", !!isDefault);
94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        format->setInt32("forced", !!isForced);
94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return format;
95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
95265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("type", type);
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response;
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t index;
95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = msg->postAndAwaitResponse(&response);
96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK && response != NULL) {
96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(response->findInt32("index", &index));
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return index;
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return -1;
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onGetSelectedTrack(sp<AMessage> msg) const {
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t tmpType;
97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("type", &tmpType));
97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    media_track_type type = (media_track_type)tmpType;
97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
97365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response = new AMessage;
97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ssize_t index = doGetSelectedTrack(type);
97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->setInt32("index", index);
97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t replyID;
97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->senderAwaitsResponse(&replyID));
97965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->postReply(replyID);
98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianssize_t NuPlayer::GenericSource::doGetSelectedTrack(media_track_type type) const {
98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const Track *track = NULL;
98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (type) {
98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case MEDIA_TRACK_TYPE_VIDEO:
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = &mVideoTrack;
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case MEDIA_TRACK_TYPE_AUDIO:
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = &mAudioTrack;
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case MEDIA_TRACK_TYPE_TIMEDTEXT:
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = &mTimedTextTrack;
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case MEDIA_TRACK_TYPE_SUBTITLE:
99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = &mSubtitleTrack;
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    default:
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (track != NULL && track->mSource != NULL) {
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return track->mIndex;
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
100465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return -1;
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("trackIndex", trackIndex);
101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    msg->setInt32("select", select);
101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response;
101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = msg->postAndAwaitResponse(&response);
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (err == OK && response != NULL) {
10170d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        CHECK(response->findInt32("err", &err));
10180d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    }
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return err;
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::onSelectTrack(sp<AMessage> msg) {
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t trackIndex, select;
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("trackIndex", &trackIndex));
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("select", &select));
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> response = new AMessage;
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t err = doSelectTrack(trackIndex, select);
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->setInt32("err", err);
103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t replyID;
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->senderAwaitsResponse(&replyID));
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    response->postReply(replyID);
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::doSelectTrack(size_t trackIndex, bool select) {
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (trackIndex >= mSources.size()) {
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_INDEX;
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!select) {
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Track* track = NULL;
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track = &mSubtitleTrack;
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFetchSubtitleDataGeneration++;
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track = &mTimedTextTrack;
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFetchTimedTextDataGeneration++;
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
10511d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        if (track == NULL) {
10521d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            return INVALID_OPERATION;
10531d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        }
10541d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        track->mSource->stop();
10551d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        track->mSource = NULL;
10561d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        track->mPackets->clear();
10571d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        return OK;
10581d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    }
10591d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
10601d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    const sp<MediaSource> source = mSources.itemAt(trackIndex);
10611d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    sp<MetaData> meta = source->getFormat();
10621d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    const char *mime;
10631d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    CHECK(meta->findCString(kKeyMIMEType, &mime));
10641d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    if (!strncasecmp(mime, "text/", 5)) {
10651d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
10661d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
10671d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        if (track->mSource != NULL && track->mIndex == trackIndex) {
10681d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            return OK;
1069feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1070feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        track->mIndex = trackIndex;
1071feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (track->mSource != NULL) {
1072feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            track->mSource->stop();
1073feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1074feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        track->mSource = mSources.itemAt(trackIndex);
1075feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        track->mSource->start();
1076feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (track->mPackets == NULL) {
1077feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
1078feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
1079feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            track->mPackets->clear();
1080feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            track->mPackets->setFormat(track->mSource->getFormat());
1081feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1082feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1083feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1084feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (isSubtitle) {
1085feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mFetchSubtitleDataGeneration++;
1086feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
1087feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mFetchTimedTextDataGeneration++;
1088feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1089feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1090feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        return OK;
1091feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
1092feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        bool audio = !strncasecmp(mime, "audio/", 6);
1093feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        Track *track = audio ? &mAudioTrack : &mVideoTrack;
1094feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (track->mSource != NULL && track->mIndex == trackIndex) {
1095feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            return OK;
1096feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1097feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1098feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
1099feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        msg->setInt32("trackIndex", trackIndex);
1100feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        msg->post();
1101feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        return OK;
1102feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
11036dbe883644940badc684957cfc381bfd115f205eEric Laurent
1104feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    return INVALID_OPERATION;
1105feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1106feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1107feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
1108feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    sp<AMessage> msg = new AMessage(kWhatSeek, id());
1109feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    msg->setInt64("seekTimeUs", seekTimeUs);
1110feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1111feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    sp<AMessage> response;
1112feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    status_t err = msg->postAndAwaitResponse(&response);
1113feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (err == OK && response != NULL) {
1114feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        CHECK(response->findInt32("err", &err));
1115feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1116feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1117feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    return err;
1118feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1119feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1120feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid NuPlayer::GenericSource::onSeek(sp<AMessage> msg) {
1121feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    int64_t seekTimeUs;
1122feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
1123feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1124feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    sp<AMessage> response = new AMessage;
1125feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    status_t err = doSeek(seekTimeUs);
1126feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    response->setInt32("err", err);
1127feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1128feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    uint32_t replyID;
1129feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    CHECK(msg->senderAwaitsResponse(&replyID));
1130feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    response->postReply(replyID);
1131feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
11321d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs) {
113465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // If the Widevine source is stopped, do not attempt to read any
11357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // more buffers.
11367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (mStopRead) {
11377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return INVALID_OPERATION;
11387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
11397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (mVideoTrack.mSource != NULL) {
114065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int64_t actualTimeUs;
11417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1143feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        seekTimeUs = actualTimeUs;
1144feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mVideoLastDequeueTimeUs = seekTimeUs;
114565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mAudioTrack.mSource != NULL) {
114865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioLastDequeueTimeUs = seekTimeUs;
1150fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    setDrmPlaybackStatusIfNeeded(Playback::START, seekTimeUs / 1000);
115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!mStarted) {
115465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        setDrmPlaybackStatusIfNeeded(Playback::PAUSE, 0);
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return OK;
115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        MediaBuffer* mb,
116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        media_track_type trackType,
116265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int64_t *actualTimeUs) {
116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
116465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t outLength = mb->range_length();
116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (audio && mAudioIsVorbis) {
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        outLength += sizeof(int32_t);
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ABuffer> ab;
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mIsWidevine && !audio) {
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // data is already provided in the buffer
117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ab = new ABuffer(NULL, mb->range_length());
117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mb->add_ref();
117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        ab->setMediaBufferBase(mb);
117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
11770d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        ab = new ABuffer(outLength);
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        memcpy(ab->data(),
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian               (const uint8_t *)mb->data() + mb->range_offset(),
118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian               mb->range_length());
118165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (audio && mAudioIsVorbis) {
118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t numPageSamples;
118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            numPageSamples = -1;
118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
11880d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint8_t* abEnd = ab->data() + mb->range_length();
119065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<AMessage> meta = ab->meta();
119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t timeUs;
119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    meta->setInt64("timeUs", timeUs);
119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
120065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const char *mime;
120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        CHECK(mTimedTextTrack.mSource != NULL
120265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
120365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->setString("mime", mime);
120465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
120565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int64_t durationUs;
120765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
120865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->setInt64("durationUs", durationUs);
120965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
121065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
121165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
121265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
121365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
121465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
121565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (actualTimeUs) {
121665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *actualTimeUs = timeUs;
121765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
121865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
121965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mb->release();
122065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mb = NULL;
122165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
122265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ab;
122365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
122465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
122565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::postReadBuffer(media_track_type trackType) {
122665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mReadBufferLock);
122765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPendingReadBufferTypes |= (1 << trackType);
123065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<AMessage> msg = new AMessage(kWhatReadBuffer, id());
123165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->setInt32("trackType", trackType);
123265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        msg->post();
1233b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
1234b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
1235b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
1236b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurentvoid NuPlayer::GenericSource::onReadBuffer(sp<AMessage> msg) {
123765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t tmpType;
123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CHECK(msg->findInt32("trackType", &tmpType));
1239b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    media_track_type trackType = (media_track_type)tmpType;
124065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
124165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // only protect the variable change, as readBuffer may
124265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // take considerable time.  This may result in one extra
124365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // read being processed, but that is benign.
1244feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        Mutex::Autolock _l(mReadBufferLock);
124565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPendingReadBufferTypes &= ~(1 << trackType);
124665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    readBuffer(trackType);
124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid NuPlayer::GenericSource::readBuffer(
125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
12520d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    // Do not read data if Widevine source is stopped
12530d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    if (mStopRead) {
125465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
125565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Track *track;
125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t maxBuffers = 1;
125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (trackType) {
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case MEDIA_TRACK_TYPE_VIDEO:
126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track = &mVideoTrack;
126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mIsWidevine) {
126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                maxBuffers = 2;
12630d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            }
12640d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            break;
12650d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        case MEDIA_TRACK_TYPE_AUDIO:
12660d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            track = &mAudioTrack;
12670d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            if (mIsWidevine) {
12680d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                maxBuffers = 8;
12690d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            } else {
12700d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                maxBuffers = 64;
127165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case MEDIA_TRACK_TYPE_SUBTITLE:
127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track = &mSubtitleTrack;
127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case MEDIA_TRACK_TYPE_TIMEDTEXT:
127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track = &mTimedTextTrack;
127865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
127965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
128065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            TRESPASS();
12817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
128365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (track->mSource == NULL) {
128465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
128565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
128665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
128765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (actualTimeUs) {
128865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *actualTimeUs = seekTimeUs;
1289de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
1290de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1291de070137f11d346fba77605bd76a44c040a618fcEric Laurent    MediaSource::ReadOptions options;
1292de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1293de070137f11d346fba77605bd76a44c040a618fcEric Laurent    bool seeking = false;
1294fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1295de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (seekTimeUs >= 0) {
1296de070137f11d346fba77605bd76a44c040a618fcEric Laurent        options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1297de070137f11d346fba77605bd76a44c040a618fcEric Laurent        seeking = true;
1298de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
1299fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1300de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) {
1301de070137f11d346fba77605bd76a44c040a618fcEric Laurent        options.setNonBlocking();
1302de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
1303de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1304de070137f11d346fba77605bd76a44c040a618fcEric Laurent    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
1305de070137f11d346fba77605bd76a44c040a618fcEric Laurent        MediaBuffer *mbuf;
130665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t err = track->mSource->read(&mbuf, &options);
13070d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi
130865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        options.clearSeekTo();
130965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
131065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (err == OK) {
131165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int64_t timeUs;
131265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
131365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
131465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioTimeUs = timeUs;
131565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
131665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mVideoTimeUs = timeUs;
131765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
1318fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1319b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent            // formatChange && seeking: track whose source is changed during selection
132065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // formatChange && !seeking: track whose source is not changed during selection
132165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // !formatChange: normal seek
132265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if ((seeking || formatChange)
132365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    && (trackType == MEDIA_TRACK_TYPE_AUDIO
132465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
132565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                ATSParser::DiscontinuityType type = (formatChange && seeking)
132665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        ? ATSParser::DISCONTINUITY_FORMATCHANGE
132765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        : ATSParser::DISCONTINUITY_NONE;
132865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
132965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
133065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
133165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs);
133265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->mPackets->queueAccessUnit(buffer);
1333b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            formatChange = false;
1334b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            seeking = false;
1335799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            ++numBuffers;
1336b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        } else if (err == WOULD_BLOCK) {
133765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
133865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (err == INFO_FORMAT_CHANGED) {
133965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#if 0
134065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->mPackets->queueDiscontinuity(
134165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ATSParser::DISCONTINUITY_FORMATCHANGE,
134265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    NULL,
134365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    false /* discard */);
134465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#endif
134565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
134665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->mPackets->signalEOS(err);
134765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
134865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
134965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
135065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
135165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
135265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}  // namespace android
135365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian