NuPlayer reset处理流程

1.NuPlayerDriver::reset()
    mPlayer->resetAsync();// 执行异步reset

    while (mResetInProgress) { // 等待reset完成,如果5秒未完成,则会出现ANR
        mCondition.wait(mLock);
    }
2.NuPlayer::resetAsync()
发送kWhatReset消息

3.kWhatReset消息的处理
NuPlayer::onMessageReceived
case kWhatReset:
(1)如果mFlushingAudio或者mFlushingVideo是AWAITING_DISCONTINUITY状态,执行
mRenderer->resume();
    if (mRenderer != NULL) {
        // There's an edge case where the renderer owns all output
        // buffers and is paused, therefore the decoder will not read
        // more input data and will never encounter the matching
        // discontinuity. To avoid this, we resume the renderer.

        if (mFlushingAudio == AWAITING_DISCONTINUITY
                || mFlushingVideo == AWAITING_DISCONTINUITY) {
            mRenderer->resume();
        }
    }
(2)如果正在flushing,则推迟执行reset
    if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
        // We're currently flushing, postpone the reset until that's
        // completed.

        LOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
                mFlushingAudio, mFlushingVideo);

        mResetPostponed = true; // 设置推迟reset标志
        break;
    }
(3)如果mAudioDecoder == NULL && mVideoDecoder == NULL,则表示已经执行完reset,则调用
finishReset()

(4)执行audio的flushDecoder

(5)执行video的flushDecoder

(6)设置变量mResetInProgress为true

4.NuPlayer::finishReset()
(1)执行mSource->stop();
(2)执行driver->notifyResetComplete()
    if (mSource != NULL) {
        mSource->stop(); // 执行NuPlayer::RTSPSource::stop()函数
        mSource.clear();
    }

    if (mDriver != NULL) {
        sp<NuPlayerDriver> driver = mDriver.promote();
        if (driver != NULL) {
            driver->notifyResetComplete();
        }
    }

4.1 NuPlayer::RTSPSource::stop()

stop函数发送消息后,断开与服务器的连接需要及时执行完成,否则会超时导致ANR。

void NuPlayer::RTSPSource::stop() {
    sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());

    sp<AMessage> dummy;
    msg->postAndAwaitResponse(&dummy); // 最终调用全局变量gLooperRoster的postAndAwaitResponse函数
}
4.2 处理kWhatDisconnect消息
void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
    if (msg->what() == kWhatDisconnect) {
        uint32_t replyID;
        CHECK(msg->senderAwaitsResponse(&replyID)); // 取得replyID

        mDisconnectReplyID = replyID;
        finishDisconnectIfPossible(); // 断开与服务器的数据链接
        return;
    }
4.3 NuPlayer::RTSPSource::finishDisconnectIfPossible
    if (mState != DISCONNECTED) {
        mHandler->disconnect(); // 执行MyHandler.h的disconnect函数,发送'abor'消息,断开与服务器的链接
        return;
    }
5.NuPlayerDriver::notifyResetComplete()
设置mResetInProgress为false,则1.中的等待完成,即reset执行结束

6.NuPlayer::flushDecoder
   (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
    mRenderer->flush(audio);
7.NuPlayer::Decoder::signalFlush()
调用mCodec->signalFlush(); 调用的是ACodec的signalFlush函数

8.ACodec::signalFlush()
发送kWhatFlush消息

9.ACodec::UninitializedState::onMessageReceived
case ACodec::kWhatFlush:
发送ACodec::kWhatFlushCompleted消息

10.对ACodec::kWhatFlushCompleted消息的处理位于NuPlayer类中
NuPlayer::onMessageReceived
case kWhatVideoNotify:
case kWhatAudioNotify:
...
    } else if (what == ACodec::kWhatFlushCompleted) {
        bool needShutdown;

        if (audio) {
            CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
            mFlushingAudio = FLUSHED;
        } else {
            CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
            mFlushingVideo = FLUSHED;

            mVideoLateByUs = 0;
        }

        LOGV("decoder %s flush completed", audio ? "audio" : "video");

        if (needShutdown) {
            LOGV("initiating %s decoder shutdown",
                 audio ? "audio" : "video");

// 调用Decoder类的initiateShutdown --> ACodec::initiateShutdown() --> 发送kWhatShutdown消息 -->
// 再发送ACodec::kWhatShutdownCompleted消息 --> 回到本函数处理ACodec::kWhatShutdownCompleted消息
            (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();

            if (audio) {
                mFlushingAudio = SHUTTING_DOWN_DECODER;
            } else {
                mFlushingVideo = SHUTTING_DOWN_DECODER;
            }
        }

        finishFlushIfPossible(); //
    }

...
    } else if (what == ACodec::kWhatShutdownCompleted) {
        LOGV("%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(); //
    }
11.finishFlushIfPossible的处理
void NuPlayer::finishFlushIfPossible() {
    if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
        return;
    }

    if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
        return;
    }

    LOGV("both audio and video are flushed now.");

    if (mTimeDiscontinuityPending) {
        mRenderer->signalTimeDiscontinuity(); // 发送消息
        mTimeDiscontinuityPending = false;
    }

// NuPlayer::Decoder::signalResume --> ACodec::signalResume --> 发送kWhatResume消息 -->
// ACodec::ExecutingState::resume --> ACodec::ExecutingState::submitOutputBuffers -->
// ACodec::BaseState::postFillThisBuffer --> kWhatInputBufferFilled -->
// ACodec::BaseState::onInputBufferFilled
    if (mAudioDecoder != NULL) {
        mAudioDecoder->signalResume();
    }

    if (mVideoDecoder != NULL) {
        mVideoDecoder->signalResume();
    }

    mFlushingAudio = NONE;
    mFlushingVideo = NONE;

    if (mResetInProgress) { // 3.(6)中设置为true了
        LOGV("reset completed");

        mResetInProgress = false;
        finishReset(); // reset执行完成,见4,5的处理
    } else if (mResetPostponed) { // 如果3.(2)中设置了推迟执行reset,则重新发送kWhatReset消息
        (new AMessage(kWhatReset, id()))->post();
        mResetPostponed = false;
    } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
        postScanSources();
    }
}

发布了270 篇原创文章 · 获赞 273 · 访问量 377万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览