前言
大家周末好,最近一个月打算专门学习播放器相关的内容,偏实战化,也算是把这段时间学习的一些基础知识,综合起来,不然一直搞理论,没有实战,提高不了多少,所学的东西,终究还是要用到实际当中去,才能产生它的价值;所以下面的这个月加油!
在6月的时候,出去面试的时候,发现了一些问题,于是乎,在下班之余在弥补一些不足之处:
今天先从ffplay开始分享我的播放器学习笔记之路:
FFplay框架分析:
在FFmpeg源码工程里面有一个源文件是ffplay.c,它是FFmpeg源码自带的播放器,调用FFmpeg和SDL API实现一个非常有用的播放器,我们经常逛的b站,它也有有一个开源项目ijkplayer就是基于ffplay.c进行二次开发的。
下面我们先来卡一下FFplay整体框架:
FFplay框架
1、播放器初始化:
-
初始化packet queue
-
初始化frame queue
-
初始化clock
2、线程的划分:
-
数据读取线程:
-
打开媒体文件
-
打开对应码流的decoder以及初始化对应的audio、video、subtitle(字幕)输出
-
创建decoder线程,audio、video和subtitle的解码线程独立
-
调用av_read_frame读取packet,并根据steam_index放入不同stream对应的packer队列
-
-
音视解码:
- 从packet queue读取packet,解出frame后放入frame queue
-
视频解码:
- 从packet queue读取packet,解出frame后放入frame queue
-
字幕解码:
- 从packet queue读取packet,解出frame后放入frame queue
-
音频播放(或者回调函数):
- 从frame queue读取frame进行播放
-
视频播放(ffplay目前是在main主线程进行视频播放):
- 从frame queue读取frame进行播放
-
字幕播放(ffplay目前是在main主线程进行字幕播放):
- 从frame queue读取frame进行播放
-
控制响应(播放、暂停、快进、快退等)(ffplay目前是在main主线程进行播放控制)
3、packet队列的设计:
-
线程安全、支持互斥、等待、唤醒
-
缓存数据大小
-
缓存包数
-
队列播放可持续时间
-
进队列、出队列
4、frame队列的设计:
-
线程的安全、支持互斥、等待、唤醒
-
缓存帧数
-
支持读取数据而不出队列
-
进队列、出队列
5、音视频同步:
-
音频同步
-
视频同步
-
外部时钟同步
6、音频处理:
-
音量调节
-
静音
-
重采样
7、视频处理:
-
图像格式转换YUV->RGB
-
图像缩放1280720(720p)->800480
8、播放器控制:
-
播放
-
暂停
-
停止
-
快进、快退
-
逐帧
-
静音
总结:
我是txp,我们下期见