首先,讓我們來了解 FFmpeg 的高層級架構。

FFmpeg 由一組工具和函式庫組成。

這些工具可用於編碼/解碼/轉碼多種不同的音訊和視訊格式,以及在網路上串流編碼後的媒體。

這些函式庫則可用於將相同的功能整合到您自己的產品中。

FFmpeg 的基本用法是解封(demux)多媒體串流(從檔案或網路取得),將其分離為音訊和視訊串流,然後將這些串流解碼為原始音訊和原始視訊資料。

為了管理媒體串流,FFmpeg 使用以下結構:

解封和解碼的過程遵循以下邏輯:

以下是從檔案讀取編碼後的多媒體串流、分析其內容並解封音訊和視訊串流所需的基本程式碼。這些功能由 libavformat 函式庫提供,它使用 AVFormatContext 和 AVStream 結構來儲存資訊。

一旦我們從多媒體檔案中取得不同的串流,我們就需要找到特定的編解碼器(codec)來將串流解碼為原始音訊和原始視訊資料。所有編解碼器都已靜態包含在 libavcodec 中。您可以透過建立 FFCodec 結構的實例並將其註冊為 libavcodec/allcodecs.c 中的 extern const FFCodec 來輕鬆建立自己的編解碼器,但這將是另一篇文章的主題。

為了找到與 AVStream 內容對應的編解碼器,我們可以使用以下程式碼:

有了從 AVStream 資訊中提取的正確編解碼器和編解碼器參數後,我們現在可以配置 AVCodecContext 結構,該結構將用於解碼對應的串流。記住我們想要從先前的串流清單(format_context->streams)中解碼的串流索引非常重要,因為稍後將使用此索引來識別由 AVFormatContext 提取的解封封包。

在以下程式碼中,我們將選擇多媒體檔案中的第一個視訊串流。

現在我們有了正在運行的解碼器,我們可以利用 AVFormatContext 結構提取解封的封包,並將它們解碼為原始視訊訊框。為此,我們需要兩個不同的結構:

上述程式碼的運作方式總結在下圖中:

您可以從此處下載完整程式碼或直接存取程式碼儲存庫。

若要建置範例,您需要 meson 和 ninja。如果您已安裝 python 和 pip,可以透過呼叫 pip3 install meson ninja 來輕鬆安裝它們。然後,一旦將範例封存檔解壓縮到 ffmpeg-101 資料夾,請進入該資料夾並呼叫:meson setup build。它將自動下載正確版本的 FFmpeg,如果您尚未在系統上安裝它。然後呼叫:ninja -C build 來建置程式碼,並執行 ./build/ffmpeg-101 sample.mp4 來執行它。

您應該會得到以下結果: