昨天剛剛梳理了Hacker Guide/Decoder:如何做一個(gè)解碼器(VLC)浪秘,今天結(jié)合一個(gè)實(shí)際點(diǎn)的 vlc-h265 集成插件的項(xiàng)目看看猪落,試試能不能順利解讀一下新編解碼器集成的思路。
參考項(xiàng)目GitHub地址:strukturag / vlc-libde265靴患。
1 整體感知
先來(lái)看一下項(xiàng)目整體的文件結(jié)構(gòu),大致了解下項(xiàng)目里有哪些模塊:
首先是右側(cè)一堆文件夾(加星號(hào)的是 VLC 沒(méi)有的):
- *debian:Debian 系統(tǒng)配置文件
- include:頭文件的存放位置
- m4:宏處理器存放位置(開(kāi)始是空的涉瘾,編譯完就有了)
- *patches:補(bǔ)丁存放位置(這里是用于記錄修改的diff信息)
- src:一大堆的源文件(主要的地方)
然后是左側(cè)一堆文件(加星號(hào)的是 VLC 沒(méi)有的):
- *.travis.yml:travis的配置文件,用于持續(xù)集成
- Makefile.am:automake編譯用捷兰,類似Makefile
- *autogen.sh:auto編譯時(shí)使用的編譯腳本
- configure.ac:autoconf編譯用立叛,類似configure
- *prepare-package.sh:依賴和環(huán)境的準(zhǔn)備腳本
注:這里autogen的編譯流程我不太熟,但順序還是 ./configure => make => make install 贡茅,但感覺(jué)這樣在準(zhǔn)備編譯時(shí)文件更加簡(jiǎn)潔秘蛇,在編譯過(guò)程中生成Makefile等等,有更好的理解歡迎指教
2 慢慢開(kāi)始讀代碼
include 是頭文件存放的地方顶考,頭文件在邏輯方面有像目錄一樣的感覺(jué)赁还,所以頭文件或許是個(gè)不錯(cuò)的開(kāi)始。
include 中有兩個(gè)頭文件:
libde265_plugin_common.h:聲明了應(yīng)當(dāng)包含的文件和一些宏定義驹沿。嗯...好像并沒(méi)有得到太多的信息艘策,主要是解釋了 VLC_CODEC_HEVC 、 VLC_CODEC_HEV1 和 VLC_CODEC_SCTE_27 三個(gè)宏定義被聲明時(shí) VLC_FOURCC 傳入的參數(shù)區(qū)別渊季。
vlc_codecs.h:這是 vlc 自己的頭文件朋蔫,記錄著解復(fù)用和解碼器需要的一些數(shù)據(jù)結(jié)構(gòu)等信息。
頭文件并沒(méi)有給什么指引...所以還是回頭看看 Makefile.am 里有沒(méi)有什么好點(diǎn)的指示却汉。
Makefile.am 的書(shū)寫(xiě)有一個(gè)很好的規(guī)律驯妄,具體對(duì)文件的分析有點(diǎn)長(zhǎng),所以整理成了一個(gè)單獨(dú)的介紹:vlc-libde265 Makefile.am 試讀病涨。
從上面這篇試讀的過(guò)程中我們找到了 h265 插件各個(gè)功能實(shí)現(xiàn)過(guò)程中使用的具體文件富玷,那么下面就是對(duì)這些文件的解讀了。
3 仔仔細(xì)細(xì)讀代碼
3.1 解碼器——libde265_plugin
解碼器除了引用了必須要的 265 頭文件外既穆,核心代碼全部在 src/codec/libde265dec.c 中赎懦,所以想要了解自然要瞅瞅這個(gè)文件里有些啥。文件還是比較正常的幻工,加注釋才900行励两,但為了盡快理解還是先暫時(shí)忽略實(shí)現(xiàn),直接從結(jié)構(gòu)層面去感知一下:
- struct decoder_sys_t:h265 解碼模塊的各個(gè)描述符
- function vlc_module_begin:初始化模塊的各個(gè)描述符
- struct picture_ref_t:vlc 以265格式存儲(chǔ)圖片時(shí)的參考(結(jié)合下面兩個(gè)函數(shù))
- function ImageFormatToChroma:圖片格式轉(zhuǎn)換(mono/420/422/444)
- function GetVlcCodec:獲取 vlc 編解碼器(根據(jù)不同格式和參數(shù)返回)
- function SetDecodeRatio:設(shè)置解碼幀率
- function Decode:核心的解碼算法部分
- function ReleasePictureRef:釋放圖像的引用
- function GetPicture:創(chuàng)建一個(gè)可以直接用于渲染的vlc圖片
- function GetBuffer:libde265 創(chuàng)建圖像后的回調(diào)
- function ReleaseBuffer:釋放圖像后的回調(diào)
- function Open:解碼器探尋
- function Close:解碼器銷毀
3.2 解復(fù)用——libde265demux_plugin
- struct struct demux_sys_t:h265 插件使用的數(shù)據(jù)信息定義
- char[] extensions:支持的擴(kuò)展名
- function Demux:解復(fù)用的核心邏輯代碼
- function Control:控制
- function Close:釋放未被使用的數(shù)據(jù)
- function Peek:按照增量的大小提前查看數(shù)據(jù)
- function SearchStartcode:尋找下一個(gè) NAL 的起始位置
3.3 針對(duì)格式插件
h265 插件還專門提供了 mkv囊颅、mp4当悔、TS 格式的專門的解復(fù)用的邏輯,至于為什么...我想大概是 h265 編碼可能主要針對(duì)在這幾個(gè)封裝下的優(yōu)化與壓縮踢代,或者說(shuō)只有在 vlc 解讀這幾個(gè)格式的時(shí)候才會(huì)選擇 h265 編碼去進(jìn)行解碼盲憎,這樣的話其他格式使用其他編碼(h264之類的)的情況下制作 h265 插件就可以只關(guān)心這幾個(gè)封裝了。
4 與上一篇 Wiki 做個(gè)對(duì)比
上一篇文章 Hacker Guide/Decoder:如何做一個(gè)解碼器(VLC)主要是一邊翻譯一邊想入門一下編解碼器的書(shū)寫(xiě)思路胳挎,在這篇文章里提出的編碼器書(shū)寫(xiě)必須要實(shí)現(xiàn)的有以下幾個(gè)方面:
- 解碼器核心
- 對(duì)輸入流的獲取
- 數(shù)據(jù)包的定義及讀取
- 數(shù)據(jù)包的更改與對(duì)齊
- 運(yùn)動(dòng)補(bǔ)償?shù)暮瘮?shù)定義
- IDCT的函數(shù)定義
- 對(duì)稱多處理的選擇(可選)
總的來(lái)看這個(gè) h265 的項(xiàng)目基目前看到的實(shí)現(xiàn):解碼器的核心實(shí)現(xiàn)饼疙,數(shù)據(jù)包的定義及讀取。輸入流的校驗(yàn)及讀取在每個(gè)具體的封裝格式中實(shí)現(xiàn)慕爬。數(shù)據(jù)包的更改與對(duì)齊窑眯、運(yùn)動(dòng)補(bǔ)償?shù)暮瘮?shù)定義屏积、 IDCT的函數(shù)定義等實(shí)現(xiàn)可以仔細(xì)找找剩下那一堆格式的文件,然后選擇必要的去實(shí)現(xiàn)磅甩。