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 88bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber int64_t seekTimeUs; 89bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber ReadOptions::SeekMode seekMode; 90bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) { 9114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return ERROR_UNSUPPORTED; 92bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 93bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t finalResult; 95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (!mImpl->hasBufferAvailable(&finalResult)) { 96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (finalResult != OK) { 97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return ERROR_END_OF_STREAM; 98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 99cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 100cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t err = mExtractor->feedMore(); 101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (err != OK) { 102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mImpl->signalEOS(err); 103cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->read(out, options); 107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source) 112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mDataSource(source), 113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mParser(new ATSParser), 114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset(0) { 115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber init(); 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mSourceImpls.size(); 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index >= mSourceImpls.size()) { 124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 127bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool seekable = true; 128bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber if (mSourceImpls.size() > 1) { 129bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber CHECK_EQ(mSourceImpls.size(), 2u); 130bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 131bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat(); 132bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber const char *mime; 133bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 134bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 135bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber if (!strncasecmp("audio/", mime, 6)) { 136bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber seekable = false; 137bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 138bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 139bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 140bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable); 141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 14484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber size_t index, uint32_t /* flags */) { 145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return index < mSourceImpls.size() 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MetaData> meta = new MetaData; 151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return meta; 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() { 157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveAudio = false; 158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveVideo = false; 1590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber int numPacketsParsed = 0; 160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (feedMore() == OK) { 162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ATSParser::SourceType type; 163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveAudio && haveVideo) { 164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveVideo) { 1670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 169386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::VIDEO).get(); 1700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 1720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber haveVideo = true; 1730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 1740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (!haveAudio) { 1780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber sp<AnotherPacketSource> impl = 1790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber (AnotherPacketSource *)mParser->getSource( 180386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ATSParser::AUDIO).get(); 1810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (impl != NULL) { 183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveAudio = true; 1840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber mSourceImpls.push(impl); 185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 1870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 188386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (++numPacketsParsed > 10000) { 1890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber break; 190cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 191cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 192cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 193df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo); 194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() { 197cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Mutex::Autolock autoLock(mLock); 198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint8_t packet[kTSPacketSize]; 200cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 201cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 202ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber if (n < (ssize_t)kTSPacketSize) { 203cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 205cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2062a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mOffset += n; 20706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return mParser->feedTSPacket(packet, kTSPacketSize); 208cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 209cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 210bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberuint32_t MPEG2TSExtractor::flags() const { 21114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return CAN_PAUSE; 212bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber} 213bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 214cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 215cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 216cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS( 2175a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 2185a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 2190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber for (int i = 0; i < 5; ++i) { 2200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber char header; 2210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber if (source->readAt(kTSPacketSize * i, &header, 1) != 1 2220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber || header != 0x47) { 2230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber return false; 2240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber } 225cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 226cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *confidence = 0.1f; 228cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 229cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 230cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 231cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 232cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 233cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 234