天天看點

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;

```