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), 1159558f6dd733dc450270f38b9a139d384d273ce0aWei Jia mLastSyncEvent(0), 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset(0) { 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber init(); 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mSourceImpls.size(); 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 124b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> MPEG2TSExtractor::getTrack(size_t index) { 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index >= mSourceImpls.size()) { 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 129540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // The seek reference track (video if present; audio otherwise) performs 130540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // seek requests, while other tracks ignore requests. 131540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), 132540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim (mSeekSyncPoints == &mSyncPoints.editItemAt(index))); 133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 136d411b4ca2945cd8974a3a78199fce94646950128Andreas Huber size_t index, uint32_t /* flags */) { 137cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return index < mSourceImpls.size() 138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 140cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MetaData> meta = new MetaData; 143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return meta; 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() { 149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveAudio = false; 150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveVideo = false; 15112a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung int64_t startTime = ALooper::GetNowUs(); 152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1539558f6dd733dc450270f38b9a139d384d273ce0aWei Jia while (feedMore(true /* isInit */) == OK) { 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveAudio && haveVideo) { 1559558f6dd733dc450270f38b9a139d384d273ce0aWei Jia addSyncPoint_l(mLastSyncEvent); 1569558f6dd733dc450270f38b9a139d384d273ce0aWei Jia mLastSyncEvent.reset(); 157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveVideo) { 1600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 162386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::VIDEO).get(); 1630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 1650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber haveVideo = true; 1660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 167540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSyncPoints.push(); 168540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints = &mSyncPoints.editTop(); 1690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveAudio) { 1730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 175386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::AUDIO).get(); 1760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 178cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveAudio = true; 1790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 180540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSyncPoints.push(); 181540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (!haveVideo) { 182540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints = &mSyncPoints.editTop(); 183540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1879558f6dd733dc450270f38b9a139d384d273ce0aWei Jia addSyncPoint_l(mLastSyncEvent); 1889558f6dd733dc450270f38b9a139d384d273ce0aWei Jia mLastSyncEvent.reset(); 1899558f6dd733dc450270f38b9a139d384d273ce0aWei Jia 19012a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung // Wait only for 2 seconds to detect audio/video streams. 19112a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung if (ALooper::GetNowUs() - startTime > 2000000ll) { 1920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber break; 193cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 196540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim off64_t size; 197540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mDataSource->getSize(&size) == OK && (haveAudio || haveVideo)) { 198540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AnotherPacketSource> impl = haveVideo 199540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ? (AnotherPacketSource *)mParser->getSource( 200540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::VIDEO).get() 201540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim : (AnotherPacketSource *)mParser->getSource( 202540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::AUDIO).get(); 2033d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim size_t prevSyncSize = 1; 204540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t durationUs = -1; 205540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim List<int64_t> durations; 206540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Estimate duration --- stabilize until you get <500ms deviation. 2073d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim while (feedMore() == OK 2083d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim && ALooper::GetNowUs() - startTime <= 2000000ll) { 2093d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim if (mSeekSyncPoints->size() > prevSyncSize) { 2103d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim prevSyncSize = mSeekSyncPoints->size(); 2113d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1) 2123d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim - mSeekSyncPoints->keyAt(0); 2133d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim off64_t diffOffset = mSeekSyncPoints->valueAt(prevSyncSize - 1) 2143d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim - mSeekSyncPoints->valueAt(0); 2153d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim durationUs = size * diffUs / diffOffset; 216540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim durations.push_back(durationUs); 217540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (durations.size() > 5) { 218540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim durations.erase(durations.begin()); 219540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t min = *durations.begin(); 220540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t max = *durations.begin(); 221540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (List<int64_t>::iterator i = durations.begin(); 222540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim i != durations.end(); 223540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ++i) { 224540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (min > *i) { 225540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim min = *i; 226540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 227540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (max < *i) { 228540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim max = *i; 229540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 230540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 231540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (max - min < 500 * 1000) { 232540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 233540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 234540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 235540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 236540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 2373d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim status_t err; 2383d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim int64_t bufferedDurationUs; 2393d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim bufferedDurationUs = impl->getBufferedDurationUs(&err); 2403d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim if (err == ERROR_END_OF_STREAM) { 2413d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim durationUs = bufferedDurationUs; 2423d83a2089f7000180a1a3ff5a9d376efe92f596cWonsik Kim } 243540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (durationUs > 0) { 244540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<MetaData> meta = impl->getFormat(); 245540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim meta->setInt64(kKeyDuration, durationUs); 246540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->setFormat(meta); 247540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 248540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 249540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 250f748dd8cac87ef0bd1deb78a6c8c71e5a9bbe36bJaesung Chung ALOGI("haveAudio=%d, haveVideo=%d, elaspedTime=%" PRId64, 25112a3d2f50dc52d8d05f5d0e932445f368248f520Jaesung Chung haveAudio, haveVideo, ALooper::GetNowUs() - startTime); 252cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 253cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2549558f6dd733dc450270f38b9a139d384d273ce0aWei Jiastatus_t MPEG2TSExtractor::feedMore(bool isInit) { 255cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Mutex::Autolock autoLock(mLock); 256cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 257cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint8_t packet[kTSPacketSize]; 258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 260ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber if (n < (ssize_t)kTSPacketSize) { 261be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen if (n >= 0) { 262be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mParser->signalEOS(ERROR_END_OF_STREAM); 263be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen } 264cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 265cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 266cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 267540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ATSParser::SyncEvent event(mOffset); 2682a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mOffset += n; 269540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event); 2709558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (event.hasReturnedData()) { 2719558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (isInit) { 2729558f6dd733dc450270f38b9a139d384d273ce0aWei Jia mLastSyncEvent = event; 2739558f6dd733dc450270f38b9a139d384d273ce0aWei Jia } else { 2749558f6dd733dc450270f38b9a139d384d273ce0aWei Jia addSyncPoint_l(event); 2759558f6dd733dc450270f38b9a139d384d273ce0aWei Jia } 2769558f6dd733dc450270f38b9a139d384d273ce0aWei Jia } 2779558f6dd733dc450270f38b9a139d384d273ce0aWei Jia return err; 2789558f6dd733dc450270f38b9a139d384d273ce0aWei Jia} 2799558f6dd733dc450270f38b9a139d384d273ce0aWei Jia 2809558f6dd733dc450270f38b9a139d384d273ce0aWei Jiavoid MPEG2TSExtractor::addSyncPoint_l(const ATSParser::SyncEvent &event) { 2819558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (!event.hasReturnedData()) { 2829558f6dd733dc450270f38b9a139d384d273ce0aWei Jia return; 2839558f6dd733dc450270f38b9a139d384d273ce0aWei Jia } 2849558f6dd733dc450270f38b9a139d384d273ce0aWei Jia 2859558f6dd733dc450270f38b9a139d384d273ce0aWei Jia for (size_t i = 0; i < mSourceImpls.size(); ++i) { 2869558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (mSourceImpls[i].get() == event.getMediaSource().get()) { 2879558f6dd733dc450270f38b9a139d384d273ce0aWei Jia KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i); 2889558f6dd733dc450270f38b9a139d384d273ce0aWei Jia syncPoints->add(event.getTimeUs(), event.getOffset()); 2899558f6dd733dc450270f38b9a139d384d273ce0aWei Jia // We're keeping the size of the sync points at most 5mb per a track. 2909558f6dd733dc450270f38b9a139d384d273ce0aWei Jia size_t size = syncPoints->size(); 2919558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (size >= 327680) { 2929558f6dd733dc450270f38b9a139d384d273ce0aWei Jia int64_t firstTimeUs = syncPoints->keyAt(0); 2939558f6dd733dc450270f38b9a139d384d273ce0aWei Jia int64_t lastTimeUs = syncPoints->keyAt(size - 1); 2949558f6dd733dc450270f38b9a139d384d273ce0aWei Jia if (event.getTimeUs() - firstTimeUs > lastTimeUs - event.getTimeUs()) { 2959558f6dd733dc450270f38b9a139d384d273ce0aWei Jia syncPoints->removeItemsAt(0, 4096); 2969558f6dd733dc450270f38b9a139d384d273ce0aWei Jia } else { 2979558f6dd733dc450270f38b9a139d384d273ce0aWei Jia syncPoints->removeItemsAt(size - 4096, 4096); 298faf755df5654c6ea0080e2af39c3d6810c0a2f14Jaesung Chung } 299540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 3009558f6dd733dc450270f38b9a139d384d273ce0aWei Jia break; 301540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 302540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 303cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 304cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 305bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const { 306540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return CAN_PAUSE | CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD; 307540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 308540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 309540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::seek(int64_t seekTimeUs, 310540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const MediaSource::ReadOptions::SeekMode &seekMode) { 311540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) { 312540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("No sync point to seek to."); 313540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // ... and therefore we have nothing useful to do here. 314540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 315540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 316540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 317540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Determine whether we're seeking beyond the known area. 318540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool shouldSeekBeyond = 319540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim (seekTimeUs > mSeekSyncPoints->keyAt(mSeekSyncPoints->size() - 1)); 320540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 321540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Determine the sync point to seek. 322540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim size_t index = 0; 323540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (; index < mSeekSyncPoints->size(); ++index) { 324540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs = mSeekSyncPoints->keyAt(index); 325540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (timeUs > seekTimeUs) { 326540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 327540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 328540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 329540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 330540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim switch (seekMode) { 331540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 332540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (index == mSeekSyncPoints->size()) { 333540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("Next sync not found; starting from the latest sync."); 334540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim --index; 335540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 336540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 337540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 338540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_CLOSEST: 339540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC", 340540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim seekMode); 341540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // fall-through 342540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 343540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (index == 0) { 344540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ALOGW("Previous sync not found; starting from the earliest " 345540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim "sync."); 346540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } else { 347540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim --index; 348540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 349540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 350540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 351540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (!shouldSeekBeyond || mOffset <= mSeekSyncPoints->valueAt(index)) { 352540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t actualSeekTimeUs = mSeekSyncPoints->keyAt(index); 353540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mOffset = mSeekSyncPoints->valueAt(index); 354540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = queueDiscontinuityForSeek(actualSeekTimeUs); 355540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 356540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 357540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 358540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 359540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 360540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (shouldSeekBeyond) { 361540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = seekBeyond(seekTimeUs); 362540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 363540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 364540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 365540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 366540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 367540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Fast-forward to sync frame. 368540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 369540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls[i]; 370540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 371540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim feedUntilBufferAvailable(impl); 372540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (impl->hasBufferAvailable(&err)) { 373540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AMessage> meta = impl->getMetaAfterLastDequeued(0); 374540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 375540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (meta == NULL) { 376540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return UNKNOWN_ERROR; 377540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 378540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int32_t sync; 379540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (meta->findInt32("isSync", &sync) && sync) { 380540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 381540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 382540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim err = impl->dequeueAccessUnit(&buffer); 383540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 384540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 385540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 386540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim feedUntilBufferAvailable(impl); 387540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 388540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 389540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 390540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 391540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 392540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 393540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::queueDiscontinuityForSeek(int64_t actualSeekTimeUs) { 394540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Signal discontinuity 395540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<AMessage> extra(new AMessage); 396540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim extra->setInt64(IStreamListener::kKeyMediaTimeUs, actualSeekTimeUs); 397540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mParser->signalDiscontinuity(ATSParser::DISCONTINUITY_TIME, extra); 398540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 399540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // After discontinuity, impl should only have discontinuities 400540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // with the last being what we queued. Dequeue them all here. 401540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 402540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls.itemAt(i); 403540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 404540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 405540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (impl->hasBufferAvailable(&err)) { 406540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 407540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 408540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 409540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim err = impl->dequeueAccessUnit(&buffer); 410540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // If the source contains anything but discontinuity, that's 411540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // a programming mistake. 412540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim CHECK(err == INFO_DISCONTINUITY); 413540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 414540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 415540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 416540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Feed until we have a buffer for each source. 417540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 418540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls.itemAt(i); 419540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 420540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = feedUntilBufferAvailable(impl); 421540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 422540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 423540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 424540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 425540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 426540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 427540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 428540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 429540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::seekBeyond(int64_t seekTimeUs) { 430540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // If we're seeking beyond where we know --- read until we reach there. 431540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim size_t syncPointsSize = mSeekSyncPoints->size(); 432540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 433540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (seekTimeUs > mSeekSyncPoints->keyAt( 434540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mSeekSyncPoints->size() - 1)) { 435540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err; 436540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (syncPointsSize < mSeekSyncPoints->size()) { 437540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim syncPointsSize = mSeekSyncPoints->size(); 438540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t syncTimeUs = mSeekSyncPoints->keyAt(syncPointsSize - 1); 439540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Dequeue buffers before sync point in order to avoid too much 440540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // cache building up. 441540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim sp<ABuffer> buffer; 442540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim for (size_t i = 0; i < mSourceImpls.size(); ++i) { 443540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl = mSourceImpls[i]; 444540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs; 445540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while ((err = impl->nextBufferTime(&timeUs)) == OK) { 446540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (timeUs < syncTimeUs) { 447540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->dequeueAccessUnit(&buffer); 448540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } else { 449540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim break; 450540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 451540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 452540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK && err != -EWOULDBLOCK) { 453540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return err; 454540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 455540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 456540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 457540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (feedMore() != OK) { 458540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return ERROR_END_OF_STREAM; 459540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 460540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 461540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 462540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 463540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 464540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 465540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t MPEG2TSExtractor::feedUntilBufferAvailable( 466540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const sp<AnotherPacketSource> &impl) { 467540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t finalResult; 468540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim while (!impl->hasBufferAvailable(&finalResult)) { 469540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (finalResult != OK) { 470540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return finalResult; 471540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 472540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 473540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = feedMore(); 474540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (err != OK) { 475540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim impl->signalEOS(err); 476540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 477540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 478540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return OK; 479bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber} 480bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 481cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 482cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 483cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS( 4845a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4855a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 4860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber for (int i = 0; i < 5; ++i) { 4870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber char header; 4880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (source->readAt(kTSPacketSize * i, &header, 1) != 1 4890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber || header != 0x47) { 4900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber return false; 4910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 492cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 493cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 4940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *confidence = 0.1f; 495cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 496cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 497cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 498cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 499cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 500cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 501