1afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber/*
2afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Copyright (C) 2012 The Android Open Source Project
3afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
4afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * you may not use this file except in compliance with the License.
6afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * You may obtain a copy of the License at
7afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
8afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber *
10afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * Unless required by applicable law or agreed to in writing, software
11afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * See the License for the specific language governing permissions and
14afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber * limitations under the License.
15afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber */
16afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
17afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "GenericSource.h"
18afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
19afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include "AnotherPacketSource.h"
20afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
21afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
22afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/ADebug.h>
23afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/foundation/AMessage.h>
24afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/DataSource.h>
25afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/FileSource.h>
26afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaBuffer.h>
27afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaDefs.h>
28afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaExtractor.h>
29afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MediaSource.h>
30afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#include <media/stagefright/MetaData.h>
31afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
32afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubernamespace android {
33afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
34afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::GenericSource(
35b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        const sp<AMessage> &notify,
36afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const char *url,
37afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const KeyedVector<String8, String8> *headers,
38afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool uidValid,
39afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        uid_t uid)
40b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    : Source(notify),
41b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber      mDurationUs(0ll),
42afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber      mAudioIsVorbis(false) {
43afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    DataSource::RegisterDefaultSniffers();
44afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
45afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<DataSource> dataSource =
46afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        DataSource::CreateFromURI(url, headers);
47afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    CHECK(dataSource != NULL);
48afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
49afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    initFromDataSource(dataSource);
50afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
51afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
52afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::GenericSource(
53b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber        const sp<AMessage> &notify,
54afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        int fd, int64_t offset, int64_t length)
55b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber    : Source(notify),
56b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber      mDurationUs(0ll),
57afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber      mAudioIsVorbis(false) {
58afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    DataSource::RegisterDefaultSniffers();
59afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
60afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
61afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
62afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    initFromDataSource(dataSource);
63afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
64afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
65afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::initFromDataSource(
66afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const sp<DataSource> &dataSource) {
67afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
68afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
69afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    CHECK(extractor != NULL);
70afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
71afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
72afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
73afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
74afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        const char *mime;
75afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
76afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
77afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        sp<MediaSource> track;
78afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
79afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (!strncasecmp(mime, "audio/", 6)) {
80afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mAudioTrack.mSource == NULL) {
81afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                mAudioTrack.mSource = track = extractor->getTrack(i);
82afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
83afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
84afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = true;
85afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                } else {
86afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mAudioIsVorbis = false;
87afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
88afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
89afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (!strncasecmp(mime, "video/", 6)) {
90afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (mVideoTrack.mSource == NULL) {
91afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                mVideoTrack.mSource = track = extractor->getTrack(i);
92afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
93afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
94afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
95afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (track != NULL) {
96afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            int64_t durationUs;
97afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (meta->findInt64(kKeyDuration, &durationUs)) {
98afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (durationUs > mDurationUs) {
99afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    mDurationUs = durationUs;
100afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
101afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
102afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
103afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
104afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
105afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
106afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas HuberNuPlayer::GenericSource::~GenericSource() {
107afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
108afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
1099575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Hubervoid NuPlayer::GenericSource::prepareAsync() {
1109575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    if (mVideoTrack.mSource != NULL) {
1119575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        sp<MetaData> meta = mVideoTrack.mSource->getFormat();
1129575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1139575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        int32_t width, height;
1149575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        CHECK(meta->findInt32(kKeyWidth, &width));
1159575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        CHECK(meta->findInt32(kKeyHeight, &height));
1169575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1179575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber        notifyVideoSizeChanged(width, height);
1189575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    }
1199575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1209575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notifyFlagsChanged(
1219575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            FLAG_CAN_PAUSE
1229575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_BACKWARD
1239575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK_FORWARD
1249575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber            | FLAG_CAN_SEEK);
1259575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
1269575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber    notifyPrepared();
1279575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber}
1289575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber
129afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::start() {
130afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    ALOGI("start");
131afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
132afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
133afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);
134afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
135afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        mAudioTrack.mPackets =
136afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            new AnotherPacketSource(mAudioTrack.mSource->getFormat());
137afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
138afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        readBuffer(true /* audio */);
139afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
140afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
141afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
142afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);
143afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
144afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        mVideoTrack.mPackets =
145afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            new AnotherPacketSource(mVideoTrack.mSource->getFormat());
146afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
147afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        readBuffer(false /* audio */);
148afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
149afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
150afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
151afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::feedMoreTSData() {
152afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
153afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
154afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
155840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
156afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
157afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
158afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (source == NULL) {
159afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return NULL;
160afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
161afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
162afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return source->getFormat();
163afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
164afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
165afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::dequeueAccessUnit(
166afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
167afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
168afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
169afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (track->mSource == NULL) {
170afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return -EWOULDBLOCK;
171afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
172afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
173afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t finalResult;
174afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
175afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        return finalResult == OK ? -EWOULDBLOCK : finalResult;
176afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
177afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
178afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
179afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
180afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    readBuffer(audio, -1ll);
181afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
182afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return result;
183afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
184afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
185afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
186afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    *durationUs = mDurationUs;
187afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
188afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
189afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
190afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huberstatus_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
191afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mVideoTrack.mSource != NULL) {
192afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        int64_t actualTimeUs;
193afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        readBuffer(false /* audio */, seekTimeUs, &actualTimeUs);
194afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
195afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seekTimeUs = actualTimeUs;
196afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
197afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
198afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (mAudioTrack.mSource != NULL) {
199afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        readBuffer(true /* audio */, seekTimeUs);
200afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
201afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
202afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    return OK;
203afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
204afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
205afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Hubervoid NuPlayer::GenericSource::readBuffer(
206afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        bool audio, int64_t seekTimeUs, int64_t *actualTimeUs) {
207afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    Track *track = audio ? &mAudioTrack : &mVideoTrack;
208afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    CHECK(track->mSource != NULL);
209afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
210afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (actualTimeUs) {
211afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        *actualTimeUs = seekTimeUs;
212afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
213afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
214afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    MediaSource::ReadOptions options;
215afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
216afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    bool seeking = false;
217afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
218afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    if (seekTimeUs >= 0) {
219afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        options.setSeekTo(seekTimeUs);
220afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        seeking = true;
221afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
222afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
223afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    for (;;) {
224afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        MediaBuffer *mbuf;
225afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        status_t err = track->mSource->read(&mbuf, &options);
226afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
227afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        options.clearSeekTo();
228afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
229afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        if (err == OK) {
230afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            size_t outLength = mbuf->range_length();
231afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
232afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (audio && mAudioIsVorbis) {
233afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                outLength += sizeof(int32_t);
234afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
235afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
236afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            sp<ABuffer> buffer = new ABuffer(outLength);
237afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
238afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            memcpy(buffer->data(),
239afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                   (const uint8_t *)mbuf->data() + mbuf->range_offset(),
240afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                   mbuf->range_length());
241afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
242afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (audio && mAudioIsVorbis) {
243afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                int32_t numPageSamples;
244afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                if (!mbuf->meta_data()->findInt32(
245afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                            kKeyValidSamples, &numPageSamples)) {
246afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    numPageSamples = -1;
247afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                }
248afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
249afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                memcpy(buffer->data() + mbuf->range_length(),
250afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                       &numPageSamples,
251afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                       sizeof(numPageSamples));
252afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
253afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
254afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            int64_t timeUs;
255afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
256afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
257afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
258afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
259afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (actualTimeUs) {
260afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                *actualTimeUs = timeUs;
261afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
262afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
263afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            mbuf->release();
264afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            mbuf = NULL;
265afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
266afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            if (seeking) {
267afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                track->mPackets->queueDiscontinuity(
268afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                        ATSParser::DISCONTINUITY_SEEK, NULL);
269afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            }
270afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
271afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueAccessUnit(buffer);
272afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            break;
273afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else if (err == INFO_FORMAT_CHANGED) {
274afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#if 0
275afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->queueDiscontinuity(
276afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber                    ATSParser::DISCONTINUITY_FORMATCHANGE, NULL);
277afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber#endif
278afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        } else {
279afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            track->mPackets->signalEOS(err);
280afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber            break;
281afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber        }
282afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber    }
283afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}
284afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber
285afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber}  // namespace android
286