1a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber/* 2a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * 4a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * you may not use this file except in compliance with the License. 6a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * You may obtain a copy of the License at 7a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * 8a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * 10a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * Unless required by applicable law or agreed to in writing, software 11a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * See the License for the specific language governing permissions and 14a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber * limitations under the License. 15a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber */ 16a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 17a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber//#define LOG_NDEBUG 0 18a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#define LOG_TAG "MPEG2TSExtractor" 19a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <utils/Log.h> 20a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 21a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include "include/MPEG2TSExtractor.h" 22b5590846c035a28399818451201aaf1256913ec3Andreas Huber#include "include/LiveSession.h" 2354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber#include "include/NuCachedSource2.h" 24a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 25a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <media/stagefright/DataSource.h> 2654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber#include <media/stagefright/MediaDebug.h> 27a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <media/stagefright/MediaDefs.h> 28a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <media/stagefright/MediaErrors.h> 29a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <media/stagefright/MediaSource.h> 30a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <media/stagefright/MetaData.h> 31a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include <utils/String8.h> 32a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 33a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include "AnotherPacketSource.h" 34a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber#include "ATSParser.h" 35a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 36a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubernamespace android { 37a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 38c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huberstatic const size_t kTSPacketSize = 188; 39c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber 40a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberstruct MPEG2TSSource : public MediaSource { 41a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber MPEG2TSSource( 42a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber const sp<MPEG2TSExtractor> &extractor, 4354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber const sp<AnotherPacketSource> &impl, 4454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber bool seekable); 45a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 46a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber virtual status_t start(MetaData *params = NULL); 47a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber virtual status_t stop(); 48a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber virtual sp<MetaData> getFormat(); 49a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 50a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber virtual status_t read( 51a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 52a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 53a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberprivate: 54a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber sp<MPEG2TSExtractor> mExtractor; 55a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber sp<AnotherPacketSource> mImpl; 56a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 5754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber // If there are both audio and video streams, only the video stream 5854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber // will be seekable, otherwise the single stream will be seekable. 5954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber bool mSeekable; 6054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 61a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource); 62a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber}; 63a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 64a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas HuberMPEG2TSSource::MPEG2TSSource( 65a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber const sp<MPEG2TSExtractor> &extractor, 6654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber const sp<AnotherPacketSource> &impl, 6754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber bool seekable) 68a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber : mExtractor(extractor), 6954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber mImpl(impl), 7054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber mSeekable(seekable) { 71a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 72a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 73a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) { 74a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return mImpl->start(params); 75a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 76a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 77a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberstatus_t MPEG2TSSource::stop() { 78a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return mImpl->stop(); 79a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 80a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 81a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() { 8254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber sp<MetaData> meta = mImpl->getFormat(); 8354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 8454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber int64_t durationUs; 85b5590846c035a28399818451201aaf1256913ec3Andreas Huber if (mExtractor->mLiveSession != NULL 86b5590846c035a28399818451201aaf1256913ec3Andreas Huber && mExtractor->mLiveSession->getDuration(&durationUs) == OK) { 8754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber meta->setInt64(kKeyDuration, durationUs); 8854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 8954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 9054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber return meta; 91a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 92a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 93a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberstatus_t MPEG2TSSource::read( 94a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber MediaBuffer **out, const ReadOptions *options) { 95a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber *out = NULL; 96a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 9754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber int64_t seekTimeUs; 9854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber ReadOptions::SeekMode seekMode; 9954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) { 10054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber mExtractor->seekTo(seekTimeUs); 10154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 10254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 103a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber status_t finalResult; 104a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber while (!mImpl->hasBufferAvailable(&finalResult)) { 105a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber if (finalResult != OK) { 106a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return ERROR_END_OF_STREAM; 107a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 108a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 109a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber status_t err = mExtractor->feedMore(); 110a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber if (err != OK) { 111a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber mImpl->signalEOS(err); 112a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 113a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 114a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 115a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return mImpl->read(out, options); 116a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 117a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 118a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber//////////////////////////////////////////////////////////////////////////////// 119a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 120a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source) 121a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber : mDataSource(source), 122a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber mParser(new ATSParser), 123a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber mOffset(0) { 124a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber init(); 125a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 126a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 127a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 128a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return mSourceImpls.size(); 129a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 130a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 131a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { 132a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber if (index >= mSourceImpls.size()) { 133a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return NULL; 134a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 135a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 13654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber bool seekable = true; 13754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber if (mSourceImpls.size() > 1) { 13854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber CHECK_EQ(mSourceImpls.size(), 2u); 13954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 14054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat(); 14154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber const char *mime; 14254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 14354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 14454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber if (!strncasecmp("audio/", mime, 6)) { 14554d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber seekable = false; 14654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 14754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 14854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 14954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable); 150a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 151a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 152a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 153a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber size_t index, uint32_t flags) { 154a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return index < mSourceImpls.size() 155a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 156a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 157a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 158a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 159a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber sp<MetaData> meta = new MetaData; 160a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 161a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 162a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return meta; 163a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 164a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 165a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Hubervoid MPEG2TSExtractor::init() { 166a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber bool haveAudio = false; 167a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber bool haveVideo = false; 168c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber int numPacketsParsed = 0; 169a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 170a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber while (feedMore() == OK) { 171a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber ATSParser::SourceType type; 172a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber if (haveAudio && haveVideo) { 173a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber break; 174a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 175c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber if (!haveVideo) { 176c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber sp<AnotherPacketSource> impl = 177c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber (AnotherPacketSource *)mParser->getSource( 178eb2f9c193d74c005a0c78e6dbed874809d55fc81Andreas Huber ATSParser::VIDEO).get(); 179c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber 180c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber if (impl != NULL) { 181c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber haveVideo = true; 182c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber mSourceImpls.push(impl); 183c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber } 184a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 185a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 186c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber if (!haveAudio) { 187c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber sp<AnotherPacketSource> impl = 188c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber (AnotherPacketSource *)mParser->getSource( 189eb2f9c193d74c005a0c78e6dbed874809d55fc81Andreas Huber ATSParser::AUDIO).get(); 190c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber 191c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber if (impl != NULL) { 192a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber haveAudio = true; 193c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber mSourceImpls.push(impl); 194a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 195c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber } 196c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber 197eb2f9c193d74c005a0c78e6dbed874809d55fc81Andreas Huber if (++numPacketsParsed > 10000) { 198c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber break; 199a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 200a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 201a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 202a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber LOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo); 203a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 204a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 205a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberstatus_t MPEG2TSExtractor::feedMore() { 206a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber Mutex::Autolock autoLock(mLock); 207a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 208a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber uint8_t packet[kTSPacketSize]; 209a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 210a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 211d6c421f1a0ae556d315159dff8a76e4a0e62e700Andreas Huber if (n < (ssize_t)kTSPacketSize) { 212a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 213a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 214a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 2154c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber mOffset += n; 216eeddb0e504abf3575b71624d9453f4acfdc1d318Andreas Huber return mParser->feedTSPacket(packet, kTSPacketSize); 217a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 218a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 219b5590846c035a28399818451201aaf1256913ec3Andreas Hubervoid MPEG2TSExtractor::setLiveSession(const sp<LiveSession> &liveSession) { 22054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber Mutex::Autolock autoLock(mLock); 22154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 222b5590846c035a28399818451201aaf1256913ec3Andreas Huber mLiveSession = liveSession; 22354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber} 22454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 22554d09724e3ea2af4e08dff47d7ade92a95784127Andreas Hubervoid MPEG2TSExtractor::seekTo(int64_t seekTimeUs) { 22654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber Mutex::Autolock autoLock(mLock); 22754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 228b5590846c035a28399818451201aaf1256913ec3Andreas Huber if (mLiveSession == NULL) { 22954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber return; 23054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 23154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 232b5590846c035a28399818451201aaf1256913ec3Andreas Huber mLiveSession->seekTo(seekTimeUs); 23354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber} 23454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 23554d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huberuint32_t MPEG2TSExtractor::flags() const { 23654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber Mutex::Autolock autoLock(mLock); 23754d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 23854d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber uint32_t flags = CAN_PAUSE; 23954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 240b5590846c035a28399818451201aaf1256913ec3Andreas Huber if (mLiveSession != NULL && mLiveSession->isSeekable()) { 24154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber flags |= CAN_SEEK_FORWARD | CAN_SEEK_BACKWARD | CAN_SEEK; 24254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber } 24354d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 24454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber return flags; 24554d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber} 24654d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber 247a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber//////////////////////////////////////////////////////////////////////////////// 248a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 249a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huberbool SniffMPEG2TS( 250efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 251efdd088a71ddd0a96cf9ca2f58e8703fe8c5c494Andreas Huber sp<AMessage> *) { 252c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber for (int i = 0; i < 5; ++i) { 253c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber char header; 254c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber if (source->readAt(kTSPacketSize * i, &header, 1) != 1 255c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber || header != 0x47) { 256c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber return false; 257c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber } 258a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber } 259a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 260c751eccad38cf46d7478eca85beefecd2c2b4c3bAndreas Huber *confidence = 0.1f; 261a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 262a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 263a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber return true; 264a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} 265a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber 266a557b24ac4dd568d86b08753f7c0361d04f80d46Andreas Huber} // namespace android 267