概述
ffplay文件概览
libavcodec
- allcodecs.c 简单的注册类函数
- avcodec.h 编解码相关结构定义和函数原型声明
- dsputil.c 限幅数组初始化
- dsputil.h 限幅数组声明
- imgconvert.c 颜色空间转换相关函数实现
- imgconvert_template.h 颜色空间转换相关结构体定义和函数实现
- msrle.c 视频RLE行程长度压缩算法解码库
- truespeech.c 语音TrueSpeech算法解码库
- truespeech_data.h 语音TrueSpeech算法解码常量数组
- utils_codec.c 一些解码相关的工具类函数的实现
libavformat
- allformats.c 简单注册类函数
- avformat.h 文件和媒体格式相关结构体定义和函数原型声明
- avidec.c AVI文件解析类函数
- avio.c 无缓冲数据IO相关函数实现
- avio.h 无缓冲数据IO相关结构体定义和函数实现
- aviobuf.c 有缓冲数据IO相关函数实现
- cutils.c 两个简单的字符串操作函数
- file.c 文件IO相关函数
- utils_format.c 文件和媒体格式相关的工具类函数的实现
libavutil
- avutil.h 简单的像素格式宏定义
- bswap.h 简单的大小端转换函数的实现
- common.h 公共的宏定义和简单函数的实现
- mathematics.h 一个简单的数学运算函数(A*B/C)
- rational.h 用两整数表示分数相关函数
berrno.h 错误码定义
ffplay.c 总控文件
播放器一般原理
七个模块按广度顺序:读文件模块、解复用模块、视频解码模块、音频解码音频、颜色空间转换模块、视频显示模块,音频播放模块。
播放器有关的filter粗略的分为五类,分别是SourceFilter,DemuxFilter,DecoderFilter,ColorSpaceConverterFilter, RenderFilter。
SourceFilter源过滤器的作用是为下级DemuxFilter以包的形式源源不断的提供数据流。在通常情况下,我们有多种方式可以获得数据流,一种是从本地文件中读取,一种是从网上获取,SourceFilter另外一个作用就是屏蔽读本地文件和获取网络数据的差别,在下一级的DemuxFilter看来,本地文件和网络数据是一样的。
DemuxFilter解复用过滤器的作用是识别文件类型,媒体类型,分离出各媒体原始数据流,打上时钟信息后送给下级DecodeFilter。为识别出不同的文件类型和媒体类型,常规的做法是读取一部分数据,然后遍历解复用过滤器支持的文件格式和媒体数据格式,做匹配来确定是哪种文件类型,哪种媒体类型;有些媒体类型的原始数据外面还有其他的信息,比如时间、包大小、是否完整包等等。DemuxFilter解析数据包后取出原始数据,有些类型的媒体不管是否是完整包都立即送往下级DecodeFilter,有些类型的媒体要送完整数据包,此时可能有一些数据包拼接的动作;当然时钟信息的计算也是DemuxFilter的工作内容,这个时钟用于各媒体之间的同步。在本例中,AVISplitter是DemuxFilter。
DecoderFilter解码过滤器的作用就是解码数据包,并且把同步时钟信息传递下去。对视频媒体而言,通常是解码成YUV数据,然后利用显卡硬件直接支持YUV格式数据Overlay快速显示的特性让显卡极速显示。YUV格式是一个统称,常见的有YV12、YUY2,UYVY等等。有些非常古老的显卡和嵌入式系统不支持YUV数据显示,那就要转换成RGB格式的数据,每一帧的每一个像素点都要转换,分别计算RGB分量,并且因为转换是浮点运算,虽然有定点算法,还是要耗掉相当一部分CPU,总体上效率底下;对音频媒体而言,通常是解码成PCM数据,然后送给声卡直接输出。在本例中,AVI Decompress和ACM Warper是DecoderFilter。
ColorSpaceConverterFilter颜色空间转换过滤器的作用是把视频解码器解码出来的数据转换成当前显示系统支持的颜色格式。通常视频解码器解码出来的是YUV数据,PC系统是直接支持YUV格式的,也支持RGB格式,有些嵌入式系统只支持RGB格式的。在本例中,视频解码器出来的是RGB8格式的数据,ColorSpaceConverterFilter把RGB8转换成RGB32显示。
RenderFilter渲染过滤器的作用就是在适当的时间渲染相应的媒体,对视频媒体就是直接显示图像,对音频就是播放声音。视音频同步的策略方法有好几种,其中最简单的一种就是默认视频和音频基准时间相同,这时音频可以不打时钟信息,通过计算音频的采样频率,量化bit数,声道数等基本参数就知道音频PCM的数据速率,按照这个速率往前播放即可;视频必须要使用同步时钟信息来决定什么时候显示。DirectShow采用一个有序链表,把接收到的数据包放进有序链表中,启动一个定时器,每次定时器时间到就扫描链表,比较时钟信息,或者显示相应的帧,或者什么也不做,每次接收到新的数据帧,首先判断时钟信息,如果是历史数据帧就丢弃,如果是将来显示数据帧就进有序链表,如果当前时间帧就直接显示。如此这样,保持视频和音频在人体感觉误差范围内相对的动态同步。在本例中VideoRendeDirectSoundDevice是RenderFilter,同时也是SinkFilter。
GraphEdit应用程序可以看成是一个支撑平台,支撑框架。它容纳各种Filter,在Filter间的传递一些通讯消息,控制Filter的运行(启动暂停停止),维护Filter运行状态。GraphEdit就像超级大管家一样,既维护管理看得见的Filter,又维护管理看不见的运行支撑环境。