FFmpeg 的常用API
附錄:FFmpeg庫介紹
庫 | 介紹 |
---|---|
libavcodec | 音視頻編解碼核心庫 編碼 ( avcodec_send_frame , avcodec_receive_packet )。解碼 ( avcodec_send_packet , avcodec_receive_frame )。 |
libavformat | 提供了音視頻流的解析和封裝功能,多種多媒體封裝格式(如 MP4、MKV、FLV、TS、AVI 等)。 分配和初始化上下文 ( avformat_alloc_context , avformat_alloc_output_context2 )。解析媒體流 ( avformat_open_input )。寫入媒體流 ( avformat_write_header , av_write_frame , av_write_trailer )。 |
libavutil | 提供多種輔助工具。 |
libswscale | 處理圖像的縮放和色彩格式轉換。像素格式轉換(從 RGB 轉換為 YUV420)。圖像的尺寸縮放(如調整視頻分辨率)。 轉換像素格式 ( sws_scale )。分配和初始化上下文 ( sws_getContext )。 |
libswresample | 處理音頻的重采樣和格式轉換 初始化重采樣上下文 ( swr_alloc_set_opts , swr_init )。音頻格式轉換 ( swr_convert )。 |
libavdevice | 處理設備輸入輸出。 提供多媒體輸入設備的支持(如攝像頭、麥克風)。 |
libpostproc | 提供視頻后處理功能。 主要用于視頻質量增強(如去塊效應、降噪處理)。配合視頻解碼器使用,改善解碼后的視頻質量。 |
附錄1:參考文獻
ffmpeg視頻編解碼流程:https://www.cnblogs.com/fxw1/p/17229792.html
常用API:https://www.cnblogs.com/linuxAndMcu/p/12041359.html
FFmpeg各版本區別:https://juejin.cn/post/7261245655128424509
附錄2:編解碼流程圖
新版本ffmpeg4.0:
老版本ffmpeg3.0:
一、通用API
1.1 av_register_all()
初始化 libavformat 和注冊所有的復用器muxer、解復用器demuxer和協議。(ffmpeg4.0已正式廢棄)
void av_register_all(void);
1.2 avcodec_find_encoder
、avcodec_find_decoder
查找具有匹配編解碼器ID的已注冊編/解碼器,位于 libavcodec\avcodec.h
// 函數的參數是一個編碼器的ID,返回查找到的編碼器(沒有找到就返回NULL)。
AVCodec *avcodec_find_encoder(enum AVCodecID id);// 函數的參數是一個解碼器的ID,返回查找到的解碼器(沒有找到就返回NULL)。
AVCodec *avcodec_find_decoder(enum AVCodecID id);
1.3 avcodec_open2()
**初始化一個視音頻編解碼器的 AVCodecContext以使用給定的AVCodec。**聲明位于 libavcodec\utils.c
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
avctx
:需要初始化的 AVCodecContext。codec
:輸入的AVCodec。options
:一些選項。例如使用libx264編碼的時候,“preset”,“tune”等都可以通過該參數設置。
1.4 avcodec_close()
關閉給定的avcodeContext并釋放與之關聯的所有數據,聲明位于 libavcodec\utils.c
int avcodec_close(AVCodecContext *avctx);
二、解碼相關API
2.1 avformat_open_input()
打開輸入流和讀取頭信息,流必須使用avformat_close_input()關閉
int avformat_open_input(AVFormatContext **ps,const char *url,AVInputFormat *fmt, AVDictionary **options);
ps
:用戶提供的AVFormatContext(由avformat_alloc_context分配)的指針。url
:打開的視音頻流的 URL。fmt
:如果!=NULL
,則此參數強制使用特定的輸入格式。否則將自動檢測格式。options
:包含AVFormatContext和demuxer私有選項的字典;一般情況下可以設置為 NULL。
2.2 avformat_find_stream_info()
**讀取檢查媒體文件的數據包以獲取具體的流信息,**如媒體存入的編碼格式。
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
ic
:媒體文件的上下文options
:字典,配置選項
2.3 av_read_frame
讀取碼流中的音頻若干幀或者視頻一幀
例如,解碼視頻的時候,每解碼一個視頻幀,需要先調用 av_read_frame() 獲得一幀視頻的壓縮數據,然后才能對該數據進行解碼。
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
2.4 avcodec_send_packet()
新版FFMPEG4.0引入:主要用于將編碼或解碼的數據包(Packet)送入編解碼器的輸入隊列
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
-
avctx
:指向AVCodecContext
結構的指針,包含與編碼器或解碼器相關的配置信息。(如avcodec_open2
初始化的編解碼器) -
avpkt
:指向AVPacket
結構的指針,表示要送入編解碼器的輸入數據包。(如av_read_frame
的數據包)
2.5 avcodec_receive_frame()
新版FFMPEG4.0引入:用于從解碼器獲取解碼后幀
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
-
avctx
:指向AVCodecContext
結構的指針,它包含與解碼器相關的上下文和配置信息。你必須在解碼器初始化后(通過avcodec_open2
)提供此參數。 -
frame
:指向AVFrame
結構的指針,接收解碼后的幀數據。AVFrame
是一個結構體,表示解碼后的視頻或音頻數據。解碼后的數據將存儲在這個結構中。
為什么要使用 avcodec_send_packet
和 avcodec_receive_frame
- 分離輸入和輸出:使用這兩個函數可以將輸入和輸出解耦,給解碼器提供更大的靈活性。例如,在多線程環境中,你可以在一個線程中調用
avcodec_send_packet
發送數據包,而在另一個線程中調用avcodec_receive_frame
獲取解碼結果。 - 線程安全:新版的 API 提供了線程安全的機制,尤其適用于異步解碼或編碼任務。
- 增強性能和靈活性:通過逐步處理數據,避免了直接處理整個解碼過程所帶來的性能瓶頸。
2.6 avformat_close_input()
對應2.1;關閉打開的流。并釋放AVFormatContext的所有內容并將*s設置為空
void avformat_close_input(AVFormatContext **s)
## 三、編碼相關API### 3.1 `avformat_alloc_output_context2`> 用于**分配并初始化**一個輸出媒體格式的上下文 (`AVFormatContext`) (通常是第一個調用的函數)```c++
int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename);
-
ctx
:指向輸出上下文指針的指針,用于存儲分配的AVFormatContext
。 -
oformat
:指定輸出格式(AVOutputFormat
),可以為NULL
。如果為NULL
,則根據format_name
或filename
自動推斷格式。 -
format_name
:指定輸出格式的名稱(如"mp4"
、"mkv"
等),用于明確輸出文件的封裝格式。可以為NULL
。 -
filename
:輸出文件的名稱。此參數會用于推斷格式(如果oformat
和format_name
都為NULL
)。
3.2 avformat_write_header()
為輸出文件寫入文件頭,準備文件封裝格式所需的元數據。
int avformat_write_header(AVFormatContext *s, AVDictionary **options);
-
s
(AVFormatContext):指向輸出上下文 (AVFormatContext
) 的指針,必須是用avformat_alloc_output_context2
創建的,并且已經設置好音視頻流 (AVStream
)。 -
options
(AVDictionary**):用于傳遞格式化選項的字典指針,可以為NULL
。-
設置編碼參數(如比特率
bit_rate
)。 -
設置容器格式選項(如
movflags
)。 -
需要在調用完成后手動釋放(通過
av_dict_free
)。
-
3.3 av_write_frame()
用于將單個媒體包(
AVPacket
)寫入輸出文件。它是音視頻數據封裝的重要步驟,直接處理編解碼后的數據幀。
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
s
(AVFormatContext*)
指向輸出上下文的指針,通常由 avformat_alloc_output_context2
創建并初始化。
pkt
(AVPacket*)
包含需要寫入的媒體數據的包(AVPacket
)。它應該包含目標流的索引 (stream_index
)、解碼后的時間戳(PTS/DTS)、以及數據緩沖區。
3.4 av_write_trailer()
用于輸出文件尾
int av_write_trailer(AVFormatContext *s)
四、圖像處理API
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
);
-
srcW
和srcH
:輸入圖像的寬度和高度。srcFormat
:輸入圖像的像素格式(AVPixelFormat
枚舉值,例如AV_PIX_FMT_YUV420P
)。 -
dstW
和dstH
:輸出圖像的寬度和高度。dstFormat
:輸出圖像的像素格式(例如AV_PIX_FMT_RGB24
)。 -
flags
:用于控制縮放的算法。可以是以下值之一或它們的組合:-
SWS_FAST_BILINEAR
:快速雙線性縮放。 -
SWS_BILINEAR
:雙線性縮放。 -
SWS_BICUBIC
:雙三次插值縮放(質量高)。 -
SWS_LANCZOS
:Lanczos重采樣(質量最高)。
-
-
srcFilter
和dstFilter
:分別為輸入和輸出圖像使用的濾波器。通常為NULL
。 -
param
:濾波器相關參數,通常為NULL
。
4.2 sws_scale()
libswscale
庫中的關鍵函數,用于在圖像轉換和縮放過程中執行實際的像素格式轉換和尺寸調整操作。它在sws_getContext
初始化的上下文中完成圖像數據處理
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[]) )
c
(struct SwsContext):指向由 sws_getContext
返回的上下文結構體,定義了轉換和縮放的參數。
srcSlice
(const uint8_t *const[]):輸入圖像的每個平面的指針數組(通常是 AVFrame->data
)。
srcStride
(const int[]):輸入圖像每行的字節數數組,對應每個數據平面(通常是 AVFrame->linesize
)。
srcSliceY
(int):輸入圖像處理的起始行號,通常為 0。
srcSliceH
(int):輸入圖像處理的行數(高度),例如 AVFrame->height
。
dst
(uint8_t *const[]):輸出圖像的每個平面的指針數組,存儲轉換后的數據。
dstStride
(const int[]):輸出圖像每行的字節數數組,對應每個數據平面。
4.3 sws_freeContext()
釋放一個 SwsContext
void sws_freeContext(struct SwsContext *swsContext)