音视频开发18 FFmpeg AVCodec 说明,AVCodecContext 说明

AVCodec 

AVCodec:是音视频编解码器结构体,用于定义特定的编解码器。
它包含了编解码器的类型、名称、支持的音视频格式、编解码函数等。
通过AVCodec结构体,可以查询和获取系统中可用的编解码器,并与AVCodecContext关联以进行音视频编解码操作。

对于音频,一定要知道 采样率,采样格式,声道数   

采样率: Sampling Rate 44100. 每秒中采集多少个音频点。 在ffmpeg 中 对应类型为 AVRational *supported_framerates
采样格式:16 bit, 32 bit, 在ffmpeg 中 对应类型为 AVSampleFormat
声道数: 1为单声道,2 为立体声 在ffmpeg 中 对应类型为 AVChannelLayout


对于视频,一定要知道视频的像素,视频的格式-也就是RGB/yuv, fps

像素,1600*780  暂时没有对应的值
RGB/YUV类型,AVPixelFormat AV_PIX_FMT_YUV420P
fps(每秒播放多少个图片)  AVRational *supported_framerates

const char *name:编解码器的名字,比较短

const char *long_name:编解码器的名字,全称,比较长

enum AVMediaType type:指明了类型,是视频,音频,还是字幕

enum AVCodecID id:ID,不重复

const AVRational *supported_framerates:支持的帧率(仅视频)

const enum AVPixelFormat *pix_fmts:支持的像素格式(仅视频)

const int *supported_samplerates:支持的采样率(仅音频)

const enum AVSampleFormat *sample_fmts:支持的采样格式(仅音频)

const uint64_t *channel_layouts:支持的声道数(仅音频)

int priv_data_size:私有数据的大小
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/leixiaohua1020/article/details/14215833

typedef struct AVCodec {
    /**
     * Name of the codec implementation.
     * The name is globally unique among encoders and among decoders (but an
     * encoder and a decoder can share the same name).
     * This is the primary way to find a codec from the user perspective.
     *编解码器实现的名称。
		 *该名称在编码器和解码器之间是全局唯一的(但编码器和解码器可以共享相同的名称)。
		 *这是从用户角度找到编解码器的主要方法。
     */
    const char *name;
    
    
    /**
     * Descriptive name for the codec, meant to be more human readable than name.
     * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
     *编解码器的描述性名称,意味着比名称更易于阅读。
		 *您应该使用NULL_IF_CONFIG_SMALL()宏来定义它。
     */
    const char *long_name;
    
    //该编解码器的 类型,enum AVMediaType type; 类似 AVMEDIA_TYPE_VIDEO,AVMEDIA_TYPE_AUDIO
    enum AVMediaType type;
    
    
    //类似 AV_CODEC_ID_AAC,AV_CODEC_ID_H264 , AAC 对应的值是十进制是86018,十六进制是15002
    enum AVCodecID id;
    
    
    /**
     * Codec capabilities.
     * see AV_CODEC_CAP_*
     * int capabilities;
     * AAC 作为 encoder 的值是98,对应的二进制是 0110 0010,对应的如下的三个值 或 起来
     *      #define AV_CODEC_CAP_DR1                 (1 <<  1)
            #define AV_CODEC_CAP_DELAY               (1 <<  5)
            #define AV_CODEC_CAP_SMALL_LAST_FRAME    (1 <<  6)
     */
    int capabilities;
    
    ///< maximum value for lowres supported by the decoder
    /// 视频专用 解码器支持的低分辨率的最大值
    uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoder
    
    // 支持的帧率(仅视频)
    const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
    
    
    /// 支持的像素格式(仅视频)
    const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
    
    ///支持的采样率(仅音频)
    const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
    
    ///支持的采样格式(仅音频)
    const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1





#if FF_API_OLD_CHANNEL_LAYOUT
    /**
     * @deprecated use ch_layouts instead
     */
    attribute_deprecated
    const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
#endif
    const AVClass *priv_class;              ///< AVClass for the private context
    const AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {AV_PROFILE_UNKNOWN}

    /**
     * Group name of the codec implementation.
     * This is a short symbolic name of the wrapper backing this codec. A
     * wrapper uses some kind of external implementation for the codec, such
     * as an external library, or a codec implementation provided by the OS or
     * the hardware.
     * If this field is NULL, this is a builtin, libavcodec native codec.
     * If non-NULL, this will be the suffix in AVCodec.name in most cases
     * (usually AVCodec.name will be of the form "<codec_name>_<wrapper_name>").
     */
    const char *wrapper_name;

    /**
     * Array of supported channel layouts, terminated with a zeroed layout.
     */
    const AVChannelLayout *ch_layouts;
} AVCodec;












视频和音频对应的参数

音频

对于音频,一定要知道 采样率,采样格式,声道数   

采样率: Sampling Rate 44100. 每秒中采集多少个音频点。 在ffmpeg 中 对应类型为 AVRational *supported_framerates
采样格式:16 bit, 32 bit, 在ffmpeg 中 对应类型为 AVSampleFormat
声道数: 1为单声道,2 为立体声 在ffmpeg 中 对应类型为 AVChannelLayout


    const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
    音频格式,支持的样本格式的数组,如果未知则为NULL,数组以-1终止   AVSampleFormat  AV_SAMPLE_FMT_S16,音频格式

    const AVChannelLayout *ch_layouts;  //Array of supported channel layouts, terminated with a zeroed layout.
   	音频的声道数
   	
   	const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
    支持的音频采样率数组,如果未知则为NULL,数组由0终止    int * 所支持的音频采样率 数组 如果有值,应该是44100,48000等







视频

对于视频,一定要知道视频的像素,视频的格式-也就是RGB/yuv, fps

像素,1600*780  暂时没有对应的值,这也很好理解,AVCodec 是编解码器的参数,编解码厂商支持的视频应该是多大的都应该支持

RGB/YUV类型,AVPixelFormat AV_PIX_FMT_YUV420P  对应 pix_fmts
fps(每秒播放多少个图片)  AVRational *supported_framerates


    // 支持的帧率(仅视频)
    const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
    
    
    /// 支持的像素格式(仅视频)
    const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
    

详细介绍几个变量:

1.enum AVMediaType type

AVMediaType定义如下

enum AVMediaType {
    AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA
    AVMEDIA_TYPE_VIDEO,
    AVMEDIA_TYPE_AUDIO,
    AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous
    AVMEDIA_TYPE_SUBTITLE,
    AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse
    AVMEDIA_TYPE_NB
};

2.enum AVCodecID id

AVCodecID定义如下:

enum AVCodecID {
    AV_CODEC_ID_NONE,
 
    /* video codecs */
    AV_CODEC_ID_MPEG1VIDEO,
    AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
    AV_CODEC_ID_MPEG2VIDEO_XVMC,
    AV_CODEC_ID_H261,
    AV_CODEC_ID_H263,
    AV_CODEC_ID_RV10,
    AV_CODEC_ID_RV20,
    AV_CODEC_ID_MJPEG,
    AV_CODEC_ID_MJPEGB,
    AV_CODEC_ID_LJPEG,
    AV_CODEC_ID_SP5X,
    AV_CODEC_ID_JPEGLS,
    AV_CODEC_ID_MPEG4,
    AV_CODEC_ID_RAWVIDEO,
    AV_CODEC_ID_MSMPEG4V1,
    AV_CODEC_ID_MSMPEG4V2,
    AV_CODEC_ID_MSMPEG4V3,
    AV_CODEC_ID_WMV1,
    AV_CODEC_ID_WMV2,
    AV_CODEC_ID_H263P,
    AV_CODEC_ID_H263I,
    AV_CODEC_ID_FLV1,
    AV_CODEC_ID_SVQ1,
    AV_CODEC_ID_SVQ3,
    AV_CODEC_ID_DVVIDEO,
    AV_CODEC_ID_HUFFYUV,
    AV_CODEC_ID_CYUV,
    AV_CODEC_ID_H264,
    ...(代码太长,略)
}

3.const enum AVPixelFormat *pix_fmts

AVPixelFormat定义如下:

enum AVPixelFormat {
    AV_PIX_FMT_NONE = -1,
    AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
    AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
    AV_PIX_FMT_RGB24,     ///< packed RGB 8:8:8, 24bpp, RGBRGB...
    AV_PIX_FMT_BGR24,     ///< packed RGB 8:8:8, 24bpp, BGRBGR...
    AV_PIX_FMT_YUV422P,   ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
    AV_PIX_FMT_YUV444P,   ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
    AV_PIX_FMT_YUV410P,   ///< planar YUV 4:1:0,  9bpp, (1 Cr & Cb sample per 4x4 Y samples)
    AV_PIX_FMT_YUV411P,   ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
    AV_PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
    AV_PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb
    AV_PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb
    AV_PIX_FMT_PAL8,      ///< 8 bit with PIX_FMT_RGB32 palette
    AV_PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
    AV_PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
    AV_PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
    AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
    AV_PIX_FMT_XVMC_MPEG2_IDCT,
    ...(代码太长,略)
}

4.const enum AVSampleFormat *sample_fmts

enum AVSampleFormat {
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
    AV_SAMPLE_FMT_FLT,         ///< float
    AV_SAMPLE_FMT_DBL,         ///< double
 
    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
    AV_SAMPLE_FMT_FLTP,        ///< float, planar
    AV_SAMPLE_FMT_DBLP,        ///< double, planar
 
    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

每一个编解码器对应一个该结构体,查看一下ffmpeg的源代码,我们可以看一下H.264解码器的结构体如下所示(h264.c):

AVCodec ff_h264_decoder = {
    .name           = "h264",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_H264,
    .priv_data_size = sizeof(H264Context),
    .init           = ff_h264_decode_init,
    .close          = ff_h264_decode_end,
    .decode         = decode_frame,
    .capabilities   = /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY |
                      CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,
    .flush= flush_dpb,
    .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
    .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
    .profiles = NULL_IF_CONFIG_SMALL(profiles),
    .priv_class     = &h264_class,
};

下面简单介绍一下遍历ffmpeg中的解码器信息的方法(这些解码器以一个链表的形式存储):
1.注册所有编解码器:av_register_all();

2.声明一个AVCodec类型的指针,比如说AVCodec* first_c;

3.调用av_codec_next()函数,即可获得指向链表下一个解码器的指针,循环往复可以获得所有解码器的信息。注意,如果想要获得指向第一个解码器的指针,则需要将该函数的参数设置为NULL。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/leixiaohua1020/article/details/14215833

AVCodec 中的 AVClass 中debug 数据:

    const AVClass *priv_class = avcodec->priv_class;

AVClass 中的 AVOption 中的关键数据

下面简单解释一下AVOption的几个成员变量:

name:名称。
help:简短的帮助。
offset:选项相对结构体首部地址的偏移量(这个很重要)。
type:选项的类型。
default_val:选项的默认值。
min:选项的最小值。
max:选项的最大值。
flags:一些标记。
unit:该选项所属的逻辑单元,可以为空。

其中,default_val是一个union类型的变量,可以根据选项数据类型的不同,取int,double,char*,AVRational(表示分数)几种类型。type是一个AVOptionType类型的变量。AVOptionType是一个枚举类型.

