文章目錄
- 🌟 前置說明:FFmpeg 中 AVFormatContext 是什么?
- 🧩 1. `avformat_alloc_context`
- 功能:
- 場景:
- 🧩 2. `avformat_open_input`
- 功能:
- 說明:
- 返回值:
- 🧩 3. `avformat_find_stream_info`
- 功能:
- 說明:
- 🧩 4. `av_read_frame`
- 功能:
- 說明:
- 🧩 5. `av_seek_frame` 和 `avformat_seek_file`
- 🔹 `av_seek_frame`
- 🔹 `avformat_seek_file`
- 🧩 6. `avformat_close_input`
- 功能:
- 注意:
- 🧩 7. `avformat_free_context`
- 功能:
- 🧪 一個最簡 FFmpeg 讀取流程(偽代碼)
🌟 前置說明:FFmpeg 中 AVFormatContext 是什么?
AVFormatContext
是 FFmpeg 中用于描述一個媒體文件或媒體流(如視頻文件、直播流)的結構體,包含了解碼器、流信息、文件路徑、數據緩沖等信息。
幾乎所有操作媒體文件的函數都圍繞這個結構體展開。
🧩 1. avformat_alloc_context
功能:
分配并初始化一個空的 AVFormatContext
結構體。
AVFormatContext *avformat_alloc_context(void);
場景:
如果你手動構建 AVFormatContext
,可以用它。但通常我們更常用的是 avformat_open_input
來自動分配。
🧩 2. avformat_open_input
功能:
打開一個輸入媒體文件,并填充 AVFormatContext
(即打開文件并準備讀取媒體信息)。
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
說明:
ps
:傳入的AVFormatContext*
的指針(通常為NULL
,內部自動分配)。url
:媒體文件路徑或流地址(如"test.mp4"
或"rtmp://..."
)fmt
:一般為NULL
,FFmpeg 自動判斷格式。options
:解封裝選項,一般也是NULL
。
返回值:
- 0 表示成功
- 負數表示失敗
🧩 3. avformat_find_stream_info
功能:
從媒體文件中讀取流信息,比如視頻流、音頻流、字幕流等。
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
說明:
調用后,可以通過 AVFormatContext->streams[i]
獲取流信息,比如幀率、分辨率、碼率、時長等。
🧩 4. av_read_frame
功能:
讀取一個包(packet),即從文件或流中讀取一幀音視頻數據。
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
說明:
- 數據讀出后存放在
AVPacket
中。 - 每次讀取的包可能來自視頻、音頻或其他流。
- 你需要檢查
pkt->stream_index
來判斷屬于哪個流。
🧩 5. av_seek_frame
和 avformat_seek_file
這兩個都用于跳轉到某個時間位置,但用法略有不同。
🔹 av_seek_frame
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
stream_index
:選擇參考哪個流(通常是視頻流)timestamp
:跳轉到的時間戳(單位是該流的 time_base)flags
:AVSEEK_FLAG_BACKWARD
:向后查找關鍵幀AVSEEK_FLAG_ANY
:允許跳非關鍵幀AVSEEK_FLAG_FRAME
:單位是幀,而不是時間戳
🔹 avformat_seek_file
int avformat_seek_file(AVFormatContext *s, int stream_index,int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
這個函數更靈活,允許設置查找時間戳范圍 [min_ts, max_ts]
,適合更復雜的跳轉需求。
🧩 6. avformat_close_input
功能:
關閉輸入文件并釋放相關資源。
void avformat_close_input(AVFormatContext **ps);
注意:
- 會釋放內部的 I/O 緩沖區和文件句柄
- 不會釋放
AVFormatContext
本體,需要用avformat_free_context
(如果你手動分配了)
🧩 7. avformat_free_context
功能:
釋放 AVFormatContext
結構體本身。
void avformat_free_context(AVFormatContext *s);
如果你使用了
avformat_alloc_context
創建的 AVFormatContext,那么用它來釋放。
🧪 一個最簡 FFmpeg 讀取流程(偽代碼)
AVFormatContext *fmt_ctx = NULL;
if (avformat_open_input(&fmt_ctx, "test.mp4", NULL, NULL) < 0) {// 打開失敗
}if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {// 獲取流信息失敗
}AVPacket pkt;
while (av_read_frame(fmt_ctx, &pkt) >= 0) {// 處理pktav_packet_unref(&pkt);
}avformat_close_input(&fmt_ctx); // 釋放文件相關資源
// 如果你手動alloc了 fmt_ctx,需要再:
avformat_free_context(fmt_ctx);