android nuplayer reset处理流程


转载
1.NuPlayerDriver::reset()
  1. mPlayer->resetAsync();// 执行异步reset  
  2.   
  3. while (mResetInProgress) { // 等待reset完成,如果5秒未完成,则会出现ANR  
  4.     mCondition.wait(mLock);  
  5. }  
2.NuPlayer::resetAsync()
发送kWhatReset消息

3.kWhatReset消息的处理
NuPlayer::onMessageReceived
case kWhatReset:
(1)如果mFlushingAudio或者mFlushingVideo是AWAITING_DISCONTINUITY状态,执行
  1. mRenderer->resume();  
  2.     if (mRenderer != NULL) {  
  3.         // There's an edge case where the renderer owns all output  
  4.         // buffers and is paused, therefore the decoder will not read  
  5.         // more input data and will never encounter the matching  
  6.         // discontinuity. To avoid this, we resume the renderer.  
  7.   
  8.         if (mFlushingAudio == AWAITING_DISCONTINUITY  
  9.                 || mFlushingVideo == AWAITING_DISCONTINUITY) {  
  10.             mRenderer->resume();  
  11.         }  
  12.     }  
(2)如果正在flushing,则推迟执行reset
  1. if (mFlushingAudio != NONE || mFlushingVideo != NONE) {  
  2.     // We're currently flushing, postpone the reset until that's  
  3.     // completed.  
  4.   
  5.     LOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",  
  6.             mFlushingAudio, mFlushingVideo);  
  7.   
  8.     mResetPostponed = true; // 设置推迟reset标志  
  9.     break;  
  10. }  
(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()
  1. if (mSource != NULL) {  
  2.     mSource->stop(); // 执行NuPlayer::RTSPSource::stop()函数  
  3.     mSource.clear();  
  4. }  
  5.   
  6. if (mDriver != NULL) {  
  7.     sp<NuPlayerDriver> driver = mDriver.promote();  
  8.     if (driver != NULL) {  
  9.         driver->notifyResetComplete();  
  10.     }  
  11. }  

4.1 NuPlayer::RTSPSource::stop()

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

  1. void NuPlayer::RTSPSource::stop() {  
  2.     sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());  
  3.   
  4.     sp<AMessage> dummy;  
  5.     msg->postAndAwaitResponse(&dummy); // 最终调用全局变量gLooperRoster的postAndAwaitResponse函数  
  6. }  
4.2 处理kWhatDisconnect消息
  1. void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {  
  2.     if (msg->what() == kWhatDisconnect) {  
  3.         uint32_t replyID;  
  4.         CHECK(msg->senderAwaitsResponse(&replyID)); // 取得replyID  
  5.   
  6.         mDisconnectReplyID = replyID;  
  7.         finishDisconnectIfPossible(); // 断开与服务器的数据链接  
  8.         return;  
  9.     }  
4.3 NuPlayer::RTSPSource::finishDisconnectIfPossible
  1. if (mState != DISCONNECTED) {  
  2.     mHandler->disconnect(); // 执行MyHandler.h的disconnect函数,发送'abor'消息,断开与服务器的链接  
  3.     return;  
  4. }  
5.NuPlayerDriver::notifyResetComplete()
设置mResetInProgress为false,则1.中的等待完成,即reset执行结束

6.NuPlayer::flushDecoder
  1. (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();  
  2.  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类中
  1. NuPlayer::onMessageReceived  
  2. case kWhatVideoNotify:  
  3. case kWhatAudioNotify:  
  4. ...  
  5.     } else if (what == ACodec::kWhatFlushCompleted) {  
  6.         bool needShutdown;  
  7.   
  8.         if (audio) {  
  9.             CHECK(IsFlushingState(mFlushingAudio, &needShutdown));  
  10.             mFlushingAudio = FLUSHED;  
  11.         } else {  
  12.             CHECK(IsFlushingState(mFlushingVideo, &needShutdown));  
  13.             mFlushingVideo = FLUSHED;  
  14.   
  15.             mVideoLateByUs = 0;  
  16.         }  
  17.   
  18.         LOGV("decoder %s flush completed", audio ? "audio" : "video");  
  19.   
  20.         if (needShutdown) {  
  21.             LOGV("initiating %s decoder shutdown",  
  22.                  audio ? "audio" : "video");  
  23.   
  24. // 调用Decoder类的initiateShutdown --> ACodec::initiateShutdown() --> 发送kWhatShutdown消息 -->  
  25. // 再发送ACodec::kWhatShutdownCompleted消息 --> 回到本函数处理ACodec::kWhatShutdownCompleted消息  
  26.             (audio ? mAudioDecoder : mVideoDecoder)->initiateShutdown();  
  27.   
  28.             if (audio) {  
  29.                 mFlushingAudio = SHUTTING_DOWN_DECODER;  
  30.             } else {  
  31.                 mFlushingVideo = SHUTTING_DOWN_DECODER;  
  32.             }  
  33.         }  
  34.   
  35.         finishFlushIfPossible(); //  
  36.     }  
  37.   
  38. ...  
  39.     } else if (what == ACodec::kWhatShutdownCompleted) {  
  40.         LOGV("%s shutdown completed", audio ? "audio" : "video");  
  41.         if (audio) {  
  42.             mAudioDecoder.clear();  
  43.   
  44.             CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);  
  45.             mFlushingAudio = SHUT_DOWN;  
  46.         } else {  
  47.             mVideoDecoder.clear();  
  48.   
  49.             CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);  
  50.             mFlushingVideo = SHUT_DOWN;  
  51.         }  
  52.   
  53.         finishFlushIfPossible(); //  
  54.     }  
11.finishFlushIfPossible的处理
  1. void NuPlayer::finishFlushIfPossible() {  
  2.     if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {  
  3.         return;  
  4.     }  
  5.   
  6.     if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {  
  7.         return;  
  8.     }  
  9.   
  10.     LOGV("both audio and video are flushed now.");  
  11.   
  12.     if (mTimeDiscontinuityPending) {  
  13.         mRenderer->signalTimeDiscontinuity(); // 发送消息  
  14.         mTimeDiscontinuityPending = false;  
  15.     }  
  16.   
  17. // NuPlayer::Decoder::signalResume --> ACodec::signalResume --> 发送kWhatResume消息 -->  
  18. // ACodec::ExecutingState::resume --> ACodec::ExecutingState::submitOutputBuffers -->  
  19. // ACodec::BaseState::postFillThisBuffer --> kWhatInputBufferFilled -->  
  20. // ACodec::BaseState::onInputBufferFilled  
  21.     if (mAudioDecoder != NULL) {  
  22.         mAudioDecoder->signalResume();  
  23.     }  
  24.   
  25.     if (mVideoDecoder != NULL) {  
  26.         mVideoDecoder->signalResume();  
  27.     }  
  28.   
  29.     mFlushingAudio = NONE;  
  30.     mFlushingVideo = NONE;  
  31.   
  32.     if (mResetInProgress) { // 3.(6)中设置为true了  
  33.         LOGV("reset completed");  
  34.   
  35.         mResetInProgress = false;  
  36.         finishReset(); // reset执行完成,见4,5的处理  
  37.     } else if (mResetPostponed) { // 如果3.(2)中设置了推迟执行reset,则重新发送kWhatReset消息  
  38.         (new AMessage(kWhatReset, id()))->post();  
  39.         mResetPostponed = false;  
  40.     } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {  
  41.         postScanSources();  
  42.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值