MPEG2TSExtractor.cpp revision be9634d071e79b72a42a4504f64eda9e2a0bceb8
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" 19cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/Log.h> 20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "include/MPEG2TSExtractor.h" 22bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/NuCachedSource2.h" 23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h> 26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h> 27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h> 28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h> 29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h> 30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h> 31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h" 33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h" 34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android { 36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatic const size_t kTSPacketSize = 188; 380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource { 40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MPEG2TSSource( 41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 42bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const sp<AnotherPacketSource> &impl, 43bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool seekable); 44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t start(MetaData *params = NULL); 46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t stop(); 47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual sp<MetaData> getFormat(); 48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t read( 50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate: 53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MPEG2TSExtractor> mExtractor; 54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<AnotherPacketSource> mImpl; 55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 56bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber // If there are both audio and video streams, only the video stream 57bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber // will be seekable, otherwise the single stream will be seekable. 58bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool mSeekable; 59bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource); 61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}; 62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource( 64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 65bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const sp<AnotherPacketSource> &impl, 66bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool seekable) 67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mExtractor(extractor), 68bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber mImpl(impl), 69bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber mSeekable(seekable) { 70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) { 73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->start(params); 74cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() { 77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->stop(); 78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() { 8114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return mImpl->getFormat(); 82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read( 85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **out, const ReadOptions *options) { 86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *out = NULL; 87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t finalResult; 89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (!mImpl->hasBufferAvailable(&finalResult)) { 90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (finalResult != OK) { 91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return ERROR_END_OF_STREAM; 92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t err = mExtractor->feedMore(); 95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (err != OK) { 96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mImpl->signalEOS(err); 97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 99cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1005d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen int64_t seekTimeUs; 1015d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen ReadOptions::SeekMode seekMode; 1025d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) { 1035d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen // A seek was requested, but we don't actually support seeking and so can only "seek" to 1045d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen // the current position 1055d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen int64_t nextBufTimeUs; 1065d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen if (mImpl->nextBufferTime(&nextBufTimeUs) != OK || seekTimeUs != nextBufTimeUs) { 1075d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen return ERROR_UNSUPPORTED; 1085d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen } 1095d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen } 1105d7c3eef1985ff15a56920c548cc4e41d6c9627aMarco Nelissen 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->read(out, options); 112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source) 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mDataSource(source), 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mParser(new ATSParser), 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset(0) { 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber init(); 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mSourceImpls.size(); 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { 128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index >= mSourceImpls.size()) { 129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 132bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool seekable = true; 133bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber if (mSourceImpls.size() > 1) { 134bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber CHECK_EQ(mSourceImpls.size(), 2u); 135bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 136bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat(); 137bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const char *mime; 138bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 139bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 140bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber if (!strncasecmp("audio/", mime, 6)) { 141bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber seekable = false; 142bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 143bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 144bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 145bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable); 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 149d411b4ca2945cd8974a3a78199fce94646950128Andreas Huber size_t index, uint32_t /* flags */) { 150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return index < mSourceImpls.size() 151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MetaData> meta = new MetaData; 156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return meta; 159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() { 162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveAudio = false; 163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveVideo = false; 1640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber int numPacketsParsed = 0; 165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (feedMore() == OK) { 167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveAudio && haveVideo) { 168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveVideo) { 1710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 173386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::VIDEO).get(); 1740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 1760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber haveVideo = true; 1770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 1780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveAudio) { 1820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 184386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::AUDIO).get(); 1850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveAudio = true; 1880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 1910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 192386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (++numPacketsParsed > 10000) { 1930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber break; 194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 197df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo); 198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 200cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() { 201cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Mutex::Autolock autoLock(mLock); 202cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 203cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint8_t packet[kTSPacketSize]; 204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 205cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 206ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber if (n < (ssize_t)kTSPacketSize) { 207be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen if (n >= 0) { 208be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mParser->signalEOS(ERROR_END_OF_STREAM); 209be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen } 210cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 211cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 212cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2132a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mOffset += n; 21406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return mParser->feedTSPacket(packet, kTSPacketSize); 215cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 216cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 217bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const { 21814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return CAN_PAUSE; 219bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber} 220bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 221cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 222cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 223cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS( 2245a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 2255a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 2260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber for (int i = 0; i < 5; ++i) { 2270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber char header; 2280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (source->readAt(kTSPacketSize * i, &header, 1) != 1 2290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber || header != 0x47) { 2300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber return false; 2310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 232cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 233cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *confidence = 0.1f; 235cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 236cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 237cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 238cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 239cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 240cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 241