說明 :將 avfromatContext 的變量依次打印分析,根據ffmpeg 給的說明,猜測,結合網上的文章字節寫測試代碼分析二。
37 AVInputFormat *iformat;
? ? /**
? ? ?* The input container format.
? ? ?*
? ? ?* Demuxing only, set by avformat_open_input().
? ? ?*/
? ? ff_const59 struct AVInputFormat *iformat;
AVInputFormat 再分析-CSDN博客
38 AVFormatInternal *internal; 對開發者隱藏,但是對于閱讀ffmpeg源碼有用。
? ? /**
? ? ?* An opaque field for libavformat internal usage.
? ? ?* Must not be accessed in any way by callers.
? ? ?*/
? ? AVFormatInternal *internal;
*libavformat內部使用的不透明字段。
*使用不得以任何方式訪問。
AVFormatContext 中的?AVFormatInternal *internal
?字段是 FFmpeg 內部用于存儲與解封裝/封裝過程相關的私有狀態數據的結構體7。以下是其核心特性的總結:
?1. 設計目的?
- ?內部數據隔離?:
internal
?封裝了?AVFormatContext
?運行時的臨時狀態和中間數據,避免用戶直接操作導致的結構不穩定或版本兼容性問題7。 - ?模塊化擴展?:通過獨立結構體管理內部狀態,方便 FFmpeg 在不同版本中擴展或修改內部實現邏輯,而無需修改?
AVFormatContext
?的公開接口7。
?2. 關鍵特性?
-
?不透明性?:
AVFormatInternal
?的具體定義未在公共頭文件(如?avformat.h
)中公開,開發者無法直接訪問其內部字段7。- 所有操作需通過 FFmpeg 提供的 API 完成(如?
avformat_open_input()
、av_read_frame()
?等)78。
-
?生命周期管理?:
internal
?的內存分配與釋放由 FFmpeg 內部自動完成,用戶無需手動干預(例如在調用?avformat_close_input()
?時會自動清理)7。- 初始化時,
internal
?通常通過?avformat_alloc_context()
?函數間接創建7。
?3. 關聯功能?
- ?流探測緩沖?:緩存輸入數據的部分內容,用于格式探測(如?
avformat_find_stream_info()
?中的流參數分析)8。 - ?中間狀態存儲?:
- 封裝/解封裝過程中的臨時數據包隊列3。
- 時間戳校正、流交錯(interleaving)等算法所需的上下文信息38。
?4. 開發者注意事項?
- ?禁止直接訪問?:由于 FFmpeg 不保證?
AVFormatInternal
?的跨版本二進制兼容性,直接操作其字段可能導致程序崩潰或未定義行為7。 - ?調試限制?:若需調試內部狀態,通常需結合 FFmpeg 源碼中的日志輸出或使用調試器跟蹤相關函數調用7。
?與類似字段的對比?
字段 | 作用域 | 可見性 | 管理方式 |
---|---|---|---|
priv_data | 格式私有數據 | 半公開(需API) | 由?AVInputFormat/AVOutputFormat ?管理14 |
?internal ? | 全局運行時 | 完全內部 | FFmpeg 內部自動管理7 |
此設計模式體現了 FFmpeg 對“接口穩定”和“實現靈活”的平衡,確保用戶僅通過規范 API 即可安全使用核心功能78。
39.AVIOInterruptCB interrupt_callback
? ? /**
? ? ?* Custom interrupt callbacks for the I/O layer.
? ? ?*
? ? ?* demuxing: set by the user before avformat_open_input().
? ? ?* muxing: set by the user before avformat_write_header()
? ? ?* (mainly useful for AVFMT_NOFILE formats). The callback
? ? ?* should also be passed to avio_open2() if it's used to
? ? ?* open the file.
? ? ?*/
? ? AVIOInterruptCB interrupt_callback;
/**
?* Callback for checking whether to abort blocking functions.
?* AVERROR_EXIT is returned in this case by the interrupted
?* function. During blocking operations, callback is called with
?* opaque as parameter. If the callback returns 1, the
?* blocking operation will be aborted.
?*
?* No members can be added to this struct without a major bump, if
?* new elements have been added after this struct in AVFormatContext
?* or AVIOContext.
?*/
typedef struct AVIOInterruptCB {
? ? int (*callback)(void*);
? ? void *opaque;
} AVIOInterruptCB;
?AVFormatContext 中的?interrupt_callback
?字段用于實現自定義 I/O 中斷控制機制,主要解決網絡流處理時的阻塞問題?。以下是其核心功能與使用方法的總結:
?1. 功能與作用?
- ?阻塞中斷?:在?
avformat_open_input()
?或?av_read_frame()
?等操作中,若因網絡延遲、設備斷開或無數據導致長時間阻塞,可通過回調函數強制終止等待12。 - ?超時控制?:允許開發者設置最大等待時間,避免程序無響應(如 RTSP 流超時斷開)48。
- ?跨協議兼容?:適用于 RTSP、RTMP 等網絡協議,彌補某些協議(如 RTMP)不支持超時參數的缺陷16。
?2. 結構體定義?
interrupt_callback
?是?AVFormatContext
?的成員,類型為?AVIOInterruptCB
,包含兩個關鍵字段:
- ?
callback
?:函數指針,指向用戶定義的中斷檢測函數。 - ?
opaque
?:用戶自定義的上下文指針(如對象實例、計時器等),傳遞給回調函數。
typedef struct AVIOInterruptCB {int (*callback)(void*); // 中斷檢測函數void *opaque; // 用戶上下文數據
} AVIOInterruptCB;
?3. 回調函數實現?
回調函數需返回 ?1
(中斷)? 或 ?0
(繼續等待)?。典型實現邏輯:
- 通過?
opaque
?獲取上下文數據(如超時起始時間)。 - 計算當前時間與起始時間的差值。
- 若超過預設閾值(如 5 秒),返回?
1
?終止操作。
// 示例:超時檢測回調
int interrupt_cb(void *ctx) {int64_t start_time = *(int64_t*)ctx; // 通過 opaque 傳遞起始時間int64_t current_time = av_gettime(); // 獲取當前時間(微秒)return (current_time - start_time > 5000000) ? 1 : 0; // 超過5秒則中斷
}
?4. 設置步驟?
- ?分配上下文?:創建?
AVFormatContext
?實例。 - ?綁定回調?:設置?
interrupt_callback
?的?callback
?和?opaque
。 - ?啟動計時?:在關鍵操作前記錄起始時間(如?
av_gettime()
)。 - ?打開輸入流?:調用?
avformat_open_input()
,阻塞操作將觸發回調檢測。
AVFormatContext *fmt_ctx = avformat_alloc_context();
int64_t timeout_start = av_gettime(); // 記錄起始時間// 設置回調函數及上下文
fmt_ctx->interrupt_callback.callback = interrupt_cb;
fmt_ctx->interrupt_callback.opaque = &timeout_start;// 打開輸入流(如 RTSP)
if (avformat_open_input(&fmt_ctx, "rtsp://example.com", NULL, NULL) < 0) {// 錯誤處理
}
?5. 注意事項?
- ?協議差異?:對于 RTSP,可同時設置?
stimeout
?參數(單位:微秒)增強超時控制68:cCopy Code
AVDictionary *options = NULL; av_dict_set(&options, "stimeout", "2000000", 0); // 2秒超時 avformat_open_input(&fmt_ctx, url, NULL, &options);
- ?線程安全?:回調函數需確保線程安全,避免競態條件8。
- ?資源釋放?:無需手動釋放?
interrupt_callback
,其生命周期與?AVFormatContext
?綁定5。
?6. 典型問題與調試?
- ?回調未觸發?:檢查是否在?
avformat_open_input()
?前正確設置回調8。 - ?誤中斷?:調整超時閾值,或在回調中增加狀態判斷(如網絡重連嘗試次數)6。
40 回調函數?io_open
謹慎
? ? /**
? ? ?* A callback for opening new IO streams.
? ? ?*
? ? ?* Whenever a muxer or a demuxer needs to open an IO stream (typically from
? ? ?* avformat_open_input() for demuxers, but for certain formats can happen at
? ? ?* other times as well), it will call this callback to obtain an IO context.
? ? ?*
? ? ?* @param s the format context
? ? ?* @param pb on success, the newly opened IO context should be returned here
? ? ?* @param url the url to open
? ? ?* @param flags a combination of AVIO_FLAG_*
? ? ?* @param options a dictionary of additional options, with the same
? ? ?* ? ? ? ? ? ? ? ?semantics as in avio_open2()
? ? ?* @return 0 on success, a negative AVERROR code on failure
? ? ?*
? ? ?* @note Certain muxers and demuxers do nesting, i.e. they open one or more
? ? ?* additional internal format contexts. Thus the AVFormatContext pointer
? ? ?* passed to this callback may be different from the one facing the caller.
? ? ?* It will, however, have the same 'opaque' field.
? ? ?*/
? ? int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url,
? ? ? ? ? ? ? ? ? ?int flags, AVDictionary **options);
目前看的信息是:avformatContext 的 io_open 回調函數 在默認情況下叫?io_open_default,在解復用的?avformat_open_input 方法中一定會調用。
io_open_default
?是 FFmpeg 中用于初始化輸入/輸出上下文 (AVIOContext
) 的關鍵函數,主要在解封裝流程中處理協議檢測與連接。以下是其核心機制與作用解析:
一、功能定位
-
?協議初始化入口?
在?avformat_open_input()
?調用流程中,io_open_default
?作為默認的 I/O 上下文初始化函數,負責根據輸入 URL 的協議類型(如 HTTP、HLS、文件)創建對應的?AVIOContext
,并綁定底層協議實現1。 -
?協議白名單校驗?
通過調用?ffio_open_whitelist
,該函數會校驗協議是否在允許范圍內,防止加載未授權的協議實現(如自定義或非標準協議),確保安全性1。 -
?多層封裝調用鏈?
其執行鏈路為:
avformat_open_input
?→?init_input
?→?io_open_default
?→?ffio_open_whitelist
?→?ffurl_open_whitelist
?→?ffurl_connect
?→ 具體協議實現(如?http_open
)1。
最終通過系統調用(如?socket
)建立網絡連接或打開本地文件12。
二、實現機制
-
?協議適配層?
io_open_default
?通過協議前綴(如?http://
、file://
)匹配對應的?URLProtocol
?實現(如?ff_http_protocol
),并初始化協議上下文 (URLContext
),最終關聯到?AVIOContext
?的?opaque
?字段15。 -
?緩沖與回調設置?
自動配置讀寫緩沖區大小,并設置默認的?read_packet
、write_packet
?等回調函數,確保數據通過協議層高效傳輸至解封裝模塊17。 -
?錯誤處理?
若協議檢測失敗(如 URL 無效或協議未注冊),函數返回錯誤碼并終止后續流程,觸發?avformat_open_input
?的異常處理邏輯1。
三、應用場景
- ?標準協議處理?:自動處理 HTTP、RTMP、HLS 等協議連接的初始化,無需手動創建?
AVIOContext
15。 - ?安全限制場景?:通過白名單機制限制可訪問的協議類型,適用于需嚴格管控輸入源的場景(如嵌入式設備)1。
四、擴展性
- ?自定義協議支持?:若需支持私有協議,需繞過?
io_open_default
,通過?avio_alloc_context
?手動創建?AVIOContext
?并注冊自定義協議實現37。
41 回調函數io_close
? ? /**
? ? ?* A callback for closing the streams opened with AVFormatContext.io_open().
? ? ?*/
? ? void (*io_close)(struct AVFormatContext *s, AVIOContext *pb);
42 int io_repositioned;
? ? /**
? ? ?* IO repositioned flag.
? ? ?* This is set by avformat when the underlaying IO context read pointer
? ? ?* is repositioned, for example when doing byte based seeking.
? ? ?* Demuxers can use the flag to detect such changes.
? ? ?*/
? ? int io_repositioned;
io_repositioned
?是 FFmpeg 中?AVFormatContext
?結構體的一個標志字段,用于指示底層 I/O 上下文的讀指針是否發生了位置重置。其核心作用與應用場景如下:
一、功能定義
-
?標志位作用?
io_repositioned
?由 FFmpeg 的解封裝模塊(avformat
)自動設置,主要用于標識底層 I/O 上下文(如?AVIOContext
)的讀指針是否被顯式重定位。例如,在基于字節的隨機訪問(byte-based seeking)時,該標志會被觸發。 -
?觸發條件?
當調用?av_seek_frame()
?或類似函數導致底層 I/O 緩沖區的讀指針位置發生變化時,io_repositioned
?會被設置為非零值,表示發生了位置重置。
二、應用場景
-
?解封裝邏輯適配?
解復用器(Demuxer)可通過檢查?io_repositioned
?標志判斷是否需要重新同步內部狀態(如重新解析流頭信息或調整時間戳計算邏輯),以應對底層 I/O 位置突變帶來的數據不一致問題。 -
?性能優化?
在處理網絡流或大文件時,通過檢測?io_repositioned
?標志,可避免無效的緩存數據讀取,確保后續操作基于最新的 I/O 位置執行1。
三、實現關聯
- ?與?
AVIOContext
?的交互?
io_repositioned
?直接關聯?AVIOContext
?的?seek
?操作,若用戶代碼通過?avio_seek()
?手動調整讀指針位置,也會觸發該標志的更新
打印值是0
avformatContext->io_repositioned;cout << "avformatContext->io_repositioned = " << avformatContext->io_repositioned << endl;
43?const uint8_t *key; int keylen;作用未知
? ? const uint8_t *key;
? ? int keylen;
44?? ? int64_t max_analyze_duration;
? ? /**
? ? ?* Maximum duration (in AV_TIME_BASE units) of the data read
? ? ?* from input in avformat_find_stream_info().
? ? ?* Demuxing only, set by the caller before avformat_find_stream_info().
? ? ?* Can be set to 0 to let avformat choose using a heuristic.
? ? ?*/
? ? int64_t max_analyze_duration;
參見?
AVFormatContext 再分析一-CSDN博客
36?int64_t max_analyze_duration; 解復用時使用,在avformat_find_stream_info 方法中使用
avfromatContext 中可以優化的參數。format_probesize,fps_probe_size,probesize,max_analyze_duration-CSDN博客
avformatContext->max_analyze_duration = 0
45? ? int max_chunk_duration;
? ? /**
? ? ?* Max chunk time in microseconds.
? ? ?* Note, not all formats support this and unpredictable things may happen if it is used when not supported.
? ? ?* - encoding: Set by user
? ? ?* - decoding: unused
? ? ?*/
? ? int max_chunk_duration;
用于設置流媒體傳輸中的最大塊持續時間。在FFmpeg的RTMP協議中,這個參數定義了每個RTMP消息的最大持續時間。如果超過這個時間,FFmpeg會自動將數據分成多個塊進行傳輸,以確保流媒體的穩定性和效率。
max_chunk_duration的作用和重要性
- ?穩定性?:通過限制每個數據塊的大小,max_chunk_duration有助于確保流媒體的穩定性。如果數據塊過大,可能會導致網絡延遲或丟包,影響觀看體驗。
- ?效率?:合理設置max_chunk_duration可以提高傳輸效率,減少緩沖時間,提升用戶體驗。
- ?兼容性?:不同的設備和網絡環境對數據塊的大小有不同的要求,合理設置max_chunk_duration可以增強兼容性。
如何設置max_chunk_duration
在FFmpeg的命令行中,可以通過-max_chunk_duration
選項來設置
打印默認值
avformatContext->max_chunk_duration = 0
46 int max_chunk_size;
? ? /**
? ? ?* Max chunk size in bytes
? ? ?* Note, not all formats support this and unpredictable things may happen if it is used when not supported.
? ? ?* - encoding: Set by user
? ? ?* - decoding: unused
? ? ?*/
? ? int max_chunk_size;
avformatContext->max_chunk_size = 0
avformat_context
?結構體中的?max_chunk_size
?字段在 FFmpeg 庫中用于控制讀取媒體文件時的最大塊大小。這個字段主要用于某些特定的格式處理,尤其是在處理非常大的數據塊時,例如在處理非常大的音頻或視頻幀時。
字段的作用
max_chunk_size
?字段通常在處理某些格式的流時非常有用,特別是在需要分割大型文件或流為較小塊進行處理時。例如,在某些情況下,直接讀取整個大型文件到一個內存塊可能會導致內存不足的問題。通過設置?max_chunk_size
,你可以指定每次讀取的最大字節數,這有助于更有效地管理內存使用。
如何使用
在 FFmpeg 的 C API 中,你可以在打開媒體文件后設置?max_chunk_size
。例如:
AVFormatContext* formatCtx = NULL;avformat_open_input(&formatCtx, "input.file", NULL, NULL);// 設置最大塊大小if (formatCtx) {formatCtx->max_chunk_size = 1024 * 1024; // 例如,設置為1MB}
注意事項
-
兼容性:不是所有的格式和流都支持?
max_chunk_size
。在某些情況下,即使設置了此值,FFmpeg 也可能忽略它。因此,最好檢查文檔和源代碼來確認你的格式支持此功能。 -
性能影響:雖然?
max_chunk_size
?可以幫助管理內存使用,但設置過小的值可能會導致性能下降,因為頻繁的磁盤I/O操作會增加。 -
默認值:如果沒有特別設置,FFmpeg 可能使用其默認的塊大小處理策略。
結論
max_chunk_size
?是一個有用的工具,特別是在處理大型媒體文件時,可以幫助優化內存使用和改善應用程序的穩定性和性能。然而,正確使用它需要你對你的媒體文件和FFmpeg的內部機制有一定的了解。在使用之前,最好查閱最新的FFmpeg文檔和源代碼以了解更多細節和最佳實踐。
47 int max_delay;
max_delay字段的作用
max_delay
字段主要用于控制媒體流在播放時的最大延遲。在一些情況下,比如直播流或需要低延遲的場景,控制延遲是非常重要的。例如,在視頻會議或實時視頻流中,延遲過高會導致用戶體驗不佳。
如何設置max_delay
在FFmpeg中,你可以通過編程方式設置AVFormatContext
的max_delay
字段來控制延遲。以下是一個基本的示例代碼,展示了如何設置這個字段:
#include <libavformat/avformat.h>int main() {AVFormatContext* formatCtx = NULL;if (avformat_open_input(&formatCtx, "input.mp4", NULL, NULL) != 0) {fprintf(stderr, "Could not open input file\n");return -1;}if (avformat_find_stream_info(formatCtx, NULL) < 0) {fprintf(stderr, "Could not find stream information\n");return -1;}// 設置最大延遲,單位為微秒(μs)formatCtx->max_delay = (int64_t)(1000000); // 例如,設置為1秒的延遲// 繼續處理...avformat_close_input(&formatCtx);return 0;}
注意事項
-
單位:
max_delay
的單位是微秒(μs)。因此,如果你想設置延遲為1秒,應該將值設置為1000000(因為1秒=1000毫秒=1000000微秒)。 -
影響:設置
max_delay
可能會影響流的播放性能和延遲特性。需要根據具體應用場景進行合理設置。 -
兼容性:不是所有的媒體格式或編解碼器都支持動態調整延遲。某些實現可能不完全遵循此設置。
-
4. ?與其他參數的關系?
-
?
AVCodecContext
?的?max_b_frames
?
若編碼層存在 B 幀(雙向預測幀),需確保?max_delay
?大于 B 幀的解碼依賴時間,否則可能導致解碼錯誤4。 -
?網絡協議緩沖區?
當通過?AVIOContext
?處理網絡流時,max_delay
?需與協議層的緩沖區大小(如?buffer_size
)協同配置,避免網絡抖動影響同步37。
結論
通過合理設置max_delay
,你可以更好地控制媒體流的播放延遲,這對于需要低延遲的應用場景(如實時視頻通信)尤其重要。確保在實際應用中根據具體需求調整此參數。
打印結果為-1
avformatContext->max_delay;cout << "avformatContext->max_delay = " << avformatContext->max_delay << endl;
48 unsigned int max_index_size;
? ? /**
? ? ?* Maximum amount of memory in bytes to use for the index of each stream.
? ? ?* If the index exceeds this size, entries will be discarded as
? ? ?* needed to maintain a smaller size. This can lead to slower or less
? ? ?* accurate seeking (depends on demuxer).
? ? ?* Demuxers for which a full in-memory index is mandatory will ignore
? ? ?* this.
? ? ?* - muxing: unused
? ? ?* - demuxing: set by user
? ? ?*/
? ? unsigned int max_index_size;
max_index_size
?字段是用來指示該容器中索引條目可能達到的最大數量。
解釋
max_index_size
?字段通常用在需要快速訪問媒體文件中的多個片段或關鍵幀的場景。例如,在視頻文件中,你可能想要快速跳轉到文件的某個特定時間點。在這種情況下,索引可以幫助你快速定位到包含目標時間點的數據塊。
使用場景
-
視頻播放:在播放視頻時,播放器可能需要根據用戶操作(如快進、快退)快速定位到視頻的特定部分。
-
媒體編輯:在編輯視頻或音頻文件時,快速訪問不同部分的內容。
如何設置和使用
在FFmpeg的API中,你通常不需要手動設置?max_index_size
,因為這個值會根據你打開的媒體文件的具體格式和內容自動確定。當你使用?avformat_open_input()
?函數打開一個媒體文件時,FFmpeg會自動填充?AVFormatContext
?結構體,包括?max_index_size
。
?歷史版本兼容性?
某些舊版本FFmpeg可能曾定義過類似字段,但在當前主流版本(如6.x)中被移除或更名。建議通過最新源碼或官方文檔確認
avformatContext->max_index_size = 1048576
49 int64_t max_interleave_delta;
? ? /**
? ? ?* Maximum buffering duration for interleaving.
? ? ?*
? ? ?* To ensure all the streams are interleaved correctly,
? ? ?* av_interleaved_write_frame() will wait until it has at least one packet
? ? ?* for each stream before actually writing any packets to the output file.
? ? ?* When some streams are "sparse" (i.e. there are large gaps between
? ? ?* successive packets), this can result in excessive buffering.
? ? ?*
? ? ?* This field specifies the maximum difference between the timestamps of the
? ? ?* first and the last packet in the muxing queue, above which libavformat
? ? ?* will output a packet regardless of whether it has queued a packet for all
? ? ?* the streams.
? ? ?*
? ? ?* Muxing only, set by the caller before avformat_write_header().
? ? ?*/
? ? int64_t max_interleave_delta;
max_interleave_delta
?字段是用于控制輸出文件中的數據交織(interleaving)的一個參數。
什么是交織(Interleaving)?
交織是指在輸出文件時,將不同流(如視頻流、音頻流)的數據交錯寫入,以減少文件頭部的延遲并提高播放的流暢性。例如,在一個視頻文件中,視頻幀和音頻幀可能會交錯出現,這樣播放器就可以在等待下一個視頻幀的同時播放音頻。
max_interleave_delta 的作用
max_interleave_delta
?字段用于控制交織過程中允許的最大時間差(以時間戳為單位)。這個參數決定了在輸出文件時,不同流之間的最大時間差。例如,如果一個視頻幀的時間戳與緊接著的音頻幀的時間戳相差超過了這個值,FFmpeg 可能會選擇等待或插入額外的數據包來調整這種差值,以確保流的正確交織。
如何設置 max_interleave_delta
在 FFmpeg 的 API 中,你可以通過直接設置?AVFormatContext
?結構體的?max_interleave_delta
?字段來調整這個值。例如:
AVFormatContext *fmt_ctx;
avformat_alloc_output_context2(&fmt_ctx, NULL, NULL, "output.mp4");
if (!fmt_ctx) {fprintf(stderr, "Could not create format context\n");exit(1);
}// 設置最大交織延遲為 100ms
fmt_ctx->max_interleave_delta = 100000; // 單位為微秒(1秒=1000000微秒)
注意事項
-
單位:
max_interleave_delta
?的單位是微秒(1秒 = 1,000,000微秒)。 -
性能影響:增加?
max_interleave_delta
?的值可以減少編碼時的等待時間,但可能會增加播放時的延遲。 -
合理設置:根據你的具體需求(如實時性要求、文件大小優化等)合理設置此值。
通過調整?max_interleave_delta
,你可以更好地控制輸出多媒體文件的性能和播放體驗。
打印
avformatContext->max_interleave_delta = 10000000
avformatContext->max_interleave_delta;cout << "avformatContext->max_interleave_delta = " << avformatContext->max_interleave_delta << endl;
50?unsigned int max_picture_buffer;
? ? /**
? ? ?* Maximum amount of memory in bytes to use for buffering frames
? ? ?* obtained from realtime capture devices.
? ? ?*/
? ? unsigned int max_picture_buffer;
用于緩沖從實時捕獲設備獲得的幀的最大內存量(字節)。
打印
avformatContext->max_picture_buffer = 3041280
51 int max_probe_packets;?
? ? /**
? ? ?* Maximum number of packets that can be probed
? ? ?* - encoding: unused
? ? ?* - decoding: set by user
? ? ?*/
? ? int max_probe_packets;
設置最大 可探測的最大數據包數
AVFormatContext
?結構體中的 ?max_probe_packets
? 字段用于控制?格式探測階段的數據包數量限制?,其作用與封裝格式的自動識別邏輯直接相關36。以下是詳細解析:
1. ?核心功能?
-
?格式探測(Probing)?
當未明確指定輸入文件的封裝格式時,FFmpeg 會通過讀取文件頭部數據(或前幾個數據包)自動推測格式類型。max_probe_packets
?定義了此階段允許讀取的?最大數據包數量?,以避免因探測耗時過長影響性能36。 -
?默認值與調整?
- 典型默認值為?
50
(具體值可能因 FFmpeg 版本而異)3。 - 若輸入文件頭部信息復雜或分布在多個數據包中,需適當增大此值以提高探測準確性36。
- 典型默認值為?
2. ?應用場景?
-
?特殊文件處理?
對于頭部信息分散的非標準文件(如某些流媒體分段文件),增加?max_probe_packets
?可確保 FFmpeg 讀取足夠的數據包完成格式識別36。 -
?延時敏感場景?
在實時流處理中,若需降低初始探測階段的延遲,可減少此參數值,但可能犧牲格式識別的可靠性36。
3. ?參數關聯性?
-
?與?
probesize
?的區別?
probesize
?限制探測階段的總字節數,而?max_probe_packets
?限制數據包數量。兩者共同作用,確保探測過程在資源消耗和準確性間權衡36。 -
?封裝格式影響?
某些格式(如 MPEG-TS)依賴多個數據包頭信息,需更高的?max_probe_packets
?值以保證正確識別6。
4. ?配置示例?
AVFormatContext *fmt_ctx = avformat_alloc_context();
fmt_ctx->max_probe_packets = 100; // 允許探測最多100個數據包
avformat_open_input(&fmt_ctx, input_file, NULL, NULL);
總結
max_probe_packets
?是 FFmpeg 格式探測機制的關鍵參數,通過控制數據包數量平衡識別精度與效率36。實際應用中需結合文件特性與性能需求動態調整。
默認打印值
avformatContext->max_probe_packets = 2500
52?int max_streams;一般也沒啥用,什么情況下1000個不夠用呢?
? ? /**
? ? ?* The maximum number of streams.
? ? ?* - encoding: unused
? ? ?* - decoding: set by user
? ? ?*/
? ? int max_streams;
在解復用的時候使用
打印值是 1000
cout << "avformatContext->max_streams = " << avformatContext->max_streams << endl;結果為:avformatContext->max_streams = 1000
?
53?int max_ts_probe,在解復用ts文件的時候用
? ? /**
? ? ?* Maximum number of packets to read while waiting for the first timestamp.
? ? ?* Decoding only.
? ? ?*/
? ? int max_ts_probe;
int?max_ts_probe:解碼TS格式時,在得到第一個PTS前可解碼的最大packet的數量。
同時關聯的還有 avformatcontext 的? ts_id .
int ts_id:TS格式中流的pid
打印結果?avformatContext->max_ts_probe = 50
avformatContext->max_ts_probe;cout << "avformatContext->max_ts_probe = " << avformatContext->max_ts_probe << endl;
從實現 看,是在?avformat_find_stream_info方法內部使用。
也就是說:如果我們讀取的ts文件,那么有可能需要調整?max_ts_probe的值,當然越大,解析的包越多,花費的時間越多
54 元數據?AVDictionary *metadata;
? ? /**
? ? ?* Metadata that applies to the whole file.
? ? ?*
? ? ?* - demuxing: set by libavformat in avformat_open_input()
? ? ?* - muxing: may be set by the caller before avformat_write_header()
? ? ?*
? ? ?* Freed by libavformat in avformat_free_context().
? ? ?*/
? ? AVDictionary *metadata;
參考
ffmpeg 元數據-CSDN博客
55 int metadata_header_padding;
? ? /**
? ? ?* Number of bytes to be written as padding in a metadata header.
? ? ?* Demuxing: Unused.
? ? ?* Muxing: Set by user via av_format_set_metadata_header_padding.
? ? ?*/
? ? int metadata_header_padding;
56
57
58
59