ffmpeg——AVOutputFormat 输出文件格式

本文介绍了FFmpeg中AVOutputFormat结构体的相关信息,包括封装格式的名称、描述、支持的编码格式以及操作函数等关键内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:介绍

ffmpeg支持各种各样的输出文件格式,MP4,FLV,3GP等等。而 AVOutputFormat 结构体则保存了这些格式的信息和一些常规设置。

官方参考: http://ffmpeg.org/doxygen/3.1/structAVOutputFormat.html

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.
     *****************************************************************
     */
    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 *);
    /**
     * Currently only used to set pixel format if not YUV420P.
     */
    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.
     *
     * 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 结构主要包含的信息有:封装名称描述编码格式信息(video/audio 默认编码格式,支持的编码格式列表)一些对封装的操作函数(write_header,write_packet,write_tailer等)。其中,AVOutputFormat没有实现AVClass接口,但它保存了一个AVClass接口,具体怎样被使用则由后续决定。例如:MOV类的AVOutputFormat封装保存的是 针对 MOVMuxContext 结构的 AVClass 接口实现。


每一种封装对应一个 AVOutputFormat 结构,ffmpeg将AVOutputFormat 按照链表存储:





### 如何在 FFmpeg 中注册 `AVOutputFormat` 为了使 FFmpeg 支持特定的输出格式,`AVOutputFormat` 的注册至关重要。通常情况下,在较新的版本中,FFmpeg 已经自动处理了许多常见的输入和输出格式的初始化工作。然而,如果需要手动操作或扩展支持,则可以通过调用相应的 API 来完成。 #### 手动注册 `AVOutputFormat` 当涉及到动态加载模块或是自定义格式时,可以利用如下方式来实现: 1. **静态编译环境下的全局注册** 对于大多数应用场景而言,默认构建过程已经包含了对常用多媒体容器的支持,并通过内部机制完成了必要的组件注册。因此一般不需要额外编写代码来进行此步骤的操作[^1]。 2. **动态注册新格式** 如果希望向程序引入一个新的输出格式(比如开发者自己设计的一种特殊封装),则需按照官方文档指导创建并填充好描述该格式的数据结构实例之后,再将其加入到系统的已知列表里去。这一步骤可通过函数 `av_register_output_format()` 实现。 下面给出一段简单的 C 语言示范片段用于说明如何添加一个假设性的名为 "myformat" 的输出格式: ```c #include <libavformat/avformat.h> // 定义自己的 AVOutputFormat 结构体变量 myoutputfmt static const AVOutputFormat myoutputfmt = { .name = "myformat", .long_name = NULL, /* 自动设置 */ .mime_type = "application/octet-stream", // 只是一个例子 .extensions = "mft", // 文件扩展名关联 .audio_codec = AV_CODEC_ID_AAC, .video_codec = AV_CODEC_ID_H264, }; int register_my_custom_format(void){ // 注册自定义输出格式 av_register_output_format(&myoutputfmt); return 0; } ``` 上述代码展示了怎样构造一个基本版的 `AVOutputFormat` 并成功挂载至 FFmpeg 内核之中以便后续使用。需要注意的是实际项目开发过程中可能还需要进一步完善更多细节配置项以及遵循最新的 SDK 文档指南进行调整优化[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值