昨天刚刚梳理了Hacker Guide/Decoder:如何做一个解码器(VLC),今天结合一个实际点的 vlc-h265 集成插件的项目看看,试试能不能顺利解读一下新编解码器集成的思路。
参考项目GitHub地址:strukturag / vlc-libde265。
1 整体感知
先来看一下项目整体的文件结构,大致了解下项目里有哪些模块:
项目文件结构(git及copyright略)
首先是右侧一堆文件夹(加星号的是 VLC 没有的):
- *debian:Debian 系统配置文件
- include:头文件的存放位置
- m4:宏处理器存放位置(开始是空的,编译完就有了)
- *patches:补丁存放位置(这里是用于记录修改的diff信息)
- src:一大堆的源文件(主要的地方)
然后是左侧一堆文件(加星号的是 VLC 没有的):
- *.travis.yml:travis的配置文件,用于持续集成
- Makefile.am:automake编译用,类似Makefile
- *autogen.sh:auto编译时使用的编译脚本
- configure.ac:autoconf编译用,类似configure
- *prepare-package.sh:依赖和环境的准备脚本
注:这里autogen的编译流程我不太熟,但顺序还是 ./configure => make => make install ,但感觉这样在准备编译时文件更加简洁,在编译过程中生成Makefile等等,有更好的理解欢迎指教
2 慢慢开始读代码
include 是头文件存放的地方,头文件在逻辑方面有像目录一样的感觉,所以头文件或许是个不错的开始。
include 中有两个头文件:
-
libde265_plugin_common.h:声明了应当包含的文件和一些宏定义。嗯...好像并没有得到太多的信息,主要是解释了 VLC_CODEC_HEVC 、 VLC_CODEC_HEV1 和 VLC_CODEC_SCTE_27 三个宏定义被声明时 VLC_FOURCC 传入的参数区别。
-
vlc_codecs.h:这是 vlc 自己的头文件,记录着解复用和解码器需要的一些数据结构等信息。
头文件并没有给什么指引...所以还是回头看看 Makefile.am 里有没有什么好点的指示。
Makefile.am 的书写有一个很好的规律,具体对文件的分析有点长,所以整理成了一个单独的介绍:vlc-libde265 Makefile.am 试读。
从上面这篇试读的过程中我们找到了 h265 插件各个功能实现过程中使用的具体文件,那么下面就是对这些文件的解读了。
3 仔仔细细读代码
3.1 解码器——libde265_plugin
解码器除了引用了必须要的 265 头文件外,核心代码全部在 src/codec/libde265dec.c 中,所以想要了解自然要瞅瞅这个文件里有些啥。文件还是比较正常的,加注释才900行,但为了尽快理解还是先暂时忽略实现,直接从结构层面去感知一下:
- struct decoder_sys_t:h265 解码模块的各个描述符
- function vlc_module_begin:初始化模块的各个描述符
- struct picture_ref_t:vlc 以265格式存储图片时的参考(结合下面两个函数)
- function ImageFormatToChroma:图片格式转换(mono/420/422/444)
- function GetVlcCodec:获取 vlc 编解码器(根据不同格式和参数返回)
- function SetDecodeRatio:设置解码帧率
- function Decode:核心的解码算法部分
- function ReleasePictureRef:释放图像的引用
- function GetPicture:创建一个可以直接用于渲染的vlc图片
- function GetBuffer:libde265 创建图像后的回调
- function ReleaseBuffer:释放图像后的回调
- function Open:解码器探寻
- function Close:解码器销毁
3.2 解复用——libde265demux_plugin
- struct struct demux_sys_t:h265 插件使用的数据信息定义
- char[] extensions:支持的扩展名
- function Demux:解复用的核心逻辑代码
- function Control:控制
- function Close:释放未被使用的数据
- function Peek:按照增量的大小提前查看数据
- function SearchStartcode:寻找下一个 NAL 的起始位置
3.3 针对格式插件
h265 插件还专门提供了 mkv、mp4、TS 格式的专门的解复用的逻辑,至于为什么...我想大概是 h265 编码可能主要针对在这几个封装下的优化与压缩,或者说只有在 vlc 解读这几个格式的时候才会选择 h265 编码去进行解码,这样的话其他格式使用其他编码(h264之类的)的情况下制作 h265 插件就可以只关心这几个封装了。
4 与上一篇 Wiki 做个对比
上一篇文章 Hacker Guide/Decoder:如何做一个解码器(VLC)主要是一边翻译一边想入门一下编解码器的书写思路,在这篇文章里提出的编码器书写必须要实现的有以下几个方面:
- 解码器核心
- 对输入流的获取
- 数据包的定义及读取
- 数据包的更改与对齐
- 运动补偿的函数定义
- IDCT的函数定义
- 对称多处理的选择(可选)
总的来看这个 h265 的项目基目前看到的实现:解码器的核心实现,数据包的定义及读取。输入流的校验及读取在每个具体的封装格式中实现。数据包的更改与对齐、运动补偿的函数定义、 IDCT的函数定义等实现可以仔细找找剩下那一堆格式的文件,然后选择必要的去实现。
网友评论