[TOC]
開始前的BB
我發現 很多都是上來直接擼,擼完了發現其實還是什麼都不會,自己知道ffmpeg有什麼自帶的東西可以參考的也不瞭解,那還搞個?,,腦海中沒有大體的認知,很容易就迷失在細節裡無法自拔,只知其術不知其道理,緊接著下一個階段就是找大佬萌新三連
不要慌
這篇文章主要就是給大家一個大體的認知,來認識FFmpeg這個框架,由表及裡,由淺入深,解開她神祕的面紗
FFmpeg框架的結構
祖傳ffmpeg結構圖鎮樓
其中 ffplay ffmpeg ffprobe 這三個是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
對應muxerAVStream
媒體檔案中每個視訊/音訊流對應一個該結構體AVCodecContext
編解碼器上下文結構,儲存了飲品是編解碼相關的資訊AVCodec
每個視訊/音訊編解碼器對應一個結構體AVPacket
儲存街鳳凰後的一幀壓縮編碼資料AVFrame
儲存一陣解碼後的畫素/取樣資料
常用核心函式
主要講 avformat
和avcodc
兩個庫的比較重要的函式
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()
讀取音視訊包AVPacketavformat_seek_file()
通過檔案位元組進行Seekav_seek_frame()
可以通過相應的格式選擇Seek到關鍵幀還是指定幀以及位元組
解複用的呼叫流程如下
- 分配一個AVFormatContext的上下文
- 開啟視訊檔案
- 尋找到對應的流資訊
- 迴圈讀取流/或者在中間seek到指定的位置
- 結束讀取,關閉流,釋放空間
更詳細的程式碼會在後面的章節中有示例程式碼
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()
關閉解碼器
解碼器的呼叫流程如下
- 分配一個AVCodecContext
- 將AVStream裡的Codec的引數傳遞到AVCodecContext
- 根據Id或者名字尋找的相應的解碼器
- 開啟解碼器
- 傳送AVPacket(解封裝的資料) ---> 接受到解碼後的資料(YUV/PCM)
- 關閉解碼器,釋放AVCodecContext
關於FFmpeg的核心的結構體與函式,以及相應的解複用/解碼的流程先了解這麼多,有個大概的印象,我們在後面的文章裡,就會慢慢體會到他們帶來的無窮快感
一袋米要抗幾樓 (痛みを感じるようにしましょう) 的佩恩警告⚠️ (づ。◕‿‿◕。)づ
未完持續。。。