android nuplayer reset处理流程

2024-05-27 11:18

本文主要是介绍android nuplayer reset处理流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载
1.NuPlayerDriver::reset() 
[cpp]  view plain copy
  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状态,执行
[cpp]  view plain copy
  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
[cpp]  view plain copy
  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()
[cpp]  view plain copy
  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。

[cpp]  view plain copy
  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消息
[cpp]  view plain copy
  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
[cpp]  view plain copy
  1. if (mState != DISCONNECTED) {  
  2.     mHandler->disconnect(); // 执行MyHandler.h的disconnect函数,发送'abor'消息,断开与服务器的链接  
  3.     return;  
  4. }  
5.NuPlayerDriver::notifyResetComplete()
设置mResetInProgress为false,则1.中的等待完成,即reset执行结束

6.NuPlayer::flushDecoder
[cpp]  view plain copy
  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类中
[cpp]  view plain copy
  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的处理
[cpp]  view plain copy
  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.     }  
  43. }  

这篇关于android nuplayer reset处理流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007322

相关文章

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

springboot启动流程过程

《springboot启动流程过程》SpringBoot简化了Spring框架的使用,通过创建`SpringApplication`对象,判断应用类型并设置初始化器和监听器,在`run`方法中,读取配... 目录springboot启动流程springboot程序启动入口1.创建SpringApplicat

通过prometheus监控Tomcat运行状态的操作流程

《通过prometheus监控Tomcat运行状态的操作流程》文章介绍了如何安装和配置Tomcat,并使用Prometheus和TomcatExporter来监控Tomcat的运行状态,文章详细讲解了... 目录Tomcat安装配置以及prometheus监控Tomcat一. 安装并配置tomcat1、安装

MySQL的cpu使用率100%的问题排查流程

《MySQL的cpu使用率100%的问题排查流程》线上mysql服务器经常性出现cpu使用率100%的告警,因此本文整理一下排查该问题的常规流程,文中通过代码示例讲解的非常详细,对大家的学习或工作有一... 目录1. 确认CPU占用来源2. 实时分析mysql活动3. 分析慢查询与执行计划4. 检查索引与表

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed