MPEG2TSExtractor.cpp revision faf755df5654c6ea0080e2af39c3d6810c0a2f14
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/* 2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License. 6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at 7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software 11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and 14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License. 15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */ 16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 17cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//#define LOG_NDEBUG 0 18cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define LOG_TAG "MPEG2TSExtractor" 19f748dd8cac87ef0bd1deb78a6c8c71e5a9bbe36bJaesung Chung 20f748dd8cac87ef0bd1deb78a6c8c71e5a9bbe36bJaesung Chung#include <inttypes.h> 21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/Log.h> 22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h" 24bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/NuCachedSource2.h" 25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 26540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim#include <media/stagefright/foundation/ABuffer.h> 27f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2812a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung#include <media/stagefright/foundation/ALooper.h> 29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h> 30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h> 31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h> 32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h> 33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h> 34540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim#include <media/IStreamSource.h> 35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h> 36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 37cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h" 38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h" 39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android { 41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatic const size_t kTSPacketSize = 188; 430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource { 45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MPEG2TSSource( 46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 47bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const sp<AnotherPacketSource> &impl, 48540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool doesSeek); 49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t start(MetaData *params = NULL); 51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t stop(); 52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual sp<MetaData> getFormat(); 53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t read( 55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 57cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate: 58cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MPEG2TSExtractor> mExtractor; 59cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<AnotherPacketSource> mImpl; 60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 61bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber // If there are both audio and video streams, only the video stream 62540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // will signal seek on the extractor; otherwise the single stream will seek. 63540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool mDoesSeek; 64bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 65cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource); 66cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}; 67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 68cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource( 69cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 70bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const sp<AnotherPacketSource> &impl, 71540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool doesSeek) 72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mExtractor(extractor), 73bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber mImpl(impl), 74540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mDoesSeek(doesSeek) { 75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) { 78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->start(params); 79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() { 82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->stop(); 83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() { 8614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return mImpl->getFormat(); 87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read( 90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **out, const ReadOptions *options) { 91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *out = NULL; 92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 93540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t seekTimeUs; 94540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ReadOptions::SeekMode seekMode; 95540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mDoesSeek && options && options->getSeekTo(&seekTimeUs, &seekMode)) { 96540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // seek is needed 97540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = mExtractor->seek(seekTimeUs, seekMode); 98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (err != OK) { 99540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 100cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 103540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mExtractor->feedUntilBufferAvailable(mImpl) != OK) { 104540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return ERROR_END_OF_STREAM; 1055d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen } 1065d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen 107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->read(out, options); 108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source) 113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mDataSource(source), 114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mParser(new ATSParser), 115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset(0) { 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber init(); 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mSourceImpls.size(); 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { 124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index >= mSourceImpls.size()) { 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 128540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // The seek reference track (video if present; audio otherwise) performs 129540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // seek requests, while other tracks ignore requests. 130540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), 131540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim (mSeekSyncPoints == &mSyncPoints.editItemAt(index))); 132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 135d411b4ca2945cd8974a3a78199fce94646950128Andreas Huber size_t index, uint32_t /* flags */) { 136cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return index < mSourceImpls.size() 137cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 140cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MetaData> meta = new MetaData; 142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return meta; 145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() { 148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveAudio = false; 149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveVideo = false; 15012a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung int64_t startTime = ALooper::GetNowUs(); 151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (feedMore() == OK) { 153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveAudio && haveVideo) { 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveVideo) { 1570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 159386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::VIDEO).get(); 1600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 1620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber haveVideo = true; 1630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 164540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSyncPoints.push(); 165540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints = &mSyncPoints.editTop(); 1660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveAudio) { 1700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 172386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::AUDIO).get(); 1730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveAudio = true; 1760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 177540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSyncPoints.push(); 178540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (!haveVideo) { 179540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints = &mSyncPoints.editTop(); 180540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 1830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 18412a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung // Wait only for 2 seconds to detect audio/video streams. 18512a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung if (ALooper::GetNowUs() - startTime > 2000000ll) { 1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber break; 187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 190540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim off64_t size; 191540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mDataSource->getSize(&size) == OK && (haveAudio || haveVideo)) { 192540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AnotherPacketSource> impl = haveVideo 193540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ? (AnotherPacketSource *)mParser->getSource( 194540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::VIDEO).get() 195540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim : (AnotherPacketSource *)mParser->getSource( 196540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::AUDIO).get(); 1973d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim size_t prevSyncSize = 1; 198540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t durationUs = -1; 199540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim List<int64_t> durations; 200540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Estimate duration --- stabilize until you get <500ms deviation. 2013d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim while (feedMore() == OK 2023d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim && ALooper::GetNowUs() - startTime <= 2000000ll) { 2033d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim if (mSeekSyncPoints->size() > prevSyncSize) { 2043d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim prevSyncSize = mSeekSyncPoints->size(); 2053d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1) 2063d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim - mSeekSyncPoints->keyAt(0); 2073d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim off64_t diffOffset = mSeekSyncPoints->valueAt(prevSyncSize - 1) 2083d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim - mSeekSyncPoints->valueAt(0); 2093d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim durationUs = size * diffUs / diffOffset; 210540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim durations.push_back(durationUs); 211540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (durations.size() > 5) { 212540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim durations.erase(durations.begin()); 213540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t min = *durations.begin(); 214540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t max = *durations.begin(); 215540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (List<int64_t>::iterator i = durations.begin(); 216540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim i != durations.end(); 217540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ++i) { 218540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (min > *i) { 219540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim min = *i; 220540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 221540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (max < *i) { 222540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim max = *i; 223540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 224540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 225540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (max - min < 500 * 1000) { 226540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 227540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 228540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 229540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 230540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 2313d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim status_t err; 2323d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim int64_t bufferedDurationUs; 2333d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim bufferedDurationUs = impl->getBufferedDurationUs(&err); 2343d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim if (err == ERROR_END_OF_STREAM) { 2353d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim durationUs = bufferedDurationUs; 2363d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim } 237540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (durationUs > 0) { 238540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<MetaData> meta = impl->getFormat(); 239540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim meta->setInt64(kKeyDuration, durationUs); 240540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->setFormat(meta); 241540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 242540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 243540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 244f748dd8cac87ef0bd1deb78a6c8c71e5a9bbe36bJaesung Chung ALOGI("haveAudio=%d, haveVideo=%d, elaspedTime=%" PRId64, 24512a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung haveAudio, haveVideo, ALooper::GetNowUs() - startTime); 246cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 247cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 248cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() { 249cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Mutex::Autolock autoLock(mLock); 250cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 251cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint8_t packet[kTSPacketSize]; 252cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 253cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 254ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber if (n < (ssize_t)kTSPacketSize) { 255be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen if (n >= 0) { 256be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mParser->signalEOS(ERROR_END_OF_STREAM); 257be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen } 258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 260cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 261540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::SyncEvent event(mOffset); 2622a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mOffset += n; 263540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event); 264540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (event.isInit()) { 265540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 266540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mSourceImpls[i].get() == event.getMediaSource().get()) { 267faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i); 268faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung syncPoints->add(event.getTimeUs(), event.getOffset()); 269faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung // We're keeping the size of the sync points at most 5mb per a track. 270faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung size_t size = syncPoints->size(); 271faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung if (size >= 327680) { 272faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung int64_t firstTimeUs = syncPoints->keyAt(0); 273faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung int64_t lastTimeUs = syncPoints->keyAt(size - 1); 274faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung if (event.getTimeUs() - firstTimeUs > lastTimeUs - event.getTimeUs()) { 275faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung syncPoints->removeItemsAt(0, 4096); 276faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung } else { 277faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung syncPoints->removeItemsAt(size - 4096, 4096); 278faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung } 279faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung } 280540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 281540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 282540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 283540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 284540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 285cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 286cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 287bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const { 288540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return CAN_PAUSE | CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD; 289540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 290540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 291540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::seek(int64_t seekTimeUs, 292540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const MediaSource::ReadOptions::SeekMode &seekMode) { 293540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) { 294540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("No sync point to seek to."); 295540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // ... and therefore we have nothing useful to do here. 296540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 297540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 298540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 299540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Determine whether we're seeking beyond the known area. 300540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool shouldSeekBeyond = 301540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim (seekTimeUs > mSeekSyncPoints->keyAt(mSeekSyncPoints->size() - 1)); 302540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 303540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Determine the sync point to seek. 304540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim size_t index = 0; 305540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (; index < mSeekSyncPoints->size(); ++index) { 306540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs = mSeekSyncPoints->keyAt(index); 307540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (timeUs > seekTimeUs) { 308540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 309540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 310540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 311540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 312540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim switch (seekMode) { 313540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 314540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (index == mSeekSyncPoints->size()) { 315540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("Next sync not found; starting from the latest sync."); 316540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim --index; 317540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 318540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 319540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 320540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_CLOSEST: 321540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC", 322540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim seekMode); 323540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // fall-through 324540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 325540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (index == 0) { 326540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("Previous sync not found; starting from the earliest " 327540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim "sync."); 328540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } else { 329540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim --index; 330540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 331540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 332540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 333540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (!shouldSeekBeyond || mOffset <= mSeekSyncPoints->valueAt(index)) { 334540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t actualSeekTimeUs = mSeekSyncPoints->keyAt(index); 335540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mOffset = mSeekSyncPoints->valueAt(index); 336540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = queueDiscontinuityForSeek(actualSeekTimeUs); 337540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 338540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 339540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 340540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 341540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 342540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (shouldSeekBeyond) { 343540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = seekBeyond(seekTimeUs); 344540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 345540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 346540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 347540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 348540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 349540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Fast-forward to sync frame. 350540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 351540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls[i]; 352540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 353540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim feedUntilBufferAvailable(impl); 354540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (impl->hasBufferAvailable(&err)) { 355540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AMessage> meta = impl->getMetaAfterLastDequeued(0); 356540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 357540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (meta == NULL) { 358540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return UNKNOWN_ERROR; 359540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 360540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int32_t sync; 361540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (meta->findInt32("isSync", &sync) && sync) { 362540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 363540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 364540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim err = impl->dequeueAccessUnit(&buffer); 365540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 366540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 367540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 368540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim feedUntilBufferAvailable(impl); 369540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 370540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 371540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 372540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 373540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 374540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 375540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::queueDiscontinuityForSeek(int64_t actualSeekTimeUs) { 376540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Signal discontinuity 377540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AMessage> extra(new AMessage); 378540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim extra->setInt64(IStreamListener::kKeyMediaTimeUs, actualSeekTimeUs); 379540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mParser->signalDiscontinuity(ATSParser::DISCONTINUITY_TIME, extra); 380540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 381540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // After discontinuity, impl should only have discontinuities 382540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // with the last being what we queued. Dequeue them all here. 383540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 384540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls.itemAt(i); 385540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 386540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 387540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (impl->hasBufferAvailable(&err)) { 388540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 389540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 390540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 391540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim err = impl->dequeueAccessUnit(&buffer); 392540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // If the source contains anything but discontinuity, that's 393540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // a programming mistake. 394540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim CHECK(err == INFO_DISCONTINUITY); 395540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 396540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 397540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 398540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Feed until we have a buffer for each source. 399540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 400540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls.itemAt(i); 401540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 402540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = feedUntilBufferAvailable(impl); 403540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 404540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 405540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 406540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 407540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 408540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 409540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 410540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 411540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::seekBeyond(int64_t seekTimeUs) { 412540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // If we're seeking beyond where we know --- read until we reach there. 413540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim size_t syncPointsSize = mSeekSyncPoints->size(); 414540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 415540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (seekTimeUs > mSeekSyncPoints->keyAt( 416540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints->size() - 1)) { 417540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 418540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (syncPointsSize < mSeekSyncPoints->size()) { 419540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim syncPointsSize = mSeekSyncPoints->size(); 420540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t syncTimeUs = mSeekSyncPoints->keyAt(syncPointsSize - 1); 421540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Dequeue buffers before sync point in order to avoid too much 422540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // cache building up. 423540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 424540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 425540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls[i]; 426540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs; 427540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while ((err = impl->nextBufferTime(&timeUs)) == OK) { 428540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (timeUs < syncTimeUs) { 429540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->dequeueAccessUnit(&buffer); 430540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } else { 431540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 432540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 433540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 434540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK && err != -EWOULDBLOCK) { 435540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 436540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 437540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 438540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 439540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (feedMore() != OK) { 440540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return ERROR_END_OF_STREAM; 441540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 442540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 443540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 444540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 445540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 446540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 447540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::feedUntilBufferAvailable( 448540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl) { 449540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t finalResult; 450540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (!impl->hasBufferAvailable(&finalResult)) { 451540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (finalResult != OK) { 452540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return finalResult; 453540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 454540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 455540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = feedMore(); 456540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 457540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->signalEOS(err); 458540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 459540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 460540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 461bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber} 462bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 463cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 464cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 465cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS( 4665a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4675a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 4680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber for (int i = 0; i < 5; ++i) { 4690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber char header; 4700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (source->readAt(kTSPacketSize * i, &header, 1) != 1 4710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber || header != 0x47) { 4720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber return false; 4730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 474cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 475cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 4760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *confidence = 0.1f; 477cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 478cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 479cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 480cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 481cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 482cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 483