FFmpeg 中的多執行緒解碼

2022-10-08 21:39:24 字數 2554 閱讀 9023

ffmpeg 中使用到的多執行緒的概念:

互斥鎖(mutex-lock)是一種訊號量,用來防止兩個執行緒在同一時刻訪問相同的共享資源,它有鎖定狀態和非鎖定狀態。

在任意時刻,乙個執行緒要想訪問共享資料,執行緒必須首先獲得mutex-lock,當此執行緒釋放此共享資料的時候必須對mutex-lock解鎖,在乙個任意的時間內,只有乙個執行緒能鎖定互斥鎖,通過函式pthread_mutex_lock上鎖,通過函式pthread_mutex_unlock解鎖。

條件變數用來提供另一種執行緒同步的方法,其基於實際的變數值來實現執行緒的同步操作,設定了條件變數的情況下,執行緒就不需要通過不停的輪詢來查詢條件是否滿足,也不需要不停的忙等,從而能夠節省很多系統資源。

乙個條件變數總是和乙個mutex-lock對應,系統通過pthread_cond_await函式來阻塞呼叫的執行緒,一直到條件變數得到滿足。

當這個執行緒阻塞的時候對應的mutex-lock會自動解鎖,但當該執行緒執行的時候,其對應的mutex-lock會被加鎖。

使用函式pthread_cond_signal來喚醒等待在條件變數的另乙個執行緒,當用來喚醒多個處於阻塞狀態執行緒時通過pthread_cond_broadcast函式來完成。

thread list,執行緒列表,執行緒列表中的每一項都對映乙個解碼執行緒。

主線程會從執行緒列表中按照序號由小到大(迴圈)提取解碼執行緒,並把解碼任務提交到該解碼執行緒。

同時主線程在提交完解碼任務後也會從執行緒列表中按照序號由小到大(迴圈)提取解碼執行緒,並嘗試從該解碼執行緒獲取解碼完成的幀。

其中右側的frame_worker_thread為解碼執行緒,在open解碼器時就已經建立,隨後阻塞在pthread_cond_wait(&p->input_cond, &p->mutex)函式。等待被主線程喚醒。

當主線程執行到ff_thread_decode_frame函式時,會呼叫submit_packet函式,這個函式的目的就是將packet包交給解碼執行緒。

submit_packet函式會呼叫pthread_cond_signal(&p->input_cond)函式,這個函式就是為喚醒剛才阻塞的解碼執行緒。

當主線程喚醒解碼執行緒後,其pthread_cond_wait(&p->output_cond, &p->progress_mutex)函式會進入阻塞狀態,等待解碼執行緒喚醒。

如果codec未實現update_thread_context()和執行緒安全的get_buffer(),則必須在解碼完成後才能將狀態轉換為status_setup_finished,意味著下乙個執行緒只能在當前執行緒解碼完成後才能開始解碼。當解碼執行緒解碼完成後,會用pthread_cond_signal(&p->output_cond)將主線程喚醒,其中會通過**函式將解碼執行緒解碼出來的frame獲取,從而輸出。

2. 如果codec實現update_thread_context()和執行緒安全的get_buffer(),執行緒狀態可以在解碼開始之前轉換為status_setup_finished,這樣,主線程就能夠被喚醒,就能夠去讀包進行下乙個包的解碼,因此下乙個執行緒就可能與當前執行緒並行。

ffmpeg的slice級並行只能在幀內並行。

如果一幀,即乙個packet分為幾個slice時,會先把這一幀前面的slice加入佇列,到最後乙個slice時統一對這一幀的所有slice進行並行解碼。其中涉及到的關鍵要素如下:

slice context list,slice的上下文是slice context(ffmpeg中的變數為slice_ctx),如果一幀中有多個slice,那麼會把slice上下文組成乙個列表。前面所說的入佇列操作會對該列表進行填充以供後續解碼使用。

m,主線程,如單執行緒一樣的流程,從使用者呼叫解碼api一直執行到我們前面所說的入佇列,到最後乙個slice時會呼叫乙個入口函式啟動多執行緒解碼操作。在呼叫入口函式後,主線程參與的多執行緒解碼過程一共包含三個步驟:

通過傳送啟動訊息啟用其它正在等待的解碼執行緒。

在啟動多執行緒解碼後,主線程也會一同作為其中乙個執行緒進行slice的解碼。

最後等待所有執行緒完成任務後返回。

t,解碼執行緒,接收到主線程所發起的啟動訊息後,解碼執行緒會到slice context list去提取其中乙個slice context(原子操作),然後進行slice解碼。

FFMPEG多執行緒併發解碼的效率測試

ffmpeg為了提高解碼速度,可以使用多執行緒併發解碼,分為執行緒級併發解碼和片級併發程式設計。併發解碼需要解決多幀依賴問題。如同時對i幀和p幀解碼,p幀依賴於i幀,怎麼辦?ffmpeg採用演算法如下 1.每個執行緒在解碼完一行巨集塊後,更新解碼高度h1 2.b p幀解碼巨集塊時,需要把待解碼巨集塊...

ffmpeg 多執行緒測試結果

其實ffmpeg支援多執行緒轉碼,但是試驗下來效果並不是和想象中的好,測試結果貼下,以饗讀者 網上有個指令碼根據核數測 bin bash echo input num read num for i 1 i num i i 1 do time ffmpeg y threads i i in.mp4 s...

FFmpeg的使用過程 解碼

1.引用標頭檔案 extern c 的解釋,c 支援函式的過載,面向過程的c語言不支援函式過載的。同乙個函式在c 中編譯後與在c中編譯後,在符號表中的簽名時不同的,假設針對同乙個函式,void decode float position,float duration 在c語言中編譯的簽名是 deco...