  AVClass中存储了AVOption类型的数组option,用于存储选项信息。AVClass有一个特点就是它必须位于其支持的结构体的第一个位置。例如,AVFormatContext和AVCodecContext都支持AVClass,观察它们结构体的定义可以发现他们结构体的第一个变量都是AVClass。截取一小段AVFormatContext的定义的开头部分,如下所示。

参考如下的

FFmpeg源代码简单分析:结构体成员管理系统-AVClass_ffmepg avclass-CSDN博客

自己打印的 AVCodec的各种数据:

void printfAVCodec(const AVCodec *avcodec){
    if(avcodec==nullptr){
        cout<<"printfAVCodec error avcodec==nullptr"<<endl;
        return ;
    }
    cout << "avcodec->name = " << avcodec->name << endl;
    cout << "avcodec->long_name = " << avcodec->long_name << endl;

    //该编解码器的 类型,enum AVMediaType type; 类似 AVMEDIA_TYPE_VIDEO,AVMEDIA_TYPE_AUDIO
    cout << "avcodec->type = " << avcodec->type << endl;

    //enum AVCodecID id; 类似 AV_CODEC_ID_AAC,AV_CODEC_ID_H264 , AAC 对应的值是十进制是86018,十六进制是15002
    cout << "avcodec->id = " << avcodec->id << endl;


    /**
     * Codec capabilities.
     * see AV_CODEC_CAP_*
     * int capabilities;
     * AAC 作为 encoder 的值是98,对应的二进制是 0110 0010,对应的如下的三个值 或 起来
     *      #define AV_CODEC_CAP_DR1                 (1 <<  1)
            #define AV_CODEC_CAP_DELAY               (1 <<  5)
            #define AV_CODEC_CAP_SMALL_LAST_FRAME    (1 <<  6)
     */
    cout << "avcodec->capabilities = " << avcodec->capabilities << endl;

    ///< maximum value for lowres supported by the decoder
    /// 视频专用 解码器支持的低分辨率的最大值
    // uint8_t max_lowres;
    cout << "avcodec->max_lowres = " << avcodec->max_lowres << endl;



    ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
    ///const AVRational *supported_framerates;
    ///支持的帧率(仅视频), 类似 每秒25张图片
    if(avcodec->supported_framerates == nullptr){
        cout<<"avcodec->supported_framerates = nullptr"<<endl;
    } else {
        cout<<"avcodec->supported_framerates != nullptr"<<endl;
        const AVRational * avr = avcodec->supported_framerates;
        int i =0;
        while(1){
            if(avr[i].den ==0 && avr[i].num == 0){
                break;
            }
            cout<<"avr["<<i <<"].den = "<< avr[i].den << " avr[" << i << "].num = " << avr[i].num << endl;
            ++i;
        }
    }


    ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
    ///const enum AVPixelFormat *pix_fmts;
    /// 支持的像素格式(仅视频),类似 AV_PIX_FMT_YUV420P
    if(avcodec->pix_fmts == nullptr){
        cout<<"avcodec->pix_fmts = nullptr"<<endl;
    }else{
        cout<<"avcodec->pix_fmts != nullptr"<<endl;
        const enum AVPixelFormat * avpixelformat = avcodec->pix_fmts;
        int i =0;
        while(1){
            if(avpixelformat[i] == -1){
                break;
            }else{
                cout<<"avpixelformat["<<i<<"] = avpixelformat[i] " <<endl;
                ++i;
            }
        }
    }



    ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
    ///     const int *supported_samplerates;
    /// 支持的采样率(仅音频)41000,48000
    if(avcodec->supported_samplerates == nullptr){
        cout<<"avcodec->supported_samplerates = nullptr"<<endl;
    }else{
        cout<<"avcodec->supported_samplerates != nullptr"<<endl;
        const int  * support_samplerates = avcodec->supported_samplerates;
        int i =0;
        while(1){
            if(support_samplerates[i] == 0){
                break;
            }else{
                cout<<"support_samplerates["<<i<<"] = " << support_samplerates[i]<<endl;
                ++i;
            }
        }
    }


    ///支持的采样格式(仅音频),类似 AV_SAMPLE_FMT_S16,FFMpeg 自带的AAC 只支持  AV_SAMPLE_FMT_FLTP,对应的十进制的值是8
    ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
    ///     const enum AVSampleFormat *sample_fmts;

    if(avcodec->sample_fmts == nullptr){
        cout<<"avcodec->sample_fmts = nullptr"<<endl;
    }else{
        cout<<"avcodec->sample_fmts != nullptr"<<endl;
        const enum AVSampleFormat *sample_fmts = avcodec->sample_fmts;
        int i =0;
        while(1){
            if(sample_fmts[i] == -1){
                break;
            }else{
                cout<<"sample_fmts["<<i<<"] = " << sample_fmts[i]<<endl;
                ++i;
            }
        }
    }



    //#if FF_API_OLD_CHANNEL_LAYOUT
    //    /**
    //     * @deprecated use ch_layouts instead
    //     */
    //    attribute_deprecated
    //    const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
    //#endif

    //该编码器支持的声道数量。已经不再使用。可以使用 const AVChannelLayout *ch_layouts; 替代
    const uint64_t *channel_layouts = avcodec->channel_layouts;

    if(channel_layouts == nullptr){
        cout<<"channel_layouts =  nullptr"<<endl; //在ffmepg 6.0的时候,使用编码器ffmpeg自带的AAC,这块为nullptr。这不合理。这里baidu了一下,发现 如下的说法:    // 不是每个codec都给出支持的channel_layout
    }else{
        cout<<"channel_layouts !=  nullptr"<<endl;
        int i = 0;
        while(1){
            if(channel_layouts[i] == 0){
                break;
            }
            cout<<"channel_layouts[<<" << i << "] = " << channel_layouts[i] << endl;
            ++i;
        }
    }

    ///这里为了方便测试 ,将已经废弃的const uint64_t *channel_layouts; 和 const AVChannelLayout *ch_layouts;对比
    /**
     * Array of supported channel layouts, terminated with a zeroed layout.
     */
    ///const AVChannelLayout *ch_layouts;
    const AVChannelLayout *ch_layouts = avcodec->ch_layouts;
    if(ch_layouts == nullptr){
        cout<<"ch_layouts =  nullptr"<<endl; //在ffmepg 6.0的时候,使用编码器ffmpeg自带的AAC,这块为nullptr。这不合理。  baidu说明如下:  // 不是每个codec都给出支持的channel_layout

    }else{
        cout<<"ch_layouts !=  nullptr"<<endl;
        int i = 0;
        while(1){
            if(ch_layouts[i].nb_channels == 0 ){
                break;
            }
            cout<<"ch_layouts[<<" << i << "].nb_channels = " << ch_layouts[i].nb_channels << endl;
            ++i;
        }
    }




    ///< AVClass for the private context
    /// const AVClass *priv_class;
    /// AVClass最主要的作用就是给结构体(例如AVFormatContext等)增加AVOption功能的支持。换句话说AVClass就是AVOption和目标结构体之间的“桥梁”。AVClass要求必须声明为目标结构体的第一个变量。
    const AVClass *priv_class = avcodec->priv_class;
    if(priv_class==nullptr){
        cout << "priv_class =  nullptr" << endl;
    }else {
        cout << "priv_class != nullptr" << endl;
        cout << "priv_class->option->name = " << priv_class->option->name << endl;

    }


    ///< array of recognized profiles, or NULL if unknown, array is terminated by {AV_PROFILE_UNKNOWN}
    ///     const AVProfile *profiles;
    /// 如果非NULL,则为此编解码器识别的配置文件数组。
    /// 该结构描述了由AVCodecID描述的单个编解码器的属性。

    const AVProfile *profiles = avcodec->profiles;
    if(profiles == nullptr){
        cout<<"profiles =  nullptr"<<endl;
    }else{
        cout<<"profiles !=  nullptr"<<endl;
        int i = 0;
        while(1){

            if(profiles[i].profile == AV_PROFILE_UNKNOWN ){
                break;
            }
            cout<<"profiles[<<" << i << "].profiles = " << profiles[i].profile <<  " profiles.name = " << profiles[i].name << endl;
            ++i;
        }
    }


    /**
     * Group name of the codec implementation.
     * This is a short symbolic name of the wrapper backing this codec.
     A wrapper uses some kind of external implementation for the codec,
      such as an external library, or a codec implementation provided by the OS or the hardware.
     * If this field is NULL, this is a builtin, libavcodec native codec.
     * If non-NULL, this will be the suffix in AVCodec.name in most cases (usually AVCodec.name will be of the form "<codec_name>_<wrapper_name>").
       const char *wrapper_name;
    */

    /**
    *编解码器实现的组名称。
    *这是支持此编解码器的包装器的简短符号名称。
    包装器对编解码器使用某种外部实现,
    诸如外部库或由OS或硬件提供的编解码器实现。
    *如果此字段为NULL,则这是一个内置的libavcodec本机编解码器。
    *如果非NULL,在大多数情况下,这将是AVCodec.name中的后缀(通常AVCodec.name的形式为“<codec_name>_<wrapper_name>”)。
    */
    const char*wrapper_name = avcodec->wrapper_name;

    if(wrapper_name == nullptr){
        cout<<"wrapper_name = nullptr"<<endl;
    }else{
        cout<<"wrapper_name = " <<wrapper_name <<endl;
    }

    cout<<"debug point "<<endl;

}

AVCodecContext 

AVCodecContext是FFmpeg编解码上下文的结构体,而AVCodec是编解码参数的结构体。AVCodecContex内部有包含AVCodec、AVCodecInternal、AVRational等结构体,包含AVCodecID、AVMediaType、AVPixelFormat、AVSampleForat等枚举类型,包含视频的width、height、framerate、bitrate等关键参数,包含音频的samplerate、channels等参数。

AVCodecContext的结构体中关键的参数如下:

视频的关键参数有:




 // 视频宽高
int width, height;
 //像素格式
enum AVPixelFormat pix_fmt;
 // 视频宽高比
AVRational sample_aspect_ratio;
 // 帧率
AVRational framerate;
 // 平均码率
int64_t bit_rate;

音频关键参数:
 



// 采样率
int sample_rate;
// 声道数
int channels;
// 声道布局
uint64_t channel_layout;
// 采样格式
enum AVSampleFormat sample_fmt;

QP量化参数相关,默认qmin=0,qmax=51,QP越小、图像质量越好:



 // 量化参数最小值
int qmin;
 // 量化参数最大值
int qmax;
 // 帧间最大量化差异
int max_qdiff;

AVCodecContext的结构体如下:

/**
 * main external API structure.
 * New fields can be added to the end with minor version bumps.
 * Removal, reordering and changes to existing fields require a major
 * version bump.
 * You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user
 * applications.
 * The name string for AVOptions options matches the associated command line
 * parameter name and can be found in libavcodec/options_table.h
 * The AVOption/command line parameter names differ in some cases from the C
 * structure field names for historic reasons or brevity.
 * sizeof(AVCodecContext) must not be used outside libav*.
 */
typedef struct AVCodecContext {
    /**
     * information on struct for av_log
     * - set by avcodec_alloc_context3
     */
    const AVClass *av_class;
    int log_level_offset;

		//在 avcodec_alloc_context3的内部实现中 codec_type的值 =  codec中的type ;参考如下方法的源码  AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
    enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
    
    // avcodec_alloc_context3的内部实现中,codec 的值 = 传递进来的 codec;AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
    const struct AVCodec  *codec;

    
    //在 avcodec_alloc_context3的内部实现中 codec_id  =  codec中的id ;  AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
    enum AVCodecID     codec_id; /* see AV_CODEC_ID_xxx */

    /**
     * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
     * This is used to work around some encoder bugs.
     * A demuxer should set this to what is stored in the field used to identify the codec.
     * If there are multiple such fields in a container then the demuxer should choose the one
     * which maximizes the information about the used codec.
     * If the codec tag field in a container is larger than 32 bits then the demuxer should
     * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
     * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
     * first.
     * - encoding: Set by user, if not then the default based on codec_id will be used.
     * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
     *这是用来解决一些编码器错误的。
		 *解复用器应该将其设置为存储在用于识别编解码器的字段中的内容。
		 *如果在一个容器中有多个这样的字段,那么解复用器应该选择最大化关于所使用的编解码器的信息的字段。
		 *如果容器中的编解码器标签字段大于32位,则解复用器应当使用表或其他结构将较长的ID重新映射到32位。或者,可以添加一个新的extra_codec_tag+大小,但为此必须首先证明一个明显的优势。
		 *-encoding:由用户设置,否则将使用基于codec_id的默认值。
		 *-解码:由用户设置,初始化时将由libavcodec转换为大写。
     */
    unsigned int codec_tag;


    void *priv_data;

    /**
     * Private context used for internal data.
     *
     * Unlike priv_data, this is not codec-specific. It is used in general
     * libavcodec functions.
     *用于内部数据的专用上下文。
		 *与priva_data不同,这不是特定于编解码器的。它用于一般的vcodec函数。
     */
    struct AVCodecInternal *internal;

    /**
     * Private data of the user, can be used to carry app specific stuff.
     * - encoding: Set by user.
     * - decoding: Set by user.
     用户的私人数据,可以用来携带应用程序特定的东西。
     */
    void *opaque;

    /**
     * the average bitrate
     * - encoding: Set by user; unused for constant quantizer encoding.
     * - decoding: Set by user, may be overwritten by libavcodec
     *             if this info is available in the stream
     *平均比特率
		 *-编码:由用户设置;未用于恒定量化器编码。(那么 ffmpeg 自带的aac编码器 是否可以理解为 非恒定量化器编码)
		 *-解码:由用户设置,但是如果流中有此信息,则用户设置的这个值可能被libavcodec覆盖
     */
    int64_t bit_rate;

    /**
     * number of bits the bitstream is allowed to diverge from the reference.
     *           the reference can be CBR (for CBR pass1) or VBR (for pass2)
     * - encoding: Set by user; unused for constant quantizer encoding.
     * - decoding: unused
         // 允许位流偏离参考的位数,包括CBR和VBR模式
bit_rate_tolerance:参数则是指编码器输出比特率的容差,单位同样为bit/s。它表示编码器在进行比特率控制时,可以允许的比特率偏差范围。如果比特率超过了这个容差范围,编码器会尝试进行调整,以保持输出比特率在指定范围内。通常情况下,bit_rate_tolerance参数应该设置为bit_rate参数的10%左右;
需要注意的是,在设置bit_rate参数时,还需要考虑到编码器支持的最大比特率。如果bit_rate超过了编码器支持的最大比特率,编码器会自动进行调整。因此,为了避免比特率过高导致编码器自动调整输出比特率,可以查询编码器支持的最大比特率,并根据其进行设置
原文链接:https://blog.csdn.net/qq_33659478/article/details/130155196
     */
    int bit_rate_tolerance;


    /**
     * Global quality for codecs which cannot change it per frame.
     * This should be proportional to MPEG-1/2/4 qscale.
     * - encoding: Set by user.
     * - decoding: unused
     这个是啥意思?当编解码器不能改变 它的 每一个 frame的时候,用这个global_quality?使用场景是啥呢?
     */
    int global_quality;

    /**
     * - encoding: Set by user.
     * - decoding: unused
     * 压缩级别
     */
    int compression_level;
#define FF_COMPRESSION_DEFAULT -1

    /**
     * AV_CODEC_FLAG_*.
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    int flags;

    /**
     * AV_CODEC_FLAG2_*
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    int flags2;

    /**
     * some codecs need / can use extradata like Huffman tables.
     * MJPEG: Huffman tables
     * rv10: additional flags
     * MPEG-4: global headers (they can be in the bitstream or here)
     * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger
     * than extradata_size to avoid problems if it is read with the bitstream reader.
     * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
     * Must be allocated with the av_malloc() family of functions.
     * - encoding: Set/allocated/freed by libavcodec.
     * - decoding: Set/allocated/freed by user.
     * 一些编解码器 需要 额外的数据,例如 哈夫曼编码表
     * MJPEG: Huffman tables
     * rv10: additional flags
     * MPEG-4: global headers
     * H264: avcConfig, include profile/level
     */
    uint8_t *extradata;
    int extradata_size;

    /**
     * This is the fundamental unit of time (in seconds) in terms
     * of which frame timestamps are represented. For fixed-fps content,
     * timebase should be 1/framerate and timestamp increments should be
     * identically 1.
     * This often, but not always is the inverse of the frame rate or field rate
     * for video. 1/time_base is not the average frame rate if the frame rate is not
     * constant.
     *
     * Like containers, elementary streams also can store timestamps, 1/time_base
     * is the unit in which these timestamps are specified.
     * As example of such codec time base see ISO/IEC 14496-2:2001(E)
     * vop_time_increment_resolution and fixed_vop_rate
     * (fixed_vop_rate == 0 implies that it is different from the framerate)
     *
     * - encoding: MUST be set by user.
     * - decoding: unused.
     指定视频的时间基准,即每个时间单位表示多少秒。通常为分数形式,例如{1, 25}表示每个时间单位为1/25秒。
     对于 固定帧来说,这个值是靠谱的。

     *如果帧速率不是恒定的,则1/time_base不是平均帧速率。
     对于编码器来说,这个值是必须设置的。对于解码器来说,这个值不需要
     */
    AVRational time_base;

#if FF_API_TICKS_PER_FRAME
    /**
     * For some codecs, the time base is closer to the field rate than the frame rate.
     * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
     * if no telecine is used ...
     *
     * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
     *
     * @deprecated
     * - decoding: Use AVCodecDescriptor.props & AV_CODEC_PROP_FIELDS
     * - encoding: Set AVCodecContext.framerate instead
     *
     */
    attribute_deprecated
    int ticks_per_frame;
#endif

    /**
     * Codec delay.
     *
     * Encoding: Number of frames delay there will be from the encoder input to
     *           the decoder output. (we assume the decoder matches the spec)
     * Decoding: Number of frames delay in addition to what a standard decoder
     *           as specified in the spec would produce.
     *
     * Video:
     *   Number of frames the decoded output will be delayed relative to the
     *   encoded input.
     *
     * Audio:
     *   For encoding, this field is unused (see initial_padding).
     *
     *   For decoding, this is the number of samples the decoder needs to
     *   output before the decoder's output is valid. When seeking, you should
     *   start decoding this many samples prior to your desired seek point.
     *
     * - encoding: Set by libavcodec.
     * - decoding: Set by libavcodec.
     /**
			*编解码器延迟。
			*
			*编码:从编码器输入到解码器输出的延迟帧数。(我们假设解码器符合规范)
			*解码:除了规范中指定的标准解码器将产生的延迟之外,还有帧数。
			*
			视频
			*解码输出将相对于编码输入延迟的帧数。
			*
			音频
			*对于编码,此字段未使用(请参见initial_padding)。
			*
			*对于解码,这是解码器需要的采样数
			在解码器的输出有效之前输出。在搜索时,您应该在所需的搜索点之前开始解码这么多样本。
			*
			*-encoding:由libavcodec设置。
			*-解码:由libavcodec设置。
     */
    int delay;


    /* video only */
    /**
     * picture width / height.
     *
     * @note Those fields may not match the values of the last
     * AVFrame output by avcodec_receive_frame() due frame
     * reordering.
     *
     * - encoding: MUST be set by user.
     * - decoding: May be set by the user before opening the decoder if known e.g.
     *             from the container. Some decoders will require the dimensions
     *             to be set by the caller. During decoding, the decoder may
     *             overwrite those values as required while parsing the data.
     */
    int width, height;

    /**
     * Bitstream width / height, may be different from width/height e.g. when
     * the decoded frame is cropped before being output or lowres is enabled.
     *
     * @note Those field may not match the value of the last
     * AVFrame output by avcodec_receive_frame() due frame
     * reordering.
     *
     * - encoding: unused
     * - decoding: May be set by the user before opening the decoder if known
     *             e.g. from the container. During decoding, the decoder may
     *             overwrite those values as required while parsing the data.
     
     /**
			*比特流宽度/高度,这个值可能和前面的宽度/高度不同
			例如当解码帧在被输出之前被裁剪或者低分辨率,该值被启用时。
			*
			*@note这些字段可能与最后一个的值不匹配
			*AVFrame由于帧重新排序而由avcodec_receive_frame()输出。
			*
			*-编码:未使用
			*-解码:如果已知,可以在打开解码器之前由程序员设置
			*例如从容器中取出。在解码期间,解码器可以在解析数据时根据需要重写那些值。

     */
    int coded_width, coded_height;


    /**
     * the number of pictures in a group of pictures, or 0 for intra_only
     * - encoding: Set by user.
     * - decoding: unused
     一组图片中的图片的数量,如果是0表示
     */
    int gop_size;

    /**
     * Pixel format, see AV_PIX_FMT_xxx.
     * May be set by the demuxer if known from headers.
     * May be overridden by the decoder if it knows better.
     *
     * @note This field may not match the value of the last
     * AVFrame output by avcodec_receive_frame() due frame
     * reordering.
     *
     * - encoding: Set by user.
     * - decoding: Set by user if known, overridden by libavcodec while
     *             parsing the data.
     图片的格式。
     这个值可以由 解复用器 从headers中获得。
     也可以从 解码器中获得,如果从解码器中获得,则更精确。
     注意的是:由于 帧的重排列,这个值 可能 和 通过avcodec_receive_frame方法获得的最后一帧 的值不一样。
     问题是:什么情况下,才不一样?
     
     */
    enum AVPixelFormat pix_fmt;

    /**
     * If non NULL, 'draw_horiz_band' is called by the libavcodec
     * decoder to draw a horizontal band. It improves cache usage. Not
     * all codecs can do that. You must check the codec capabilities
     * beforehand.
     * When multithreading is used, it may be called from multiple threads
     * at the same time; threads might draw different parts of the same AVFrame,
     * or multiple AVFrames, and there is no guarantee that slices will be drawn
     * in order.
     * The function is also used by hardware acceleration APIs.
     * It is called at least once during frame decoding to pass
     * the data needed for hardware render.
     * In that mode instead of pixel data, AVFrame points to
     * a structure specific to the acceleration API. The application
     * reads the structure and can change some fields to indicate progress
     * or mark state.
     * - encoding: unused
     * - decoding: Set by user.
     * @param height the height of the slice
     * @param y the y position of the slice
     * @param type 1->top field, 2->bottom field, 3->frame
     * @param offset offset into the AVFrame.data from which the slice should be read
     */
    void (*draw_horiz_band)(struct AVCodecContext *s,
                            const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
                            int y, int type, int height);

    /**
     * Callback to negotiate the pixel format. Decoding only, may be set by the
     * caller before avcodec_open2().
     *
     * Called by some decoders to select the pixel format that will be used for
     * the output frames. This is mainly used to set up hardware acceleration,
     * then the provided format list contains the corresponding hwaccel pixel
     * formats alongside the "software" one. The software pixel format may also
     * be retrieved from \ref sw_pix_fmt.
     *
     * This callback will be called when the coded frame properties (such as
     * resolution, pixel format, etc.) change and more than one output format is
     * supported for those new properties. If a hardware pixel format is chosen
     * and initialization for it fails, the callback may be called again
     * immediately.
     *
     * This callback may be called from different threads if the decoder is
     * multi-threaded, but not from more than one thread simultaneously.
     *
     * @param fmt list of formats which may be used in the current
     *            configuration, terminated by AV_PIX_FMT_NONE.
     * @warning Behavior is undefined if the callback returns a value other
     *          than one of the formats in fmt or AV_PIX_FMT_NONE.
     * @return the chosen format or AV_PIX_FMT_NONE
     */
    enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);

    /**
     * maximum number of B-frames between non-B-frames
     * Note: The output will be delayed by max_b_frames+1 relative to the input.
     * - encoding: Set by user.
     * - decoding: unused
     // 非B帧之间的最大B帧数
     */
    int max_b_frames;

    /**
     * qscale factor between IP and B-frames
     * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
     * - encoding: Set by user.
     * - decoding: unused
     */
    float b_quant_factor;

    /**
     * qscale offset between IP and B-frames
     * - encoding: Set by user.
     * - decoding: unused
     */
    float b_quant_offset;

    /**
     * Size of the frame reordering buffer in the decoder.
     * For MPEG-2 it is 1 IPB or 0 low delay IP.
     * - encoding: Set by libavcodec.
     * - decoding: Set by libavcodec.
     // 是否有B帧
     */
    int has_b_frames;

    /**
     * qscale factor between P- and I-frames
     * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset).
     * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
     * - encoding: Set by user.
     * - decoding: unused
     */
    float i_quant_factor;

    /**
     * qscale offset between P and I-frames
     * - encoding: Set by user.
     * - decoding: unused
     */
    float i_quant_offset;

    /**
     * luminance masking (0-> disabled)
     * - encoding: Set by user.
     * - decoding: unused
     */
    float lumi_masking;

    /**
     * temporary complexity masking (0-> disabled)
     * - encoding: Set by user.
     * - decoding: unused
     */
    float temporal_cplx_masking;

    /**
     * spatial complexity masking (0-> disabled)
     * - encoding: Set by user.
     * - decoding: unused
     */
    float spatial_cplx_masking;

    /**
     * p block masking (0-> disabled)
     * - encoding: Set by user.
     * - decoding: unused
     */
    float p_masking;

    /**
     * darkness masking (0-> disabled)
     * - encoding: Set by user.
     * - decoding: unused
     */
    float dark_masking;

#if FF_API_SLICE_OFFSET
    /**
     * slice count
     * - encoding: Set by libavcodec.
     * - decoding: Set by user (or 0).
     */
    attribute_deprecated
    int slice_count;

    /**
     * slice offsets in the frame in bytes
     * - encoding: Set/allocated by libavcodec.
     * - decoding: Set/allocated by user (or NULL).
     */
    attribute_deprecated
    int *slice_offset;
#endif

    /**
     * sample aspect ratio (0 if unknown)
     * That is the width of a pixel divided by the height of the pixel.
     * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
     * - encoding: Set by user.
     * - decoding: Set by libavcodec.
         // 视频宽高比,对于某些视频标准,分子和分母必须相对素数且小于256。

     */
    AVRational sample_aspect_ratio;

    /**
     * motion estimation comparison function
     * - encoding: Set by user.
     * - decoding: unused
     */
    int me_cmp;
    /**
     * subpixel motion estimation comparison function
     * - encoding: Set by user.
     * - decoding: unused
     */
    int me_sub_cmp;
    /**
     * macroblock comparison function (not supported yet)
     * - encoding: Set by user.
     * - decoding: unused
     */
    int mb_cmp;
    /**
     * interlaced DCT comparison function
     * - encoding: Set by user.
     * - decoding: unused
     */
    int ildct_cmp;
#define FF_CMP_SAD          0
#define FF_CMP_SSE          1
#define FF_CMP_SATD         2
#define FF_CMP_DCT          3
#define FF_CMP_PSNR         4
#define FF_CMP_BIT          5
#define FF_CMP_RD           6
#define FF_CMP_ZERO         7
#define FF_CMP_VSAD         8
#define FF_CMP_VSSE         9
#define FF_CMP_NSSE         10
#define FF_CMP_W53          11
#define FF_CMP_W97          12
#define FF_CMP_DCTMAX       13
#define FF_CMP_DCT264       14
#define FF_CMP_MEDIAN_SAD   15
#define FF_CMP_CHROMA       256

    /**
     * ME diamond size & shape
     * - encoding: Set by user.
     * - decoding: unused
     */
    int dia_size;

    /**
     * amount of previous MV predictors (2a+1 x 2a+1 square)
     * - encoding: Set by user.
     * - decoding: unused
     */
    int last_predictor_count;

    /**
     * motion estimation prepass comparison function
     * - encoding: Set by user.
     * - decoding: unused
     */
    int me_pre_cmp;

    /**
     * ME prepass diamond size & shape
     * - encoding: Set by user.
     * - decoding: unused
     */
    int pre_dia_size;

    /**
     * subpel ME quality
     * - encoding: Set by user.
     * - decoding: unused
     */
    int me_subpel_quality;

    /**
     * maximum motion estimation search range in subpel units
     * If 0 then no limit.
     *
     * - encoding: Set by user.
     * - decoding: unused
     */
    int me_range;

    /**
     * slice flags
     * - encoding: unused
     * - decoding: Set by user.
     */
    int slice_flags;
#define SLICE_FLAG_CODED_ORDER    0x0001 ///< draw_horiz_band() is called in coded order instead of display
#define SLICE_FLAG_ALLOW_FIELD    0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics)
#define SLICE_FLAG_ALLOW_PLANE    0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)

    /**
     * macroblock decision mode
     * - encoding: Set by user.
     * - decoding: unused
     */
    int mb_decision;
#define FF_MB_DECISION_SIMPLE 0        ///< uses mb_cmp
#define FF_MB_DECISION_BITS   1        ///< chooses the one which needs the fewest bits
#define FF_MB_DECISION_RD     2        ///< rate distortion

    /**
     * custom intra quantization matrix
     * Must be allocated with the av_malloc() family of functions, and will be freed in
     * avcodec_free_context().
     * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL.
     * - decoding: Set/allocated/freed by libavcodec.
     */
    uint16_t *intra_matrix;

    /**
     * custom inter quantization matrix
     * Must be allocated with the av_malloc() family of functions, and will be freed in
     * avcodec_free_context().
     * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL.
     * - decoding: Set/allocated/freed by libavcodec.
     */
    uint16_t *inter_matrix;

    /**
     * precision of the intra DC coefficient - 8
     * - encoding: Set by user.
     * - decoding: Set by libavcodec
     */
    int intra_dc_precision;

    /**
     * Number of macroblock rows at the top which are skipped.
     * - encoding: unused
     * - decoding: Set by user.
     */
    int skip_top;

    /**
     * Number of macroblock rows at the bottom which are skipped.
     * - encoding: unused
     * - decoding: Set by user.
     */
    int skip_bottom;

    /**
     * minimum MB Lagrange multiplier
     * - encoding: Set by user.
     * - decoding: unused
     */
    int mb_lmin;

    /**
     * maximum MB Lagrange multiplier
     * - encoding: Set by user.
     * - decoding: unused
     */
    int mb_lmax;

    /**
     * - encoding: Set by user.
     * - decoding: unused
     */
    int bidir_refine;

    /**
     * minimum GOP size
     * - encoding: Set by user.
     * - decoding: unused
         // 最小GOP数
     */
    int keyint_min;

    /**
     * number of reference frames
     * - encoding: Set by user.
     * - decoding: Set by lavc.
         // 参考帧数量
     */
    int refs;

    /**
     * Note: Value depends upon the compare function used for fullpel ME.
     * - encoding: Set by user.
     * - decoding: unused
     */
    int mv0_threshold;

    /**
     * Chromaticity coordinates of the source primaries.
     * - encoding: Set by user
     * - decoding: Set by libavcodec
     */
    enum AVColorPrimaries color_primaries;

    /**
     * Color Transfer Characteristic.
     * - encoding: Set by user
     * - decoding: Set by libavcodec
     */
    enum AVColorTransferCharacteristic color_trc;

    /**
     * YUV colorspace type.
     * - encoding: Set by user
     * - decoding: Set by libavcodec
     */
    enum AVColorSpace colorspace;

    /**
     * MPEG vs JPEG YUV range.
     * - encoding: Set by user to override the default output color range value,
     *   If not specified, libavcodec sets the color range depending on the
     *   output format.
     * - decoding: Set by libavcodec, can be set by the user to propagate the
     *   color range to components reading from the decoder context.
     */
    enum AVColorRange color_range;

    /**
     * This defines the location of chroma samples.
     * - encoding: Set by user
     * - decoding: Set by libavcodec
     */
    enum AVChromaLocation chroma_sample_location;

    /**
     * Number of slices.
     * Indicates number of picture subdivisions. Used for parallelized
     * decoding.
     * - encoding: Set by user
     * - decoding: unused
     */
    int slices;

    /** Field order
     * - encoding: set by libavcodec
     * - decoding: Set by user.
     */
    enum AVFieldOrder field_order;

    /* audio only */
    int sample_rate; ///< samples per second 采样率

#if FF_API_OLD_CHANNEL_LAYOUT
    /**
     * number of audio channels
     * @deprecated use ch_layout.nb_channels
     */
    attribute_deprecated
    int channels;       //声道数
#endif

    /**
     * audio sample format
     * - encoding: Set by user.
     * - decoding: Set by libavcodec.
     */
    enum AVSampleFormat sample_fmt;  ///< sample format  采样格式

    /* The following data should not be initialized. */
    /**
     * Number of samples per channel in an audio frame.
     *
     * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame
     *   except the last must contain exactly frame_size samples per channel.
     *   May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the
     *   frame size is not restricted.
     * - decoding: may be set by some decoders to indicate constant frame size
     */
    int frame_size;

#if FF_API_AVCTX_FRAME_NUMBER
    /**
     * Frame counter, set by libavcodec.
     *
     * - decoding: total number of frames returned from the decoder so far.
     * - encoding: total number of frames passed to the encoder so far.
     *
     *   @note the counter is not incremented if encoding/decoding resulted in
     *   an error.
     *   @deprecated use frame_num instead
     */
    attribute_deprecated
    int frame_number;
#endif

    /**
     * number of bytes per packet if constant and known or 0
     * Used by some WAV based audio codecs.
     */
    int block_align;

    /**
     * Audio cutoff bandwidth (0 means "automatic")
     * - encoding: Set by user.
     * - decoding: unused
         // 音频截止带宽:Audio cutoff bandwidth
     */
    int cutoff;

#if FF_API_OLD_CHANNEL_LAYOUT
    /**
     * Audio channel layout.
     * - encoding: set by user.
     * - decoding: set by user, may be overwritten by libavcodec.
     * @deprecated use ch_layout
     */
    attribute_deprecated
    uint64_t channel_layout;

    /**
     * Request decoder to use this channel layout if it can (0 for default)
     * - encoding: unused
     * - decoding: Set by user.
     * @deprecated use "downmix" codec private option
     */
    attribute_deprecated
    uint64_t request_channel_layout;
#endif

    /**
     * Type of service that the audio stream conveys.
     * - encoding: Set by user.
     * - decoding: Set by libavcodec.
     */
    enum AVAudioServiceType audio_service_type;

    /**
     * desired sample format
     * - encoding: Not used.
     * - decoding: Set by user.
     * Decoder will decode to this format if it can.
     */
    enum AVSampleFormat request_sample_fmt;

