summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-12-21 10:22:33 -0800
committerAndreas Huber <andih@google.com>2010-12-21 10:22:33 -0800
commit3831a066bcf1019864a94d2bc7b4c9241efc5c22 (patch)
tree13addfa6d2406f60574c3393a153f133d13690b9 /media
parent54c02a58e5ad4b7b2668f63caa9d189e958f5544 (diff)
downloadframeworks_av-3831a066bcf1019864a94d2bc7b4c9241efc5c22.zip
frameworks_av-3831a066bcf1019864a94d2bc7b4c9241efc5c22.tar.gz
frameworks_av-3831a066bcf1019864a94d2bc7b4c9241efc5c22.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.cpp28
-rw-r--r--media/libmediaplayerservice/nuplayer/DecoderWrapper.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp100
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h8
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp16
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp23
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h6
-rw-r--r--media/libstagefright/ACodec.cpp3
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp9
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp2
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> &notify);
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> &notify, 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) {