diff options
author | Andreas Huber <andih@google.com> | 2010-12-21 10:22:33 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-12-21 10:22:33 -0800 |
commit | 41c3f740485a069bf101d5a1e5263880ca1035ef (patch) | |
tree | 19fafbf9dfb14679663832e486eba91fd9f2134c /media | |
parent | 41e7e6f9339cd9181df26ca96f0ac133371bc524 (diff) | |
download | frameworks_base-41c3f740485a069bf101d5a1e5263880ca1035ef.zip frameworks_base-41c3f740485a069bf101d5a1e5263880ca1035ef.tar.gz frameworks_base-41c3f740485a069bf101d5a1e5263880ca1035ef.tar.bz2 |
Squashed commit of the following:
commit 63be8ceb8b2354fb997a277c0092abae015ecf10
Author: Andreas Huber <andih@google.com>
Date: Fri Dec 17 13:45:34 2010 -0800
Enable handling of discontinuities that involve potential format changes.
Change-Id: I21848a113db8764abb54bdcf302b0923253eaf4d
commit d18a7f80ec09af382026809263dcbbfa9e7a9ec8
Author: Andreas Huber <andih@google.com>
Date: Fri Dec 17 13:45:01 2010 -0800
Signal whether or not a format change occured as part of the discontinuity.
Change-Id: I06e64f542f4369549c9cebbb892dc612346ae43d
commit c400adbd5fdbd65cfef7aed9ec65bcaace4bb69b
Author: Andreas Huber <andih@google.com>
Date: Fri Dec 17 13:44:46 2010 -0800
A little more instrumentation of ACodec
Change-Id: I07f4aeccbbd15cdd9f80f48c3f92ee984ef6d92b
commit 1d802ee01f47b3cdc5b89502cec7fbb595e197a3
Author: Andreas Huber <andih@google.com>
Date: Fri Dec 17 13:43:58 2010 -0800
Only sync audio/video queues if both types of media are actually present.
Change-Id: Ic88edf9bb1ebd4034c08747cce9877a4e28e0d35
commit e402da39d9a4d8b75653a78f728e20a3ef0fb497
Author: Andreas Huber <andih@google.com>
Date: Fri Dec 17 13:42:24 2010 -0800
Disable the random seek for now.
Change-Id: Iddd597b546e2f229e88214f9bdd6452bb188105e
Change-Id: I27c4d9ba916080be94ce6117dbb095e9022ed62b
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp | 28 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/DecoderWrapper.h | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 100 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 8 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 16 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h | 5 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp | 23 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 6 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 3 | ||||
-rw-r--r-- | media/libstagefright/httplive/LiveSession.cpp | 9 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 2 |
11 files changed, 172 insertions, 29 deletions
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp index 9738e33..4d4cd8d 100644 --- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp +++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp @@ -151,6 +151,7 @@ struct DecoderWrapper::WrapperReader : public AHandler { const sp<AMessage> ¬ify); void start(); + void stop(); void readMore(bool flush = false); protected: @@ -189,6 +190,10 @@ void DecoderWrapper::WrapperReader::start() { readMore(); } +void DecoderWrapper::WrapperReader::stop() { + CHECK_EQ(mDecoder->stop(), (status_t)OK); +} + void DecoderWrapper::WrapperReader::readMore(bool flush) { if (!flush && mEOS) { return; @@ -351,6 +356,10 @@ void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) { onSetup(msg); break; + case kWhatShutdown: + onShutdown(); + break; + case kWhatInputDataRequested: { postFillBuffer(); @@ -493,6 +502,25 @@ void DecoderWrapper::onSetup(const sp<AMessage> &msg) { ++mNumPendingDecodes; } +void DecoderWrapper::onShutdown() { + mReaderLooper->stop(); + mReaderLooper.clear(); + + mReader->stop(); + mReader.clear(); + + mSource.clear(); + + mNumOutstandingInputBuffers = 0; + mNumOutstandingOutputBuffers = 0; + mNumPendingDecodes = 0; + mFlushing = false; + + sp<AMessage> notify = mNotify->dup(); + notify->setInt32("what", ACodec::kWhatShutdownCompleted); + notify->post(); +} + void DecoderWrapper::postFillBuffer() { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", ACodec::kWhatFillThisBuffer); diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h index 883b356..b9be12c 100644 --- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.h +++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.h @@ -66,6 +66,7 @@ private: bool mFlushing; void onSetup(const sp<AMessage> &msg); + void onShutdown(); void onFlush(); void onResume(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index e99c24a..d3dab13 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -23,6 +23,7 @@ #include "NuPlayerRenderer.h" #include "NuPlayerStreamListener.h" +#include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -31,6 +32,8 @@ #include <media/stagefright/MetaData.h> #include <surfaceflinger/Surface.h> +#define SHUTDOWN_ON_DISCONTINUITY 0 + namespace android { //////////////////////////////////////////////////////////////////////////////// @@ -132,10 +135,16 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { case kWhatScanSources: { - instantiateDecoder(false, &mVideoDecoder); + instantiateDecoder( + false, + &mVideoDecoder, + false /* ignoreCodecSpecificData */); if (mAudioSink != NULL) { - instantiateDecoder(true, &mAudioDecoder); + instantiateDecoder( + true, + &mAudioDecoder, + false /* ignoreCodecSpecificData */); } if (mEOS) { @@ -182,22 +191,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { LOGI("decoder %s flush completed", audio ? "audio" : "video"); - if (mFlushingAudio == FLUSHED && mFlushingVideo == FLUSHED) { - LOGI("both audio and video are flushed now."); - - mRenderer->signalTimeDiscontinuity(); +#if SHUTDOWN_ON_DISCONTINUITY + LOGI("initiating %s decoder shutdown", + audio ? "audio" : "video"); - if (mAudioDecoder != NULL) { - mAudioDecoder->signalResume(); - } + (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown(); - if (mVideoDecoder != NULL) { - mVideoDecoder->signalResume(); - } - - mFlushingAudio = NONE; - mFlushingVideo = NONE; + if (audio) { + mFlushingAudio = SHUTTING_DOWN_DECODER; + } else { + mFlushingVideo = SHUTTING_DOWN_DECODER; } +#endif + + finishFlushIfPossible(); } else if (what == ACodec::kWhatOutputFormatChanged) { CHECK(audio); @@ -213,6 +220,23 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mAudioSink->close(); CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK); mAudioSink->start(); + + mRenderer->signalAudioSinkChanged(); + } else if (what == ACodec::kWhatShutdownCompleted) { + LOGI("%s shutdown completed", audio ? "audio" : "video"); + if (audio) { + mAudioDecoder.clear(); + + CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER); + mFlushingAudio = SHUT_DOWN; + } else { + mVideoDecoder.clear(); + + CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER); + mFlushingVideo = SHUT_DOWN; + } + + finishFlushIfPossible(); } else { CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer); @@ -265,6 +289,43 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { } } +void NuPlayer::finishFlushIfPossible() { + if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) { + return; + } + + if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) { + return; + } + + LOGI("both audio and video are flushed now."); + + mRenderer->signalTimeDiscontinuity(); + + if (mFlushingAudio == SHUT_DOWN) { + instantiateDecoder( + true, + &mAudioDecoder, + true /* ignoreCodecSpecificData */); + CHECK(mAudioDecoder != NULL); + } else if (mAudioDecoder != NULL) { + mAudioDecoder->signalResume(); + } + + if (mFlushingVideo == SHUT_DOWN) { + instantiateDecoder( + false, + &mVideoDecoder, + true /* ignoreCodecSpecificData */); + CHECK(mVideoDecoder != NULL); + } else if (mVideoDecoder != NULL) { + mVideoDecoder->signalResume(); + } + + mFlushingAudio = NONE; + mFlushingVideo = NONE; +} + void NuPlayer::feedMoreTSData() { CHECK(!mEOS); @@ -285,7 +346,10 @@ void NuPlayer::feedMoreTSData() { } else { if (buffer[0] == 0x00) { // XXX legacy - mTSParser->signalDiscontinuity(ATSParser::DISCONTINUITY_SEEK); + mTSParser->signalDiscontinuity( + buffer[1] == 0x00 + ? ATSParser::DISCONTINUITY_SEEK + : ATSParser::DISCONTINUITY_FORMATCHANGE); } else { mTSParser->feedTSPacket(buffer, sizeof(buffer)); } @@ -354,7 +418,7 @@ status_t NuPlayer::dequeueAccessUnit( } status_t NuPlayer::instantiateDecoder( - bool audio, sp<Decoder> *decoder) { + bool audio, sp<Decoder> *decoder, bool ignoreCodecSpecificData) { if (*decoder != NULL) { return OK; } @@ -378,7 +442,7 @@ status_t NuPlayer::instantiateDecoder( looper()->registerHandler(*decoder); const sp<MetaData> &meta = source->getFormat(); - (*decoder)->configure(meta); + (*decoder)->configure(meta, ignoreCodecSpecificData); return OK; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 9a5a6c4..fad1ce1 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -79,14 +79,16 @@ private: NONE, AWAITING_DISCONTINUITY, FLUSHING_DECODER, - FLUSHED + SHUTTING_DOWN_DECODER, + FLUSHED, + SHUT_DOWN, }; FlushStatus mFlushingAudio; FlushStatus mFlushingVideo; status_t instantiateDecoder( - bool audio, sp<Decoder> *decoder); + bool audio, sp<Decoder> *decoder, bool ignoreCodecSpecificData); status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg); void renderBuffer(bool audio, const sp<AMessage> &msg); @@ -100,6 +102,8 @@ private: void feedMoreTSData(); void notifyListener(int msg, int ext1, int ext2); + void finishFlushIfPossible(); + DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index d1ed222..1d78808 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -42,7 +42,8 @@ NuPlayer::Decoder::Decoder( NuPlayer::Decoder::~Decoder() { } -void NuPlayer::Decoder::configure(const sp<MetaData> &meta) { +void NuPlayer::Decoder::configure( + const sp<MetaData> &meta, bool ignoreCodecSpecificData) { CHECK(mCodec == NULL); CHECK(mWrapper == NULL); @@ -54,6 +55,10 @@ void NuPlayer::Decoder::configure(const sp<MetaData> &meta) { sp<AMessage> format = makeFormat(meta); + if (ignoreCodecSpecificData) { + mCSD.clear(); + } + if (mSurface != NULL) { format->setObject("surface", mSurface); } @@ -282,5 +287,14 @@ void NuPlayer::Decoder::signalResume() { } } +void NuPlayer::Decoder::initiateShutdown() { + if (mCodec != NULL) { + mCodec->initiateShutdown(); + } else { + CHECK(mWrapper != NULL); + mWrapper->initiateShutdown(); + } +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index 77800be..07fe47e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -29,9 +29,12 @@ struct DecoderWrapper; struct NuPlayer::Decoder : public AHandler { Decoder(const sp<AMessage> ¬ify, const sp<Surface> &surface = NULL); - void configure(const sp<MetaData> &meta); + void configure( + const sp<MetaData> &meta, bool ignoreCodecSpecificData); + void signalFlush(); void signalResume(); + void initiateShutdown(); protected: virtual ~Decoder(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 855bc0a..57a652c 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -39,7 +39,9 @@ NuPlayer::Renderer::Renderer( mAnchorTimeRealUs(-1), mFlushingAudio(false), mFlushingVideo(false), - mSyncQueues(true) { + mHasAudio(mAudioSink != NULL), + mHasVideo(true), + mSyncQueues(mHasAudio && mHasVideo) { } NuPlayer::Renderer::~Renderer() { @@ -87,7 +89,7 @@ void NuPlayer::Renderer::signalTimeDiscontinuity() { CHECK(mVideoQueue.empty()); mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; - mSyncQueues = true; + mSyncQueues = mHasAudio && mHasVideo; } void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { @@ -142,6 +144,12 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) { break; } + case kWhatAudioSinkChanged: + { + onAudioSinkChanged(); + break; + } + default: TRESPASS(); break; @@ -163,6 +171,10 @@ void NuPlayer::Renderer::postDrainAudioQueue() { msg->post(10000); } +void NuPlayer::Renderer::signalAudioSinkChanged() { + (new AMessage(kWhatAudioSinkChanged, id()))->post(); +} + void NuPlayer::Renderer::onDrainAudioQueue() { uint32_t numFramesPlayed; CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK); @@ -264,7 +276,7 @@ void NuPlayer::Renderer::postDrainVideoQueue() { if (mAnchorTimeMediaUs < 0) { delayUs = 0; - if (mAudioSink == NULL) { + if (!mHasAudio) { mAnchorTimeMediaUs = mediaTimeUs; mAnchorTimeRealUs = ALooper::GetNowUs(); } @@ -492,5 +504,10 @@ bool NuPlayer::Renderer::dropBufferWhileFlushing( return true; } +void NuPlayer::Renderer::onAudioSinkChanged() { + CHECK(!mDrainAudioQueuePending); + mNumFramesWritten = 0; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 834ddc5..eaa004a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -37,6 +37,8 @@ struct NuPlayer::Renderer : public AHandler { void signalTimeDiscontinuity(); + void signalAudioSinkChanged(); + enum { kWhatEOS, kWhatFlushComplete, @@ -54,6 +56,7 @@ private: kWhatQueueBuffer, kWhatQueueEOS, kWhatFlush, + kWhatAudioSinkChanged, }; struct QueueEntry { @@ -81,6 +84,8 @@ private: bool mFlushingAudio; bool mFlushingVideo; + bool mHasAudio; + bool mHasVideo; bool mSyncQueues; void onDrainAudioQueue(); @@ -92,6 +97,7 @@ private: void onQueueBuffer(const sp<AMessage> &msg); void onQueueEOS(const sp<AMessage> &msg); void onFlush(const sp<AMessage> &msg); + void onAudioSinkChanged(); void notifyEOS(bool audio); void notifyFlushComplete(bool audio); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 77276ab..3bb61f2 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1157,6 +1157,9 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { if (!msg->findObject("buffer", &obj)) { CHECK(msg->findInt32("err", &err)); + LOGV("[%s] saw error %d instead of an input buffer", + mCodec->mComponentName.c_str(), err); + obj.clear(); } diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 30ac404..cc7189c 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -468,13 +468,16 @@ void LiveSession::onDownloadNext() { return; } - if (explicitDiscontinuity - || (mPrevBandwidthIndex >= 0 - && (size_t)mPrevBandwidthIndex != bandwidthIndex)) { + bool bandwidthChanged = + mPrevBandwidthIndex >= 0 + && (size_t)mPrevBandwidthIndex != bandwidthIndex; + + if (explicitDiscontinuity || bandwidthChanged) { // Signal discontinuity. sp<ABuffer> tmp = new ABuffer(188); memset(tmp->data(), 0, tmp->size()); + tmp->data()[1] = bandwidthChanged; mDataSource->queueBuffer(tmp); } diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index de6346b..afacb2e 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -284,7 +284,7 @@ ATSParser::Stream::Stream( : mProgram(program), mElementaryPID(elementaryPID), mStreamType(streamType), - mBuffer(new ABuffer(128 * 1024)), + mBuffer(new ABuffer(192 * 1024)), mPayloadStarted(false), mQueue(streamType == 0x1b ? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) { |