第一次写blog,只是为了记下学习的过程。android中东西很多,架构和流程都很复杂,经常发现以前学习过的很多东西,即使当时看明白没多久就忘记了,只能重新拾起再看。
于是想起blog这个东东,写下来总不会忘记,也和别人一起共享。
以下基于android 4.4 KK简单地描述下流媒体的渲染过程,第一次写没有太多经验,主要涉及到的模块有nuplayer, nuplayerrenderer等
1 NuPlayer.cpp 中的 onMessageReceived,这是nuplayer的消息处理逻辑,其中有
-->消息处理逻辑: what == ACodec::kWhatDrainThisBuffer //从OMX DL层来的消息,ACodec间接转发,解码已经完成,让IL取走解码数据,就是拿去显示
-->这个消息里调用 :renderBuffer(audio, codecRequest); //调用nuplayer中的渲染函数renderBuffer
2 renderBuffer ,进行一些简单检查,当前是否合适去显示
-->调用render的queueBuffer
3 NuplayerRenderer::queueBuffer
-->简单地封装一个kWhatQueueBuffer消息并发送
4 在renderer中的onMessageReceived中接收kWhatQueueBuffer消息
-->调用onQueueBuffer函数
5 onQueueBuffer函数
-->核心就是根据发送来的消息是audio还是video,进行对应的处理。如果是audio就把当前ABuffer放进audio队列,video就把ABuffer放进video 队列
这里主要关心的是video,所以关注postDrainVideoQueue函数
6 postDrainVideoQueue函数
-->主要就是封装kWhatDrainVideoQueue消息并发送,包括了一些额外处理
7 在onMessageReceived中处理kWhatDrainVideoQueue
-->调用onDrainVideoQueue函数,真正的处理函数
-->调用postDrainVideoQueue函数,再次post,形成一个循环,直到处理结束?
8 onDrainVideoQueue函数
--> 调用 mSoftRenderer->render,使用software render去渲染图像,渲染过程就是把数据拷贝到native window中的过程
-->这个函数里面会做一些判断,如果当前需要渲染的帧已经落后音频太多,则把当前帧做丢弃处理。这时候屏幕上就看到不连续的画面了,俗称掉帧。
9 Software Renderer
-->这个里面逻辑不是太多,就是一些简单地判断当前视频数据的格式,然后做一些转换,转换成native win或者平台能够支持的格式 ,然后拷贝到native window。这里面有关stride的东西一直没完全弄懂,尤其是那个c_stride,c_size。我知道stride是像素宽度对齐到4、8、16边界后的值,但是源码里的c_stride, c_size实在没弄明白,有明白的请帮忙解释一二。