最近领导让工作空闲之余对ijkplayer进行二次开发,在开发过程中,决定写一些关于播放器的博客,以便记录学习过程。
一般播放器的流程:
- streaming。这里包括下载和流媒体协议解析,这里重点就是控制下载缓存的ringbuffer。
- Demux。这里对容器进行音视频分离。
- Audio Decode & Video Decode。音视频解码。Android的解码最终都是通过OMX IL最终调用到芯片方案商的硬解。
- Audio render & Video render。音视频渲染。Audio render可以采用OpenSLES或者AudioTrack,AudioTrack最终通过AudioFlinger渲染。Video Render可以采用OpenGLES或者Surface(native层的surface即为ANativeWindow),底层最终用SurfaceFlinger渲染。
- AVSync。音视频同步,这个发生在音视频渲染之前。一般都是以audio pts为标准。一般逻辑为:如果audio frame 比video frame快,就丢掉video frame去追赶audio。如果audio frame比video frame慢,就调整底层video的渲染速度,这个时候看到的效果就是video慢放,而audio正常。
整个播放流程实际上就是一个buffer传递的过程,从最开始下载的缓存buffer到demux后的audio es buffer和video es buffer,以及decode之后的pcm buffer和YUV buffer。
后续以ijkplayer为例进行详细的分析一个播放器播放视频的过程。