FFmpeg使用很久了,一直沒有認真看過FFmpeg内部源碼所提供的各種機制和功能。本文的主要目标是能夠初步總結FFmpeg的avutil中所提供的功能。
從FFmpeg官網的文檔-libavutil來看,avutil主要有一下幾種功能(順序做了重排):
數學函數
字元串操作
記憶體管理相關
資料結構相關
錯誤碼及錯誤處理
日志輸出
其他輔助資訊,比如密鑰、哈希值、宏、庫版本、常量等
本文将逐個介紹比較avutil所提供的比較常用的函數。
注意本文編寫時ffmpeg版本為3.3
顧名思義,這部分主要提供與基本數學概念相關的功能,友善數學調用及處理。
有理數的定義如下
近似取值的枚舉值<code>enum AVRounding</code>:
enumerator
value
description
AV_ROUND_ZERO
向零取整
AV_ROUND_INF
1
向非零取整
AV_ROUND_DOWN
2
向負無窮取整
AV_ROUND_UP
3
向正無窮取整
AV_ROUND_NEAR_INF
5
向無窮取整,包含中點位置
AV_ROUND_PASS_MINMAX
8192
透傳INT64_MIN/MAX,避免出現AV_NOPTS_VALUE
其他數學函數如下:
字元串相關函數主要涉及在代碼中的字元串操作邏輯。
其中定義了如下宏:
定義的宏有:
Enumerator
AV_ESCAPE_MODE_AUTO
使用自動選擇的反轉移模式
AV_ESCAPE_MODE_BACKSLASH
使用反斜杠轉譯
AV_ESCAPE_MODE_QUOTE
使用單引号轉譯
支援的接口如下:
記憶體管理相關函數主要涉及堆管理。其中堆函數包括:
avutil中的資料結構包括:
AVBuffer是一系列支援引用計數的資料緩沖的API集合。
其中定義了如下結構體
提供了以下函數:
AVBufferPool是一個由AVBuffer構成的、沒有線程鎖的、線程安全的緩沖池。頻繁的配置設定和釋放大量記憶體緩沖區效率可能會較低。AVBufferPool主要解決使用者需要使用同樣長度的緩沖區的情況(比如,原始音視訊幀)。
在開始使用者可以調用av_buffer_pool_init來建立緩沖池。然後在任何時間都可以調用av_buffer_pool_get()來獲得buffer,在該buffer的引用計數為0時,将會傳回給緩沖池,這樣就可以被循環使用了。
在使用者使用完緩沖池之後可以調用av_buffer_pool_uninit()來釋放緩沖池。
其中提供的函數包括:
AVFrame是對原始多媒體資料的一個基于引用計數的抽象,比較常用的是音頻幀和視訊幀。這裡不給出AVFrame的定義了,有興趣的可以參考libavutil/frame.h。
AVFrame必須使用av_frame_alloc()函數進行配置設定。需要注意的是該函數僅僅常見AVFrame本身,AVFrame中的資料緩沖必須通過其他方式管理。AVFrame必須使用av_frame_free()函數釋放。
AVFrame通常是配置設定一次,然後用于存放不同的資料,例如AVFrame可以儲存從decoder中解碼出來的資料。在這種情況下 av_frame_unref()将釋放所有由frame添加的引用計數并将其重置為初始值。
AVFrame中的資料通常基于AVBuffer API提供的引用計數機制。其中的引用計數是儲存在AVFrame.buf/AVFrame.extended_buf中的。
sizeof(AVFrame)并不是公開API的一部分,以保證AVFrame中新添加成員之後可以正常運作。
AVFrame中的成員可以通過AVOptions通路,使用其對應的名稱字元串即可。AVFrame的AVClass可以通過avcodec_get_frame_class()函數獲得。
它提供的主要函數包括:
AVOptions提供了通用的option設定和擷取機制,可适用于任意struct(通常要求該結構體的第一個成員必須是AVClass指針,該AVClass.options必須指向一個AVOptions的靜态數組,以NULL作為結束)。後續會詳細介紹其中原理,這裡隻整理ffmpeg針對AVOptions所提供的函數。
Option設定函數-set
Option擷取函數-get
結構體定義
支援的宏和枚舉值
支援的函數如下:
一個簡單的鍵值對的字典集。其中公開的隻有以下結構
支援宏如下:
name
desc
AV_DICT_MATCH_CASE
大小寫完全比對的key檢索
AV_DICT_IGNORE_SUFFIX
忽略字尾
AV_DICT_DONT_STRDUP_KEY
4
不複制key
AV_DICT_DONT_STRDUP_VAL
8
不複制value
AV_DICT_DONT_OVERWRITE
16
不要覆寫原有值
AV_DICT_APPEND
32
如果存在,則添加
AV_DICT_MULTIKEY
64
支援多重鍵值
函數如下:
低複雜度的樹容器。插入、删除、查找等常用操作都是O(log n)複雜度的實作版本。
提供以下接口:
這部分主要提供統一的錯誤處理邏輯,可以參考下。其中提供機制如下:
宏
函數包括
日志子產品主要提供日志輸出的相關接口和宏,通過這些接口外部可以完全控制ffmpeg所有的日志輸出。
其中定義的宏如下:
AV_LOG_QUIET
-8
無任何日志輸出
AV_LOG_PANIC
發生無法處理的錯誤,程式将崩潰
AV_LOG_FATAL
發生無法恢複的錯誤,例如特定格式的檔案頭沒找到
AV_LOG_ERROR
發生錯誤,無法無損恢複,但是對後續運作無影響
AV_LOG_WARNING
24
警告資訊,有些部分不太正确,可能會也可能不會導緻問題
AV_LOG_INFO
标準資訊輸出,通常可以使用這個
AV_LOG_VERBOSE
40
詳細資訊,通常比較多,頻繁輸出那種
AV_LOG_DEBUG
48
僅用于libav*開發者使用的标志
AV_LOG_TRACE
56
特别繁瑣的調試資訊,僅用在libav*開發中
支援的函數接口有:
包括密鑰、哈希值、宏、庫版本、常量等。
FFmpeg支援AES、Base64、blowfish等常用的密鑰算法,hash函數支援CRC、MD5、SHA、SHA-512等。
字元串處理宏
庫版本宏
函數有
時間戳相關的常量宏
同時額外定義了以下結構:
最後一部分是關于AVPicture的用法說明,其中包括像素采樣格式、基本圖像平面操作等。
枚舉量有:
函數有:
到此,本文簡單的整理了下FFmpeg中libavutil所提供的主要函數和常量,僅僅是為了整理了解,如果大家需要檢視具體文檔,建議使用FFmpeg官網的doxygen生成的标準文檔。
整理本文的目的隻是為了加強記憶。後續會介紹下AVOption、AVLog、AVBuffer的實作細節。
參考ffmpeg-doxygen