ffmpeg的HEVC解碼源代碼分析(一)整體框架

通過調試ffmpeg對HEVC碼流(格式爲es流,就是rawvideo)的解碼過程,分析ffmpeg的HEVC解碼過程和實現方法。

首先要說的是調試所用的工程的config爲:./configure –disable-asm –disable-pthreads –enable-debug –disable-optimizations進行configure。

禁用了pthread,所以涉及到pthread的函數都不採用。

配置和編譯的詳細過程見文章《Linux環境下,用eclipse對ffmpeg源代碼進行調試》。

輸入爲HEVC的純碼流,輸出爲YUV文件。

開始調試,進入main函數後的函數調用關係如圖fig.A所示:


fig.A中大多數的步驟都是ffmpeg中各種codec通用的,不針對HEVC。

1.註冊變量和函數,通過一系列的函數順序實現,包括:avcodec_register_all(),avfilter_register_all,av_register_all等等。

2.ffmpeg_parse_options():深入分析輸入參數。對輸入輸出文件做分析。

爲什麼說深入呢?因爲這個函數做了很多工作:將用戶的命令行分解,打開輸入的碼流文件,並對碼流文件進行試解碼(調用函數try_decode_frame)以分析輸入碼流的特徵。所以運行完這個函數,ffmpeg已經可以確定輸入文件的文件類型,codec等等信息了。

3.transcode():字面意思是轉碼,就是將輸入文件轉成輸出文件的格式,對視頻來說就是一個解碼到YUV圖像,再進行編碼的過程,在本文中,輸出爲YUV,就不用再進行編碼了。

3.1:transcode_init():初始化,輸入輸出文件的各種配置,比如色彩空間,文件格式等等。

3.2:transcode_step()到process_init(): 開始轉碼,對本文來說就是解碼。

3.2.1:get_input_packet(),av_read_frame(),read_from_packet_buffer()函數,完成的任務就是從輸入碼流中讀入一個packet,將信息存放到結構體AVPacket(AVPacket的分析見《ffmpeg重要結構體之AVPacket》)。packet的含義我個人理解就是能解出一幀圖像的碼流單元。

舉個例子,對於HEVC,在某碼流開始時,前6個nal的類型依次爲:VPS,SPS,PPS,SEI,slice,slice.兩個slice的nal組成一幀,則第一個packet就由這6個nal組成。

3.2.2 :從process_input_packet()一直到avctx->codec->decode(),avctx->codec->decode()指向hevc_decode_frame(),正式進入到HEVC解碼部分。


fig.B從函數hevc_decode_frame()開始的函數調用關係。hevc_decode_frame()調用decode_nal_units(),逐個解析nalu。

1.ff_hevc_split_packet():這個函數將AVPacket分解爲一個個的nalu,並將每個nalu的信息存放的結構體HEVCContext的成員HEVCPacket pkt(見《ffmpeg重要結構體之HEVCContext和HEVCFrame》)中,舉個例子,一個packet中有10個nalu,ff_hevc_split_packet()會將這10個nalu的類型和長度都解析出來,並存好。

2.decode_nal_unit():此函數解碼一個nalu的碼流,根據nalu的類型調用不同的函數進行處理。

2.1:碼流解析:當nalu的類型爲VPS,PPS,SPS,或者SEI時,decode_nal_unit()調用相對應的解析函數進行處理。

這個步驟相對簡單,解析函數比如ff_hevc_decode_nal_sps(),基本上就是按照HEVC的標準,將碼流元素逐個讀入,並存放的過程。

2.2slice解碼:當nalu的類型爲slice的時候,會先調用hls_slice_header()函數,將slice header 的信息讀入,然後便是HEVC的slice解碼。

hevc_frame_start()和函數ff_hevc_slice_rpl()涉及到DPB(decoded picture buffer)管理和rpl(reference picture list)解析即應用,以後會展開討論。

hls_decode_entry()就是逐個解碼slice中的CTU(coding tree unit)了,在其他文章裏會繼續討論。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章