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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user