    /**
     * This callback is called at the beginning of each frame to get data
     * buffer(s) for it. There may be one contiguous buffer for all the data or
     * there may be a buffer per each data plane or anything in between. What
     * this means is, you may set however many entries in buf[] you feel necessary.
     * Each buffer must be reference-counted using the AVBuffer API (see description
     * of buf[] below).
     *
     * The following fields will be set in the frame before this callback is
     * called:
     * - format
     * - width, height (video only)
     * - sample_rate, channel_layout, nb_samples (audio only)
     * Their values may differ from the corresponding values in
     * AVCodecContext. This callback must use the frame values, not the codec
     * context values, to calculate the required buffer size.
     *
     * This callback must fill the following fields in the frame:
     * - data[]
     * - linesize[]
     * - extended_data:
     *   * if the data is planar audio with more than 8 channels, then this
     *     callback must allocate and fill extended_data to contain all pointers
     *     to all data planes. data[] must hold as many pointers as it can.
     *     extended_data must be allocated with av_malloc() and will be freed in
     *     av_frame_unref().
     *   * otherwise extended_data must point to data
     * - buf[] must contain one or more pointers to AVBufferRef structures. Each of
     *   the frame's data and extended_data pointers must be contained in these. That
     *   is, one AVBufferRef for each allocated chunk of memory, not necessarily one
     *   AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(),
     *   and av_buffer_ref().
     * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
     *   this callback and filled with the extra buffers if there are more
     *   buffers than buf[] can hold. extended_buf will be freed in
     *   av_frame_unref().
     *
     * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call
     * avcodec_default_get_buffer2() instead of providing buffers allocated by
     * some other means.
     *
     * Each data plane must be aligned to the maximum required by the target
     * CPU.
     *
     * @see avcodec_default_get_buffer2()
     *
     * Video:
     *
     * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused
     * (read and/or written to if it is writable) later by libavcodec.
     *
     * avcodec_align_dimensions2() should be used to find the required width and
     * height, as they normally need to be rounded up to the next multiple of 16.
     *
     * Some decoders do not support linesizes changing between frames.
     *
     * If frame multithreading is used, this callback may be called from a
     * different thread, but not from more than one at once. Does not need to be
     * reentrant.
     *
     * @see avcodec_align_dimensions2()
     *
     * Audio:
     *
     * Decoders request a buffer of a particular size by setting
     * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may,
     * however, utilize only part of the buffer by setting AVFrame.nb_samples
     * to a smaller value in the output frame.
     *
     * As a convenience, av_samples_get_buffer_size() and
     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2()
     * functions to find the required data size and to fill data pointers and
     * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
     * since all planes must be the same size.
     *
     * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
     *
     * - encoding: unused
     * - decoding: Set by libavcodec, user can override.
     */
    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);

    /* - encoding parameters */
    float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
    float qblur;      ///< amount of qscale smoothing over time (0.0-1.0)

    /**
     * minimum quantizer
     * - encoding: Set by user.
     * - decoding: unused
         // 量化参数最小值
     */
    int qmin;

    /**
     * maximum quantizer
     * - encoding: Set by user.
         // 量化参数最大值
     * - decoding: unused
     */
    int qmax;

    /**
     * maximum quantizer difference between frames
     * - encoding: Set by user.
     * - decoding: unused
         // 帧间最大量化差异
     */
    int max_qdiff;

    /**
     * decoder bitstream buffer size
     * - encoding: Set by user.
     * - decoding: May be set by libavcodec.
     */
    int rc_buffer_size;

    /**
     * ratecontrol override, see RcOverride
     * - encoding: Allocated/set/freed by user.
     * - decoding: unused
     */
    int rc_override_count;
    RcOverride *rc_override;

    /**
     * maximum bitrate
     * - encoding: Set by user.
     * - decoding: Set by user, may be overwritten by libavcodec.
     */
    int64_t rc_max_rate;

    /**
     * minimum bitrate
     * - encoding: Set by user.
     * - decoding: unused
     */
    int64_t rc_min_rate;

    /**
     * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
     * - encoding: Set by user.
     * - decoding: unused.
     */
    float rc_max_available_vbv_use;

    /**
     * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
     * - encoding: Set by user.
     * - decoding: unused.
     */
    float rc_min_vbv_overflow_use;

    /**
     * Number of bits which should be loaded into the rc buffer before decoding starts.
     * - encoding: Set by user.
     * - decoding: unused
     */
    int rc_initial_buffer_occupancy;

    /**
     * trellis RD quantization
     * - encoding: Set by user.
     * - decoding: unused
     */
    int trellis;

    /**
     * pass1 encoding statistics output buffer
     * - encoding: Set by libavcodec.
     * - decoding: unused
     */
    char *stats_out;

    /**
     * pass2 encoding statistics input buffer
     * Concatenated stuff from stats_out of pass1 should be placed here.
     * - encoding: Allocated/set/freed by user.
     * - decoding: unused
     */
    char *stats_in;

    /**
     * Work around bugs in encoders which sometimes cannot be detected automatically.
     * - encoding: Set by user
     * - decoding: Set by user
     */
    int workaround_bugs;
#define FF_BUG_AUTODETECT       1  ///< autodetection
#define FF_BUG_XVID_ILACE       4
#define FF_BUG_UMP4             8
#define FF_BUG_NO_PADDING       16
#define FF_BUG_AMV              32
#define FF_BUG_QPEL_CHROMA      64
#define FF_BUG_STD_QPEL         128
#define FF_BUG_QPEL_CHROMA2     256
#define FF_BUG_DIRECT_BLOCKSIZE 512
#define FF_BUG_EDGE             1024
#define FF_BUG_HPEL_CHROMA      2048
#define FF_BUG_DC_CLIP          4096
#define FF_BUG_MS               8192 ///< Work around various bugs in Microsoft's broken decoders.
#define FF_BUG_TRUNCATED       16384
#define FF_BUG_IEDGE           32768

    /**
     * strictly follow the standard (MPEG-4, ...).
     * - encoding: Set by user.
     * - decoding: Set by user.
     * Setting this to STRICT or higher means the encoder and decoder will
     * generally do stupid things, whereas setting it to unofficial or lower
     * will mean the encoder might produce output that is not supported by all
     * spec-compliant decoders. Decoders don't differentiate between normal,
     * unofficial and experimental (that is, they always try to decode things
     * when they can) unless they are explicitly asked to behave stupidly
     * (=strictly conform to the specs)
     * This may only be set to one of the FF_COMPLIANCE_* values in defs.h.
     */
    int strict_std_compliance;

    /**
     * error concealment flags
     * - encoding: unused
     * - decoding: Set by user.
     */
    int error_concealment;
#define FF_EC_GUESS_MVS   1
#define FF_EC_DEBLOCK     2
#define FF_EC_FAVOR_INTER 256

    /**
     * debug
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    int debug;
#define FF_DEBUG_PICT_INFO   1
#define FF_DEBUG_RC          2
#define FF_DEBUG_BITSTREAM   4
#define FF_DEBUG_MB_TYPE     8
#define FF_DEBUG_QP          16
#define FF_DEBUG_DCT_COEFF   0x00000040
#define FF_DEBUG_SKIP        0x00000080
#define FF_DEBUG_STARTCODE   0x00000100
#define FF_DEBUG_ER          0x00000400
#define FF_DEBUG_MMCO        0x00000800
#define FF_DEBUG_BUGS        0x00001000
#define FF_DEBUG_BUFFERS     0x00008000
#define FF_DEBUG_THREADS     0x00010000
#define FF_DEBUG_GREEN_MD    0x00800000
#define FF_DEBUG_NOMC        0x01000000

    /**
     * Error recognition; may misdetect some more or less valid parts as errors.
     * This is a bitfield of the AV_EF_* values defined in defs.h.
     *
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    int err_recognition;

#if FF_API_REORDERED_OPAQUE
    /**
     * opaque 64-bit number (generally a PTS) that will be reordered and
     * output in AVFrame.reordered_opaque
     * - encoding: Set by libavcodec to the reordered_opaque of the input
     *             frame corresponding to the last returned packet. Only
     *             supported by encoders with the
     *             AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability.
     * - decoding: Set by user.
     *
     * @deprecated Use AV_CODEC_FLAG_COPY_OPAQUE instead
     */
    attribute_deprecated
    int64_t reordered_opaque;
#endif

    /**
     * Hardware accelerator in use
     * - encoding: unused.
     * - decoding: Set by libavcodec
     */
    const struct AVHWAccel *hwaccel;

    /**
     * Legacy hardware accelerator context.
     *
     * For some hardware acceleration methods, the caller may use this field to
     * signal hwaccel-specific data to the codec. The struct pointed to by this
     * pointer is hwaccel-dependent and defined in the respective header. Please
     * refer to the FFmpeg HW accelerator documentation to know how to fill
     * this.
     *
     * In most cases this field is optional - the necessary information may also
     * be provided to libavcodec through @ref hw_frames_ctx or @ref
     * hw_device_ctx (see avcodec_get_hw_config()). However, in some cases it
     * may be the only method of signalling some (optional) information.
     *
     * The struct and its contents are owned by the caller.
     *
     * - encoding: May be set by the caller before avcodec_open2(). Must remain
     *             valid until avcodec_free_context().
     * - decoding: May be set by the caller in the get_format() callback.
     *             Must remain valid until the next get_format() call,
     *             or avcodec_free_context() (whichever comes first).
     */
    void *hwaccel_context;

    /**
     * error
     * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR.
     * - decoding: unused
     */
    uint64_t error[AV_NUM_DATA_POINTERS];

    /**
     * DCT algorithm, see FF_DCT_* below
     * - encoding: Set by user.
     * - decoding: unused
         // DCT算法
     */
    int dct_algo;
#define FF_DCT_AUTO    0
#define FF_DCT_FASTINT 1
#define FF_DCT_INT     2
#define FF_DCT_MMX     3
#define FF_DCT_ALTIVEC 5
#define FF_DCT_FAAN    6

    /**
     * IDCT algorithm, see FF_IDCT_* below.
     * - encoding: Set by user.
     * - decoding: Set by user.
         // IDCT算法
     */
    int idct_algo;
#define FF_IDCT_AUTO          0
#define FF_IDCT_INT           1
#define FF_IDCT_SIMPLE        2
#define FF_IDCT_SIMPLEMMX     3
#define FF_IDCT_ARM           7
#define FF_IDCT_ALTIVEC       8
#define FF_IDCT_SIMPLEARM     10
#define FF_IDCT_XVID          14
#define FF_IDCT_SIMPLEARMV5TE 16
#define FF_IDCT_SIMPLEARMV6   17
#define FF_IDCT_FAAN          20
#define FF_IDCT_SIMPLENEON    22
#if FF_API_IDCT_NONE
// formerly used by xvmc
#define FF_IDCT_NONE          24
#endif
#define FF_IDCT_SIMPLEAUTO    128

    /**
     * bits per sample/pixel from the demuxer (needed for huffyuv).
     * - encoding: Set by libavcodec.
     * - decoding: Set by user.
     */
     int bits_per_coded_sample;

    /**
     * Bits per sample/pixel of internal libavcodec pixel/sample format.
     * - encoding: set by user.
     * - decoding: set by libavcodec.
     */
    int bits_per_raw_sample;

    /**
     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
     * - encoding: unused
     * - decoding: Set by user.
     */
     int lowres;

    /**
     * thread count
     * is used to decide how many independent tasks should be passed to execute()
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    int thread_count;

    /**
     * Which multithreading methods to use.
     * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread,
     * so clients which cannot provide future frames should not use it.
     *
     * - encoding: Set by user, otherwise the default is used.
     * - decoding: Set by user, otherwise the default is used.
     */
    int thread_type;
#define FF_THREAD_FRAME   1 ///< Decode more than one frame at once
#define FF_THREAD_SLICE   2 ///< Decode more than one part of a single frame at once

    /**
     * Which multithreading methods are in use by the codec.
     * - encoding: Set by libavcodec.
     * - decoding: Set by libavcodec.
     */
    int active_thread_type;

    /**
     * The codec may call this to execute several independent things.
     * It will return only after finishing all tasks.
     * The user may replace this with some multithreaded implementation,
     * the default implementation will execute the parts serially.
     * @param count the number of things to execute
     * - encoding: Set by libavcodec, user can override.
     * - decoding: Set by libavcodec, user can override.
     */
    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);

    /**
     * The codec may call this to execute several independent things.
     * It will return only after finishing all tasks.
     * The user may replace this with some multithreaded implementation,
     * the default implementation will execute the parts serially.
     * @param c context passed also to func
     * @param count the number of things to execute
     * @param arg2 argument passed unchanged to func
     * @param ret return values of executed functions, must have space for "count" values. May be NULL.
     * @param func function that will be called count times, with jobnr from 0 to count-1.
     *             threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
     *             two instances of func executing at the same time will have the same threadnr.
     * @return always 0 currently, but code should handle a future improvement where when any call to func
     *         returns < 0 no further calls to func may be done and < 0 is returned.
     * - encoding: Set by libavcodec, user can override.
     * - decoding: Set by libavcodec, user can override.
     */
    int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);

    /**
     * noise vs. sse weight for the nsse comparison function
     * - encoding: Set by user.
     * - decoding: unused
         // 噪声权重
     */
     int nsse_weight;

    /**
     * profile
     * - encoding: Set by user.
     * - decoding: Set by libavcodec.
     * See the AV_PROFILE_* defines in defs.h.
     */
     int profile;
