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