02FFMPEG的AVInputFormat结构体分析

02FFMPEG的AVInputFormat结构体分析

概述:
该结构体位于libavformat库中的avformat.h中。

1 AVInputFormat结构体
对于FFmpeg没给注释的,我尽量找对应的注释,确实没有的证明我们不需要知道。

/*
 * 该结构体保存着输入文件指明码流数据用到封装格式。例如flv,mkv。 可认为是存放文件的头部相关属性信息。例如flv的头部。位于封装上下文结构体AVFormatContext的内部。
 * 
 * 注意:该结构体只有在解复用时才有效,由avformat_open_input打开时初始化赋值。复用时该结构体无效,因为复用时是输出,有效的是输出的AVOutputFormat *oformat。
*/
typedef struct AVInputFormat {
    /**
     * 以逗号分隔的格式短名称列表。新名字可能会追加一个小突起(某个辅助标识)。
     */
    const char *name;

    /**
     * 格式的描述性名称,这意味着比名称name更易于人类阅读。你应该使用NULL_IF_CONFIG_SMALL()宏来定义它。即与上面的name是一样的意思。
     */
    const char *long_name;

    /**
     * flags可以使用的标记宏: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
     */
    int flags;

    /**
     * 如果定义了扩展,则不执行探查。通常不应该使用猜测扩展格式,因为它不够可靠。
     */
    const char *extensions;

    const struct AVCodecTag * const *codec_tag;

    const AVClass *priv_class; ///< AVClass for the private context

    /**
     * 用逗号分隔的mime类型列表。
     * 在探测时,它用于检查匹配的mime类型。
     * 可查看av_probe_input_format2函数
     */
    const char *mime_type;

    /*****************************************************************
     * 这一行以下的字段都不是公共API的一部分。它们可能不会被libavformat之外的使用,并且可以被随意更改和删除。
     * 新的公共字段应该在正上方添加。
     *****************************************************************
     */
#if FF_API_NEXT
    ff_const59 struct AVInputFormat *next;//指向下一输入封装格式的结构体
#endif

    /**
     * Raw demuxers store their codec ID here.
     * 原始demuxer解复用存储它们的编解码器ID在这里。
     */
    int raw_codec_id;

    /**
     * 私有数据的大小,以便在wrapper包装器中进行分配。
     */
    int priv_data_size;

    /**
     * 告知给定文件是否有机会以这种格式被解析。
     * 提供的缓冲区保证是AVPROBE_PADDING_SIZE字节大,所以除非您需要更多,否则不必检查它。
     */
    int (*read_probe)(const AVProbeData *);

    /**
     * 读取格式头,并初始化AVFormatContext结构体
     * return 0 表示操作成功。
     * 应该调用avformat_new_stream来创建新的流(这里可不看,防止混乱,它这里指的应该是输入时内部自己需要创建新的流)。
     */
    int (*read_header)(struct AVFormatContext *);

    /**
     * 读一个包,把它放在'pkt'。还设置了pts和旗帜。
     * 'avformat_new_stream'只能在AVFMTCTX_NOHEADER标志被使用的情况下被调用,并且只能在调用线程中调用(不是在后台线程中)。
     * return 0表示操作成功, < 0 发生异常。
     * 在返回一个错误,pkt必须是未被调用者引用。即没有allocated或者在函数返回之前被释放了。
     */
    int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);

    /**
     * 关闭流。
     * AVFormatContext和AVStreams不是由这个函数释放的。
     */
    int (*read_close)(struct AVFormatContext *);

    /**
     * 在stream_index流组件的流中,使用一个给定的timestamp,seek到附近帧。
     * 参1:stream_index不能为-1。
     * 参3:选择在没有精确匹配的情况下应该首选的方向。即如果没有完全匹配,决定向前还是向后匹配。
     * return >= 0 成功。(但不一定是新的偏移)
     */
    int (*read_seek)(struct AVFormatContext *,
                     int stream_index, int64_t timestamp, int flags);

    /**
     * 获取流[stream_index]中的下一个时间戳。time_base单位。
     * 
     * 如果发生错误,返回这个时间戳或AV_NOPTS_VALUE。
     */
    int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
                              int64_t *pos, int64_t pos_limit);

    /**
     * 开始/恢复播放-只有在使用基于网络的RTSP格式时才有意义。
     */
    int (*read_play)(struct AVFormatContext *);

    /**
     * 暂停播放-只有在使用基于网络的格式(RTSP)时才有意义。
     */
    int (*read_pause)(struct AVFormatContext *);

    /**
     * seek到指定时间戳ts。
     * 进行seeking搜索的目的是使所有活动流都可以成功显示的点最接近ts,并且在min/max_ts区间内。
     * 活动流是所有拥有AVStream.discard < AVDISCARD_ALL的流(我也暂时不太懂这句话的意思)。
     * 参1:s输入封装格式上下文。
     * 参2:stream_index 需要快进/后退操作的流。
     * 参3,参4:seek的区间,ts需要在这个范围中。
     * 参5:与上面的一样,如果没有完全匹配,决定向前还是向后匹配。
     */
    int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);

    /**
     * 返回设备列表和它的属性。
     * 更多详细可查看avdevice_list_devices()函数。
     */
    int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);

    /**
     * 初始化创建设备功能子模块。
     * 更多详细可查看avdevice_capabilities_create()函数。
     */
    int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);

    /**
     * 释放设备能力子模块。
     * 更多详细可查看avdevice_capabilities_free()函数。
     */
    int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);
} AVInputFormat;

2 AVInputFormat中重要的成员
实际上该结构体并无太重要的成员,它里面只是存储了输入文件的相关属性。例如flv,mkv封装格式名称。其它均为avformat内部处理封装格式的API,即mime_type以下的字段。

typedef struct AVInputFormat {
	const char *name;//输入时的封装格式名
	const char *long_name;//同上,但是更人性化
	const char *extensions;//输入封装格式的扩展名
	/*......*/
}AVInputFormat;

3 总结AVInputFormat输入封装格式结构体
1)解复用时由avformat_open_input初始化赋值,且只在解复用有效,复用无效(不使用它,而使用另一个AVOutputFormat )。
注:有效是指输入时的AVFormatContext->AVInputFormat有效,而输出时是指另一个AVFormatContext->AVOutputFormat有效,第一个AVFormatContext和第二个AVFormatContext是不同的,一个是输入时的解封装上下文,一个是输出时的封装上下文。

2)存放输入文件的相关封装属性和其它处理封装格式的API,且这些API只在avformat内部有效。

这个结构体非常简单,我们只需要知道总结的那两点,即它如何初始化赋值和它的作用即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值