From be9634d071e79b72a42a4504f64eda9e2a0bceb8 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Wed, 15 Apr 2015 14:33:39 -0700 Subject: Signal EOS at end of mpeg video to flush out final sample Change-Id: I27196a4a4b7fe37da52d3ee99da8cb80294d36d0 --- media/libstagefright/mpeg2ts/ATSParser.cpp | 8 ++++++++ media/libstagefright/mpeg2ts/ESQueue.cpp | 21 ++++++++++++++++++++- media/libstagefright/mpeg2ts/ESQueue.h | 2 ++ media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp | 3 +++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 482ccff..1eae6cf 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -136,6 +136,7 @@ private: sp mBuffer; sp mSource; bool mPayloadStarted; + bool mEOSReached; uint64_t mPrevPTS; @@ -493,6 +494,7 @@ ATSParser::Stream::Stream( mPCR_PID(PCR_PID), mExpectedContinuityCounter(-1), mPayloadStarted(false), + mEOSReached(false), mPrevPTS(0), mQueue(NULL) { switch (mStreamType) { @@ -692,6 +694,8 @@ void ATSParser::Stream::signalEOS(status_t finalResult) { if (mSource != NULL) { mSource->signalEOS(finalResult); } + mEOSReached = true; + flush(); } status_t ATSParser::Stream::parsePES(ABitReader *br) { @@ -902,6 +906,10 @@ void ATSParser::Stream::onPayloadData( status_t err = mQueue->appendData(data, size, timeUs); + if (mEOSReached) { + mQueue->signalEOS(); + } + if (err != OK) { return; } diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index f257289..5527df0 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -38,7 +38,8 @@ namespace android { ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags) : mMode(mode), - mFlags(flags) { + mFlags(flags), + mEOSReached(false) { } sp ElementaryStreamQueue::getFormat() { @@ -244,6 +245,11 @@ static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) { status_t ElementaryStreamQueue::appendData( const void *data, size_t size, int64_t timeUs) { + + if (mEOSReached) { + ALOGE("appending data after EOS"); + return ERROR_MALFORMED; + } if (mBuffer == NULL || mBuffer->size() == 0) { switch (mMode) { case H264: @@ -1282,4 +1288,17 @@ sp ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { return NULL; } +void ElementaryStreamQueue::signalEOS() { + if (!mEOSReached) { + if (mMode == MPEG_VIDEO) { + const char *theEnd = "\x00\x00\x01\x00"; + appendData(theEnd, 4, 0); + } + mEOSReached = true; + } else { + ALOGW("EOS already signaled"); + } +} + + } // namespace android diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h index eb4b1c9..a6d812f 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.h +++ b/media/libstagefright/mpeg2ts/ESQueue.h @@ -46,6 +46,7 @@ struct ElementaryStreamQueue { ElementaryStreamQueue(Mode mode, uint32_t flags = 0); status_t appendData(const void *data, size_t size, int64_t timeUs); + void signalEOS(); void clear(bool clearFormat); sp dequeueAccessUnit(); @@ -60,6 +61,7 @@ private: Mode mMode; uint32_t mFlags; + bool mEOSReached; sp mBuffer; List mRangeInfos; diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index 33cfd1d..74cb5d8 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -204,6 +204,9 @@ status_t MPEG2TSExtractor::feedMore() { ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize); if (n < (ssize_t)kTSPacketSize) { + if (n >= 0) { + mParser->signalEOS(ERROR_END_OF_STREAM); + } return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; } -- cgit v1.1