NuPlayer reset处理流程
2012-03-12 10:23
435 查看
1.NuPlayerDriver::reset()
发送kWhatReset消息
3.kWhatReset消息的处理
NuPlayer::onMessageReceived
case kWhatReset:
(1)如果mFlushingAudio或者mFlushingVideo是AWAITING_DISCONTINUITY状态,执行
finishReset()
(4)执行audio的flushDecoder
(5)执行video的flushDecoder
(6)设置变量mResetInProgress为true
4.NuPlayer::finishReset()
(1)执行mSource->stop();
(2)执行driver->notifyResetComplete()
4.1 NuPlayer::RTSPSource::stop()
stop函数发送消息后,断开与服务器的连接需要及时执行完成,否则会超时导致ANR。
设置mResetInProgress为false,则1.中的等待完成,即reset执行结束
6.NuPlayer::flushDecoder
调用mCodec->signalFlush(); 调用的是ACodec的signalFlush函数
8.ACodec::signalFlush()
发送kWhatFlush消息
9.ACodec::UninitializedState::onMessageReceived
case ACodec::kWhatFlush:
发送ACodec::kWhatFlushCompleted消息
10.对ACodec::kWhatFlushCompleted消息的处理位于NuPlayer类中
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(); } }
相关文章推荐
- android nuplayer reset处理流程
- NuPlayer的处理流程
- NuPlayer的处理流程
- ICS4.0.3创建NuPlayer的处理流程
- ICS4.0.3创建NuPlayer的处理流程
- ICS4.0.3创建NuPlayer的处理流程
- ATL 7.0中 NT服务的处理流程
- Asp.Net构架(Http请求处理流程)
- linux bridge处理流程
- 前台js文件上传,后台jfinal处理,全流程
- 职业能力名称匹配去噪处理流程样例
- Android输入法框架中按键消息的处理流程
- wxWidgets:消息处理流程
- xmemcached-yanf4j事件处理流程(二)
- 忆龙2009:URPF的处理流程
- Arm架构异常处理流程之缺页异常
- Linux内核数据包处理流程-数据包接收(3)
- STM32中断流程处理
- Android rtsp流媒体音视频帧的处理流程
- 【转帖】Windows异常处理流程