#if FF_API_FF_PROFILE_LEVEL
    /** @deprecated The following defines are deprecated; use AV_PROFILE_*
     * in defs.h instead. */
#define FF_PROFILE_UNKNOWN -99
#define FF_PROFILE_RESERVED -100

#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW  1
#define FF_PROFILE_AAC_SSR  2
#define FF_PROFILE_AAC_LTP  3
#define FF_PROFILE_AAC_HE   4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD   22
#define FF_PROFILE_AAC_ELD  38
#define FF_PROFILE_MPEG2_AAC_LOW 128
#define FF_PROFILE_MPEG2_AAC_HE  131

#define FF_PROFILE_DNXHD         0
#define FF_PROFILE_DNXHR_LB      1
#define FF_PROFILE_DNXHR_SQ      2
#define FF_PROFILE_DNXHR_HQ      3
#define FF_PROFILE_DNXHR_HQX     4
#define FF_PROFILE_DNXHR_444     5

#define FF_PROFILE_DTS                20
#define FF_PROFILE_DTS_ES             30
#define FF_PROFILE_DTS_96_24          40
#define FF_PROFILE_DTS_HD_HRA         50
#define FF_PROFILE_DTS_HD_MA          60
#define FF_PROFILE_DTS_EXPRESS        70
#define FF_PROFILE_DTS_HD_MA_X        61
#define FF_PROFILE_DTS_HD_MA_X_IMAX   62


#define FF_PROFILE_EAC3_DDP_ATMOS         30

#define FF_PROFILE_TRUEHD_ATMOS           30

#define FF_PROFILE_MPEG2_422    0
#define FF_PROFILE_MPEG2_HIGH   1
#define FF_PROFILE_MPEG2_SS     2
#define FF_PROFILE_MPEG2_SNR_SCALABLE  3
#define FF_PROFILE_MPEG2_MAIN   4
#define FF_PROFILE_MPEG2_SIMPLE 5

#define FF_PROFILE_H264_CONSTRAINED  (1<<9)  // 8+1; constraint_set1_flag
#define FF_PROFILE_H264_INTRA        (1<<11) // 8+3; constraint_set3_flag

#define FF_PROFILE_H264_BASELINE             66
#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
#define FF_PROFILE_H264_MAIN                 77
#define FF_PROFILE_H264_EXTENDED             88
#define FF_PROFILE_H264_HIGH                 100
#define FF_PROFILE_H264_HIGH_10              110
#define FF_PROFILE_H264_HIGH_10_INTRA        (110|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_MULTIVIEW_HIGH       118
#define FF_PROFILE_H264_HIGH_422             122
#define FF_PROFILE_H264_HIGH_422_INTRA       (122|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_STEREO_HIGH          128
#define FF_PROFILE_H264_HIGH_444             144
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE  244
#define FF_PROFILE_H264_HIGH_444_INTRA       (244|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_CAVLC_444            44

#define FF_PROFILE_VC1_SIMPLE   0
#define FF_PROFILE_VC1_MAIN     1
#define FF_PROFILE_VC1_COMPLEX  2
#define FF_PROFILE_VC1_ADVANCED 3

#define FF_PROFILE_MPEG4_SIMPLE                     0
#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE            1
#define FF_PROFILE_MPEG4_CORE                       2
#define FF_PROFILE_MPEG4_MAIN                       3
#define FF_PROFILE_MPEG4_N_BIT                      4
#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE           5
#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION      6
#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE     7
#define FF_PROFILE_MPEG4_HYBRID                     8
#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME         9
#define FF_PROFILE_MPEG4_CORE_SCALABLE             10
#define FF_PROFILE_MPEG4_ADVANCED_CODING           11
#define FF_PROFILE_MPEG4_ADVANCED_CORE             12
#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
#define FF_PROFILE_MPEG4_SIMPLE_STUDIO             14
#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE           15

#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0   1
#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1   2
#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION  32768
#define FF_PROFILE_JPEG2000_DCINEMA_2K              3
#define FF_PROFILE_JPEG2000_DCINEMA_4K              4

#define FF_PROFILE_VP9_0                            0
#define FF_PROFILE_VP9_1                            1
#define FF_PROFILE_VP9_2                            2
#define FF_PROFILE_VP9_3                            3

#define FF_PROFILE_HEVC_MAIN                        1
#define FF_PROFILE_HEVC_MAIN_10                     2
#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE          3
#define FF_PROFILE_HEVC_REXT                        4
#define FF_PROFILE_HEVC_SCC                         9

#define FF_PROFILE_VVC_MAIN_10                      1
#define FF_PROFILE_VVC_MAIN_10_444                 33

#define FF_PROFILE_AV1_MAIN                         0
#define FF_PROFILE_AV1_HIGH                         1
#define FF_PROFILE_AV1_PROFESSIONAL                 2

#define FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT            0xc0
#define FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT 0xc1
#define FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT         0xc2
#define FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS                0xc3
#define FF_PROFILE_MJPEG_JPEG_LS                         0xf7

#define FF_PROFILE_SBC_MSBC                         1

#define FF_PROFILE_PRORES_PROXY     0
#define FF_PROFILE_PRORES_LT        1
#define FF_PROFILE_PRORES_STANDARD  2
#define FF_PROFILE_PRORES_HQ        3
#define FF_PROFILE_PRORES_4444      4
#define FF_PROFILE_PRORES_XQ        5

#define FF_PROFILE_ARIB_PROFILE_A 0
#define FF_PROFILE_ARIB_PROFILE_C 1

#define FF_PROFILE_KLVA_SYNC 0
#define FF_PROFILE_KLVA_ASYNC 1

#define FF_PROFILE_EVC_BASELINE             0
#define FF_PROFILE_EVC_MAIN                 1
#endif

    /**
     * Encoding level descriptor.
     * - encoding: Set by user, corresponds to a specific level defined by the
     *   codec, usually corresponding to the profile level, if not specified it
     *   is set to FF_LEVEL_UNKNOWN.
     * - decoding: Set by libavcodec.
     * See AV_LEVEL_* in defs.h.
     */
     int level;
#if FF_API_FF_PROFILE_LEVEL
    /** @deprecated The following define is deprecated; use AV_LEVEL_UNKOWN
     * in defs.h instead. */
#define FF_LEVEL_UNKNOWN -99
#endif

    /**
     * Skip loop filtering for selected frames.
     * - encoding: unused
     * - decoding: Set by user.
     */
    enum AVDiscard skip_loop_filter;

    /**
     * Skip IDCT/dequantization for selected frames.
     * - encoding: unused
     * - decoding: Set by user.
     */
    enum AVDiscard skip_idct;

    /**
     * Skip decoding for selected frames.
     * - encoding: unused
     * - decoding: Set by user.
     */
    enum AVDiscard skip_frame;

    /**
     * Header containing style information for text subtitles.
     * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
     * [Script Info] and [V4+ Styles] section, plus the [Events] line and
     * the Format line following. It shouldn't include any Dialogue line.
     * - encoding: Set/allocated/freed by user (before avcodec_open2())
     * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
     */
    uint8_t *subtitle_header;
    int subtitle_header_size;

    /**
     * Audio only. The number of "priming" samples (padding) inserted by the
     * encoder at the beginning of the audio. I.e. this number of leading
     * decoded samples must be discarded by the caller to get the original audio
     * without leading padding.
     *
     * - decoding: unused
     * - encoding: Set by libavcodec. The timestamps on the output packets are
     *             adjusted by the encoder so that they always refer to the
     *             first sample of the data actually contained in the packet,
     *             including any added padding.  E.g. if the timebase is
     *             1/samplerate and the timestamp of the first input sample is
     *             0, the timestamp of the first output packet will be
     *             -initial_padding.
     */
    int initial_padding;

    /**
     * - decoding: For codecs that store a framerate value in the compressed
     *             bitstream, the decoder may export it here. { 0, 1} when
     *             unknown.
     * - encoding: May be used to signal the framerate of CFR content to an
     *             encoder.
     */
    AVRational framerate;

    /**
     * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
     * - encoding: unused.
     * - decoding: Set by libavcodec before calling get_format()
     */
    enum AVPixelFormat sw_pix_fmt;

    /**
     * Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
     * - encoding: unused.
     * - decoding: set by user.
     */
    AVRational pkt_timebase;

    /**
     * AVCodecDescriptor
     * - encoding: unused.
     * - decoding: set by libavcodec.
     */
    const struct AVCodecDescriptor *codec_descriptor;

    /**
     * Current statistics for PTS correction.
     * - decoding: maintained and used by libavcodec, not intended to be used by user apps
     * - encoding: unused
     */
    int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
    int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
    int64_t pts_correction_last_pts;       /// PTS of the last frame
    int64_t pts_correction_last_dts;       /// DTS of the last frame

    /**
     * Character encoding of the input subtitles file.
     * - decoding: set by user
     * - encoding: unused
     */
    char *sub_charenc;

    /**
     * Subtitles character encoding mode. Formats or codecs might be adjusting
     * this setting (if they are doing the conversion themselves for instance).
     * - decoding: set by libavcodec
     * - encoding: unused
     */
    int sub_charenc_mode;
#define FF_SUB_CHARENC_MODE_DO_NOTHING  -1  ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
#define FF_SUB_CHARENC_MODE_AUTOMATIC    0  ///< libavcodec will select the mode itself
#define FF_SUB_CHARENC_MODE_PRE_DECODER  1  ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
#define FF_SUB_CHARENC_MODE_IGNORE       2  ///< neither convert the subtitles, nor check them for valid UTF-8

    /**
     * Skip processing alpha if supported by codec.
     * Note that if the format uses pre-multiplied alpha (common with VP6,
     * and recommended due to better video quality/compression)
     * the image will look as if alpha-blended onto a black background.
     * However for formats that do not use pre-multiplied alpha
     * there might be serious artefacts (though e.g. libswscale currently
     * assumes pre-multiplied alpha anyway).
     *
     * - decoding: set by user
     * - encoding: unused
     */
    int skip_alpha;

    /**
     * Number of samples to skip after a discontinuity
     * - decoding: unused
     * - encoding: set by libavcodec
     */
    int seek_preroll;

    /**
     * custom intra quantization matrix
     * - encoding: Set by user, can be NULL.
     * - decoding: unused.
     */
    uint16_t *chroma_intra_matrix;

    /**
     * dump format separator.
     * can be ", " or "\n      " or anything else
     * - encoding: Set by user.
     * - decoding: Set by user.
     */
    uint8_t *dump_separator;

    /**
     * ',' separated list of allowed decoders.
     * If NULL then all are allowed
     * - encoding: unused
     * - decoding: set by user
     */
    char *codec_whitelist;

    /**
     * Properties of the stream that gets decoded
     * - encoding: unused
     * - decoding: set by libavcodec
     */
    unsigned properties;
