From 386d609dc513e838c7e7c4c46c604493ccd560be Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Thu, 19 May 2011 08:37:39 -0700 Subject: Support mpeg1,2 audio and mpeg1,2,4 video content extraction from .ts streams. Change-Id: I9d2ee63495f161e30daba7c3aab16cb9d8ced6a5 --- media/libstagefright/mpeg2ts/ATSParser.cpp | 130 +++++- media/libstagefright/mpeg2ts/ATSParser.h | 15 +- media/libstagefright/mpeg2ts/ESQueue.cpp | 485 +++++++++++++++++++++- media/libstagefright/mpeg2ts/ESQueue.h | 8 +- media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp | 6 +- 5 files changed, 614 insertions(+), 30 deletions(-) (limited to 'media/libstagefright/mpeg2ts') diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 7d4bc6e..5bbc2b4 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -44,7 +44,7 @@ namespace android { static const size_t kTSPacketSize = 188; struct ATSParser::Program : public RefBase { - Program(ATSParser *parser, unsigned programMapPID); + Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID); bool parsePID( unsigned pid, unsigned payload_unit_start_indicator, @@ -63,8 +63,15 @@ struct ATSParser::Program : public RefBase { return mFirstPTSValid; } + unsigned number() const { return mProgramNumber; } + + void updateProgramMapPID(unsigned programMapPID) { + mProgramMapPID = programMapPID; + } + private: ATSParser *mParser; + unsigned mProgramNumber; unsigned mProgramMapPID; KeyedVector > mStreams; bool mFirstPTSValid; @@ -107,7 +114,7 @@ private: DiscontinuityType mPendingDiscontinuity; sp mPendingDiscontinuityExtra; - ElementaryStreamQueue mQueue; + ElementaryStreamQueue *mQueue; void flush(); void parsePES(ABitReader *br); @@ -126,11 +133,14 @@ private: //////////////////////////////////////////////////////////////////////////////// -ATSParser::Program::Program(ATSParser *parser, unsigned programMapPID) +ATSParser::Program::Program( + ATSParser *parser, unsigned programNumber, unsigned programMapPID) : mParser(parser), + mProgramNumber(programNumber), mProgramMapPID(programMapPID), mFirstPTSValid(false), mFirstPTS(0) { + LOGV("new program number %u", programNumber); } bool ATSParser::Program::parsePID( @@ -299,7 +309,7 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) { } sp ATSParser::Program::getSource(SourceType type) { - size_t index = (type == MPEG2ADTS_AUDIO) ? 0 : 0; + size_t index = (type == AUDIO) ? 0 : 0; for (size_t i = 0; i < mStreams.size(); ++i) { sp source = mStreams.editValueAt(i)->getSource(type); @@ -338,14 +348,43 @@ ATSParser::Stream::Stream( mBuffer(new ABuffer(192 * 1024)), mPayloadStarted(false), mPendingDiscontinuity(DISCONTINUITY_NONE), - mQueue(streamType == 0x1b - ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) { + mQueue(NULL) { mBuffer->setRange(0, 0); + switch (mStreamType) { + case STREAMTYPE_H264: + mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264); + break; + case STREAMTYPE_MPEG2_AUDIO_ATDS: + mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC); + break; + case STREAMTYPE_MPEG1_AUDIO: + case STREAMTYPE_MPEG2_AUDIO: + mQueue = new ElementaryStreamQueue( + ElementaryStreamQueue::MPEG_AUDIO); + break; + + case STREAMTYPE_MPEG1_VIDEO: + case STREAMTYPE_MPEG2_VIDEO: + mQueue = new ElementaryStreamQueue( + ElementaryStreamQueue::MPEG_VIDEO); + break; + + case STREAMTYPE_MPEG4_VIDEO: + mQueue = new ElementaryStreamQueue( + ElementaryStreamQueue::MPEG4_VIDEO); + break; + + default: + break; + } + LOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType); } ATSParser::Stream::~Stream() { + delete mQueue; + mQueue = NULL; } void ATSParser::Stream::parse( @@ -397,7 +436,7 @@ void ATSParser::Stream::signalDiscontinuity( { bool isASeek = (type == DISCONTINUITY_SEEK); - mQueue.clear(!isASeek); + mQueue->clear(!isASeek); uint64_t resumeAtPTS; if (extra != NULL @@ -444,6 +483,12 @@ void ATSParser::Stream::parsePES(ABitReader *br) { LOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix); + if (packet_startcode_prefix != 1) { + LOGV("Supposedly payload_unit_start=1 unit does not start " + "with startcode."); + return; + } + CHECK_EQ(packet_startcode_prefix, 0x000001u); unsigned stream_id = br->getBits(8); @@ -611,22 +656,28 @@ void ATSParser::Stream::onPayloadData( const uint8_t *data, size_t size) { LOGV("onPayloadData mStreamType=0x%02x", mStreamType); + if (mQueue == NULL) { + return; + } + CHECK(PTS_DTS_flags == 2 || PTS_DTS_flags == 3); int64_t timeUs = mProgram->convertPTSToTimestamp(PTS); - status_t err = mQueue.appendData(data, size, timeUs); + status_t err = mQueue->appendData(data, size, timeUs); if (err != OK) { return; } sp accessUnit; - while ((accessUnit = mQueue.dequeueAccessUnit()) != NULL) { + while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) { if (mSource == NULL) { - sp meta = mQueue.getFormat(); + sp meta = mQueue->getFormat(); if (meta != NULL) { - LOGV("created source!"); + LOGV("Stream PID 0x%08x of type 0x%02x now has data.", + mElementaryPID, mStreamType); + mSource = new AnotherPacketSource(meta); if (mPendingDiscontinuity != DISCONTINUITY_NONE) { @@ -638,13 +689,13 @@ void ATSParser::Stream::onPayloadData( mSource->queueAccessUnit(accessUnit); } - } else if (mQueue.getFormat() != NULL) { + } else if (mQueue->getFormat() != NULL) { // After a discontinuity we invalidate the queue's format // and won't enqueue any access units to the source until // the queue has reestablished the new format. if (mSource->getFormat() == NULL) { - mSource->setFormat(mQueue.getFormat()); + mSource->setFormat(mQueue->getFormat()); } mSource->queueAccessUnit(accessUnit); } @@ -652,9 +703,30 @@ void ATSParser::Stream::onPayloadData( } sp ATSParser::Stream::getSource(SourceType type) { - if ((type == AVC_VIDEO && mStreamType == 0x1b) - || (type == MPEG2ADTS_AUDIO && mStreamType == 0x0f)) { - return mSource; + switch (type) { + case VIDEO: + { + if (mStreamType == STREAMTYPE_H264 + || mStreamType == STREAMTYPE_MPEG1_VIDEO + || mStreamType == STREAMTYPE_MPEG2_VIDEO + || mStreamType == STREAMTYPE_MPEG4_VIDEO) { + return mSource; + } + break; + } + + case AUDIO: + { + if (mStreamType == STREAMTYPE_MPEG1_AUDIO + || mStreamType == STREAMTYPE_MPEG2_AUDIO + || mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) { + return mSource; + } + break; + } + + default: + break; } return NULL; @@ -729,7 +801,21 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { LOGV(" program_map_PID = 0x%04x", programMapPID); - mPrograms.push(new Program(this, programMapPID)); + bool found = false; + for (size_t index = 0; index < mPrograms.size(); ++index) { + const sp &program = mPrograms.itemAt(index); + + if (program->number() == program_number) { + program->updateProgramMapPID(programMapPID); + found = true; + break; + } + } + + if (!found) { + mPrograms.push( + new Program(this, program_number, programMapPID)); + } } } @@ -805,8 +891,16 @@ void ATSParser::parseTS(ABitReader *br) { } sp ATSParser::getSource(SourceType type) { + int which = -1; // any + for (size_t i = 0; i < mPrograms.size(); ++i) { - sp source = mPrograms.editItemAt(i)->getSource(type); + const sp &program = mPrograms.editItemAt(i); + + if (which >= 0 && (int)program->number() != which) { + continue; + } + + sp source = program->getSource(type); if (source != NULL) { return source; diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index 3936f05..1e6451d 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -48,8 +48,8 @@ struct ATSParser : public RefBase { void signalEOS(status_t finalResult); enum SourceType { - AVC_VIDEO, - MPEG2ADTS_AUDIO + VIDEO, + AUDIO }; sp getSource(SourceType type); @@ -59,6 +59,17 @@ protected: virtual ~ATSParser(); private: + enum { + // From ISO/IEC 13818-1: 2000 (E), Table 2-29 + STREAMTYPE_MPEG1_VIDEO = 0x01, + STREAMTYPE_MPEG2_VIDEO = 0x02, + STREAMTYPE_MPEG1_AUDIO = 0x03, + STREAMTYPE_MPEG2_AUDIO = 0x04, + STREAMTYPE_MPEG2_AUDIO_ATDS = 0x0f, + STREAMTYPE_MPEG4_VIDEO = 0x10, + STREAMTYPE_H264 = 0x1b, + }; + struct Program; struct Stream; diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index dcaf9f7..f8a1d84 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "include/avc_utils.h" @@ -79,11 +80,49 @@ static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) { return true; } +static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) { + if (size < 3) { + // Not enough data to verify header. + return false; + } + + if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) { + return false; + } + + unsigned ID = (ptr[1] >> 3) & 3; + + if (ID == 1) { + return false; // reserved + } + + unsigned layer = (ptr[1] >> 1) & 3; + + if (layer == 0) { + return false; // reserved + } + + unsigned bitrateIndex = (ptr[2] >> 4); + + if (bitrateIndex == 0x0f) { + return false; // reserved + } + + unsigned samplingRateIndex = (ptr[2] >> 2) & 3; + + if (samplingRateIndex == 3) { + return false; // reserved + } + + return true; +} + status_t ElementaryStreamQueue::appendData( const void *data, size_t size, int64_t timeUs) { if (mBuffer == NULL || mBuffer->size() == 0) { switch (mMode) { case H264: + case MPEG_VIDEO: { #if 0 if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) { @@ -105,7 +144,40 @@ status_t ElementaryStreamQueue::appendData( } if (startOffset > 0) { - LOGI("found something resembling an H.264 syncword at " + LOGI("found something resembling an H.264/MPEG syncword at " + "offset %ld", + startOffset); + } + + data = &ptr[startOffset]; + size -= startOffset; +#endif + break; + } + + case MPEG4_VIDEO: + { +#if 0 + if (size < 3 || memcmp("\x00\x00\x01", data, 3)) { + return ERROR_MALFORMED; + } +#else + uint8_t *ptr = (uint8_t *)data; + + ssize_t startOffset = -1; + for (size_t i = 0; i + 2 < size; ++i) { + if (!memcmp("\x00\x00\x01", &ptr[i], 3)) { + startOffset = i; + break; + } + } + + if (startOffset < 0) { + return ERROR_MALFORMED; + } + + if (startOffset > 0) { + LOGI("found something resembling an H.264/MPEG syncword at " "offset %ld", startOffset); } @@ -148,6 +220,33 @@ status_t ElementaryStreamQueue::appendData( break; } + case MPEG_AUDIO: + { + uint8_t *ptr = (uint8_t *)data; + + ssize_t startOffset = -1; + for (size_t i = 0; i < size; ++i) { + if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) { + startOffset = i; + break; + } + } + + if (startOffset < 0) { + return ERROR_MALFORMED; + } + + if (startOffset > 0) { + LOGI("found something resembling an MPEG audio " + "syncword at offset %ld", + startOffset); + } + + data = &ptr[startOffset]; + size -= startOffset; + break; + } + default: TRESPASS(); break; @@ -190,11 +289,18 @@ status_t ElementaryStreamQueue::appendData( } sp ElementaryStreamQueue::dequeueAccessUnit() { - if (mMode == H264) { - return dequeueAccessUnitH264(); - } else { - CHECK_EQ((unsigned)mMode, (unsigned)AAC); - return dequeueAccessUnitAAC(); + switch (mMode) { + case H264: + return dequeueAccessUnitH264(); + case AAC: + return dequeueAccessUnitAAC(); + case MPEG_VIDEO: + return dequeueAccessUnitMPEGVideo(); + case MPEG4_VIDEO: + return dequeueAccessUnitMPEG4Video(); + default: + CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO); + return dequeueAccessUnitMPEGAudio(); } } @@ -455,4 +561,371 @@ sp ElementaryStreamQueue::dequeueAccessUnitH264() { return NULL; } +sp ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { + const uint8_t *data = mBuffer->data(); + size_t size = mBuffer->size(); + + if (size < 4) { + return NULL; + } + + uint32_t header = U32_AT(data); + + size_t frameSize; + int samplingRate, numChannels, bitrate, numSamples; + CHECK(GetMPEGAudioFrameSize( + header, &frameSize, &samplingRate, &numChannels, + &bitrate, &numSamples)); + + if (size < frameSize) { + return NULL; + } + + sp accessUnit = new ABuffer(frameSize); + memcpy(accessUnit->data(), data, frameSize); + + memmove(mBuffer->data(), + mBuffer->data() + frameSize, + mBuffer->size() - frameSize); + + mBuffer->setRange(0, mBuffer->size() - frameSize); + + int64_t timeUs = fetchTimestamp(frameSize); + CHECK_GE(timeUs, 0ll); + + accessUnit->meta()->setInt64("timeUs", timeUs); + + if (mFormat == NULL) { + mFormat = new MetaData; + mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); + mFormat->setInt32(kKeySampleRate, samplingRate); + mFormat->setInt32(kKeyChannelCount, numChannels); + } + + return accessUnit; +} + +static void EncodeSize14(uint8_t **_ptr, size_t size) { + CHECK_LE(size, 0x3fff); + + uint8_t *ptr = *_ptr; + + *ptr++ = 0x80 | (size >> 7); + *ptr++ = size & 0x7f; + + *_ptr = ptr; +} + +static sp MakeMPEGVideoESDS(const sp &csd) { + sp esds = new ABuffer(csd->size() + 25); + + uint8_t *ptr = esds->data(); + *ptr++ = 0x03; + EncodeSize14(&ptr, 22 + csd->size()); + + *ptr++ = 0x00; // ES_ID + *ptr++ = 0x00; + + *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag + + *ptr++ = 0x04; + EncodeSize14(&ptr, 16 + csd->size()); + + *ptr++ = 0x40; // Audio ISO/IEC 14496-3 + + for (size_t i = 0; i < 12; ++i) { + *ptr++ = 0x00; + } + + *ptr++ = 0x05; + EncodeSize14(&ptr, csd->size()); + + memcpy(ptr, csd->data(), csd->size()); + + return esds; +} + +sp ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() { + const uint8_t *data = mBuffer->data(); + size_t size = mBuffer->size(); + + bool sawPictureStart = false; + int pprevStartCode = -1; + int prevStartCode = -1; + int currentStartCode = -1; + + size_t offset = 0; + while (offset + 3 < size) { + if (memcmp(&data[offset], "\x00\x00\x01", 3)) { + ++offset; + continue; + } + + pprevStartCode = prevStartCode; + prevStartCode = currentStartCode; + currentStartCode = data[offset + 3]; + + if (currentStartCode == 0xb3 && mFormat == NULL) { + memmove(mBuffer->data(), mBuffer->data() + offset, size - offset); + size -= offset; + (void)fetchTimestamp(offset); + offset = 0; + mBuffer->setRange(0, size); + } + + if ((prevStartCode == 0xb3 && currentStartCode != 0xb5) + || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) { + // seqHeader without/with extension + + if (mFormat == NULL) { + CHECK_GE(size, 7u); + + unsigned width = + (data[4] << 4) | data[5] >> 4; + + unsigned height = + ((data[5] & 0x0f) << 8) | data[6]; + + mFormat = new MetaData; + mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); + mFormat->setInt32(kKeyWidth, width); + mFormat->setInt32(kKeyHeight, height); + + LOGI("found MPEG2 video codec config (%d x %d)", width, height); + + sp csd = new ABuffer(offset); + memcpy(csd->data(), data, offset); + + memmove(mBuffer->data(), + mBuffer->data() + offset, + mBuffer->size() - offset); + + mBuffer->setRange(0, mBuffer->size() - offset); + size -= offset; + (void)fetchTimestamp(offset); + offset = 0; + + // hexdump(csd->data(), csd->size()); + + sp esds = MakeMPEGVideoESDS(csd); + mFormat->setData( + kKeyESDS, kTypeESDS, esds->data(), esds->size()); + + return NULL; + } + } + + if (mFormat != NULL && currentStartCode == 0x00) { + // Picture start + + if (!sawPictureStart) { + sawPictureStart = true; + } else { + sp accessUnit = new ABuffer(offset); + memcpy(accessUnit->data(), data, offset); + + memmove(mBuffer->data(), + mBuffer->data() + offset, + mBuffer->size() - offset); + + mBuffer->setRange(0, mBuffer->size() - offset); + + int64_t timeUs = fetchTimestamp(offset); + CHECK_GE(timeUs, 0ll); + + offset = 0; + + accessUnit->meta()->setInt64("timeUs", timeUs); + + LOGV("returning MPEG video access unit at time %lld us", + timeUs); + + // hexdump(accessUnit->data(), accessUnit->size()); + + return accessUnit; + } + } + + ++offset; + } + + return NULL; +} + +static ssize_t getNextChunkSize( + const uint8_t *data, size_t size) { + static const char kStartCode[] = "\x00\x00\x01"; + + if (size < 3) { + return -EAGAIN; + } + + if (memcmp(kStartCode, data, 3)) { + TRESPASS(); + } + + size_t offset = 3; + while (offset + 2 < size) { + if (!memcmp(&data[offset], kStartCode, 3)) { + return offset; + } + + ++offset; + } + + return -EAGAIN; +} + +sp ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { + uint8_t *data = mBuffer->data(); + size_t size = mBuffer->size(); + + enum { + SKIP_TO_VISUAL_OBJECT_SEQ_START, + EXPECT_VISUAL_OBJECT_START, + EXPECT_VO_START, + EXPECT_VOL_START, + WAIT_FOR_VOP_START, + SKIP_TO_VOP_START, + + } state; + + if (mFormat == NULL) { + state = SKIP_TO_VISUAL_OBJECT_SEQ_START; + } else { + state = SKIP_TO_VOP_START; + } + + int32_t width = -1, height = -1; + + size_t offset = 0; + ssize_t chunkSize; + while ((chunkSize = getNextChunkSize( + &data[offset], size - offset)) > 0) { + bool discard = false; + + unsigned chunkType = data[offset + 3]; + + switch (state) { + case SKIP_TO_VISUAL_OBJECT_SEQ_START: + { + if (chunkType == 0xb0) { + // Discard anything before this marker. + + state = EXPECT_VISUAL_OBJECT_START; + } else { + discard = true; + } + break; + } + + case EXPECT_VISUAL_OBJECT_START: + { + CHECK_EQ(chunkType, 0xb5); + state = EXPECT_VO_START; + break; + } + + case EXPECT_VO_START: + { + CHECK_LE(chunkType, 0x1f); + state = EXPECT_VOL_START; + break; + } + + case EXPECT_VOL_START: + { + CHECK((chunkType & 0xf0) == 0x20); + + CHECK(ExtractDimensionsFromVOLHeader( + &data[offset], chunkSize, + &width, &height)); + + state = WAIT_FOR_VOP_START; + break; + } + + case WAIT_FOR_VOP_START: + { + if (chunkType == 0xb3 || chunkType == 0xb6) { + // group of VOP or VOP start. + + mFormat = new MetaData; + mFormat->setCString( + kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); + + mFormat->setInt32(kKeyWidth, width); + mFormat->setInt32(kKeyHeight, height); + + LOGI("found MPEG4 video codec config (%d x %d)", + width, height); + + sp csd = new ABuffer(offset); + memcpy(csd->data(), data, offset); + + // hexdump(csd->data(), csd->size()); + + sp esds = MakeMPEGVideoESDS(csd); + mFormat->setData( + kKeyESDS, kTypeESDS, + esds->data(), esds->size()); + + discard = true; + state = SKIP_TO_VOP_START; + } + + break; + } + + case SKIP_TO_VOP_START: + { + if (chunkType == 0xb6) { + offset += chunkSize; + + sp accessUnit = new ABuffer(offset); + memcpy(accessUnit->data(), data, offset); + + memmove(data, &data[offset], size - offset); + size -= offset; + mBuffer->setRange(0, size); + + int64_t timeUs = fetchTimestamp(offset); + CHECK_GE(timeUs, 0ll); + + offset = 0; + + accessUnit->meta()->setInt64("timeUs", timeUs); + + LOGV("returning MPEG4 video access unit at time %lld us", + timeUs); + + // hexdump(accessUnit->data(), accessUnit->size()); + + return accessUnit; + } else if (chunkType != 0xb3) { + offset += chunkSize; + discard = true; + } + + break; + } + + default: + TRESPASS(); + } + + if (discard) { + (void)fetchTimestamp(offset); + memmove(data, &data[offset], size - offset); + size -= offset; + offset = 0; + mBuffer->setRange(0, size); + } else { + offset += chunkSize; + } + } + + return NULL; +} + } // namespace android diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h index 153cfe6..4035ed3 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.h +++ b/media/libstagefright/mpeg2ts/ESQueue.h @@ -31,7 +31,10 @@ struct MetaData; struct ElementaryStreamQueue { enum Mode { H264, - AAC + AAC, + MPEG_AUDIO, + MPEG_VIDEO, + MPEG4_VIDEO, }; ElementaryStreamQueue(Mode mode); @@ -57,6 +60,9 @@ private: sp dequeueAccessUnitH264(); sp dequeueAccessUnitAAC(); + sp dequeueAccessUnitMPEGAudio(); + sp dequeueAccessUnitMPEGVideo(); + sp dequeueAccessUnitMPEG4Video(); // consume a logical (compressed) access unit of size "size", // returns its timestamp in us (or -1 if no time information). diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index dfec47f..8250ad1 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -175,7 +175,7 @@ void MPEG2TSExtractor::init() { if (!haveVideo) { sp impl = (AnotherPacketSource *)mParser->getSource( - ATSParser::AVC_VIDEO).get(); + ATSParser::VIDEO).get(); if (impl != NULL) { haveVideo = true; @@ -186,7 +186,7 @@ void MPEG2TSExtractor::init() { if (!haveAudio) { sp impl = (AnotherPacketSource *)mParser->getSource( - ATSParser::MPEG2ADTS_AUDIO).get(); + ATSParser::AUDIO).get(); if (impl != NULL) { haveAudio = true; @@ -194,7 +194,7 @@ void MPEG2TSExtractor::init() { } } - if (++numPacketsParsed > 2500) { + if (++numPacketsParsed > 10000) { break; } } -- cgit v1.1