天天看點

FFmpeg libavutil主要功能概述

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