#define FF_CODEC_PROPERTY_LOSSLESS        0x00000001
#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
#define FF_CODEC_PROPERTY_FILM_GRAIN      0x00000004

    /**
     * Additional data associated with the entire coded stream.
     *
     * - decoding: may be set by user before calling avcodec_open2().
     * - encoding: may be set by libavcodec after avcodec_open2().
     */
    AVPacketSideData *coded_side_data;
    int            nb_coded_side_data;

    /**
     * A reference to the AVHWFramesContext describing the input (for encoding)
     * or output (decoding) frames. The reference is set by the caller and
     * afterwards owned (and freed) by libavcodec - it should never be read by
     * the caller after being set.
     *
     * - decoding: This field should be set by the caller from the get_format()
     *             callback. The previous reference (if any) will always be
     *             unreffed by libavcodec before the get_format() call.
     *
     *             If the default get_buffer2() is used with a hwaccel pixel
     *             format, then this AVHWFramesContext will be used for
     *             allocating the frame buffers.
     *
     * - encoding: For hardware encoders configured to use a hwaccel pixel
     *             format, this field should be set by the caller to a reference
     *             to the AVHWFramesContext describing input frames.
     *             AVHWFramesContext.format must be equal to
     *             AVCodecContext.pix_fmt.
     *
     *             This field should be set before avcodec_open2() is called.
     */
    AVBufferRef *hw_frames_ctx;

    /**
     * Audio only. The amount of padding (in samples) appended by the encoder to
     * the end of the audio. I.e. this number of decoded samples must be
     * discarded by the caller from the end of the stream to get the original
     * audio without any trailing padding.
     *
     * - decoding: unused
     * - encoding: unused
     */
    int trailing_padding;

    /**
     * The number of pixels per image to maximally accept.
     *
     * - decoding: set by user
     * - encoding: set by user
     */
    int64_t max_pixels;

    /**
     * A reference to the AVHWDeviceContext describing the device which will
     * be used by a hardware encoder/decoder.  The reference is set by the
     * caller and afterwards owned (and freed) by libavcodec.
     *
     * This should be used if either the codec device does not require
     * hardware frames or any that are used are to be allocated internally by
     * libavcodec.  If the user wishes to supply any of the frames used as
     * encoder input or decoder output then hw_frames_ctx should be used
     * instead.  When hw_frames_ctx is set in get_format() for a decoder, this
     * field will be ignored while decoding the associated stream segment, but
     * may again be used on a following one after another get_format() call.
     *
     * For both encoders and decoders this field should be set before
     * avcodec_open2() is called and must not be written to thereafter.
     *
     * Note that some decoders may require this field to be set initially in
     * order to support hw_frames_ctx at all - in that case, all frames
     * contexts used must be created on the same device.
     */
    AVBufferRef *hw_device_ctx;

    /**
     * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated
     * decoding (if active).
     * - encoding: unused
     * - decoding: Set by user (either before avcodec_open2(), or in the
     *             AVCodecContext.get_format callback)
     */
    int hwaccel_flags;

    /**
     * Video decoding only. Certain video codecs support cropping, meaning that
     * only a sub-rectangle of the decoded frame is intended for display.  This
     * option controls how cropping is handled by libavcodec.
     *
     * When set to 1 (the default), libavcodec will apply cropping internally.
     * I.e. it will modify the output frame width/height fields and offset the
     * data pointers (only by as much as possible while preserving alignment, or
     * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that
     * the frames output by the decoder refer only to the cropped area. The
     * crop_* fields of the output frames will be zero.
     *
     * When set to 0, the width/height fields of the output frames will be set
     * to the coded dimensions and the crop_* fields will describe the cropping
     * rectangle. Applying the cropping is left to the caller.
     *
     * @warning When hardware acceleration with opaque output frames is used,
     * libavcodec is unable to apply cropping from the top/left border.
     *
     * @note when this option is set to zero, the width/height fields of the
     * AVCodecContext and output AVFrames have different meanings. The codec
     * context fields store display dimensions (with the coded dimensions in
     * coded_width/height), while the frame fields store the coded dimensions
     * (with the display dimensions being determined by the crop_* fields).
     */
    int apply_cropping;

    /*
     * Video decoding only.  Sets the number of extra hardware frames which
     * the decoder will allocate for use by the caller.  This must be set
     * before avcodec_open2() is called.
     *
     * Some hardware decoders require all frames that they will use for
     * output to be defined in advance before decoding starts.  For such
     * decoders, the hardware frame pool must therefore be of a fixed size.
     * The extra frames set here are on top of any number that the decoder
     * needs internally in order to operate normally (for example, frames
     * used as reference pictures).
     */
    int extra_hw_frames;

    /**
     * The percentage of damaged samples to discard a frame.
     *
     * - decoding: set by user
     * - encoding: unused
     */
    int discard_damaged_percentage;

    /**
     * The number of samples per frame to maximally accept.
     *
     * - decoding: set by user
     * - encoding: set by user
     */
    int64_t max_samples;

    /**
     * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of
     * metadata exported in frame, packet, or coded stream side data by
     * decoders and encoders.
     *
     * - decoding: set by user
     * - encoding: set by user
     */
    int export_side_data;

    /**
     * This callback is called at the beginning of each packet to get a data
     * buffer for it.
     *
     * The following field will be set in the packet before this callback is
     * called:
     * - size
     * This callback must use the above value to calculate the required buffer size,
     * which must padded by at least AV_INPUT_BUFFER_PADDING_SIZE bytes.
     *
     * In some specific cases, the encoder may not use the entire buffer allocated by this
     * callback. This will be reflected in the size value in the packet once returned by
     * avcodec_receive_packet().
     *
     * This callback must fill the following fields in the packet:
     * - data: alignment requirements for AVPacket apply, if any. Some architectures and
     *   encoders may benefit from having aligned data.
     * - buf: must contain a pointer to an AVBufferRef structure. The packet's
     *   data pointer must be contained in it. See: av_buffer_create(), av_buffer_alloc(),
     *   and av_buffer_ref().
     *
     * If AV_CODEC_CAP_DR1 is not set then get_encode_buffer() must call
     * avcodec_default_get_encode_buffer() instead of providing a buffer allocated by
     * some other means.
     *
     * The flags field may contain a combination of AV_GET_ENCODE_BUFFER_FLAG_ flags.
     * They may be used for example to hint what use the buffer may get after being
     * created.
     * Implementations of this callback may ignore flags they don't understand.
     * If AV_GET_ENCODE_BUFFER_FLAG_REF is set in flags then the packet may be reused
     * (read and/or written to if it is writable) later by libavcodec.
     *
     * This callback must be thread-safe, as when frame threading is used, it may
     * be called from multiple threads simultaneously.
     *
     * @see avcodec_default_get_encode_buffer()
     *
     * - encoding: Set by libavcodec, user can override.
     * - decoding: unused
     */
    int (*get_encode_buffer)(struct AVCodecContext *s, AVPacket *pkt, int flags);

    /**
     * Audio channel layout.
     * - encoding: must be set by the caller, to one of AVCodec.ch_layouts.
     * - decoding: may be set by the caller if known e.g. from the container.
     *             The decoder can then override during decoding as needed.
     */
    AVChannelLayout ch_layout;

    /**
     * Frame counter, set by libavcodec.
     *
     * - decoding: total number of frames returned from the decoder so far.
     * - encoding: total number of frames passed to the encoder so far.
     *
     *   @note the counter is not incremented if encoding/decoding resulted in
     *   an error.
     */
    int64_t frame_num;
} AVCodecContext;


视频的关键参数有:


 // 视频宽高
int width, height;
 //像素格式
enum AVPixelFormat pix_fmt;
 // 视频宽高比
AVRational sample_aspect_ratio;
 // 帧率
AVRational framerate;
 // 平均码率
int64_t bit_rate;


音频关键参数:

// 采样率
int sample_rate;
// 声道数
int channels;
// 声道布局
uint64_t channel_layout;
// 采样格式
enum AVSampleFormat sample_fmt;



QP量化参数相关,默认qmin=0,qmax=51,QP越小、图像质量越好:

 // 量化参数最小值
int qmin;
 // 量化参数最大值
int qmax;
 // 帧间最大量化差异
int max_qdiff;

AVCodecContext 的应用

1.视频编码器


编码器上下文AVCodecContext是FFmpeg中用于描述编码器状态的结构体,包含了许多参数和配置选项,用于控制编码器的行为和性能。下面是一些常用的视频编码器上下文参数及其意义的详细讲解

1、codec_id:指定编码器的ID,如AV_CODEC_ID_H264表示H.264编码器。

pCodecCtx->codec_id = AV_CODEC_ID_H264;

2、bit_rate:指定编码的比特率,即视频数据每秒使用的比特数,通常以bit/s为单位。该参数的大小直接影响到视频的质量和大小,过高的比特率可能会导致视频过大,而过低的比特率可能会导致视频质量下降。

pCodecCtx->bit_rate = 3000000; // 比特率3000Kbps

2、width/height:指定视频的宽度和高度,单位为像素。

pCodecCtx->width = 1920;        // 1080P
pCodecCtx->height = 1080;

3、gop_size:指定关键帧(I帧)的间隔大小,即每隔多少帧就产生一个I帧。该参数的大小通常与视频的帧率和编码器的性能有关,过小的间隔可能会导致视频质量下降,而过大的间隔可能会导致视频播放时的卡顿现象。

pCodecCtx->gop_size = 25;

4、max_b_frames:指定编码器允许使用的最大B帧数量。B帧通常是在前后两个关键帧之间插入的一种帧类型,可以提高视频压缩比和画面流畅度,但同时也增加了编码器的计算量。

pCodecCtx->max_b_frames = 2;

5、pix_fmt:指定输入数据的像素格式,例如AV_PIX_FMT_YUV420P表示420格式的YUV数据。

pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;

6、time_base:指定视频的时间基准,即每个时间单位表示多少秒。通常为分数形式,例如{1, 25}表示每个时间单位为1/25秒。

pCodecCtx->time_base = (AVRational){1, 25};

7、workaround_bugs:用于指定编码器是否需要尝试解决一些已知的编码器或解码器的问题。将该参数设置为FF_BUG_AUTODETECT表示编码器会自动检测和解决一些已知的问题,包括一些标准不一致或解码器错误等问题。
 

在实际应用中,是否需要设置取决于具体的应用场景。如果您的应用程序需要处理多种不同的视频源或使用多种不同的解码器进行解码,那么可以考虑设置该参数,以确保编码器能够处理各种不同的视频源和解码器。但如果您的应用程序只处理特定类型的视频源或使用特定的解码器进行解码,可以考虑禁用该参数以提高编码效率。

pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT; // 0是禁用

8、thread_count:指定编码器使用的线程数量,用于提高编码器的并行处理能力。线程数的大小应根据实际情况和计算资源进行设置。

 
pCodecCtx->thread_count = 4;

9、refs:表示编码器在编码过程中可以参考的前向帧的数量。参考帧的数量对编码效果和编码速度都有影响。一般情况下,参考帧数量越多,编码效果越好,但编码速度也越慢。
 

对于参考帧的设置,需要综合考虑编码效果和编码速度。如果您的视频场景比较简单,可以将ref设置为1,这样可以提高编码速度,但可能会影响编码质量。如果您需要更好的编码质量,可以将ref设置为2或更高,但这样会降低编码速度。
所以,具体的ref设置要根据您的具体场景和需求来进行选择。如果您的视频场景比较简单,可以将ref设置为1,否则可以考虑适当增加ref的值。
需要注意的是,ref的值不能超过编码器支持的最大值,否则会导致编码器初始化失败。对于H.264编码器,默认的最大参考帧数是16,因此将ref设置为16或更高可能会导致编码器初始化失败。

pCodecCtx->refs = 1;

10、flags:指定编码器的各种标志,用于控制编码器的行为和性能。

 
// 生成全局头信息,在某些情况下非常有用,例如将H.264码流封装为MP4或MKV格式时,可以让封装器更容易地处理。
// 具体来说,全局头包含编码器的配置参数和SPS/PPS信息,这些信息对于解码器的正确解码非常重要。
// 因此,如果您需要将编码后的视频流进行封装,建议设置该标志。如果您仅仅需要将编码后的视频流保存为裸流,则不必设置该标志。
pCodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

// 表示输出的视频流可能会被截断。在一些情况下,输出的视频流可能会被截断,例如网络传输过程中发生了丢包,
//或者存储设备写入速度不足等。如果输出的视频流被截断,那么解码器可能无法正确解码视频流,导致输出的视频出现异常。
// 因此,是否需要设置取决于具体的应用场景。如果您的应用程序需要保证输出的视频流的完整性,那么可以考虑设置该参数。但如果您的应用程序对视频流的完整性要求不高,可以不设置该参数。
pCodecCtx->flags |= AV_CODEC_FLAG_TRUNCATED;

