天天看点

avformat_find_stream_info

```

// 类似于一个接口类,多态为每一个容器格式,mp4,flv等等,还有一堆read_header,read_probe等接口函数

// 是解复用对象,每一种文件容器格式对应一个AVInputFormat,在程序运行时有多个实例。

// 在ffmpeg初始化时,把所有的容器格式通过next组成链表,查找也是通过遍历链表就行查找。

// 以MP3为例

 AVInputFormat ff_mp3_demuxer = {

    .name = "mp3",

    .long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),

    .read_probe = mp3_read_probe,

    .read_header = mp3_read_header,

    .read_packet = mp3_read_packet,

    .read_seek = mp3_seek,

    .priv_data_size = sizeof(MP3DecContext),

    .flags = AVFMT_GENERIC_INDEX,

    .extensions = "mp2,mp3,m2a,mpa",

    .priv_class = &demuxer_class,

}

typedef struct AVInputFormat {

    //格式的短名称,例子中就是mp3

    const char *name; 

    //格式的长名称,egg中的"MP2/3 (MPEG audio layer 2/3)"

    const char *long_name;

    int flags;

    //如果定义了拓展,则不进行格式探测,但是不常用,应为不可靠

    const char *extensions; 

    const struct AVCodecTag * const *codec_tag;

     ///< AVClass for the private context 用于内部的Context

    const AVClass *priv_class;

    //mime类型,如video/avc,在probing时需要检查

    const char *mime_type; 

    //**************************下面都是非公共字段**************************************\

    //链表指针,指向下一个AVInputFormat

    struct AVInputFormat *next;

    //原始Demuxer存储的codec_id

    int raw_codec_id; 

    //某种格式文件的数据大小

    int priv_data_size; 

    //读取probe数据,提供的probe数据必须保证AVPROBE_PADDING_SIZE

    int (*read_probe)(AVProbeData *); 

    //读取format头并初始化AVFormatContext结构,返回0,表示ok

    int (*read_header)(struct AVFormatContext *);

    //读取一个packet,并保存到传入的pkt指针中

    int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); 

    //关闭流

    int (*read_close)(struct AVFormatContext *);

    //seek到给定的时间戳

    int (*read_seek)(struct AVFormatContext *,int stream_index, int64_t timestamp, int flags); 

    //读取给定的时间戳

    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 *);

     //快进快退到指定时间戳

    int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);

    //返回设备列表及其属性

    int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); 

    //初始化设备能力子模块

    int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);

    // 释放设备能力子模块

    int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);

} AVInputFormat;

```