關於FFMPEG的解碼模型

波波敲程式碼發表於2020-12-19

關於FFMPEG的解碼模型

FFMPEG程式碼量很大,所以如果只是看程式碼必然容易從入門到放棄,為了更好的瞭解這座寶庫,我選擇了gdb除錯ffmpeg_g的方式。從實際的效果看,確實能夠比較清晰的順利整個FFMPEG的脈絡。這次我想了解的是ffmpeg到底是如何將h264碼流解碼成yuv的,選用的測試命令如下:

./ffmpeg_g -i test.h264  -vcodec rawvideo -an out.yuv

在這裡插入圖片描述
外部通過avcodec_send_packet呼叫,將需要解碼的pkt包提交給後臺的解碼執行緒,後臺解碼執行緒再呼叫h264解碼回撥函式進行解碼。

解碼執行緒的建立

使用gdb工具,在解碼回撥h264_decode_frame設定斷點,可以得到如下呼叫堆疊。
在這裡插入圖片描述
可以確定,這是一個專門用於解碼的執行緒,從程式碼中索引執行緒工作回撥函式frame_worker_thread,只有建立它的時候有呼叫。
在這裡插入圖片描述
在此行再設定斷點,我們可以知道到底是誰建立了它,以及什麼時候建立的。
在這裡插入圖片描述
從堆疊看就是在呼叫avcodec_open2開啟解碼器的時候,ffmpeg就已經為我們構建瞭解碼模型!

推包

這一部分講一講ffmpeg是如何將包推送給後臺執行緒的。我們注意觀察解碼執行緒,看看它到底是如何接收外界包的
在這裡插入圖片描述
很明顯,外界是將資料裝載到了PerThreadContext::avpkt這個變數中,對於PerThreadContext,我們先按下不表,只需瞭解它就是一個執行緒結構體物件罷了,裝載了各種執行緒所需的資料,包括外界給它的包。換言之,只需按圖索驥跟蹤這個變數,就可以知道是誰,通過什麼樣的方式給它傳資料的。經過一番折騰,我確實找到了一個地方

在這裡插入圖片描述
為了確認,在此處設定斷點,ffmpeg確實在不斷的呼叫此函式推包。而最外層API函式正是我們常用的avcodec_send_packet。
在這裡插入圖片描述

相關文章