当前位置:网站首页>【学习】从零开始的音视频开发(9)——NuPlayer
【学习】从零开始的音视频开发(9)——NuPlayer
2022-04-23 07:16:00 【Panic Lin】
NuPlayer基于StagefrightPlayer的基础类构建,利用了底层的ALooper/AHandler机制来进行异步解码播放,Alooper轮循队列中的消息,把消息推送到AHandler处理,最后通过handleMessage函数回调,做相应的逻辑处理
NuPlayer整体结构
MediaPlayerFactory通过工厂模式创建NuPlayerFactory,然后通过NuPlayerFactory创建NuPlayerDriver,接着通过NuPlayerDriver构建一个NuPlayer,NuPlayer作为播放器,其中设计数据解析、解码、渲染等过程


NuPlayer的构建过程
在上层调用setDataSource函数后,开始到达MediaPlayerService的setDataSource函数,通过getPlayerType函数获取播放器类型

播放器类型枚举如下

这时再回到MediaPlayerFactory中看看getPlayerType函数

接下来进入一个宏函数,宏的主要作用是替换,提高代码的执行效率,因为其省去了分配和释放栈帧、传参、传返回值等一系列工作

这个宏函数的标示遍历map中存放的播放器工厂类,调用scoreFactory可以得到播放器的播放能力,如果是NuPlayer,默认有一个0.8的值,返回的ret就是NuPlayerFactory对象,如果得到的值为0.0,就进入getDefaultPlayerType函数

默认也是NuPlayerFactory
针对NuPlayerFactory不会直接创建NuPlayer,而是在NuPlayerDriver的构造函数中创建一个NuPlayerDriver

在NuPlayerDriver的构造函数中,创建了一个NuPlayer,NuPlayerDriver是对NuPlayer的封装,继承MediaPlayerInterface接口。通过NuPlayer可以实现播放功能,主要用于通知上面的流程
NuPlayer继承自AHandler,并且引入了AMessage,通过ALooper来处理消息,比如它的prepareAsync函数

实际就是发送一个kWhatPrepare消息。在onMessageReceived函数中,收到消息并进行处理(该函数太长,仅摘取kWhatPrepare部分分析)

NuPlayer的数据解析模块
解析的模块主要是NuPlayerSource以及继承它的几个类,如HTTPLiveSource、RTSPSource、GenericSource等
在NuPlayer中调用setDataSourceAsync函数后

这里会根据不同协议选择不同的Source对象,有了这个Source对象后,发送kWhatSetDataSource消息(下图同样只是该函数部分截图)

通过具体的Source解析完数据,再把Source强制转换成mSource给Decoder使用,这时里面就包含了数据相关信息,其中的一个HTTPLiveSource,主要用于解析HLS协议

当调用HTTPLiveSource的prepareAsync函数时

内部主要构建了一个LiveSession对象,通过LiveSession内部的connectAsync函数,创建一个会话


查看onConnect函数

网络请求,开始取播放列表,在取到播放列表后进行回调(下图是回调函数)

上面的代码主要是根据URL返回的M3U文件,获取对应的BandwidthItem,如果熟悉M3U文件,可以知道M3U文件有一级索引和二级索引,下图是一些举例

其主要作用是动态码率适应,BANDWIDTH越大,分辨率越高。BINDWIDTH实际上就是带宽
若想获得某个Track的信息,得到视频、音频、字幕相关信息,可以通过LiveSession的getTrackInfo函数

到此数据解析模块完成,视频源的主要作用都是得到音视频数据信息,最终通过mSource变量传递给解码器
NuPlayer的解码模块
它引入了NuPlayerDecoderBase,这是一个基类,真正的解码器逻辑在NuPlayerDecoder.cpp中,它继承了这个基类,下面先查看实例化解码器

上面的代码构造了Decoder对象,且进行了初始化和构建解码器
由于NuPlayerDecoder继承自NuPlayerDecoderBase类,所以Configure函数会执行NuPlayerDecoder的Configure函数,最终回调onConfigure函数,其位于NuPlayerDecoder.cpp中

