2.AVFormatContext和AVInputFormat

参考https://blog.csdn.net/leixiaohua1020/article/details/14214705

 

AVFormatContext: 用来存储视音频封装格式(flv,mp4,rmvb,avi)中包含的所有信息 很多函数都要用到它作为参数。

AVFormatContext结构体如下所示(显示部分成员,后续深入添加):

typedef struct AVFormatContext {
    
    const AVClass *av_class;    //包含AVCodecContext, AVFormatContext 

    /**
     * The input container format.
     *
     * Demuxing only, set by avformat_open_input().
     */
    ff_const59 struct AVInputFormat *iformat;        //AVInputFormat:封装格式(flv、mkv、avi等),调用avformat_open_input()时,该成员就会被初始化

  
    ff_const59 struct AVOutputFormat *oformat;    //输入的封装格式(生成视频),调用avformat_write_header()时,该成员就会被初始化

   
    unsigned int nb_streams;  //AVFormatContext中的流个数,一般为2,如果要设置,则只能通过avformat_new_stream()来设置

    AVStream **streams;        //输入视频的AVStream流数组,通过avformat_open_input()来初始化流信息

#if FF_API_FORMAT_FILENAME
    
    attribute_deprecated
    char filename[1024];        //输入输出文件名路径,通过avformat_open_input()和avformat_write_header()来设置
#endif

   
    char *url;        //输入或输出URL,与filename字段不同,此字段没有长度限制。通过avformat_open_input()和avformat_write_header()来设置

    /**
     * Position of the first frame of the component, in
     * AV_TIME_BASE fractional seconds. NEVER set this value directly:
     * It is deduced from the AVStream values.
     *
     * Demuxing only, set by libavformat.
     */
    int64_t start_time;        //第一帧的时间位置,一般为0


    int64_t duration;        //所有的总时长(如果要切进度,最好还是用AVStreams里的duration),以微妙为单位,换算以秒为单位: duration/AV_TIME_BASE

    /**
     * Total stream bitrate in bit/s, 0 if not
     * available. Never set it directly if the file_size and the
     * duration are known as FFmpeg can compute it automatically.
     */
    int64_t bit_rate;        //输入视频的码率,单位为bit/s

    unsigned int packet_size;
    int max_delay;


    const uint8_t *key;
    int keylen;

    unsigned int nb_programs;
    AVProgram **programs;

    enum AVCodecID video_codec_id; //需要强制设置的视频编码id,默认为0,自动设置

  
    enum AVCodecID audio_codec_id;        //需要强制设置的音频编码id,默认为0,自动设置

  
    enum AVCodecID subtitle_codec_id;//需要强制设置的字幕编码id,默认为0,自动设置

    
    AVDictionary *metadata;        //整个文件的元数据,可以通过通过av_dict_get()函数获得视频的原数据,AVDictionary包含两个成员key和value
    //使用循环读出
        //(需要读取的数据,字段名称,前一条字段(循环时使用),参数)
    //while(m=av_dict_get(pFormatCtx->metadata,"",m,AV_DICT_IGNORE_SUFFIX)){
    //    key.Format(m->key);
    //    value.Format(m->value);
    //    qDebug()<<"key-value:"<<key<<"\t:"+value+"\r\n" ;
    //}

   
    int64_t start_time_realtime;    //流的实际启动时间,以微秒为单位

    int probe_score;        //格式探测得分,100是最大的分数,这意味着FFmpeg确信格式是真实的

  
    AVCodec *video_codec;        //用户设置的强制视频解码器,如果用户未设置,就为NULL

    AVCodec *audio_codec;        //用户设置的强制音频解码器

    AVCodec *subtitle_codec; //用户设置的强制字幕解码器

   ... ...
} AVFormatContext;

 其中iformat成员就是指向视频/音频流的封装格式(flv、mkv、avi等)具体结构体的指针.

该成员的AVInputFormat结构体如下所示(显示部分成员,后续深入添加):

typedef struct AVInputFormat
{

const char *name; // 封装格式的名字, 比如,“mov” “mp4” 等。

const char *long_name;    ///封装格式的长名字
//标示具体的format对应的Context 的size,如:MovContext。

const char *extensions;    //扩展名,如果定义了, 则不执行探测视频格式, 通常不使用扩展格式猜测,因为不可靠
//具体的操作函数 int(*read_probe)(AVProbeData*); int(*read_header)(struct AVFormatContext *,AVFormatParameters *ap); int(*read_packet)(struct AVFormatContext *, AVPacket *pkt); int(*read_close)(struct AVFormatContext*); struct AVInputFormat *next; } AVInputFormat

 

posted @ 2020-06-24 16:53  诺谦  阅读(1956)  评论(0编辑  收藏  举报