/**
* @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
#endif
ff_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。以下是其核心功能和用法解析:
核心作用
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。通过 flags
字段控制封装行为,常见值包括:
AVFMT_GLOBALHEADER
AVFMT_VARIABLE_FPS
AVFMT_TS_NONSTRICT
通过格式名称、文件扩展名或 MIME 类型查找支持的封装器:
AVOutputFormat *fmt = av_guess_format("flv", NULL, NULL); // 获取 FLV 封装器
将 AVOutputFormat
绑定到 AVFormatContext
并执行封装操作:
AVFormatContext *oc = NULL;
avformat_alloc_output_context2(&oc, fmt, NULL, "output.flv"); // 分配上下文并关联格式
定义新的封装器需实现 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, // 数据包写入逻辑
// ...
};
AVFormatContext
AVOutputFormat
作为其成员 oformat
,驱动封装流程的控制逻辑58;AVCodecContext
audio_codec
/video_codec
关联默认编码器参数,影响流配置4;priv_data
)FLVContext
)46。AVOutputFormat
是 FFmpeg 封装功能的核心,开发者通过配置其字段和函数指针实现不同格式的写入逻辑。实际应用中需结合目标格式的文档和源码(如 FLV、MP4 的实现)调整参数和行为。
AVInputFormat 再分析-CSDN博客