从onConfigure函数可以看到,NuPlayerDecoder引入了MediaCodec作为解码器。通过CreateByType/CreateByComponentName创建了Codec对象。
NuPlayer的渲染模块
主要功能
1.将音视频原始数据缓存到队列
2.音频数据消耗播放
3.视频数据消耗显示
4.音视频同步
5.播放器控制
将音视频原始数据缓存到队列,在NuPlayerRenderer.h中,存在一个QueueEntry结构体和两个队列


数据在onQueueBuffer函数中进行添加

而音频的播放在NuPlayerRenderer中,会先调用openAudioSink函数

发送一个kWhatOpenAudioSink消息,收到消息后进行如下处理

调用onOpenAudioSink函数

这里打开了AudioSink(音频后端)。当将音频数据放入音频队列时,会接着调用postDrainAudioQueue_l函数

上图代码发送了一个kWhatDrainAudioQueue

主要是有一个进行判断的onDrainAudioQueue函数,判断是否需要重新向AudioSink写入数据

到这里,这个音频播放流程如下:先打开音频后端,然后当向音频队列中发送数据,音频队列同时向音频后端写入数据,以供播放音频
视频显示的话,同样是在视频原始数据进入视频队列后,开始执行postDrainVideoQueue函数

这里先发送一个kWhatDrainVideoQueue的消息,然后进行音视频同步,发送消息后会出发调用onDrainVideoQueue

NuPlayer::Renderer使用的是以视频为基准的同步机制,解码后的音频数据时间戳如果大于视频数据时间戳,直接丢弃音频包,然后直接渲染视频。同步机制主要位于视频缓冲区处理部分的onDrainVideoQueue和音频缓冲区处理部分的onDrainVideoQueue中。音视频的渲染都采用类似定时器的机制,只不过视频显示需要依赖于实际解码器,音频播放需要依赖于AudioSink接口
版权声明
本文为[Panic Lin]所创,转载请带上原文链接,感谢
https://blog.csdn.net/PanicLin/article/details/124356518
边栏推荐
- [go]常见的并发模型[泛型版]
- Positioning of high precision welding manipulator
- js常用数组方法
- Smart business card applet business card details page function implementation key code
- php生成短链接:将数字转成字母,将字母转成数字
- Penetration test interview collection -- HVV---
- Implementation principle of instanceof
- 数据安全问题已成隐患,看vivo如何让“用户数据”重新披甲
- 怎么读书读论文
- QFileDialog 选择多个文件或文件夹
猜你喜欢

欧圣电气深交所上市:市值52亿 陆为东父女为美国籍
![[programming practice / embedded competition] learning record of embedded competition (I): establishment of TCP server and web interface](/img/f1/09de53509479a01098d3cf46bf48eb.jpg)
[programming practice / embedded competition] learning record of embedded competition (I): establishment of TCP server and web interface

The third divisor of leetcode simple question

谈谈那些基础但不简单的股票数据

青苹果影视系统源码 影视聚合 影视导航 影视点播网站源码

Ubuntu安装Mysql并查询平均成绩

Comparison of indoor positioning methods of several intelligent robots

Data security has become a hidden danger. Let's see how vivo can make "user data" armor again

Discussion on ES6 tail tune optimization

Why are there 1px problems? How?
随机推荐
Ignis公链的NFT生态发展:Unicorn.art的捐赠开发之路
The following program deletes n consecutive words starting from the ith character from the string str
php生成短链接:将数字转成字母,将字母转成数字
QFileDialog 选择多个文件或文件夹
Transformer-XL: Attentive Language ModelsBeyond a Fixed-Length Context 论文总结
Depth of binary tree
将实例化对象的方法 给新的对象用
Install MySQL for Ubuntu and query the average score
Qt编译QtXlsx库
万物互联下如何对设备进行加密
js常用数组方法
智能名片小程序名片详情页功能实现关键代码
Brief description of CPU
Fibula dynamic programming
Manipulator motion planning in 3C assembly
[effective go Chinese translation] part I
总线结构概述
ApplicationReadyEvent的使用
PHP generates short links: convert numbers to letters and letters to numbers
Ubuntu安装Mysql并查询平均成绩