MPEG2TSExtractor.cpp revision 5a1c3529e4fa2f8a11054181294e0ce79fff8dd3
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" 22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/DataSource.h> 24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h> 25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h> 26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaSource.h> 27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h> 28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/String8.h> 29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h" 31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h" 32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android { 34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct MPEG2TSSource : public MediaSource { 36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MPEG2TSSource( 37cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<AnotherPacketSource> &impl); 39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t start(MetaData *params = NULL); 41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t stop(); 42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual sp<MetaData> getFormat(); 43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual status_t read( 45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate: 48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MPEG2TSExtractor> mExtractor; 49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<AnotherPacketSource> mImpl; 50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource); 52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}; 53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSSource::MPEG2TSSource( 55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<MPEG2TSExtractor> &extractor, 56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber const sp<AnotherPacketSource> &impl) 57cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mExtractor(extractor), 58cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mImpl(impl) { 59cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::start(MetaData *params) { 62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->start(params); 63cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 65cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::stop() { 66cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->stop(); 67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 68cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 69cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSSource::getFormat() { 70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->getFormat(); 71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSSource::read( 74cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber MediaBuffer **out, const ReadOptions *options) { 75cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *out = NULL; 76cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t finalResult; 78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (!mImpl->hasBufferAvailable(&finalResult)) { 79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (finalResult != OK) { 80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return ERROR_END_OF_STREAM; 81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber status_t err = mExtractor->feedMore(); 84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (err != OK) { 85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mImpl->signalEOS(err); 86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mImpl->read(out, options); 90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberMPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source) 95cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber : mDataSource(source), 96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mParser(new ATSParser), 97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset(0) { 98cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber init(); 99cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 100cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t MPEG2TSExtractor::countTracks() { 102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return mSourceImpls.size(); 103cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) { 106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index >= mSourceImpls.size()) { 107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return new MPEG2TSSource(this, mSourceImpls.editItemAt(index)); 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getTrackMetaData( 114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber size_t index, uint32_t flags) { 115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return index < mSourceImpls.size() 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ? mSourceImpls.editItemAt(index)->getFormat() : NULL; 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MetaData> MPEG2TSExtractor::getMetaData() { 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MetaData> meta = new MetaData; 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return meta; 124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid MPEG2TSExtractor::init() { 127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveAudio = false; 128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool haveVideo = false; 129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (feedMore() == OK) { 131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ATSParser::SourceType type; 132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveAudio && haveVideo) { 133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (haveVideo) { 136cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber type = ATSParser::MPEG2ADTS_AUDIO; 137cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else { 138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber type = ATSParser::AVC_VIDEO; 139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 140cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<AnotherPacketSource> impl = 141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber (AnotherPacketSource *)mParser->getSource(type).get(); 142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (impl != NULL) { 144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (type == ATSParser::MPEG2ADTS_AUDIO) { 145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveAudio = true; 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else { 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber haveVideo = true; 148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mSourceImpls.push(impl); 150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber LOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo); 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatus_t MPEG2TSExtractor::feedMore() { 157cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Mutex::Autolock autoLock(mLock); 158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber static const size_t kTSPacketSize = 188; 160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 161cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint8_t packet[kTSPacketSize]; 162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); 163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (n < (ssize_t)kTSPacketSize) { 165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; 166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mOffset += kTSPacketSize; 169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mParser->feedTSPacket(packet, kTSPacketSize); 170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return OK; 172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 174cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberbool SniffMPEG2TS( 1775a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 1785a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 179e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#if 0 180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber char header; 181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (source->readAt(0, &header, 1) != 1 || header != 0x47) { 182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return false; 183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *confidence = 0.05f; 186cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_MPEG2TS); 187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 189e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#else 190e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber // For now we're going to never identify this type of stream, since we'd 191e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber // just base our decision on a single byte... 192e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber // Instead you can instantiate an MPEG2TSExtractor by explicitly stating 193e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber // its proper mime type in the call to MediaExtractor::Create(...). 194e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber return false; 195e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber#endif 196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 197cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 199