AVOutputFormat 结构体
/*** @addtogroup lavf_encoding* @{*/
typedef struct AVOutputFormat {const char *name;/*** Descriptive name for the format, meant to be more human-readable* than name. You should use the NULL_IF_CONFIG_SMALL() macro* to define it.*/const char *long_name;const char *mime_type;const char *extensions; /**< comma-separated filename extensions *//* output support */enum AVCodecID audio_codec; /**< default audio codec */enum AVCodecID video_codec; /**< default video codec */enum AVCodecID subtitle_codec; /**< default subtitle codec *//*** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER,* AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,* AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE*/int flags;/*** List of supported codec_id-codec_tag pairs, ordered by "better* choice first". The arrays are all terminated by AV_CODEC_ID_NONE.*/const struct AVCodecTag * const *codec_tag;const AVClass *priv_class; ///< AVClass for the private context/****************************************************************** No fields below this line are part of the public API. They* may not be used outside of libavformat and can be changed and* removed at will.* New public fields should be added right above.******************************************************************//*** The ff_const59 define is not part of the public API and will* be removed without further warning.*/
#if FF_API_AVIOFORMAT
#define ff_const59
#else
#define ff_const59 const
#endifff_const59 struct AVOutputFormat *next;/*** size of private data so that it can be allocated in the wrapper*/int priv_data_size;int (*write_header)(struct AVFormatContext *);/*** Write a packet. If AVFMT_ALLOW_FLUSH is set in flags,* pkt can be NULL in order to flush data buffered in the muxer.* When flushing, return 0 if there still is more data to flush,* or 1 if everything was flushed and there is no more buffered* data.*/int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);int (*write_trailer)(struct AVFormatContext *);/*** A format-specific function for interleavement.* If unset, packets will be interleaved by dts.*/int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,AVPacket *in, int flush);/*** Test if the given codec can be stored in this container.** @return 1 if the codec is supported, 0 if it is not.* A negative number if unknown.* MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC*/int (*query_codec)(enum AVCodecID id, int std_compliance);void (*get_output_timestamp)(struct AVFormatContext *s, int stream,int64_t *dts, int64_t *wall);/*** Allows sending messages from application to device.*/int (*control_message)(struct AVFormatContext *s, int type,void *data, size_t data_size);/*** Write an uncoded AVFrame.** See av_write_uncoded_frame() for details.** The library will free *frame afterwards, but the muxer can prevent it* by setting the pointer to NULL.*/int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index,AVFrame **frame, unsigned flags);/*** Returns device list with it properties.* @see avdevice_list_devices() for more details.*/int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);/*** Initialize device capabilities submodule.* @see avdevice_capabilities_create() for more details.*/int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);/*** Free device capabilities submodule.* @see avdevice_capabilities_free() for more details.*/int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);enum AVCodecID data_codec; /**< default data codec *//*** Initialize format. May allocate data here, and set any AVFormatContext or* AVStream parameters that need to be set before packets are sent.* This method must not write output.** Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure** Any allocations made here must be freed in deinit().*/int (*init)(struct AVFormatContext *);/*** Deinitialize format. If present, this is called whenever the muxer is being* destroyed, regardless of whether or not the header has been written.** If a trailer is being written, this is called after write_trailer().** This is called if init() fails as well.*/void (*deinit)(struct AVFormatContext *);/*** Set up any necessary bitstream filtering and extract any extra data needed* for the global header.* Return 0 if more packets from this stream must be checked; 1 if not.*/int (*check_bitstream)(struct AVFormatContext *, const AVPacket *pkt);
} AVOutputFormat;
AVOutputFormat
是 FFmpeg 中用于管理输出文件容器格式的核心结构体,定义了封装(Muxing)行为的关键属性和操作方法14。以下是其核心功能和用法解析:
1. 功能与定义
-
核心作用
AVOutputFormat
描述输出容器格式的元数据和操作接口,支持 MP4、FLV、TS 等格式的封装逻辑实现14。
每个支持的格式对应一个独立的AVOutputFormat
实例,并以链表形式组织存储14。 -
结构体定义关键字段
typedef struct AVOutputFormat {const char *name; // 格式短名称(如 "flv")const char *long_name; // 易读的格式全称(如 "FLV (Flash Video)")const char *mime_type; // MIME 类型(如 "video/x-flv")const char *extensions; // 文件扩展名(如 "flv")enum AVCodecID audio_codec; // 默认音频编码格式enum AVCodecID video_codec; // 默认视频编码格式// 函数指针(初始化、写头/数据包/尾部等)int (*write_header)(AVFormatContext *);int (*write_packet)(AVFormatContext *, AVPacket *);int (*write_trailer)(AVFormatContext *);// 其他字段(flags、私有数据大小等)// ...
} AVOutputFormat;
关键字段说明:
name
/long_name
:标识封装格式类型14;audio_codec
/video_codec
:指定默认音视频编码格式4;- 函数指针(如
write_header
):实现格式封装的具体逻辑48。
2. 标志位(flags)
通过 flags
字段控制封装行为,常见值包括:
-
AVFMT_GLOBALHEADER
要求编码器生成全局头信息(如 H.264 的 SPS/PPS),适用于 MP4 等格式6; -
AVFMT_VARIABLE_FPS
允许可变帧率封装,适用于直播流场景6; -
AVFMT_TS_NONSTRICT
允许时间戳非严格递增,增强容错性6。
3. 使用场景与示例
3.1 获取输出格式
通过格式名称、文件扩展名或 MIME 类型查找支持的封装器:
AVOutputFormat *fmt = av_guess_format("flv", NULL, NULL); // 获取 FLV 封装器
3.2 初始化封装上下文
将 AVOutputFormat
绑定到 AVFormatContext
并执行封装操作:
AVFormatContext *oc = NULL;
avformat_alloc_output_context2(&oc, fmt, NULL, "output.flv"); // 分配上下文并关联格式
3.3 自定义格式实现
定义新的封装器需实现 AVOutputFormat
的函数接口。以 FLV 为例:
AVOutputFormat ff_flv_muxer = {.name = "flv",.long_name = "FLV (Flash Video)",.mime_type = "video/x-flv",.priv_data_size = sizeof(FLVContext), // 私有数据存储格式特定参数.audio_codec = AV_CODEC_ID_MP3,.video_codec = AV_CODEC_ID_FLV1,.write_header = flv_write_header, // 自定义头部写入逻辑.write_packet = flv_write_packet, // 数据包写入逻辑// ...
};
4. 与其他组件的关系
-
AVFormatContext
AVOutputFormat
作为其成员oformat
,驱动封装流程的控制逻辑58; -
AVCodecContext
通过audio_codec
/video_codec
关联默认编码器参数,影响流配置4; - 私有数据(
priv_data
)
存储格式特定的上下文信息(如 FLV 的FLVContext
)46。
总结
AVOutputFormat
是 FFmpeg 封装功能的核心,开发者通过配置其字段和函数指针实现不同格式的写入逻辑。实际应用中需结合目标格式的文档和源码(如 FLV、MP4 的实现)调整参数和行为。
AVInputFormat 再分析-CSDN博客