本文主要是介绍android nuplayer reset处理流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转载1.NuPlayerDriver::reset()
[cpp] view plain copy
- mPlayer->resetAsync();// 执行异步reset
- while (mResetInProgress) { // 等待reset完成,如果5秒未完成,则会出现ANR
- mCondition.wait(mLock);
- }
发送kWhatReset消息
3.kWhatReset消息的处理
NuPlayer::onMessageReceived
case kWhatReset:
(1)如果mFlushingAudio或者mFlushingVideo是AWAITING_DISCONTINUITY状态,执行
[cpp] view plain copy
- 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();
- }
- }
[cpp] view plain copy
- 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;
- }
finishReset()
(4)执行audio的flushDecoder
(5)执行video的flushDecoder
(6)设置变量mResetInProgress为true
4.NuPlayer::finishReset()
(1)执行mSource->stop();
(2)执行driver->notifyResetComplete()
[cpp] view plain copy
- 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。
[cpp] view plain copy
- void NuPlayer::RTSPSource::stop() {
- sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
- sp<AMessage> dummy;
- msg->postAndAwaitResponse(&dummy); // 最终调用全局变量gLooperRoster的postAndAwaitResponse函数
- }
[cpp] view plain copy
- void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
- if (msg->what() == kWhatDisconnect) {
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID)); // 取得replyID
- mDisconnectReplyID = replyID;
- finishDisconnectIfPossible(); // 断开与服务器的数据链接
- return;
- }
[cpp] view plain copy
- if (mState != DISCONNECTED) {
- mHandler->disconnect(); // 执行MyHandler.h的disconnect函数,发送'abor'消息,断开与服务器的链接
- return;
- }
设置mResetInProgress为false,则1.中的等待完成,即reset执行结束
6.NuPlayer::flushDecoder
[cpp] view plain copy
- (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
- mRenderer->flush(audio);
调用mCodec->signalFlush(); 调用的是ACodec的signalFlush函数
8.ACodec::signalFlush()
发送kWhatFlush消息
9.ACodec::UninitializedState::onMessageReceived
case ACodec::kWhatFlush:
发送ACodec::kWhatFlushCompleted消息
10.对ACodec::kWhatFlushCompleted消息的处理位于NuPlayer类中
[cpp] view plain copy
- 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(); //
- }
[cpp] view plain copy
- 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处理流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!