Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 222e6892 authored by Andreas Huber's avatar Andreas Huber
Browse files

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
parent f74dcfcf
Loading
Loading
Loading
Loading
+52 −18
Original line number Diff line number Diff line
@@ -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,17 +199,19 @@ 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
                if (formatChange) {
                    LOGI("initiating %s decoder shutdown",
                         audio ? "audio" : "video");

@@ -202,7 +222,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    } 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
+3 −0
Original line number Diff line number Diff line
@@ -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);
};

+2 −2
Original line number Diff line number Diff line
@@ -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;
        }
+5 −3
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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();