NuPlayer reset處理流程

來源:互聯網
上載者:User

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::onMessageReceivedcase 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();    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.