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
This commit is contained in:
Andreas Huber
2010-12-22 10:03:04 -08:00
parent f74dcfcf00
commit 222e689267
5 changed files with 63 additions and 24 deletions

View File

@@ -32,8 +32,6 @@
#include <media/stagefright/MetaData.h>
#include <surfaceflinger/Surface.h>
#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<AMessage> &msg) {
switch (msg->what()) {
case kWhatSetDataSource:
@@ -181,28 +199,30 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &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<AMessage> &msg) {
sp<AMessage> 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<AMessage> &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<AMessage> &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

View File

@@ -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);
};

View File

@@ -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;
}

View File

@@ -63,8 +63,6 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *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<ABuffer> &buffer) {
mCondition.signal();
}
void AnotherPacketSource::queueDiscontinuity() {
void AnotherPacketSource::queueDiscontinuity(bool formatChange) {
sp<ABuffer> 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);

View File

@@ -42,7 +42,7 @@ struct AnotherPacketSource : public MediaSource {
status_t nextBufferTime(int64_t *timeUs);
void queueAccessUnit(const sp<ABuffer> &buffer);
void queueDiscontinuity();
void queueDiscontinuity(bool formatChange);
void signalEOS(status_t result);
void clear();