二、FFmpeg的模組結構

Mirs發表於2019-04-10

[TOC]

開始前的BB

我發現 很多都是上來直接擼,擼完了發現其實還是什麼都不會,自己知道ffmpeg有什麼自帶的東西可以參考的也不瞭解,那還搞個?,,腦海中沒有大體的認知,很容易就迷失在細節裡無法自拔,只知其術不知其道理,緊接著下一個階段就是找大佬萌新三連

二、FFmpeg的模組結構

不要慌

這篇文章主要就是給大家一個大體的認知,來認識FFmpeg這個框架,由表及裡,由淺入深,解開她神祕的面紗

二、FFmpeg的模組結構

FFmpeg框架的結構

祖傳ffmpeg結構圖鎮樓

FFmpeg結構

其中 ffplay ffmpeg ffprobe 這三個是ffmpeg裡面的能編譯為可執行檔案的三個功能很強大的東西,這個在我們上面下載的動態庫/靜態庫檔案裡的

二、FFmpeg的模組結構

  • ffplay: ffplay是一個非常經典的播放器實現,對於做播放器的朋友,寫播放器的時候一定要要去參考,像ijkplayer 就是基於ffplay,同步等地方改動的很少,大部分改動都在顯示的部分,主要是實現瞭解碼後的yuv資料上傳到opengles,以及封裝音訊播放的介面(AudioTrack)等。

  • ffmpeg: ffmpeg這個工具裡面包含了很多功能,像軌道提取,視訊裁剪,轉碼、水印、濾鏡等功能

  • ffprobe: ffprobe是一個檢視視訊格式資訊的工具,包括封裝資訊、視訊資訊、音訊資訊等

以上三個工具我們下章講他一些常用的命令。

底層支撐庫簡介

除了這三個工具類外,底層的組成部分有以下幾個:

avutil

avutil 核心的工具庫;其他的模組都會依賴這個庫,定義了一些常用的列舉,工具類(加解密、時間、日誌,FIFO佇列、記憶體分配、大小端轉換等)

avformat

avformat 協議與格式庫; 這個模組封裝了Protocol、Demuxer、Muxer層,是ffmpeg最重要的模組之一,相當於Android中的 MediaExtracotor

avcodec

avcodec 編解碼庫;封裝了Codec,該模組內建很多解碼器,在自己的註冊列表中,一些有自己的License的第三方Codec,比如X264.fdk-aac等都可以通過外掛的方式新增進來

avfilter

avfilter 音視訊濾鏡庫;提供了很多音訊與視訊特效處理,可以在編解碼過程中直接呼叫該模組為音視訊資料做特效處理,這個處理是利用CPU進行處理的,音訊的處理一般都是比較快,影響不是特別的大 視訊的處理的,,效率是沒有利用OpenGL通過GPU進行處理快

avdevice

avdevice 輸入輸出裝置庫; 比如,需要編譯出播放聲音或者視訊的ffplay,就需要確保此模組是開啟狀態,同時也需要SDL庫的預編譯,這個裝置模組的播放聲音與播放視訊使用的都是SDL庫,也包含了其他的輸入/輸出裝置

swresample

swresample 音訊衝取樣模組;可以對數字音訊進行聲道數、取樣率、位寬等多種基本資訊的轉換,比如將SimpleForamt為AV_SAMPLE_FMT_FLTP轉換為AV_SAMPLE_FMT_S16P格式的

swscale

swscale 影象資料格式轉換模組; 比如可以將YUV資料轉換為RGB資料,尺寸從1920 * 1080 縮放為 800 * 480

postproc

postproc avfilter的處理會依賴該模組的一些函式

常用資料結構

  • AVFormatContext 封裝格式上下文結構體,儲存了視訊檔案封裝格式相關資訊
  • AVInputFormat demuxer結構體,每一種封裝格式對應一個該結構體(FLV MKV MP4 AVI) AVOutpuFormat 對應muxer
  • AVStream 媒體檔案中每個視訊/音訊流對應一個該結構體
  • AVCodecContext 編解碼器上下文結構,儲存了飲品是編解碼相關的資訊
  • AVCodec每個視訊/音訊編解碼器對應一個結構體
  • AVPacket 儲存街鳳凰後的一幀壓縮編碼資料
  • AVFrame 儲存一陣解碼後的畫素/取樣資料

常用核心函式

主要講 avformatavcodc兩個庫的比較重要的函式

avformat

  • avformat_network_init() 註冊網路,初始化網路庫以及網路加密協議相關的庫 (openssl)
  • avformat_alloc_context() 負責申請一個AvFormatContext結構的記憶體,並進行簡單的初始化
  • avforamt_free_context() 釋放該結構體裡的所有東西,以及他本身 ,通常與avformat_alloc_context()成對出現
  • avformat_close_input() 關閉解複用器,關閉後就不需要呼叫avforamt_free_context()進行釋放,因為他內部會呼叫avformat_free_context()方法進行釋放
  • avformat_open_input() 開啟輸入檔案
  • avformat_find_stream_info()獲取視訊檔案資訊
  • av_read_frame() 讀取音視訊包AVPacket
  • avformat_seek_file() 通過檔案位元組進行Seek
  • av_seek_frame() 可以通過相應的格式選擇Seek到關鍵幀還是指定幀以及位元組

解複用的呼叫流程如下

二、FFmpeg的模組結構

  1. 分配一個AVFormatContext的上下文
  2. 開啟視訊檔案
  3. 尋找到對應的流資訊
  4. 迴圈讀取流/或者在中間seek到指定的位置
  5. 結束讀取,關閉流,釋放空間

更詳細的程式碼會在後面的章節中有示例程式碼

avcodec

  • avcodec_alloc_context3() 分配解碼器的上下文
  • avcodec_find_decoder() 根據Id查詢解碼器
  • avcodec_find_decoder_by_name() 根據解碼器名字查詢解碼器
  • avcodec_open2() 開啟編解碼器
  • avcodec_send_packet() 傳送解封裝後的資料包
  • avcodec_recive_frame() 接受解碼後的資料
  • avcodec_free_context() 釋放解碼器上下文
  • avcodec_close()關閉解碼器

解碼器的呼叫流程如下

二、FFmpeg的模組結構

  1. 分配一個AVCodecContext
  2. 將AVStream裡的Codec的引數傳遞到AVCodecContext
  3. 根據Id或者名字尋找的相應的解碼器
  4. 開啟解碼器
  5. 傳送AVPacket(解封裝的資料) ---> 接受到解碼後的資料(YUV/PCM)
  6. 關閉解碼器,釋放AVCodecContext

關於FFmpeg的核心的結構體與函式,以及相應的解複用/解碼的流程先了解這麼多,有個大概的印象,我們在後面的文章裡,就會慢慢體會到他們帶來的無窮快感

二、FFmpeg的模組結構

一袋米要抗幾樓 (痛みを感じるようにしましょう) 的佩恩警告⚠️ (づ。◕‿‿◕。)づ

未完持續。。。

相關文章