11、bit_rate_tolerance:参数则是指编码器输出比特率的容差,单位同样为bit/s。它表示编码器在进行比特率控制时,可以允许的比特率偏差范围。如果比特率超过了这个容差范围,编码器会尝试进行调整,以保持输出比特率在指定范围内。通常情况下,bit_rate_tolerance参数应该设置为bit_rate参数的10%左右;

需要注意的是,在设置bit_rate参数时,还需要考虑到编码器支持的最大比特率。如果bit_rate超过了编码器支持的最大比特率,编码器会自动进行调整。因此,为了避免比特率过高导致编码器自动调整输出比特率,可以查询编码器支持的最大比特率,并根据其进行设置

pCodecCtx->bit_rate_tolerance = pCodecCtx->bit_rate / 10;

12、profile:影响编码器的性能和输出视频的兼容性,H.264编码器支持多个profile,包括baseline、main、high等。不同的profile对应着不同的编码复杂度和输出视频兼容性。其中,baseline编码速度快,但是编码复杂度和输出视频兼容性一般,high则刚好相反;

对于H.264编码器而言,默认情况下profile参数的值是未定义的,需要手动设置。一般来说,如果不进行设置,编码器会根据当前的参数自动选择一个合适的profile。但是,在特定的应用场景下,手动设置profile参数可以带来更好的编码效果和更高的兼容性。

pCodecCtx->profile = FF_PROFILE_H264_BASELINE;

constrained profile可以使得输出的视频更加稳定、兼容性更好,但是可能会影响视频的质量。在一些情况下,constrained profile会限制一些高级的编码特性,使得编码效果与非constrained profile相比略有差别,如果您的应用程序对视频质量要求较高,且不希望受到任何限制,那么可以不设置该参数。但如果您希望输出的视频具有更高的兼容性、更加稳定,那么可以考虑设置该参数

pCodecCtx->profile |= FF_PROFILE_H264_CONSTRAINED;

13、priv_data:私有数据,即编码器的私有数据,用于存储编码器的内部状态和数据结构;
 

可以注意到,有些参数可以直接通过AVCodecContext的成员赋值,有些是通过priv_data来赋值,两个设置作用一样,理论上只需要通过一种方式设置就行;但两者之间还是有所差异,可以根据自己的需要进行设置,具体如下:

1、有些参数必须使用priv_data来设置,比如字符串类型的;或者AVCodecContext的成员没有的;
2、将配置参数设置到编码器的私有数据中,可以确保这些参数只对该编码器实例有效,并且不会对其他编码器实例产生影响。这对于同时处理多个视频流的应用程序非常重要,因为每个流可能需要不同的编码参数。此外,使用私有数据设置参数可以避免在参数传递过程中出现不必要的副作用或错误,提高代码的健壮性和可维护性

14 preset:参数是x264编码器的一种预设选项,用于设置编码速度和编码质量的平衡。

不同的预设选项可以在编码速度和编码质量之间进行权衡,通常可以选择的预设选项包括:ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo,其中ultrafast是最快的预设,placebo是最慢但是编码效果最好的预设;
如果对编码速度没有过高的要求,可以设置preset参数为slow或者slower,这样可以获得更好的编码质量。但是需要注意的是,使用更慢的预设会增加编码时间和计算资源的消耗,对于某些场景可能会影响实时性能。
因此,如果在实时场景中需要编码视频,并且需要保证编码速度和实时性能,那么可以考虑设置预设为ultrafast或superfast。如果需要更高的编码质量,并且可以承受一定的延迟,可以选择更慢的预设

av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0);

15 slice-max-size:用于指定编码器在生成码流时,切片(slice)的最大大小(字节数)。

这个参数的默认值是0,表示不限制切片大小。
如果设置了slice-max-size参数,则编码器将尝试将生成的每个切片大小限制在指定的最大大小内,从而可以控制编码输出码率的变化范围。通常情况下,设置slice-max-size参数可以有效地控制输出码率和码流大小,并提高编码输出的质量和稳定性。
在具体应用中,是否需要设置slice-max-size参数取决于视频源的特点和应用需求。如果您的视频源较为稳定,码率变化不大,可以不设置该参数。但是如果您的视频源波动较大,码率变化较大,则可以考虑设置slice-max-size参数以控制输出码率和码流大小。

// 我这边用的rtp封包发送,减去头部12
av_opt_set_int(pCodecCtx->priv_data, "slice-max-size", 1500-12, 0);

16 crf:设置 H.264 编码时使用的 Constant Rate Factor (CRF) 的值。

CRF 是一种自适应比特率控制方法,可以在保持视频质量不变的情况下,自动调整输出码率。具体来说,CRF 值越小,输出的视频质量越高,但输出的码率也会越大。CRF 值一般取值范围为 0-51,其中 0 表示无损编码,而 51 则表示最低质量的编码。一般来说,推荐的 CRF 值为 18-28 之间。默认值为 23。因此,如果你希望自适应控制视频码率,同时又想保持较高的视频质量,可以设置一个较小的 CRF 值,如 18。如果你想在保证视频质量的情况下控制视频码率,可以将 CRF 值调大一些,如 28。
注意,如果你设置了 CRF 值,那么其他控制比特率的参数(如 bit_rate 和 bit_rate_tolerance)将会被忽略,因为 CRF 会自动调整输出码率

av_opt_set_int(pCodecCtx->priv_data, "crf", 18, 0);

16、level:参数用于控制输出视频的级别。H.264标准规定了不同级别的输出视频所能达到的最大帧率、最大码率、最大分辨率等参数,因此选择合适的级别可以确保输出视频的兼容性和质量;

pCodecCtx->level = 41;

2.音频编码器

1、codec_id(编解码器ID):

类型:enum AVCodecID
默认值:AV_CODEC_ID_NONE
作用:指定要使用的音频编解码器的ID。例如,对于AAC编码,可以将其设置为AV_CODEC_ID_AAC。该参数告诉FFmpeg选择正确的编解码器进行音频编码。

2、codec_type(编解码器类型):

类型:enum AVMediaType
默认值:AVMEDIA_TYPE_UNKNOWN
作用:指定音频流的类型。对于音频编码,该参数应设置为AVMEDIA_TYPE_AUDIO。这有助于FFmpeg正确识别流的类型并应用适当的编码器

3、bit_rate(比特率):

类型:int64_t
默认值:0
作用:控制编码后音频的比特率(即每秒传输的位数),通常以比特/秒(bps)为单位,一般为(sample_rate * 8 * channel_num)。
这里有个疑问,中间这个值为什么是8,应该是  (每个样本的大小才合理),
上述公式应该是:  采样率 * 每一个采样样本的大小  * 声道数量

较高的比特率可提供更好的音频质量,但会产生较大的文件大小。


例如 如果48000 ,f32le,2声道
48000 * 4 *2 = 384000

如果是44100,s16le,2声道
44100 *2*2 = 176,400

如果按照默认值 128000,除以2声道,pcm数据格式是 s16le ,
128000/2/2 = 32000  那么这个32000应该是采样率





Set bit rate in bits/s. Setting this automatically activates constant bit rate (CBR) mode. If this option is unspecified it is set to 128kbps.

注意,这里是 编码后 音频的比特率。不是PCM的,因此不可以用 PCM的 AV_SAMPLE_FMT_FLTP


4、sample_fmt(采样格式):

类型:enum AVSampleFormat
默认值:AV_SAMPLE_FMT_NONE
作用:指定音频采样数据的格式。常见的采样格式包括有符号整数(如AV_SAMPLE_FMT_S16)、无符号整数、浮点数等。选择合适的采样格式与源音频数据的格式相匹配,以确保编码器能够正确处理音频数据。

5、sample_rate(采样率):

类型:int
默认值:0
作用:定义每秒钟采样的样本数。常见的采样率包括 44100 Hz(CD音质)、48000 Hz(DVD音质)等。较高的采样率可提供更好的音频质量,但也会增加文件大小。

6、channels(声道数):

类型:int
默认值:0
作用:定义音频数据的声道数,常见的值为 1(单声道)和 2(立体声)。根据源音频数据的声道数,选择适当的值以确保编码器能正确处理声道布局

7、frame_size(帧大小):即每个帧中包含的采样点数

类型:int
默认值:0
作用:指定音频编码器的输出帧大小。帧大小表示每个编码帧中包含的采样点数。对于某些编码器,帧大小需要是固定值。指定正确的帧大小可以确保编码器按预期处理音频数据。

8、time_base.num 和 time_base.den(时间基准):

类型:int
默认值:0
作用:time_base 表示时间的基准单位,用于指定音频流的时间基准。time_base.num 表示每秒钟的时间单位数,time_base.den 表示每个时间单位的时长。这些参数影响音频的时间戳和持续时间的计算。

9、bit_rate_tolerance(比特率容差):

类型:int
默认值:0
作用:指定比特率容差的上限。比特率容差表示编码器在尽力满足指定比特率的同时,允许的最大比特率偏差量。较大的容差值可能会导致音频质量的损失,但也有助于适应比特率变化的情况。

10、channel_layout(声道布局):

类型:uint64_t
默认值:0
作用:指定音频流的声道布局。声道布局描述音频数据中各声道的位置和顺序。例如,对于立体声,可以使用AV_CH_LAYOUT_STEREO。正确的声道布局设置有助于确保编码器正确处理音频流中的声道信息。

3.音频解码器

1、codec_id(编解码器ID):

类型:enum AVCodecID
默认值:AV_CODEC_ID_NONE
作用:指定要使用的音频解码器的ID。例如,对于AAC解码,可以将其设置为AV_CODEC_ID_AAC。该参数告诉FFmpeg选择正确的解码器进行音频解码。

2、codec_type(编解码器类型):

类型:enum AVMediaType
默认值:AVMEDIA_TYPE_UNKNOWN
作用:指定音频流的类型。对于音频解码,该参数应设置为AVMEDIA_TYPE_AUDIO。这有助于FFmpeg正确识别流的类型并应用适当的解码器。

3、request_sample_fmt(采样格式):

类型:enum AVSampleFormat
默认值:AV_SAMPLE_FMT_NONE
作用:是用于向解码器请求特定的采样格式,而不是实际指定解码后的采样格式。解码器将音频数据转换为指定的采样格式,以便后续处理和播放。常见的采样格式包括有符号整数(如AV_SAMPLE_FMT_S16)、无符号整数、浮点数等。

4、sample_rate(采样率):

类型:int
默认值:0
作用:指定解码后音频数据的采样率。解码器将音频数据重新采样为指定的采样率,以匹配后续处理或播放的要求。通常,采样率应与解码前音频数据的采样率一致。

5、channels(声道数):

类型:int
默认值:0
作用:指定解码后音频数据的声道数。解码器将音频数据转换为指定的声道布局,以匹配后续处理或播放的需求。通常,声道数应与解码前音频数据的声道数一致。

6、request_channel_layout(声道布局):

类型:uint64_t
默认值:0
作用:是用于向解码器请求特定的声道布局,而不是实际指定解码后的声道布局。声道布局描述音频数据中各声道的位置和顺序。解码器将音频数据转换为指定的声道布局,以便后续处理或播放。

7、flags(标志):

类型:int

默认值:0
作用:用于设置解码器的一些选项和标志。例如,可以启用解码器低延迟模式(pCodecCtx->flags |= AV_CODEC_FLAG_LOW_DELAY); 将解码器上下文的 flags 参数
设置为 AV_CODEC_FLAG_LOW_DELAY,在音频实时解码的情况下,可以尽快地产生解码后的音频输出。它在实时应用中很有用,例如实时通信、语音聊天、语音识别等场景,
其中延迟是关键因素。通过启用低延迟模式,解码器可能会采取一些策略来减小延迟,例如减少内部缓冲区的大小、禁用一些处理步骤或优化算法等。这可以使解码器更加敏捷地响应输入数据,
并尽快输出解码后的音频。但请注意,低延迟模式可能会对解码器的质量产生一定的影响,因为某些优化步骤可能会受到限制。因此,在使用低延迟模式时需要权衡实时性和音频质量之间的平衡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值