From 53df1a460bcfdd129ca2bc416dee2009e35c042e Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 22 Dec 2010 10:03:04 -0800 Subject: Distinguish discontinuities w/ a format change from those without. Shutdown decoders as needed in anticipation of a format change, otherwise just flush. Change-Id: Ieb04f8aa8658569b091409c4903075fd496e5abb --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 70 ++++++++++++++++------ media/libmediaplayerservice/nuplayer/NuPlayer.h | 3 + media/libstagefright/mpeg2ts/ATSParser.cpp | 4 +- .../libstagefright/mpeg2ts/AnotherPacketSource.cpp | 8 ++- media/libstagefright/mpeg2ts/AnotherPacketSource.h | 2 +- 5 files changed, 63 insertions(+), 24 deletions(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index d3dab13..967fa49 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -32,8 +32,6 @@ #include #include -#define SHUTDOWN_ON_DISCONTINUITY 0 - namespace android { //////////////////////////////////////////////////////////////////////////////// @@ -78,6 +76,26 @@ void NuPlayer::start() { (new AMessage(kWhatStart, id()))->post(); } +// static +bool NuPlayer::IsFlushingState(FlushStatus state, bool *formatChange) { + switch (state) { + case FLUSHING_DECODER: + if (formatChange != NULL) { + *formatChange = false; + } + return true; + + case FLUSHING_DECODER_FORMATCHANGE: + if (formatChange != NULL) { + *formatChange = true; + } + return true; + + default: + return false; + } +} + void NuPlayer::onMessageReceived(const sp &msg) { switch (msg->what()) { case kWhatSetDataSource: @@ -181,28 +199,30 @@ void NuPlayer::onMessageReceived(const sp &msg) { } else if (what == ACodec::kWhatEOS) { mRenderer->queueEOS(audio, ERROR_END_OF_STREAM); } else if (what == ACodec::kWhatFlushCompleted) { + bool formatChange; + if (audio) { - CHECK_EQ((int)mFlushingAudio, (int)FLUSHING_DECODER); + CHECK(IsFlushingState(mFlushingAudio, &formatChange)); mFlushingAudio = FLUSHED; } else { - CHECK_EQ((int)mFlushingVideo, (int)FLUSHING_DECODER); + CHECK(IsFlushingState(mFlushingVideo, &formatChange)); mFlushingVideo = FLUSHED; } LOGI("decoder %s flush completed", audio ? "audio" : "video"); -#if SHUTDOWN_ON_DISCONTINUITY - LOGI("initiating %s decoder shutdown", - audio ? "audio" : "video"); + if (formatChange) { + LOGI("initiating %s decoder shutdown", + audio ? "audio" : "video"); - (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); + (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); - if (audio) { - mFlushingAudio = SHUTTING_DOWN_DECODER; - } else { - mFlushingVideo = SHUTTING_DOWN_DECODER; + if (audio) { + mFlushingAudio = SHUTTING_DOWN_DECODER; + } else { + mFlushingVideo = SHUTTING_DOWN_DECODER; + } } -#endif finishFlushIfPossible(); } else if (what == ACodec::kWhatOutputFormatChanged) { @@ -451,8 +471,8 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp &msg) { sp reply; CHECK(msg->findMessage("reply", &reply)); - if ((audio && mFlushingAudio == FLUSHING_DECODER) - || (!audio && mFlushingVideo == FLUSHING_DECODER)) { + if ((audio && IsFlushingState(mFlushingAudio)) + || (!audio && IsFlushingState(mFlushingVideo))) { reply->setInt32("err", INFO_DISCONTINUITY); reply->post(); return OK; @@ -467,14 +487,25 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp &msg) { return err; } else if (err != OK) { if (err == INFO_DISCONTINUITY) { - LOGI("%s discontinuity", audio ? "audio" : "video"); + int32_t formatChange; + if (!accessUnit->meta()->findInt32( + "format-change", &formatChange)) { + formatChange = 0; + } + + LOGI("%s discontinuity (formatChange=%d)", + audio ? "audio" : "video", formatChange); + (audio ? mAudioDecoder : mVideoDecoder)->signalFlush(); mRenderer->flush(audio); if (audio) { CHECK(mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY); - mFlushingAudio = FLUSHING_DECODER; + + mFlushingAudio = formatChange + ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; + if (mFlushingVideo == NONE) { mFlushingVideo = (mVideoDecoder != NULL) ? AWAITING_DISCONTINUITY @@ -483,7 +514,10 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp &msg) { } else { CHECK(mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY); - mFlushingVideo = FLUSHING_DECODER; + + mFlushingVideo = formatChange + ? FLUSHING_DECODER_FORMATCHANGE : FLUSHING_DECODER; + if (mFlushingAudio == NONE) { mFlushingAudio = (mAudioDecoder != NULL) ? AWAITING_DISCONTINUITY diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index fad1ce1..d4e7428 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -79,6 +79,7 @@ private: NONE, AWAITING_DISCONTINUITY, FLUSHING_DECODER, + FLUSHING_DECODER_FORMATCHANGE, SHUTTING_DOWN_DECODER, FLUSHED, SHUT_DOWN, @@ -104,6 +105,8 @@ private: void finishFlushIfPossible(); + static bool IsFlushingState(FlushStatus state, bool *formatChange = NULL); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index afacb2e..ee9b573 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -334,7 +334,7 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) { if (mStreamType == 0x1b && mSource != NULL) { // Don't signal discontinuities on audio streams. - mSource->queueDiscontinuity(); + mSource->queueDiscontinuity(true /* formatChange */); } break; } @@ -348,7 +348,7 @@ void ATSParser::Stream::signalDiscontinuity(DiscontinuityType type) { if (mSource != NULL) { mSource->clear(); - mSource->queueDiscontinuity(); + mSource->queueDiscontinuity(!isASeek); } break; } diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index 7a1d5b0..a8fe2c1 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -63,8 +63,6 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp *buffer) { int32_t discontinuity; if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity) && discontinuity) { - buffer->clear(); - return INFO_DISCONTINUITY; } @@ -125,10 +123,14 @@ void AnotherPacketSource::queueAccessUnit(const sp &buffer) { mCondition.signal(); } -void AnotherPacketSource::queueDiscontinuity() { +void AnotherPacketSource::queueDiscontinuity(bool formatChange) { sp buffer = new ABuffer(0); buffer->meta()->setInt32("discontinuity", true); + if (formatChange) { + buffer->meta()->setInt32("format-change", true); + } + Mutex::Autolock autoLock(mLock); mBuffers.push_back(buffer); diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h index 2bc7404..f25a067 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h @@ -42,7 +42,7 @@ struct AnotherPacketSource : public MediaSource { status_t nextBufferTime(int64_t *timeUs); void queueAccessUnit(const sp &buffer); - void queueDiscontinuity(); + void queueDiscontinuity(bool formatChange); void signalEOS(status_t result); void clear(); -- cgit v1.1