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

Commit 56c7950d authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Steve Kondik
Browse files

nuplayer: Fix incorrect state handling while shutting down a decoder

This patch fixes a race condition between a flush issued by NuPlayer
as part of reset and the handling of an offload teardown message.

If the offload teardown message gets handled while NuPlayer is waiting for
a flush complete message, the audio decoder is cleared while the decoder
is being flushed. On receiving a flush complete message,
NuPlayer tries to initiate shutdown on an already cleared decoder
leading to a crash

To avoid this, reject all flush requests if the decoder is
already shutdown or pending shutdown.

CRs-Fixed: 821831
Change-Id: I4c6f2c8d346931006acdd3b522310ed234ab72f1
parent 49a2379d
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -934,17 +934,13 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                int32_t reason;
                CHECK(msg->findInt32("reason", &reason));
                closeAudioSink();
                if (!mOffloadDecodedPCM) {
                    mAudioDecoder.clear();
                    ++mAudioDecoderGeneration;
                } else {
                    ALOGV("Decoded PCM offload flushing mFLushingAudio %d", mFlushingAudio);

                if (mAudioDecoder != NULL && mFlushingAudio == NONE) {
                    mDeferredActions.push_back(
                        new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
                                               FLUSH_CMD_NONE /* video */));
                }
                }

                mRenderer->flush(
                        true /* audio */, false /* notifyComplete */);
                if (mVideoDecoder != NULL) {
@@ -1530,6 +1526,18 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
        return;
    }

    FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;

    bool inShutdown = *state != NONE &&
                      *state != FLUSHING_DECODER &&
                      *state != FLUSHED;

    // Reject flush if the decoder state is not one of the above
    if (inShutdown) {
        ALOGI("flush %s called while in shutdown", audio ? "audio" : "video");
        return;
    }

    // Make sure we don't continue to scan sources until we finish flushing.
    ++mScanSourcesGeneration;
    mScanSourcesPending = false;