一、通用API
1.1 av_register_all()
初始化 libavformat 和注冊所有的復用器、解復用器和協議處理器。如果不調用這個函數,可以調用下面的三個函數來選擇支持的格式。
- 注冊復用器的函數是
av_register_output_format()。 - 注冊解復用器的函數是
av_register_input_format()。 - 注冊協議處理器的函數是
ffurl_register_protocol()。
注:FFmpeg4.0 以上的版本,這個函數已經被廢棄。
1.2 內存的分配和釋放(av_malloc()、av_free()等)
av_malloc() 和 av_free() 都是簡單的封裝了系統函數 malloc() 和free(),並做了一些錯誤檢查工作。同理的還有 av_realloc()。
1.3 avcodec_find_encoder() 和 avcodec_find_decoder()
avcodec_find_encoder() 用於查找 FFmpeg 的編碼器,avcodec_find_decoder() 用於查找 FFmpeg 的解碼器,聲明都位於 libavcodec\avcodec.h。其原型如下:
// 函數的參數是一個編碼器的ID,返回查找到的編碼器(沒有找到就返回NULL)。
AVCodec *avcodec_find_encoder(enum AVCodecID id);
// 函數的參數是一個解碼器的ID,返回查找到的解碼器(沒有找到就返回NULL)。
AVCodec *avcodec_find_decoder(enum AVCodecID id);
1.4 avcodec_open2()
用於初始化一個視音頻編解碼器的 AVCodecContext,聲明位於 libavcodec\utils.c。其原型如下:
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
- avctx:需要初始化的 AVCodecContext。
- codec:輸入的AVCodec。
- options:一些選項。例如使用libx264編碼的時候,“preset”,“tune”等都可以通過該參數設置。
1.5 avcodec_close()
用於關閉編碼器,聲明位於 libavcodec\utils.c。其原型如下:
int avcodec_close(AVCodecContext *avctx)
該函數只有一個參數,就是需要關閉的編碼器的 AVCodecContext。
二、解碼API
下面介紹解碼需要用到的幾個函數,聲明都位於 libavformat\avformat.h。
2.1 avformat_open_input()
打開輸出的流和讀取頭信息。其原型如下:
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options)
- ps:函數調用成功之后處理過的 AVFormatContext 結構體。
- url:打開的視音頻流的 URL。
- fmt:強制指定 AVFormatContext 中 AVInputFormat 的。這個參數一般情況下可以設置為 NULL,這樣 FFmpeg 可以自動檢測 AVInputFormat。
- options:附加的一些選項,一般情況下可以設置為 NULL。
函數執行成功的話,其返回值大於等於 0。
2.2 avformat_find_stream_info()
讀取音視頻數據來獲取一些相關的信息。其原型如下:
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
2.3 av_read_frame
讀取碼流中的音頻若干幀或者視頻一幀。例如,解碼視頻的時候,每解碼一個視頻幀,需要先調用 av_read_frame() 獲得一幀視頻的壓縮數據,然后才能對該數據進行解碼。其原型如下:
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
2.4 avformat_close_input()
關閉打開的流。其原型如下:
void avformat_close_input(AVFormatContext **s)
三、編碼API
在基於 FFmpeg 的音視頻編碼器程序中,avformat_alloc_output_context2() 函數通常是第一個調用的函數(除了組件注冊函數 av_register_all())。另外介紹 FFmpeg 的寫文件用到的 3 個函數,聲明都位於 libavformat\avformat.h:
- av_write_frame() 用於寫視頻數據;
- avformat_write_header() 用於寫視頻文件頭;
- av_write_trailer() -用於寫視頻文件尾。
3.1 avformat_alloc_output_context2()
初始化一個用於輸出的 AVFormatContext 結構體。其原型如下:
int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat * oformat, const char * format_name, const char * filename)
3.2 avformat_write_header()
分配一個 stream 的私有數據而且寫 stream 的 header 到一個輸出的媒體文件。其原型如下:
int avformat_write_header(AVFormatContext *s, AVDictionary ** options)
3.3 av_write_frame()
用於輸出一幀視音頻數據。其原型如下:
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
參數 s 為用於輸出的 AVFormatContext,參數 pkt 為等待輸出的 AVPacket。
3.4 av_write_trailer()
用於輸出文件尾。其原型如下:
int av_write_trailer(AVFormatContext *s)
它只需要指定一個參數,即用於輸出的 AVFormatContext,函數正常執行后返回值等於 0。
四、圖像處理API
libswscale 是一個主要用於處理圖片像素數據的類庫。可以完成圖片像素格式的轉換,圖片的拉伸等工作。libswscale 常用的函數數量很少,一般情況下就3個,聲明都位於 libswscale\swscale.h:
sws_getContext():分配和返回一個SwsContext。
sws_scale():處理圖像數據。
sws_freeContext():釋放一個SwsContext。
其中 sws_getContext() 也可以用 sws_getCachedContext() 取代。
4.1 sws_getContext()
分配和返回一個 SwsContext。其原型如下:
struct SwsContext* sws_getContext ( int srcW,
int srcH,
enum AVPixelFormat srcFormat,
int dstW,
int dstH,
enum AVPixelFormat dstFormat,
int flags,
SwsFilter * srcFilter,
SwsFilter * dstFilter,
const double * param
)
4.2 sws_scale()
處理圖像數據。其原型如下:
int sws_scale(struct SwsContext *c,
const uint8_t * const srcSlice[],
const int srcStride[], int srcSliceY,
int srcSliceH, uint8_t *const dst[],
const int dstStride[]) )
4.3 sws_freeContext()
釋放一個 SwsContext。其原型如下:
void sws_freeContext(struct SwsContext *swsContext)
五、其它API
5.1 日志輸出系統(av_log()等)
av_log() 是 FFmpeg 中輸出日志的函數。一般情況下 FFmpeg 類庫的源代碼中是不允許使用 printf() 這種的函數的,所有的輸出一律使用 av_log()。av_log() 的聲明位於 libavutil\log.h,其原型如下:
void av_log(void* avcl, int level, const char *fmt, ...)
函數最后一個參數是 “…”。
在 C 語言中,在函數參數數量不確定的情況下使用 “…” 來代表參數。例如 printf() 的原型定義為:int printf (const char*, ...)。
參考:
雷霄驊大神的FFmpeg的庫函數源代碼分析文章列表:
【通用】
FFmpeg 源代碼簡單分析:av_register_all()
FFmpeg 源代碼簡單分析:avcodec_register_all()
FFmpeg 源代碼簡單分析:內存的分配和釋放(av_malloc()、av_free()等)
FFmpeg 源代碼簡單分析:常見結構體的初始化和銷毀(AVFormatContext,AVFrame等)
FFmpeg 源代碼簡單分析:av_find_decoder()和av_find_encoder()
FFmpeg 源代碼簡單分析:avcodec_open2()
FFmpeg 源代碼簡單分析:avcodec_close()
【解碼】
圖解FFMPEG打開媒體的函數avformat_open_input
FFmpeg 源代碼簡單分析:avformat_open_input()
FFmpeg 源代碼簡單分析:avformat_find_stream_info()
FFmpeg 源代碼簡單分析:av_read_frame()
FFmpeg 源代碼簡單分析:avcodec_decode_video2()
FFmpeg 源代碼簡單分析:avformat_close_input()
【編碼】
FFmpeg 源代碼簡單分析:avformat_alloc_output_context2()
FFmpeg 源代碼簡單分析:avformat_write_header()
FFmpeg 源代碼簡單分析:avcodec_encode_video()
FFmpeg 源代碼簡單分析:av_write_frame()
FFmpeg 源代碼簡單分析:av_write_trailer()
【其它】
FFmpeg源代碼簡單分析:日志輸出系統(av_log()等)
FFmpeg源代碼簡單分析:結構體成員管理系統-AVClass
FFmpeg源代碼簡單分析:結構體成員管理系統-AVOption
FFmpeg源代碼簡單分析:libswscale的sws_getContext()
FFmpeg源代碼簡單分析:libswscale的sws_scale()
FFmpeg源代碼簡單分析:libavdevice的avdevice_register_all()
FFmpeg源代碼簡單分析:libavdevice的gdigrab
