參考鏈接
- FFMPEG結構體分析:AVFormatContext_雷霄驊的博客-CSDN博客_avformatcontext
AVFormatContext
- AVFormatContext是包含碼流參數較多的結構體
- 結構體的定義位于libavformat/avformat.h

/*** Format I/O context.//格式化 I/O 上下文* New fields can be added to the end with minor version bumps.//可以將新字段添加到末尾,并帶有較小的版本顛簸* Removal, reordering and changes to existing fields require a major//移除、重新排序和更改現有字段需要專業* version bump.//版本顛簸* sizeof(AVFormatContext) must not be used outside libav*, use//sizeof(AVFormatContext) 不能在 libav* 之外使用,使用* avformat_alloc_context() to create an AVFormatContext.//avformat_alloc_context() 創建一個 AVFormatContext** Fields can be accessed through AVOptions (av_opt*),//可以通過 AVOptions (av_opt*) 訪問字段* the name string used matches the associated command line parameter name and//使用的名稱字符串匹配相關的命令行參數名稱和* can be found in libavformat/options_table.h.//可以在 libavformat/options_table.h 中找到* The AVOption/command line parameter names differ in some cases from the C//AVOption/命令行參數名稱在某些情況下與 C 不同* structure field names for historic reasons or brevity.//出于歷史原因或簡潔的結構字段名稱*/
typedef struct AVFormatContext {/*** A class for logging and @ref avoptions. Set by avformat_alloc_context().* Exports (de)muxer private options if they exist.* 用于記錄和@ref avoptions 的類。 由 avformat_alloc_context() 設置。 * 導出(de)muxer 私有選項(如果存在)。*/const AVClass *av_class;/*** The input container format.//輸入容器格式** Demuxing only, set by avformat_open_input().//解復用,由avformat_open_input()進行參數設置*/const struct AVInputFormat *iformat;/*** The output container format.//輸出容器格式** Muxing only, must be set by the caller before avformat_write_header().* 僅復用,必須由調用者在 avformat_write_header() 之前設置*/const struct AVOutputFormat *oformat;/*** Format private data. This is an AVOptions-enabled struct //格式化私人數據。 這是一個啟用 AVOptions 的結構* if and only if iformat/oformat.priv_class is not NULL. //當且僅當 iformat/oformat.priv_class 不為 NULL** - muxing: set by avformat_write_header() //復用:由 avformat_write_header() 設置* - demuxing: set by avformat_open_input() //解復用:由 avformat_open_input() 設置*/void *priv_data;/*** I/O context.//I/O 上下文** - demuxing: either set by the user before avformat_open_input() (then* the user must close it manually) or set by avformat_open_input().* 解復用:由用戶在 avformat_open_input() 之前設置(然后用戶必須手動關閉)或通過 avformat_open_input() 設置。 * - muxing: set by the user before avformat_write_header(). The caller must* take care of closing / freeing the IO context.* 復用:由用戶在 avformat_write_header() 之前設置。 調用者必須負責關閉/釋放 IO 上下文* Do NOT set this field if AVFMT_NOFILE flag is set in //如果設置了 AVFMT_NOFILE 標志,請不要設置此字段* iformat/oformat.flags. In such a case, the (de)muxer will handle //iformat/oformat.flags。 在這種情況下,(de)muxer 將處理* I/O in some other way and this field will be NULL. //以其他方式進行 I/O,此字段將為 NULL*/AVIOContext *pb;/* stream info */ 流信息/*** Flags signalling stream properties. A combination of AVFMTCTX_*. //標志信號流屬性。 AVFMTCTX_* 的組合* Set by libavformat. //由 libavformat 設置*/int ctx_flags;/*** Number of elements in AVFormatContext.streams. //AVFormatContext.streams 中的元素數量** Set by avformat_new_stream(), must not be modified by any other code. //由 avformat_new_stream() 設置,不得被任何其他代碼修改*/unsigned int nb_streams;/*** A list of all streams in the file. New streams are created with* avformat_new_stream(). //文件中所有流的列表。 新的流使用avformat_new_stream()進行創建** - demuxing: streams are created by libavformat in avformat_open_input(). //解復用:流由 libavformat 在 avformat_open_input() 中創建* If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also * appear in av_read_frame(). //如果在 ctx_flags 中設置了 AVFMTCTX_NOHEADER,那么新的流也可能出現在 av_read_frame() 中* - muxing: streams are created by the user before avformat_write_header(). //復用:流由用戶在 avformat_write_header() 之前創建** Freed by libavformat in avformat_free_context(). //在 avformat_free_context() 中被 libavformat 釋放*/AVStream **streams;/*** input or output URL. Unlike the old filename field, this field has no* length restriction. //輸入或輸出 URL。 與舊的文件名字段不同,該字段沒有長度限制** - demuxing: set by avformat_open_input(), initialized to an empty* string if url parameter was NULL in avformat_open_input().* 解復用:由 avformat_open_input() 設置,如果 avformat_open_input() 中的 url 參數為 NULL,則將其初始化為空字符串字符串* - muxing: may be set by the caller before calling avformat_write_header()* (or avformat_init_output() if that is called first) to a string* which is freeable by av_free(). Set to an empty string if it* was NULL in avformat_init_output().* 復用:可以在調用 avformat_write_header() 之前由調用者設置(或 avformat_init_output() 如果首先調用)到一個字符串* 在 avformat_init_output() 中為 NULL,** Freed by libavformat in avformat_free_context(). //在 avformat_free_context() 中被 libavformat 釋放*/char *url;/*** Position of the first frame of the component, in //組件第一幀的位置* AV_TIME_BASE fractional seconds. NEVER set this value directly: //AV_TIME_BASE 小數秒。 切勿直接設置此值* It is deduced from the AVStream values. //它是從 AVStream 值推導出來的** Demuxing only, set by libavformat. //僅解復用,由 libavformat 設置*/int64_t start_time;/*** Duration of the stream, in AV_TIME_BASE fractional * seconds. Only set this value if you know none of the individual stream* durations and also do not set any of them. This is deduced from the* AVStream values if not set.** 流的持續時間,以 AV_TIME_BASE 小數秒為單位。 僅當您不知道任何單個流持續時間并且不設置* 任何一個時才設置此值。 如果未設置,則從 AVStream 值推導出來。** Demuxing only, set by libavformat. //僅解復用,由 libavformat 設置*/int64_t duration;/*** Total stream bitrate in bit/s, 0 if not* available. Never set it directly if the file_size and the* duration are known as FFmpeg can compute it automatically.** 以比特/秒為單位的總流比特率,如果不可用,則為 0。 * 請不要直接設置它,如果FFmpeg知道文件大小和持續時間則可以自動計算,*/int64_t bit_rate;unsigned int packet_size;int max_delay;/*** Flags modifying the (de)muxer behaviour. A combination of AVFMT_FLAG_*.* Set by the user before avformat_open_input() / avformat_write_header().* 修改(de)muxer 行為的標志。 avformat_open_input() / avformat_write_header() 之前用戶設置的 AVFMT_FLAG_* 的組合*/int flags;
#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. //即使需要解析未來的幀,也會生成缺失的點
#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. //忽略索引。
#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. //從輸入讀取數據包時不要阻塞
#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS //忽略同時包含 DTS 和 PTS 的幀上的 DTS
#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container //不要從其他值推斷任何值,只返回存儲在容器中的內容
#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
//不要使用 AVParsers,您還必須設置 AVFMT_FLAG_NOFILLIN,因為填充代碼適用于幀并且不解析 -> 不幀。 如果解析以查找幀邊界已被禁用,則查找幀也無法工作
#define AVFMT_FLAG_NOBUFFER 0x0040 ///< Do not buffer frames when possible //盡可能不要緩沖幀
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it. //調用者提供了一個自定義 AVIOContext,不要使用 avio_close() 它。
#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted //丟棄標記為損壞的幀
#define AVFMT_FLAG_FLUSH_PACKETS 0x0200 ///< Flush the AVIOContext every packet. //刷新每個數據包的 AVIOContext。
/*** When muxing, try to avoid writing any random/volatile data to the output. //復用時,盡量避免將任何隨機/易失性數據寫入輸出* This includes any random IDs, real-time timestamps/dates, muxer version, etc. //這包括任何隨機 ID、實時時間戳/日期、復用器版本等** This flag is mainly intended for testing. //此標志主要用于測試*/#define AVFMT_FLAG_BITEXACT 0x0400
#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) //嘗試通過 dts 交錯輸出的數據包(使用此標志會減慢解復用速度)
#if FF_API_LAVF_PRIV_OPT
#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (deprecated, does nothing) //通過延遲打開編解碼器來啟用私有選項(已棄用,不執行任何操作)
#endif
#define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats //對某些格式啟用快速但不準確的搜索
#define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. //當最短的流停止時停止混合
#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Add bitstream filters as requested by the muxer //根據復用器的要求添加比特流過濾器/*** Maximum number of bytes read from input in order to determine stream* properties. Used when reading the global header and in* avformat_find_stream_info().* * 從輸入中讀取的最大字節數以確定流屬性。 在讀取全局標頭和 avformat_find_stream_info() 時使用** Demuxing only, set by the caller before avformat_open_input(). //僅解復用,由調用者在 avformat_open_input() 之前設置** @note this is \e not used for determining the \ref AVInputFormat //@note 這不是 \e 用于確定 \ref AVInputFormat "輸入格式"* "input format" * @sa format_probesize @sa format_probesize*/int64_t probesize;/*** Maximum duration (in AV_TIME_BASE units) of the data read* from input in avformat_find_stream_info(). //從 avformat_find_stream_info() 中的輸入讀取的數據的最大持續時間(以 AV_TIME_BASE 為單位)* Demuxing only, set by the caller before avformat_find_stream_info(). //僅解復用,由調用者在 avformat_find_stream_info() 之前設置* Can be set to 0 to let avformat choose using a heuristic. //可以設置為 0 讓 avformat 使用啟發式方法進行選擇*/int64_t max_analyze_duration;const uint8_t *key;int keylen;unsigned int nb_programs;AVProgram **programs;/*** Forced video codec_id. //強制視頻 codec_id* Demuxing: Set by user. //解復用:由用戶設置*/enum AVCodecID video_codec_id;/*** Forced audio codec_id. //強制音頻 codec_id* Demuxing: Set by user. //解復用:由用戶設置*/enum AVCodecID audio_codec_id;/*** Forced subtitle codec_id. //強制字幕 codec_id* Demuxing: Set by user. //解復用:由用戶設置*/enum AVCodecID subtitle_codec_id;/*** 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;/*** Maximum amount of memory in bytes to use for buffering frames* obtained from realtime capture devices. //用于緩沖從實時捕獲設備獲得的幀的最大內存量(以字節為單位)*/unsigned int max_picture_buffer;/*** Number of chapters in AVChapter array. //AVChapter 數組中的章節數* When muxing, chapters are normally written in the file header,* so nb_chapters should normally be initialized before write_header* is called. Some muxers (e.g. mov and mkv) can also write chapters* in the trailer. To write chapters in the trailer, nb_chapters* must be zero when write_header is called and non-zero when* write_trailer is called.* 復用時,章節通常寫入文件頭,因此 nb_chapters 通常應在調用 write_header 之前初始化* 一些混音器(例如 mov 和 mkv)也可以在預告片中編寫章節* 要在預告片中寫入章節,調用 write_header 時 nb_chapters 必須為零,調用 write_trailer 時 nb_chapters 必須為非零* - muxing: set by user //muxing:由用戶設置* - demuxing: set by libavformat //解復用:由 libavformat 設置*/unsigned int nb_chapters;AVChapter **chapters;/*** Metadata that applies to the whole file. //適用于整個文件的元數據** - demuxing: set by libavformat in avformat_open_input() //解復用:由 avformat_open_input() 中的 libavformat 設置* - muxing: may be set by the caller before avformat_write_header() //muxing:可以在 avformat_write_header() 之前由調用者設置** Freed by libavformat in avformat_free_context(). //在 avformat_free_context() 中被 libavformat 釋放*/AVDictionary *metadata;/*** Start time of the stream in real world time, in microseconds //實時流的開始時間,以微秒為單位* since the Unix epoch (00:00 1st January 1970). That is, pts=0 in the* stream was captured at this real world time. //自 Unix 時代(1970 年 1 月 1 日 00:00)開始。 也就是說,流中的 pts=0 是在這個真實世界時間捕獲的* - muxing: Set by the caller before avformat_write_header(). If set to* either 0 or AV_NOPTS_VALUE, then the current wall-time will* be used.* muxing:由調用者在 avformat_write_header() 之前設置。 如果設置為 0 或 AV_NOPTS_VALUE,則將使用當前的掛墻時間* - demuxing: Set by libavformat. AV_NOPTS_VALUE if unknown. Note that* the value may become known after some number of frames* have been received.* 解復用:由 libavformat 設置。 AV_NOPTS_VALUE 如果未知。 請注意,在接收到一定數量的幀后,該值可能會變得已知。*/int64_t start_time_realtime;/*** The number of frames used for determining the framerate in* avformat_find_stream_info(). //用于確定 avformat_find_stream_info() 中的幀速率的幀數* Demuxing only, set by the caller before avformat_find_stream_info(). //僅解復用,由調用者在 avformat_find_stream_info() 之前設置*/int fps_probe_size;/*** Error recognition; higher values will detect more errors but may* misdetect some more or less valid parts as errors. //錯誤識別; 較高的值將檢測到更多的錯誤,但可能會將某些或多或少的有效部分誤檢測為錯誤* Demuxing only, set by the caller before avformat_open_input(). //僅解復用,由調用者在 avformat_open_input() 之前設置*/int error_recognition;/*** Custom interrupt callbacks for the I/O layer. //I/O 層的自定義中斷回調** demuxing: set by the user before avformat_open_input(). //demuxing:由用戶在 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. //muxing:在 avformat_write_header() 之前由用戶設置(主要用于 AVFMT_NOFILE 格式)。 如果用于打開文件,還應將回調傳遞給 avio_open2()*/AVIOInterruptCB interrupt_callback;/*** Flags to enable debugging. //啟用調試的標志*/int debug;
#define FF_FDEBUG_TS 0x0001/*** 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.* 為確保所有流正確交錯,av_interleaved_write_frame() 將等待每個流至少有一個數據包,然后再將任何數據包實際寫入輸出文件。* 當某些流是“稀疏的”時(即連續數據包之間有很大的間隙),這可能會導致過度緩沖。* 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.* 此字段指定復用隊列中第一個和最后一個數據包的時間戳之間的最大差值,超過該值 libavformat 將輸出一個數據包,無論它是否已為所有流排隊一個數據包。* Muxing only, set by the caller before avformat_write_header(). //僅復用,由調用者在 avformat_write_header() 之前設置*/int64_t max_interleave_delta;/*** Allow non-standard and experimental extension //允許非標準和實驗性擴展* @see AVCodecContext.strict_std_compliance*/int strict_std_compliance;/*** Flags indicating events happening on the file, a combination of* AVFMT_EVENT_FLAG_*. //指示文件上發生的事件的標志,AVFMT_EVENT_FLAG_* 的組合** - demuxing: may be set by the demuxer in avformat_open_input(),* avformat_find_stream_info() and av_read_frame(). Flags must be cleared* by the user once the event has been handled.* 解復用:可以由解復用器在 avformat_open_input() 中設置,avformat_find_stream_info() 和 av_read_frame()。 處理完事件后,用戶必須清除標志。* - muxing: may be set by the user after avformat_write_header() to* indicate a user-triggered event. The muxer will clear the flags for* events it has handled in av_[interleaved]_write_frame().* muxing:可以在 avformat_write_header() 之后由用戶設置以指示用戶觸發的事件.復用器將清除它在 av_[interleaved]_write_frame() 中處理的事件的標志。*/int event_flags;
/*** - demuxing: the demuxer read new metadata from the file and updated* AVFormatContext.metadata accordingly* - muxing: the user updated AVFormatContext.metadata and wishes the muxer to* write it into the file*/
#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001/*** Maximum number of packets to read while waiting for the first timestamp.* Decoding only.*/int max_ts_probe;/*** Avoid negative timestamps during muxing.* Any value of the AVFMT_AVOID_NEG_TS_* constants.* Note, this works better when using av_interleaved_write_frame().* - muxing: Set by user* - demuxing: unused*/int avoid_negative_ts;
#define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by target format
#define AVFMT_AVOID_NEG_TS_DISABLED 0 ///< Do not shift timestamps even when they are negative.
#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that they start at 0/*** Transport stream id.* This will be moved into demuxer private options. Thus no API/ABI compatibility*/int ts_id;/*** Audio preload 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 audio_preload;/*** 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;/*** 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;/*** forces the use of wallclock timestamps as pts/dts of packets* This has undefined results in the presence of B frames.* - encoding: unused* - decoding: Set by user*/int use_wallclock_as_timestamps;/*** avio flags, used to force AVIO_FLAG_DIRECT.* - encoding: unused* - decoding: Set by user*/int avio_flags;/*** The duration field can be estimated through various ways, and this field can be used* to know how the duration was estimated.* - encoding: unused* - decoding: Read by user*/enum AVDurationEstimationMethod duration_estimation_method;/*** Skip initial bytes when opening stream* - encoding: unused* - decoding: Set by user*/int64_t skip_initial_bytes;/*** Correct single timestamp overflows* - encoding: unused* - decoding: Set by user*/unsigned int correct_ts_overflow;/*** Force seeking to any (also non key) frames.* - encoding: unused* - decoding: Set by user*/int seek2any;/*** Flush the I/O context after each packet.* - encoding: Set by user* - decoding: unused*/int flush_packets;/*** format probing score.* The maximal score is AVPROBE_SCORE_MAX, its set when the demuxer probes* the format.* - encoding: unused* - decoding: set by avformat, read by user*/int probe_score;/*** Maximum number of bytes read from input in order to identify the* \ref AVInputFormat "input format". Only used when the format is not set* explicitly by the caller.* 從輸入讀取的最大字節數,以識別 \ref AVInputFormat “輸入格式”。 僅在調用者未明確設置格式時使用* Demuxing only, set by the caller before avformat_open_input(). //僅解復用,由調用者在 avformat_open_input() 之前設置** @sa probesize*/int format_probesize;/*** ',' separated list of allowed decoders.* If NULL then all are allowed* - encoding: unused* - decoding: set by user*/char *codec_whitelist;/*** ',' separated list of allowed demuxers. //',' 允許的分離器的分隔列表。* If NULL then all are allowed* - encoding: unused* - decoding: set by user*/char *format_whitelist;/*** IO repositioned flag. //IO 重新定位標志* This is set by avformat when the underlaying IO context read pointer* is repositioned, for example when doing byte based seeking. //這是在底層 IO 上下文讀取指針重新定位時由 avformat 設置的,例如在進行基于字節的查找時* Demuxers can use the flag to detect such changes. //Demuxers 可以使用該標志來檢測此類更改*/int io_repositioned;/*** Forced video codec. //強制視頻編解碼器* This allows forcing a specific decoder, even when there are multiple with* the same codec_id. //這允許強制使用特定的解碼器,即使有多個具有相同的 codec_id* Demuxing: Set by user //解復用:由用戶設置*/const AVCodec *video_codec;/*** Forced audio codec. //強制音頻編解碼器* This allows forcing a specific decoder, even when there are multiple with* the same codec_id. //這允許強制使用特定的解碼器,即使有多個具有相同的 codec_id* Demuxing: Set by user //解復用:由用戶設置*/const AVCodec *audio_codec;/*** Forced subtitle codec. //強制字幕編解碼器* This allows forcing a specific decoder, even when there are multiple with* the same codec_id. //這允許強制使用特定的解碼器,即使有多個具有相同的 codec_id* Demuxing: Set by user //解復用:由用戶設置*/const AVCodec *subtitle_codec;/*** Forced data codec. //強制數據編解碼器* This allows forcing a specific decoder, even when there are multiple with * the same codec_id.//這允許強制使用特定的解碼器,即使有多個具有相同的 codec_id* Demuxing: Set by user //解復用:由用戶設置*/const AVCodec *data_codec;/*** 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. //Muxing:由用戶通過 av_format_set_metadata_header_padding 設置*/int metadata_header_padding;/*** User data.* This is a place for some private data of the user.*/void *opaque;/*** Callback used by devices to communicate with application. //設備用于與應用程序通信的回調。*/av_format_control_message control_message_cb;/*** Output timestamp offset, in microseconds. //輸出時間戳偏移量,以微秒為單位* Muxing: set by user*/int64_t output_ts_offset;/*** dump format separator. //轉儲格式分隔符* can be ", " or "\n " or anything else //可以是 ", " 或 "\n" 或其他任何東西* - muxing: Set by user.* - demuxing: Set by user.*/uint8_t *dump_separator;/*** Forced Data codec_id. //強制數據 codec_id* Demuxing: Set by user.*/enum AVCodecID data_codec_id;/*** ',' separated list of allowed protocols. //',' 分隔的允許協議列表* - encoding: unused* - decoding: set by user*/char *protocol_whitelist;/*** A callback for opening new IO streams. //打開新 IO 流的回調** 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.* 每當復用器或解復用器需要打開 IO 流(通常來自解復用器的 avformat_open_input(),但對于某些格式也可能在其他時間發生),它將調用此回調以獲取 IO 上下文。* @param s the format context //s 格式上下文* @param pb on success, the newly opened IO context should be returned here //pb 成功,這里應該返回新打開的 IO 上下文* @param url the url to open //url 要打開的 url* @param flags a combination of AVIO_FLAG_* //標記 AVIO_FLAG_ 的組合** @param options a dictionary of additional options, with the same* semantics as in avio_open2() //options 附加選項的字典,具有相同的語義如 avio_open2()* @return 0 on success, a negative AVERROR code on failure //0 成功,負 AVERROR 代碼失敗** @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.* 某些復用器和解復用器會進行嵌套,即它們會打開一個或多個額外的內部格式上下文。 因此,傳遞給此回調的 AVFormatContext 指針可能與面向調用者的指針不同。* 但是,它將具有相同的“不透明”字段。*/int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url,int flags, AVDictionary **options);/*** A callback for closing the streams opened with AVFormatContext.io_open(). //用于關閉使用 AVFormatContext.io_open() 打開的流的回調。*/void (*io_close)(struct AVFormatContext *s, AVIOContext *pb);/*** ',' separated list of disallowed protocols. //不允許的協議的單獨列表* - encoding: unused* - decoding: set by user*/char *protocol_blacklist;/*** The maximum number of streams.* - encoding: unused* - decoding: set by user*/int max_streams;/*** Skip duration calcuation in estimate_timings_from_pts. //在 pts 的估計時間中跳過持續時間計算。* - encoding: unused* - decoding: set by user*/int skip_estimate_duration_from_pts;/*** Maximum number of packets that can be probed //可探測的最大數據包數* - encoding: unused //編碼:未使用* - decoding: set by user //解碼:由用戶設置*/int max_probe_packets;/*** A callback for closing the streams opened with AVFormatContext.io_open(). //用于關閉使用 AVFormatContext.io_open() 打開的流的回調** Using this is preferred over io_close, because this can return an error. //使用 this 優于 io_close,因為這可能會返回錯誤* Therefore this callback is used instead of io_close by the generic //因此,如果 io_close 為 NULL 或默認值,則通用 libavformat 代碼使用此回調而不是 io_close* libavformat code if io_close is NULL or the default.** @param s the format context //格式上下文* @param pb IO context to be closed and freed //IO 上下文被關閉和釋放* @return 0 on success, a negative AVERROR code on failure //0 成功,負 AVERROR 代碼失敗*/int (*io_close2)(struct AVFormatContext *s, AVIOContext *pb);
} AVFormatContext;
- ?AVFormatCOntext是ffmpeg開發中貫穿始終的數據結構,許多函數均以它為參數
- 它是FFmpeg解封裝(flv、MP4、rmvb、avi)功能的結構體
- 幾個主要變量的作用,限定范圍為編碼領域
- AVIOContext *pb;? 輸入數據的緩存
- unsigned int nb_streams; 音視頻流的個數
- AVStream **streams; 音視頻流
- int64_t duration; 時長(單位:微秒us,轉換為秒需要除以1000000)
- int64_t bit_rate; 比特率(單位bps,轉換為kbps需要除以1000)
- AVDictionary *metadata; 元數據
將視頻的時長轉換為HH:MM:SS的形式
AVFormatContext *pFormatCtx;
CString timelong;
...
//duration是以微秒為單位
//轉換成hh:mm:ss形式
int tns, thh, tmm, tss;
tns = (pFormatCtx->duration)/1000000; //微秒 -> 秒
thh = tns / 3600; //計算 時
tmm = (tns % 3600) / 60; //計算 分
tss = (tns % 60); //計算 秒
timelong.Format("%02d:%02d:%02d",thh,tmm,tss); //指定輸出格式
- 視頻的原數據(metadata)信息可以通過AVDictionary獲取。
- 元數據存儲在AVDictionaryEntry結構體中,如下所示
typedef struct AVDictionaryEntry {char *key;char *value;
} AVDictionaryEntry;typedef struct AVDictionary AVDictionary;
- 每一條元數據分為key和value兩個屬性。
- 在ffmpeg中通過av_dict_get()函數獲得視頻的原數據。
AVDictionaryEntry *av_dict_get(const AVDictionary *m, const char *key,const AVDictionaryEntry *prev, int flags)
{unsigned int i, j;if (!m)return NULL;if (prev)i = prev - m->elems + 1;elsei = 0;for (; i < m->count; i++) {const char *s = m->elems[i].key;if (flags & AV_DICT_MATCH_CASE)for (j = 0; s[j] == key[j] && key[j]; j++);elsefor (j = 0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++);if (key[j])continue;if (s[j] && !(flags & AV_DICT_IGNORE_SUFFIX))continue;return &m->elems[i];}return NULL;
}
- 下列代碼顯示了獲取元數據并存入meta字符串變量的過程,注意每一條key和value之間有一個"\t:",value之后有一個"\r\n"
//MetaData------------------------------------------------------------
//從AVDictionary獲得
//需要用到AVDictionaryEntry對象
//CString author,copyright,description;
CString meta=NULL,key,value;
AVDictionaryEntry *m = NULL;
//不用一個一個找出來
/* m=av_dict_get(pFormatCtx->metadata,"author",m,0);
author.Format("作者:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"copyright",m,0);
copyright.Format("版權:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"description",m,0);
description.Format("描述:%s",m->value);
*/
//使用循環讀出
//(需要讀取的數據,字段名稱,前一條字段(循環時使用),參數)
while(m=av_dict_get(pFormatCtx->metadata,"",m,AV_DICT_IGNORE_SUFFIX)){key.Format(m->key);value.Format(m->value);meta+=key+"\t:"+value+"\r\n" ;
}