06FFMPEG的AVCodecContext结构体分析

2023-11-12

06FFMPEG的AVCodecContext结构体分析

概述:
该结构体位于libavcodec库中的avcodec.h中。

1 AVCodecContext编解码上下文结构体
位于libavcodec库里。
AVFormatContext,AVInputFormat,AVOutputFormat,AVStream均位于libavformat库里。最长的结构体,将近两千行。但是新版本avformat58.dll开始注明该编解码上下文将被逐渐弃用,而采用同样在流中的AVCodecParameters *codecpar字段。

该结构体包含着关于编解码器的信息。

typedef struct AVCodecContext {
    /**
     * 关于av_log结构的信息。
     * - 由avcodec_alloc_context3函数设置。
     */
    const AVClass *av_class;
    int log_level_offset;

    enum AVMediaType codec_type; /* 媒体类型,具体可以看AVMEDIA_TYPE_xxx */
    const struct AVCodec  *codec;/* 编解码器 */
    enum AVCodecID     codec_id; /* 编解码的ID,具体可以看AV_CODEC_ID_xxx */

    /**
     * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
     * 我保持上面该句的原英文:四字符代码,小端字节存储。所以A为低字节,D为高字节。例如D左移24位即位移3个字节后就变成了第四个字节的内容。
     * 
     * 这是用来解决一些encoder编码器的错误。
     * 
     * demuxer解复用器应该将其设置为:存储在用于识别编解码器的字段中。
     * 如果一个容器中有多个这样的字段,demuxer解复用器应该选择最大化信息的编解码器。
     * 如果容器中的codec_tag字段大于32位,demuxer解复用器应该用表或其他结构将较长的ID重新映射为32位。
     * 另外,也可以添加一个新的extra_codec_tag + 大小,但为此必须首先展示一个明显的优势。
     * - encoding编码: 由用户设置,如果没有,则将使用基于codec_id的默认值。
     * - decoding解码: 由用户设置,初始化时将被libavcodec库转换为大写。
     */
    unsigned int codec_tag;

    void *priv_data;

    /**
     * 用于内部数据的私有上下文。
     * 
     * 与priv_data不同,这不是特定于编解码的。它在一般的libavcodec函数中使用。
     */
    struct AVCodecInternal *internal;

    /**
     * 用户的私有数据,可以用来携带应用程序特定的东西。
     * - encoding编码: 由用户设置。
     * - decoding解码: 由用户设置。
     */
    void *opaque;

    /**
     * 平均比特率(码率)。
     * - encoding编码: 由用户设置; 不用于常量量化编码。
     * - decoding解码: 由用户设置, 如果这个码率信息是在流中可用的话,可能被libavcodec覆盖。
     */
    int64_t bit_rate;

    /**
     * 允许比特流偏离参考的比特数。
     * the reference can be CBR (for CBR pass1) or VBR (for pass2)。--这句笔者看不懂,不知道如何翻译。。。
     * 
     * - encoding编码: 由用户设置; 不用于常量量化编码。
     * - decoding解码: 未使用。
     */
    int bit_rate_tolerance;

    /**
     * 编解码器的全局质量,不能每帧改变它。
     * 这应该与MPEG-1/2/4 qscale成比例。
     * - encoding编码: 由用户设置。
     * - decoding解码: 未使用。
     */
    int global_quality;

    /**
     * - encoding编码: 由用户设置。
     * - decoding解码: 未使用。
     */
    int compression_level;
#define FF_COMPRESSION_DEFAULT -1

    /**
     * AV_CODEC_FLAG_*.
     * - encoding编码: 由用户设置。
     * - decoding解码: 由用户设置。
     */
    int flags;

    /**
     * AV_CODEC_FLAG2_*
     * - encoding编码: 由用户设置。
     * - decoding解码: 由用户设置。
     */
    int flags2;

    /**
     * 一些编解码器需要/或者能够使用像哈夫曼表的extradata额外数据(该存储着SPS,PPS的相应信息)。
     * MJPEG: 哈夫曼表。
     * rv10: 附加标志。
     * MPEG-4: 全局头(它们可以在bitstream比特流中或这里)。
     * 分配的内存应该是AV_INPUT_BUFFER_PADDING_SIZE更大的比起extradata_size,以避免使用位流读取器读取时出现问题。
     * extradata的字节内容不能依赖于体系结构或CPU字节顺序。
     * 必须与av_malloc()家族函数一起分配。
     * - encoding编码: 设置/分配/释放均由libavcodec库处理。
     * - decoding:  设置/分配/释放均由用户处理。
     *  
     * 注:个人编码时遇到过这样的问题,若这两字段不设置,我们推live流是正常的,但推hls是失败的。具体你可以看FFmepgff_isom_write_avcc函数,该函数中将AV_CODEC_ID_H264转化时,发现extradata_size如果小于等于6就不帮你转,以至于无法转成AV_CODEC_ID_AAC在nginx传输。
     */
    uint8_t *extradata;
    int extradata_size;

    /**
     * 这是表示帧时间戳的基本时间单位(秒)。对于固定帧率fps的内容,时基应该是1/帧率,时间戳的增量应该是相同的1(应该是指以该时基为增量)。
     * 这字段通常与视频流的帧率或场率相反,但不总是相反。如果帧速率不是恒定的,1/time_base不是平均帧速率。
     * 
     * 与容器一样,基本流也可以存储时间戳,1/time_base是指定这些时间戳的单位(因为该字段常设为帧率倒数,所以取倒数刚好为帧率)。
     * 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编码: 必须由用户设置。
     * - decoding解码: 解码时该字段是被废弃的,使用帧率代替。
     * 
     */
    AVRational time_base;

    /**
     * 对于一些编解码器,时基比帧率更接近于场率。
     * 最值得注意的是,如果没有使用telecine,H.264和MPEG-2指定time_base为帧时长的一半。
     * 
     * 设置每帧time_base时基的滴答数。默认1,例如,H.264/MPEG-2设置为2。
     */
    int ticks_per_frame;

    /**
     * 编解码延迟。
     *
     * Encoding编码: 从编码器输入到解码器输出的帧延迟数(即编码时输出到输出流中的解码器帧的延时),我们假设解码器符合规范。
     * Decoding解码: 除了规格中指定的标准解码器所产生的帧延迟数。
     *
     * Video:
     *   被解码的输出相对于被编码的输入延迟的帧数。即和上面意思一样。
     *
     * Audio:
     *   对于编码,这个字段是不用的(参见initial_padding)。
     * 
     * 对于decoding解码,这是在decoder解码器的输出有效之前,解码器需要输出的样本数。在查找时,您应该在期望的查找(seek)点之前开始decoding解码这多个样本。
     *
     * - encoding编码: 由libavcodec库设置。
     * - decoding解码: 由libavcodec库设置。
     */
    int delay;


    /* video only */
    /**
     * 图片的长和宽(分辨率),只有视频才有。
     *
     * 注意:由于帧重排序,这些字段可能与avcodec_decode_video2最后一次AVFrame输出的值不匹配。
     *
     * - encoding: 必须由用户设置。
     * - decoding: 可能由用户在打开解码器(如从容器中)之前设置。 一些解码器将要求由调用者设置该尺寸。在解码期间,解码器可以在解析数据时根据需要重写这些值。
     */
    int width, height;

    /**
     * 位流的宽度/高度,可能与宽度/高度不同,例如,当解码帧在输出之前被裁剪或低分辨率被启用。
     *
     * 注意:由于帧重新排序,这些字段可能与avcodec_receive_frame()最后一次AVFrame输出的值不匹配
     *
     * - encoding: 未使用。
     * - decoding: 可能由用户在打开解码器(如从容器中)之前设置。在解码期间,解码器可以在解析数据时根据需要重写这些值。
     */
    int coded_width, coded_height;

    /**
     * 一组图片的数量。即多少帧后重新出现新的I帧,0对于intra_only。
     * - encoding编码: 由用户设置。
     * - decoding解码: 未使用。
     */
    int gop_size;

    /**
     * 像素格式,见AV_PIX_FMT_xxx。一般设置为AV_PIX_FMT_YUV420P。
     * 可以由demuxer解复用器设置,如果在头部已知。
     * 可能被解码器重写,如果它知道更多的话。
     *
     * 注意:由于帧重新排序,这个字段可能与avcodec_receive_frame()最后一次AVFrame输出的值不匹配。
     *
     * - encoding编码: 由用户设置。
     * - decoding解码: 如果已知由用户设置, 在解析数据时被libavcodec库重写。
     */
    enum AVPixelFormat pix_fmt;

    /**
     * 如果非空,'draw_horiz_band'被libavcodec库的decoder解码器调用,来绘制水平波段。它提高了缓存的使用。并不是所有的编解码器都能做到这一点。您必须事先检查编解码器的能力。
     * 当使用多线程时,它可以被多个线程同时调用;线程可能会绘制同一个AVFrame的不同部分,或者多个AVFrame,并且不能保证切片将按照顺序绘制。
     * 硬件加速api也使用该函数。
     * 它在帧解码期间至少被调用一次,以传递硬件渲染所需的数据。
     * 在这种模式下,AVFrame不是指向像素数据,而是指向一个特定于加速API的结构。应用程序读取该结构,并可以更改某些字段以指示进度或标记状态。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     * 参数height:切片高度。
     * 参数y:切片y坐标。
     * 参数type: 1->top field, 2->bottom field, 3->frame。
     * 参数offset: 偏移到应该从中读取切片的AVFrame.data。
     */
    void (*draw_horiz_band)(struct AVCodecContext *s,
                            const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
                            int y, int type, int height);

    /**
     * 回调以协商pixelFormat。
     * 参数fmt:fmt是编解码器支持的格式列表,它以-1结束,因为0是一种有效的格式,格式是按质量排序的。
     * The first is always the native one.第一个总是本地(native)的。
     * 注意:如果所选(硬件加速)像素格式初始化失败,可能会立即再次调用回调函数。
     * 
     * 警告:如果回调返回的值不在fmt格式列表中,则警告行为未定义。
     * 返回寻找的格式。
     * - encoding: 未使用。
     * - decoding: 由用户设置, 如果没有设置那么本地的格式(native format)将被选择。
     */
    enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);

    /**
     * 非B帧之间的最大B帧数。
     * 注意:相对于输入,输出将被max_b_frames+1延迟。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int max_b_frames;

    /**
     * IP和b帧之间的qscale因子(qscale factor between IP and B-frames)。
     * If > 0,那么最后一个p帧量化器将被使用 (q= lastp_q*factor+offset)。
     * If < 0,那么正常的ratecontrol(速率控制)将完成 (q= -normal_q*factor+offset).
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float b_quant_factor;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替 */
    attribute_deprecated
    int b_frame_strategy;
#endif

    /**
     * IP和b帧之间的qscale偏移量。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float b_quant_offset;

    /**
     * 译码器中帧重排序缓冲区的大小。
     * 对于MPEG-2,它是1 IPB或0低延迟IP(For MPEG-2 it is 1 IPB or 0 low delay IP)。
     * - encoding: 由libavcodec库设置。
     * - decoding: 由libavcodec库设置。
     */
    int has_b_frames;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替 */
    attribute_deprecated
    int mpeg_quant;
#endif

    /**
     * P帧和i帧之间的qscale因子。
     * If > 0,那么使用最后一个p帧量化器 (q = lastp_q * factor + offset)。
     * If < 0,那么正常的ratecontrol(速率控制)将完成 (q= -normal_q*factor+offset).
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float i_quant_factor;

    /**
     * P帧和i帧之间的qscale偏移量。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float i_quant_offset;

    /**
     * 亮度掩蔽 (0-> disabled)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float lumi_masking;

    /**
     * 临时复杂性掩蔽 (0-> disabled)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float temporal_cplx_masking;

    /**
     * 空间复杂性掩蔽 (0-> disabled)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float spatial_cplx_masking;

    /**
     * p block 掩蔽 (0-> disabled)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float p_masking;

    /**
     * 黑暗掩蔽 (0-> disabled)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float dark_masking;

    /**
     * 切片数。
     * - encoding: 由libavcodec库设置。
     * - decoding: 由用户设置(or 0)。
     */
    int slice_count;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替 */
    attribute_deprecated
     int prediction_method;
#define FF_PRED_LEFT   0
#define FF_PRED_PLANE  1
#define FF_PRED_MEDIAN 2
#endif

    /**
     * 帧中的切片偏移量(以字节为单位)。
     * - encoding: Set/allocated by libavcodec.
     * - decoding: Set/allocated by user (or NULL).
     */
    int *slice_offset;

    /**
     * 样本比例 (0 if unknown)。
     * 也就是像素的宽度除以像素的高度。
     * 对于某些视频标准,分子和分母必须是相对质数且小于256的。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    AVRational sample_aspect_ratio;

    /**
     * 运动估计比较函数(数)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int me_cmp;
    /**
     * 亚像素运动估计比较函数(数)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int me_sub_cmp;
    /**
     * 宏块比较函数(数)(不支持)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int mb_cmp;
    /**
     * 交错DCT比较函数(数)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    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

    /**
     * 我的钻石(diamond,方块)尺寸和形状。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int dia_size;

    /**
     * 之前MV预测器的数量 (2a+1 x 2a+1 square)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int last_predictor_count;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替 */
    attribute_deprecated
    int pre_me;
#endif

    /**
     * 运动估计前置比较函数(数)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int me_pre_cmp;

    /**
     * ME prepass diamond size & shape(不知道怎么翻译prepass,应该指用于保存它上面测完通过的dia_size值)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int pre_dia_size;

    /**
     * subpel ME quality。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int me_subpel_quality;

    /**
     * 最大运动估计搜索范围(单位为subpel)。
     * 如果是0,则没有限制。
     *
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int me_range;

    /**
     * 切片标志。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    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)

    /**
     * 宏模块决定模式。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int mb_decision;
#define FF_MB_DECISION_SIMPLE 0        ///< 使用mb_cmp。
#define FF_MB_DECISION_BITS   1        ///< 选择一个需要最少比特的。
#define FF_MB_DECISION_RD     2        ///< 速率失真。

    /**
     * 自定义(intra)内量化矩阵。
     * 必须与av_malloc()函数家族分配,并将在avcodec_free_context()中释放。
     * - encoding: 通过用户设置和分配,释放通过libavcodec库。可以是空NULL。
     * - decoding: 设置,分配,释放均通过libavcodec库。
     */
    uint16_t *intra_matrix;

    /**
     * 自定义(inter)互量化矩阵。
     * 必须与av_malloc()函数家族分配,并将在avcodec_free_context()中释放。
     * - encoding: 通过用户设置和分配,释放通过libavcodec库。可以是空NULL。
     * - decoding: 设置,分配,释放均通过libavcodec库。
     */
    uint16_t *inter_matrix;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替 */
    attribute_deprecated
    int scenechange_threshold;

    /** 使用编码器私有选项代替 */
    attribute_deprecated
    int noise_reduction;
#endif

    /**
     * 精度的内部直流系数 - 8。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    int intra_dc_precision;

    /**
     * 顶部跳过的宏块行数。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    int skip_top;

    /**
     * 底部跳过的宏块行数。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    int skip_bottom;

    /**
     * 最小MB拉格朗日乘子。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int mb_lmin;

    /**
     * 最小MB拉格朗日乘子。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int mb_lmax;

#if FF_API_PRIVATE_OPT
    /**
     * 使用编码器私有选项代替。
     */
    attribute_deprecated
    int me_penalty_compensation;
#endif

    /**
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int bidir_refine;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int brd_scale;
#endif

    /**
     * 最小视频帧组的大小。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int keyint_min;

    /**
     * 参考帧的数目。
     * - encoding: 由用户设置。
     * - decoding: 由lavc设置。
     */
    int refs;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int chromaoffset;
#endif

    /**
     * 注意:值取决于fullpel ME使用的比较函数。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int mv0_threshold;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int b_sensitivity;
#endif

    /**
     * 源初选的色度坐标。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVColorPrimaries color_primaries;

    /**
     * 颜色传输特性。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVColorTransferCharacteristic color_trc;

    /**
     * YUV彩色空间类型。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVColorSpace colorspace;

    /**
     * MPEG vs JPEG YUV range.
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVColorRange color_range;

    /**
     * 这就定义了色度样品的位置。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVChromaLocation chroma_sample_location;

    /**
     * 切片的个数。
     * 表示图像细分的数量。用于并行译码。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int slices;

    /** 字段排序。
     * - encoding: 由libavcodec库设置。
     * - decoding: 由用户设置。
     */
    enum AVFieldOrder field_order;

    /* audio only */
    int sample_rate; ///< 每秒采样率。
    int channels;    ///< 音频通道数量。

    /**
     * 音频样本格式。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVSampleFormat sample_fmt;  ///< 样本格式。

    /* 不应该初始化以下数据。 */
    /**
     * 在一个音频帧中每个频道的样本数。
     *
     * - encoding: 由avcodec_open2()中的libavcodec设置。除了最后一帧之外,每个提交的帧必须包含每个通道的帧大小样本。
     * 	 当编解码器有AV_CODEC_CAP_VARIABLE_FRAME_SIZE设置时可能是0,那么帧大小是不受限制的。
     * - decoding:可能被一些解码器设置,以表示恒定帧大小。
     */
    int frame_size;

    /**
     * 帧计数器(frame counter),由libavcodec设置。
     *
     * - decoding: 到目前为止从解码器返回的帧总数。
     * - encoding: 到目前为止传递给编码器的帧总数。
     *
     *   注意:如果编码/解码导致错误,计数器(即该字段)不会增加。
     */
    int frame_number;

    /**
     * 如果常量和已知或0使用一些基于WAV的音频编解码器,(代表)每个包的字节数。
     */
    int block_align;

    /**
     * 音频截止带宽(0表示“自动”)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int cutoff;

    /**
     * 音频通道布局。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置, 可能会被libavcodec库重写。
     */
    uint64_t channel_layout;

    /**
     * 如果可以,请求解码器使用此通道布局(默认为0)。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    uint64_t request_channel_layout;

    /**
     * 音频流传输的服务类型。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    enum AVAudioServiceType audio_service_type;

    /**
     * 期待(需要)的样本格式。
     * - encoding: 不使用。
     * - decoding: 由用户设置。
     * 解码器将解码到这种格式,如果它可以。
     */
    enum AVSampleFormat request_sample_fmt;

    /**
     * 这个回调在每一帧的开始被调用,以获得它的数据缓冲区。可以为所有数据设置一个连续缓冲区,也可以为每个数据平面或两者之间的任何东西设置一个缓冲区。这意味着,您可以在buf[]中设置您认为必要的任意数量的条目。每个缓冲区必须使用AVBuffer API进行引用计数(参见下面对buf[]的描述)。
     * 
     * 下面的字段会在这个回调被调用之前被设置在框架中:
     * - format
     * - width, height (video only)
     * - sample_rate, channel_layout, nb_samples (audio only)
     * 它们的值可能与AVCodecContext中相应的值不同。这个回调必须使用帧值(frame values)而不是编解码器上下文的值来计算所需的缓冲区大小。
     *
     * 这个回调必须填充帧中的以下字段:
     * - data[]
     * - linesize[]
     * - extended_data:
     * 如果数据是超过8个通道的平面音频,那么这个回调必须分配和填充extended_data以包含所有指向所有数据平面的指针。data[]必须保存尽可能多的指针。
     * extended_data必须用av_malloc()分配,并将在av_frame_unref()中释放。
     *   *否则extended_data必须指向数据。
     * - buf[]必须包含一个或多个指向AVBufferRef结构的指针。 帧的每个数据和extended_data指针都必须包含在其中。也就是说,每个分配的内存块对应一个AVBufferRef,而不是每个data[]条目对应一个AVBufferRef。参见:av_buffer_create()、av_buffer_alloc()和av_buffer_ref()。
     * - 这个回调必须使用av_malloc()分配extended_buf和nb_extended_buf,如果缓冲区超过了buf[]所能容纳的,则用额外的缓冲区填充。extended_buf将在av_frame_unref()中释放。
     *
     * 如果AV_CODEC_CAP_DR1没有设置,那么get_buffer2()必须调用avcodec_default_get_buffer2(),而不是提供通过其他方式分配的缓冲区。
     *
     * 每个数据平面必须与目标CPU所需的最大数据平面对齐。
     *
     * 参见avcodec_default_get_buffer2()。
     *
     * Video:
     * 
     * 如果AV_GET_BUFFER_FLAG_REF设置在这个标志,那么这个框架可能会被libavcodec库重用(读和/或写,如果它是可写的)。
     *
     * 应该使用avcodec_align_dimensions2()来查找所需的宽度和高度,因为它们通常需要四舍五入到16的下一个倍数。
     *
     * 有些解码器不支持帧之间的行变换。
     *
     * 如果使用了帧的多线程并且设置了thread_safe_callbacks,这个回调可以从不同的线程调用,但不能同时从多个线程调用。不需要重入。
     *
     * 参见avcodec_align_dimensions2()。
     *
     * Audio:
     * 
     * 解码器通过在调用get_buffer2()之前设置AVFrame.nb_samples来请求一个特定大小的缓冲区。然而,解码器可能通过在输出帧时将AVFrame.nb_samples设置为较小的值,而仅利用该缓冲区的一部分。
     *
     * 方便起见,自定义get_buffer2()函数可以使用libavutil中的av_samples_get_buffer_size()和av_samples_fill_arrays()来查找所需的数据大小并填充数据指针和行大小(linesize)。 在AVFrame.linesize中,只有linesize[0]可以设置对于音频,因为所有的平面必须是相同的大小。
     *
     * 参见av_samples_get_buffer_size(), av_samples_fill_arrays()。
     *
     * - encoding: 未使用。
     * - decoding: 由libavcodec库设置, 用户可以重写。
     */
    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);

    /**
     *  如果非零,从avcodec_decode_video2()和avcodec_decode_audio4()返回的解码音频和视频帧将被引用计数并且是无限期有效的。当不再需要它们时,调用者必须使用av_frame_unref()释放它们。
     * 否则,解码帧必须不能被调用者释放,并且只能在下一次解码调用之前有效。
     * 
     * 如果使用avcodec_receive_frame(),它总是自动启用。
     *
     * - encoding: 未使用。
     * - decoding: 由调用者在avcodec_open2()之前调用。
     */
    attribute_deprecated
    int refcounted_frames;

    /* - 编码参数 */
    float qcompress;  ///< 简单场景和困难场景(easy & hard scenes)之间的qscale数量变化(0.0-1.0)。
    float qblur;      ///< 随着时间的推移,qscale平滑的数量(0.0-1.0)。

    /**
     * 最小量化器。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int qmin;

    /**
     * 最大量化器。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int qmax;

    /**
     * 帧之间的最大量化器差。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int max_qdiff;

    /**
     * decoder解码器bitstream位流缓冲区的大小。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int rc_buffer_size;

    /**
     * 速率控制重写,参见RcOverride。
     * - encoding: 分配/设置/释放均由用户处理。
     * - decoding: 未使用
     */
    int rc_override_count;
    RcOverride *rc_override;

    /**
     * 最大比特率(一般叫码率)。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置, 可能被libavcodec库重写。
     */
    int64_t rc_max_rate;

    /**
     * 最小比特率。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int64_t rc_min_rate;

    /**
     * 速率控制尝试去使用,在最大值,可以使用而不出现下溢的值。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float rc_max_available_vbv_use;

    /**
     * 速率控制尝试去使用, 在最小值, 值乘以防止vbv溢出所需的量。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    float rc_min_vbv_overflow_use;

    /**
     * 解码开始前应装入rc缓冲区的位数(Number of bits)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int rc_initial_buffer_occupancy;

#if FF_API_CODER_TYPE
#define FF_CODER_TYPE_VLC       0
#define FF_CODER_TYPE_AC        1
#define FF_CODER_TYPE_RAW       2
#define FF_CODER_TYPE_RLE       3
    /**
     * 使用编码器私有选项代替。  */
    attribute_deprecated
    int coder_type;
#endif /* FF_API_CODER_TYPE */

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int context_model;
#endif

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int frame_skip_threshold;

    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int frame_skip_factor;

    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int frame_skip_exp;

    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int frame_skip_cmp;
#endif /* FF_API_PRIVATE_OPT */

    /**
     * 格子框架RD量子化。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    int trellis;

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int min_prediction_order;

    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int max_prediction_order;

    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int64_t timecode_frame_start;
#endif

#if FF_API_RTP_CALLBACK
    /**
     * 弃用。
     */
    /* RTP回调:每当encoder编码器有数据包要发送时,就会调用这个函数。*/
    /* 如果数据开始伴随着开始码(这是它应该的),它依赖于编码器。H.263就是。 */
    /* mb_nb包含RTP有效负载中编码的宏块数量。*/
    attribute_deprecated
    void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
#endif

#if FF_API_PRIVATE_OPT
    /** 使用编码器私有选项代替。 */
    attribute_deprecated
    int rtp_payload_size;   /* RTP有效负载的大小:编码器将尽其所能交付一个小于rtp_payload_size的数据块,该数据块将从编解码器的开始码开始,例如H.263等。  */
                            /* 这没有考虑到传输的RTP有效负载中的任何特定报头  */
#endif

#if FF_API_STAT_BITS
    /* 统计,用于2次编码 */
    attribute_deprecated
    int mv_bits;
    attribute_deprecated
    int header_bits;
    attribute_deprecated
    int i_tex_bits;
    attribute_deprecated
    int p_tex_bits;
    attribute_deprecated
    int i_count;
    attribute_deprecated
    int p_count;
    attribute_deprecated
    int skip_count;
    attribute_deprecated
    int misc_bits;

    /** @弃用,这个字段是不使用的。 */
    attribute_deprecated
    int frame_bits;
#endif

    /**
     *  pass1编码统计信息输出缓冲区。
     * - encoding: 由libavcodec库设置。
     * - decoding: 未使用。
     */
    char *stats_out;

    /**
     * pass2编码统计信息输入缓冲区。
     * 从pass1的stats_out连接的内容应该放在这里。
     * - encoding: Allocated/set/freed分配/设置/释放由用户处理。
     * - decoding: 未使用。
     */
    char *stats_in;

    /**
     * 解决(work)编码器中有时无法自动检测到的bug。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int workaround_bugs;
#define FF_BUG_AUTODETECT       1  ///< 自动检测。
#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 ///< 解决微软解码器的各种bug。
#define FF_BUG_TRUNCATED       16384
#define FF_BUG_IEDGE           32768

    /**
     * 严格遵循标准(MPEG-4,…)
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     * 将其设置为严格或更高意味着编码器和解码器通常会做一些愚蠢的事情,而将其设置为非官方或更低将意味着编码器可能会产生不被所有规范兼容的解码器支持的输出。
     * 解码器不会区分正常的、非官方的和实验的(也就是说,他们总是在可能的时候尝试解码东西),除非他们被明确地要求做出愚蠢的行为(=严格遵守规范)。
 */
    int strict_std_compliance;
#define FF_COMPLIANCE_VERY_STRICT   2 ///< 严格遵守旧的、更严格的版本规范或参考软件。
#define FF_COMPLIANCE_STRICT        1 ///< 无论结果如何,严格遵守规范中的所有内容。
#define FF_COMPLIANCE_NORMAL        0
#define FF_COMPLIANCE_UNOFFICIAL   -1 ///< 允许的非官方扩展。
#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< 允许非标准化的实验性东西(内容)。

	/**
     * 错误隐藏的标志。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    int error_concealment;
#define FF_EC_GUESS_MVS   1
#define FF_EC_DEBLOCK     2
#define FF_EC_FAVOR_INTER 256

    /**
     * debug调试。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    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
#if FF_API_DEBUG_MV
/**
 * 弃用,这选项不做任何事情。
 */
#define FF_DEBUG_MV          32
#endif
#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
#if FF_API_DEBUG_MV
#define FF_DEBUG_VIS_QP      0x00002000
#define FF_DEBUG_VIS_MB_TYPE 0x00004000
#endif
#define FF_DEBUG_BUFFERS     0x00008000
#define FF_DEBUG_THREADS     0x00010000
#define FF_DEBUG_GREEN_MD    0x00800000
#define FF_DEBUG_NOMC        0x01000000

#if FF_API_DEBUG_MV
    /**
     * debug调试。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int debug_mv;
#define FF_DEBUG_VIS_MV_P_FOR  0x00000001 // 可视化向前预测P帧的MVs。
#define FF_DEBUG_VIS_MV_B_FOR  0x00000002 // 可视化向前预测B帧的MVs。
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 // 可视化向后预测B帧的MVs。
#endif

    /**
     *错误识别; 可能会将一些或多或少有效的部分误检为错误。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    int err_recognition;

/**
 * 验证嵌入在bitstream比特流中的校验和(可以是编码的或解码的数据,取决于编解码器),并在不匹配时打印错误信息。
 * 如果还设置了AV_EF_EXPLODE,则校验和不匹配将导致解码器返回错误。
 */
#define AV_EF_CRCCHECK  (1<<0)
#define AV_EF_BITSTREAM (1<<1)          ///< 检测比特流规格(具体)偏差。
#define AV_EF_BUFFER    (1<<2)          ///< 检测错误的比特流长度。
#define AV_EF_EXPLODE   (1<<3)          ///< 在小错误检测中中断decoding解码。

#define AV_EF_IGNORE_ERR (1<<15)        ///< 忽略错误并继续。
#define AV_EF_CAREFUL    (1<<16)        ///< 考虑那些违反规范、计算速度快且不被广泛认为是错误的东西。
#define AV_EF_COMPLIANT  (1<<17)        ///< 将所有不符合规范的行为视为错误。
#define AV_EF_AGGRESSIVE (1<<18)        ///< 把一个正常的编码器不应该做的事情看作错误。


    /**
     * 将被重新排序并在AVFrame.reordered_opaque中输出的(opaque,不透明的)64位数字(通常是PTS)。
     * - encoding: 由libavcodec设置为与最后返回的包对应的输入帧的reordered_opaque。 仅由具有AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE功能的编码器支持。
     * - decoding: 由用户设置。
     */
    int64_t reordered_opaque;

    /**
     * 硬件加速器在使用。
     * - encoding: 未使用。
     * - decoding: 由libavcodec库设置。
     */
    const struct AVHWAccel *hwaccel;

    /**
     * 硬件加速器上下文。
     * 对于某些硬件加速器,用户需要提供全局上下文。在这种情况下,它持有FFmpeg不能实例化自己的显示依赖数据。 请参考FFmpeg HW加速器文档了解如何填写这些。例如,对于VA API,这是一个struct vaapi_context。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    void *hwaccel_context;

    /**
     * 错误。
     * - encoding: 由libavcodec库设置如果flags & AV_CODEC_FLAG_PSNR为真时。
     * - decoding: 未使用。
     */
    uint64_t error[AV_NUM_DATA_POINTERS];

    /**
     * DCT算法,见下面的FF_DCT_*
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
    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算法, 见下面的FF_IDCT_*。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    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
#define FF_IDCT_NONE          24 /* XvMC使用FF_IDCT_PERM_NONE提取IDCT系数。 */
#define FF_IDCT_SIMPLEAUTO    128

    /**
     * 来自demuxer的每个样本/像素的比特数(huffyuv需要)。
     * - encoding: 由libavcodec库设置。
     * - decoding: 由用户设置。
     */
     int bits_per_coded_sample;

    /**
     * 内部libavcodec像素/样本格式的每个样本/像素位。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
    int bits_per_raw_sample;

#if FF_API_LOWRES
    /**
     * 低分辨率的解码, 1-> 1/2 size, 2->1/4 size。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
     int lowres;
#endif

#if FF_API_CODED_FRAME
    /**
     * 位流中的图片。
     * - encoding: 由libavcodec库设置。
     * - decoding: 未使用。
     *
     * 弃用:use the quality factor packet side data instead
     */
    attribute_deprecated AVFrame *coded_frame;
#endif

    /**
     * 线程数。
     * 用于决定应该传递多少独立任务给execute()去执行。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int thread_count;

    /**
     * 使用哪些多线程方法。
     * 使用FF_THREAD_FRAME会增加每个线程一帧的解码延迟,所以不能提供未来帧的客户端不应该使用它。
     *
     * - encoding: 由用户设置,否则使用默认值。
     * - decoding: 由用户设置,否则使用默认值。
     */
    int thread_type;
#define FF_THREAD_FRAME   1 ///< 一次解码多帧。
#define FF_THREAD_SLICE   2 ///< 一次解码一个单一帧的多个部分。

    /**
     * 编解码器使用哪些多线程方法。
     * - encoding: 由libavcodec库设置。
     * - decoding: 由libavcodec库设置。
     */
    int active_thread_type;

    /**
     * 如果它的自定义get_buffer()回调可以从另一个线程同步调用,则由客户端设置,这允许更快的多线程解码。
     * draw_horiz_band()将从其他线程调用,而与此设置无关。
     * 如果使用默认的get_buffer(),则忽略它。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int thread_safe_callbacks;

    /**
     * 编解码器可以调用这个来执行几个独立的事情。
     * 它只会在完成所有任务后返回。
     * 用户可以用一些多线程实现替换它,默认实现将串行(连续)执行这部分。
     * 参数count:执行事情的个数。
     * - encoding: 由libavcodec库设置,用户可以重写。
     * - decoding: 由libavcodec库设置,用户可以重写。
     */
    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);

    /**
     * 编解码器可以调用这个来执行几个独立的事情。
     * 它只会在完成所有任务后返回。
     * 用户可以用一些多线程实现替换它,默认实现将串行(连续)执行这部分。
     * 还可以查看avcodec_thread_init和例如这个--enable-pthread配置选项。
     * 参数c:上下文也传递给函数。
     * 参数count:执行事情的个数。
     * 参数arg2: 不加更改地传递给函数。
     * 参数ret: 执行函数的返回值,必须有“count”值的空间。 可能是NULL。
     * 参数func: 将被调用count次的函数,其中jobnr从0到count-1。
     * 参数threadnr:范围将在0 to c->thread_count-1 < MAX_THREADS,这样就不会有两个函数实例在同一时间有相同的threadnr在执行。
     * 当前总是返回0,但是代码应该处理将来的改进,当任何对func的调用返回< 0时,没有进一步的对func的调用可能被认作完成并且返回< 0。
     * - encoding: 由libavcodec库设置,用户可以重写。
     * - decoding: 由libavcodec库设置,用户可以重写。
     */
    int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);

    /**
     * 噪声,看nsse比较函数的weight(noise vs. sse weight for the nsse comparison function)。
     * - encoding: 由用户设置。
     * - decoding: 未使用。
     */
     int nsse_weight;

    /**
     * 配置文件。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
     int profile;
#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_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_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

    /**
     * level。
     * - encoding: 由用户设置。
     * - decoding: 由libavcodec库设置。
     */
     int level;
#define FF_LEVEL_UNKNOWN -99

    /**
     * 跳过所选帧的循环过滤。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    enum AVDiscard skip_loop_filter;

    /**
     * 跳过所选帧的IDCT/解量化。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    enum AVDiscard skip_idct;

    /**
     * 跳过解码选择帧。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    enum AVDiscard skip_frame;

    /**
     * 包含文本字幕样式信息的头。
     * 对于SUBTITLE_ASS字幕类型,它应该包含整个ASS [Script Info]和[V4+ Styles]部分,加上[Events]行和后面的格式行。 它不应该包括任何对话行。
     * - 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;

#if FF_API_VBV_DELAY
    /**
     * VBV delay coded in the last frame (in periods of a 27 MHz clock).
     * 在最后一帧的VBV延迟解码(在一个27MHz的时钟周期)。
     * 用于兼容TSmuxing复用。
     * - encoding: 由libavcodec库设置。
     * - decoding: 未使用。
     * 被弃用, 这个值现在导出为AV_PKT_DATA_CPB_PROPERTIES包边数据(packet side data)的一部分。
     */
    attribute_deprecated
    uint64_t vbv_delay;
#endif

#if FF_API_SIDEDATA_ONLY_PKT
    /**
     * 只有编码,默认情况下设置。 允许编码器输出包不包含任何编码数据,只有边数据。
     *
     * 有些编码器需要输出这样的数据包,例如在编码结束时更新一些流参数。
     *
     * 弃用。此字段禁用默认行为,保留它只是为了兼容性。
     */
    attribute_deprecated
    int side_data_only_packets;
#endif

    /**
     * 只有音频有。由编码器在音频开始处插入的“priming”样本(填充)的数目。
     * 例如,这个领先的解码样本的数量必须被调用者丢弃,以获得原始音频没有领先的填充。
     *
     * - decoding: 未使用。
     * - encoding: 由libavcodec库设置。 输出包上的时间戳由编码器调整,以便它们总是引用实际包含在包中的数据的第一个样本,包括任何添加的填充。 例如,如果时间基为1/samplerate,第一个输入样本的时间戳为0,那么第一个输出包的时间戳为-initial_padding。
     */
    int initial_padding;

    /**
     * - decoding: 对于在压缩比特流中存储帧速率值的编解码器,解码器可以在这里导出它。当未知时为{0,1}。
     * - encoding: 可用于将CFR内容的帧率信号发送给编码器。
     */
    AVRational framerate;

    /**
     * 有名无实的未加速像素格式,请参见AV_PIX_FMT_xxx。
     * - encoding: 未使用。
     * - decoding: 由libavcodec库设置在调用get_format()之前。
     */
    enum AVPixelFormat sw_pix_fmt;

    /**
     * 在pkt_dts/pts和AVPacket.dts/pts的时间基。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    AVRational pkt_timebase;

    /**
     * 编解码器描述器。
     * - encoding: 未使用。
     * - decoding: 由libavcodec库设置。
     */
    const AVCodecDescriptor *codec_descriptor;

#if !FF_API_LOWRES
    /**
     * 低分辨率的解码, 1-> 1/2 size, 2->1/4 size
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
     int lowres;
#endif

    /**
     * PTS修正的当前统计数据。
     * - decoding: 由libavcodec维护和使用,不打算由用户应用程序使用。
     * - encoding: 未使用。
     */
    int64_t pts_correction_num_faulty_pts; /// 到目前为止,错误PTS值的数量。
    int64_t pts_correction_num_faulty_dts; /// 到目前为止,错误DTS值的数量
    int64_t pts_correction_last_pts;       /// 最后一帧的PTS。
    int64_t pts_correction_last_dts;       /// 最后一帧的DTS。

    /**
     * 输入字幕文件的字符编码。
     * - decoding: 由用户设置。
     * - encoding: 未使用。
     */
    char *sub_charenc;

    /**
     * 字幕字符编码模式。格式或编解码器可能会调整此设置(例如,如果它们自己正在进行转换)。
     * - decoding: 由libavcodec库设置。
     * - encoding: 未使用。
     */
    int sub_charenc_mode;
#define FF_SUB_CHARENC_MODE_DO_NOTHING  -1  ///< 什么都不做(demuxer输出的流应该已经是UTF-8格式,或者编解码器是位图)。
#define FF_SUB_CHARENC_MODE_AUTOMATIC    0  ///< libavcodec会选择模式本身。
#define FF_SUB_CHARENC_MODE_PRE_DECODER  1  ///< AVPacket数据需要被重新编码到UTF-8后才能被发送到解码器,需要iconv。
#define FF_SUB_CHARENC_MODE_IGNORE       2  ///< 不要转换字幕,也不要检查它们是否有有效的UTF-8。

    /**
     * 如果被编解码器支持,则跳过处理alpha。
     * 注意,如果格式使用预乘alpha (VP6中常见的,由于视频质量/压缩更好而推荐使用),图像看起来就像alpha混合到黑色背景上。
     * 然而,对于那些不使用预乘alpha的格式,可能会有一些严重的问题(尽管libswscale目前已经假设了预乘alpha)。
     *
     * - decoding: 由用户设置。
     * - encoding: 未使用。
     */
    int skip_alpha;

    /**
     * 不连续后要跳过的样本数。
     * - decoding: 未使用。
     * - encoding: 由libavcodec库设置。
     */
    int seek_preroll;

#if !FF_API_DEBUG_MV
    /**
     * 调试运动矢量(debug motion vectors)。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int debug_mv;
#define FF_DEBUG_VIS_MV_P_FOR  0x00000001 //可视化向前预测P帧的MVs。
#define FF_DEBUG_VIS_MV_B_FOR  0x00000002 //可视化向前预测B帧的MVs。
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //可视化向后预测B帧的MVs。
#endif

    /**
     * 自定义内(intra)量化矩阵。
     * - encoding: 由用户设置,可以是NULL。
     * - decoding: 未使用。
     */
    uint16_t *chroma_intra_matrix;

    /**
     * 转储格式分离器(dump format separator)。
     * can be ", " or "\n      " or anything else。
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    uint8_t *dump_separator;

    /**
     * ',' 允许的解码器的分离列表。
     * 如果是NULL,那么所有都是允许的。
     * - encoding: 未使用。
     * - decoding: 由用户设置。
     */
    char *codec_whitelist;

    /**
     * 被解码的流的属性。
     * - encoding: 未使用。
     * - decoding:由libavcodec库设置。
     */
    unsigned properties;
#define FF_CODEC_PROPERTY_LOSSLESS        0x00000001
#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002

    /**
     * 与整个编码流关联的附加数据。
     *
     * - decoding: 未使用。
     * - encoding: 可以由libavcodec库在avcodec_open2()之后设置。
     */
    AVPacketSideData *coded_side_data;
    int            nb_coded_side_data;

    /** 
     * 对AVHWFramesContext的引用,用于描述输入(编码)或输出(解码)帧。引用由调用方设置,然后由libavcodec拥有(和释放)——在设置之后,调用方不应该读取它。
     * 
     * - decoding: 这个字段应该由来自get_format()回调的调用者设置。 前面的引用(如果有的话)总是在get_format()调用之前由libavcodec解除。
     * 如果默认的get_buffer2()与hwaccel像素格式一起使用,那么这个AVHWFramesContext将用于分配帧缓冲区。
     *
     * - encoding: 对于配置为使用hwaccel像素格式的硬件编码器,这个字段应该被调用者设置成参考(引用reference)描述输入帧的AVHWFramesContext。AVHWFramesContext.format必须等于AVCodecContext.pix_fmt。
     *
     * 这个字段应该在调用avcodec_open2()之前设置。
     */
    AVBufferRef *hw_frames_ctx;

    /**
     * 控制AVSubtitle.rects[N]->ass的形式。
     * - decoding: 由用户设置。
     * - encoding: 未使用。
     */
    int sub_text_format;
#define FF_SUB_TEXT_FMT_ASS              0
#if FF_API_ASS_TIMING
#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1
#endif

    /**
     * 只有音频有。由编码器附加到音频末尾的填充量(在示例中)。例如,这些解码样本的数量必须被调用者从流的末尾丢弃,以获得原始的音频,而没有任何尾部填充。
     *
     * - decoding: 未使用。
     * - encoding: 未使用。
     */
    int trailing_padding;

    /**
     * 每幅图像最大可接受的像素数。
     *
     * - encoding: 由用户设置。
     * - decoding: 由用户设置。
     */
    int64_t max_pixels;

    /**
     * 对AVHWDeviceContext的一个参考(引用reference),描述设备将被硬件编码器/解码器使用。
     * 参考(引用reference)由调用者设置,然后由libavcodec拥有(和释放)。
     * 
     * 如果编解码器设备不需要硬件帧,或者使用libavcodec内部分配的任何帧,就应该使用这个。
     * 如果用户希望提供作为编码器输入或解码器输出的任何帧,则应该使用hw_frames_ctx。
     * 当在一个解码器的get_format()中设置了hw_frames_ctx时,在对相关流段进行解码时该字段将被忽略,但是可以在随后的get_format()调用中再次使用该字段。
     *
     * 对于编码器和解码器,这个字段都应该在调用avcodec_open2()之前设置,而不能在其后写入。
     *
     * 注意,为了支持hw_frames_ctx,一些解码器可能需要在一开始就设置这个字段——在这种情况下,所使用的所有帧上下文必须在同一设备上创建。
     */
    AVBufferRef *hw_device_ctx;

    /**
     * AV_HWACCEL_FLAG_*标志的位集(Bit set),它影响硬件加速解码(如果是活动的)。
     * - encoding: 未使用。
     * - decoding: 由用户设置(在avcodec_open2()之前或在AVCodecContext.get_format callback)。
     */
    int hwaccel_flags;

    /**
     * 视频decoding解码才有。 某些视频编解码器支持裁剪,这意味着只有解码帧的子矩形用于显示。 这个选项控制libavcodec如何处理剪切。
     *
     * 当设置为1(默认值)时,libavcodec将在内部应用剪切。
     * 例如,它将修改输出帧的width/height字段和偏移数据指针(只有在尽可能对齐的情况下,或者完整数量( full amount)如果设置了AV_CODEC_FLAG_UNALIGNED)。以至于解码器输出的帧仅参考裁剪区域。
     * 输出帧的crop_*字段将为零。
     * 
     * 当设置为0时,输出帧的width/height字段将被设置为编码的维度,而crop_*字段将描述裁剪矩形。应用裁剪是留给调用者的。
     * 
     * 警告:当使用不透明(opaque)输出帧的硬件加速时,libavcodec无法提供从上/左边界剪裁。
     * 
     * 注意:当这个选项设置为0时,AVCodecContext的width/height字段和输出的AVFrames有不同的含义。
     * 编解码器上下文字段存储显示维度(编码维度以coded_width/height表示),而frame帧字段存储编码维度(显示维度由crop_*字段决定)。
     */
    int apply_cropping;

    /*
     * 只有视频decoding解码有。 设置解码器将分配给调用者使用的额外硬件帧的数量。这必须在调用avcodec_open2()之前设置。
     * 
     * 一些硬件解码器要求在解码开始之前预先定义所有用于输出的帧。对于这样的解码器,硬件帧池因此必须是一个固定的大小。
     * 这里设置的额外帧位于解码器内部正常运行所需的任何数字之上(例如,用作参考图片的帧)。
     */
    int extra_hw_frames;

    /**
     * 丢弃一帧的受损样本的百分比。
     *
     * - decoding: 由用户设置。
     * - encoding: 未使用。
     */
    int discard_damaged_percentage;

    /**
     * 每帧最多可接受的样本数。
     *
     * - decoding: 由用户设置。
     * - encoding: 由用户设置。
     */
    int64_t max_samples;

    /**
     * AV_CODEC_EXPORT_DATA_*标志的位集(Bit set),它影响解码器和编码器在帧、包或编码流边数据(coded stream side data)中导出的元数据(metadata)的类型。
     *
     * - decoding: set by user
     * - encoding: set by user
     */
    int export_side_data;
} AVCodecContext;

2 AVCodecContext中重要的成员

enum AVMediaType codec_type;//媒体类型,具体可以看AVMEDIA_TYPE_xxx即编解码器的类型(视频,音频...)。
const struct AVCodec  *codec;/* 编解码器(H.264,MPEG2...) */
enum AVCodecID     codec_id; /* 编解码的ID,具体可以看AV_CODEC_ID_xxx */
unsigned int codec_tag;//这是用来解决一些encoder编码器的错误。一般设置为0。例如写头前初始化时stream->codec->codec_tag = 0;。
int64_t bit_rate;//平均比特率(码率)。encoding编码: 由用户设置; 不用于常量量化编码。decoding解码: 由用户设置, 如果这个码率信息是在流中可用的话,可能被libavcodec覆盖。
int bit_rate_tolerance;//允许比特流偏离参考的比特数。encoding编码: 由用户设置; 不用于常量量化编码。decoding解码: 未使用。
int flags;//AV_CODEC_FLAG_*.例如写头时满足m_formatContext->oformat->flags & AVFMT_GLOBALHEADER时,设置全局头AV_CODEC_FLAG_GLOBAL_HEADER;
uint8_t *extradata;//针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等),具体看上面解析。
int extradata_size;//extradata缓冲区大小。这两个字段非常重要。
AVRational time_base;//该字段与流中的time_base同名,但意思不一样,流中的是与时间相关的时基单位,这里的意思主要是帧率,一般设置为帧率的倒数,例如帧率fps={25,1},那么该字段一般设置为{1,25},但不一定是帧率的倒数。上面原文已经很清楚了。
int width, height;//图片的长和宽(分辨率),只有视频才有。
int coded_width, coded_height;//位流的宽度/高度,可能与宽度/高度不同,例如,当解码帧在输出之前被裁剪或低分辨率被启用。具体看上面。
int gop_size;//一组图片的数量。即多少帧后重新出现新的I帧。
enum AVPixelFormat pix_fmt;//像素格式,见AV_PIX_FMT_xxx。一般设置为AV_PIX_FMT_YUV420P。
float b_quant_factor;//IP和b帧之间的qscale因子,同样还有I帧,P帧的因子,这里了解一下。
AVRational sample_aspect_ratio;//样本比例 (0 if unknown)。也就是像素的宽度除以像素的高度。
int refs;//参考帧的数目。即运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)。
int sample_rate; // 每秒采样率。
int channels;    // 音频通道数量。也叫声道数(音频)。
enum AVSampleFormat sample_fmt;  //音频(采样)样本格式。

 /* 不应该初始化以下数据。 */
uint64_t channel_layout;//音频通道布局。
int profile;//型--配置文件。(H.264里面就有,其他编码标准应该也有),即该字段下的那些宏。AVRational framerate;
int level;//(和profile差不太多)。
AVRational framerate;//解码:对于在压缩比特流中存储帧速率值的编解码器,解码器可以在这里导出它。当未知时为{0,1}。编码:可用于将CFR内容的帧率信号发送给编码器。

该结构体里面包含了很多关于运动矢量,宏块,音视频编解码器相关的字段。太多了而且编码中并不常用,所以没例举出来。

3 AVCodecContext中部分成员的代码例子讲解
1)enum AVMediaType codec_type
一般用来获取视频和音频的下标(轨道)。然后再进一步处理。

for (i = 0; i < in_fmt_ctx->nb_streams; i++) {
		inStream = in_fmt_ctx->streams[i];
		if (inStream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {//可用新版本或者旧版本编解码上下文
			//获取视频下标
			video_index = i;
		}
		else if (inStream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
			audio_index = i;
		}
	}

2)const struct AVCodec *codec
该字段为编解码器,在调用打开流信息函数avformat_find_stream_info后并未初始化,必须调用avcodec_find_decoder函数查找对应的编解码器开辟空间初始化。

	//获取编码器类型的名字
	if (video_index != -1) {
		//不能通过第一种方法取名字,因为在未调用查找编码器前,编码器是没有被赋值的,会造成非法访问
		//1)video_codec_long_name = in_fmt_ctx->streams[video_index]->codec->codec->long_name;
		codecID = in_fmt_ctx->streams[video_index]->codecpar->codec_id;
		codec = avcodec_find_decoder(codecID);
		if (codec == NULL) {
			video_codec_long_name = "";//表示没有找到这种编解码器
		}
		video_codec_long_name = codec->long_name;
	}

该字段还有一个函数可以开辟空间,即avcodec_find_encoder。两者内部都调用同一函数,区别是decoder是传0,encoder传1。
具体看雷神的这篇:

https://blog.csdn.net/leixiaohua1020/article/details/44084557

3)enum AVCodecID codec_id
看上面,通过输入流文件的编解码id去寻找可用的编解码器。

4)unsigned int codec_tag
这是用来解决一些encoder编码器的错误。一般设置为0。例如在写头前初始化时:

stream->codec->codec_tag = 0;

5)int64_t bit_rate
平均比特率(码率)。

			//码率bit_rate总共在封装上下文和编解码上下文中含有,均为平均码率.前者代表总流的平均码率,后者为用户设置的编码时的平均码率(有可能被关闭).使用时应该取前者为先.
			if (in_fmt_ctx->bit_rate <= 0) {
				bit_rate = inStream->codecpar->bit_rate / 1000;//转成Kb字节单位,默认为字节
			}
			else {
				bit_rate = in_fmt_ctx->bit_rate / 1000;
			}

6)int flags
该字段一般用于在写头前设置相应宏标志,常用的是全局宏,使它写头时发送头部信息。

	if (this->m_outputContext->oformat->flags & AVFMT_GLOBALHEADER) {
		stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
	}

7)uint8_t *extradata和int extradata_size
这两个字段包含着H264的SPS和PPS的信息和大小。空间需要自己开辟且数据为自行设计。否则使用nginx推hls时会报错。

	unsigned char sps_pps[26] = { 0x00, 0x00, 0x00, 0x01, 0x67, 0x4D, 0x00, 0x1E, 0x9D, 0xA8, 0x2C , 0x04 , 0x9A , 0x6E , 0x02 , 0x02 , 0x02 , 0x04,
		0x00 , 0x00 , 0x00 , 0x01 , 0x68 , 0xEE , 0x3C , 0x80 };
	pCodecCtxEnc->extradata_size = 26;
	pCodecCtxEnc->extradata = (uint8_t*)av_malloc(26);
	if (pCodecCtxEnc->extradata == NULL) {
		printf("could not av_malloc the video params extradata!\n");
	}
	memcpy(pCodecCtxEnc->extradata, sps_pps, 26);

8)AVRational time_base
该字段与流中的time_base同名,但意思不一样,流中的是与时间相关的时基单位,这里的意思主要是帧率,一般设置为帧率的倒数,例如帧率fps={25,1},那么该字段一般设置为{1,25},但不一定是帧率的倒数。上面原文已经很清楚了。
该字段一般设为帧率的倒数。

	//存储在AVCodecContext的帧率的倒数(一般为倒数),为时间戳的增量,并非时基.
	pCodecCtxEnc->time_base.num = 1;
	pCodecCtxEnc->time_base.den = 25;	
	
	
	//下面给出如何获取流中的帧率例子。注意:本字段是在编解码器上下文,下面例子的两个帧率在流中。//
	
	//获取帧率,帧率的打印都在流中的两个成员(下面其实还有一个不过一般不考虑).且应取平均帧率为先,为{x,0},{0,1}则取实时帧率
	if (inStream->avg_frame_rate.den == 0 || (inStream->avg_frame_rate.num == 0 && inStream->avg_frame_rate.den == 1)) {
		m_fps = inStream->r_frame_rate.num / inStream->r_frame_rate.den;
	}
	else {
		m_fps = inStream->avg_frame_rate.num / inStream->avg_frame_rate.den;
	}

9)int width, height
图片的长和宽(分辨率),只有视频才有。写头前初始化时直接自己设置即可。

	pCodecCtxEnc->width = 1920;
	pCodecCtxEnc->height = 1080;

10)int gop_size
一组图片的数量。即多少帧后重新出现新的I帧。同样在写头前初始化时自己设置。

pCodecCtxEnc->gop_size = 50;

11)enum AVPixelFormat pix_fmt
像素格式,见AV_PIX_FMT_xxx。一般设置为AV_PIX_FMT_YUV420P。

pCodecCtxEnc->pix_fmt = AV_PIX_FMT_YUV420P;

12)AVRational framerate
解码:对于在压缩比特流中存储帧率的编解码器,解码器可以在这里导出它。当未知时为{0,1}。编码:可用于将CFR内容的帧率信号发送给编码器。

//该字段一般不需要理会。一般与流中的两个帧率avg_frame_rate,r_frame_rate一样。

好了,这个字段暂时研究到这里。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

06FFMPEG的AVCodecContext结构体分析 的相关文章

  • VLC 和 ffmpeg 如何协同工作?

    我从源代码编译了VLC 它运行良好 当我执行 Vlc 时 vlc 运行 我还从源代码编译了 ffmpeg 它也运行良好 当我执行 ffmpeg i f toto flv mp3 vn acodec copy new toto mp3 时 会
  • MP4 到 DASH(bash 脚本)

    我有一个网站 用户可以在其中上传视频文件 我想使用 DASH 流式传输所有内容以获得自适应比特率流式传输 因此 我编写了一个 bash 脚本 由 cron 运行 将所有 mp4 文件转换为 DASH 但它无法正常工作 出了什么问题 例如 使
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • ffmpeg AVFrame 到 opencv Mat 转换

    我目前正在开发一个使用 ffmpeg 解码接收到的帧的项目 解码后 我想将 AVFrame 转换为 opencv Mat 帧 以便我可以在 imShow 函数上播放它 我拥有的是字节流 我将其读入缓冲区 解码为 AVFrame f fope
  • OpenCV IP 相机应用程序崩溃 [h264 @ 0xxxxx] 访问单元中缺少图片

    我在 cpp 中有一个 opencv 应用程序 它使用 opencv 的简单结构捕获视频流并将其保存到视频文件中 它与我的网络摄像头完美配合 但是 当我运行它从 IP 摄像机捕获流时 它可能会在大约十秒后崩溃 我的编译命令是 g O3 IP
  • FFmpeg - 来自 NodeJS 的 RTMP 流,流比实时更快

    我的目标是在 Node 中渲染画布 并将该画布流式传输到 RTMP 服务器 最终是 Twitch 但现在我正在在本地 RTMP 服务器上测试 流式传输到 RTMP 的标准方式似乎是ffmpeg 所以我使用它 从 NodeJS 中作为子进程生
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • Windows 上的 ffmpeg-android ndk

    我正在尝试编译 bash 文件 带有 android ndk 的 ffmpeg 我收到如下错误 arm linux androideabi gcc 无法创建可执行文件 C 编译器测试失败 Makefile 2 config mak 没有这样
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • Bash 脚本:自动为 mpeg-dash 进行 ffmpeg 编码

    我正在编写一个 bash 文件来创建视频编码和串联 以供 dash 实时流媒体使用 基本上 它读取输入视频文件夹 将所有视频编码为三种分辨率格式 然后将它们连接起来创建三个适应集 DIAGRAM 该脚本检查 fps 一致性 如果输入不是 1
  • 如何将 MP3 音频文件读入 numpy 数组/将 numpy 数组保存到 MP3?

    有没有办法从 MP3 音频文件中读取 写入 MP3 音频文件numpy具有类似 API 的数组scipy io wavfile read https docs scipy org doc scipy 0 14 0 reference gen
  • 使用 Coldfusion 的 CFFILE 标签监控 FFMpeg 的进度日志

    我想学习如何使用 ColdFusion 中的 CFFILE 标签来读取文本文件的内容 就我而言 该文本文件是 FFMpeg 在对媒体文件进行转码时生成的进度日志 我想编写一个 ColdFusion 脚本 该脚本将定期轮询进度日志 直到日志表
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • Xuggler 未转换 .webm 文件?

    我只是尝试使用 Xuggler 将 mov 文件转换为 webm 这应该可以工作 因为 FFMPEG 支持 webm 文件 这是我的代码 IMediaReader reader ToolFactory makeReader home use
  • 如何在google colab中安装ffmpeg包

    我正在尝试使用 Google Colab 来做一些事情 我特别想用ffmpeg打包到从图像创建视频 https stackoverflow com a 44951066 6890234 但 ffmpeg 似乎工作得不太好 这个 在最后一个块
  • FFMPEG:将 YUV 数据转储到 AVFrame 结构中

    我正在尝试转储YUV420数据进入AVFrameFFMPEG 的结构 从下面的链接 http ffmpeg org doxygen trunk structAVFrame html http ffmpeg org doxygen trunk
  • ffmpeg计算视频比特率

    我想知道如何计算该视频的比特率 http jell yfish us media jellyfish 30 mbps hd hevc mkv http jell yfish us media jellyfish 30 mbps hd hev
  • 如何使用 ffmpeg av_seek_frame() 在具有帧号的情况下读取任何帧

    int64 t timeBase timeBase int64 t pavStrm gt time base num AV TIME BASE int64 t pavStrm gt time base den int64 t seekTar
  • 如何在不指定像素格式的情况下从 AVFrame.data[] 和 AVFrame.linesize[] 获取原始帧数据?

    我的总体想法是frame data 根据视频的像素格式 RGB 或 YUV 进行解释 但是有没有通用的方法可以从帧中获取所有像素数据 我只想计算帧数据的哈希值 而不解释它来显示图像 根据 AVFrame h uint8 t AVFrame

随机推荐

  • Python删除字符串中连续重复字符,保留所有去重后字符

    看了很多攻略 但都是全部去除字符串中所有的重复字符或者全部去除字符串所有相邻的重复字符 如果希望得到字符串中相邻字符去重后的全部字符 比如字符串a abbcccd222aaabbbddfff6e 去重后能得到 abcd2abdf6e 那可以
  • CMake中if的使用

    CMake中的if命令用于有条件地执行一组命令 其格式如下 if
  • 判断字符串是否为回文串的Java实现方法(收藏自力扣)

    先把字符串转成字符数组 可以调用toCharArray 方法 public char toCharArray 将此字符串转换为一个新的字符数组 Returns 一种新分配的字符数组 其长度是该字符串的长度 其内容被初始化为包含由该字符串表示
  • 时间序列模型Prophet使用详细讲解

    之前我们已经讲过了如何在Windows系统下安装Python版本的Prophet 详细见这里 接下来的几个部分 我们说下如何使用Prophet 以此来体验下Prophet的丰富内容 内容会比较多 主要翻译自官方文档 教程中使用的数据集可在
  • DAP数据分析平台权限体系说明

    数据对于企业来说是非常重要的 所以产品的安全性需要有所保证 而权限分配就是一种保障方式 通过不同权限查看到不同的数据进行数据隔离 保障数据的安全性 DAP数据分析平台通过授权管理进行角色授权 配置授权 业务授权实现三权分立 不同的用户能看到
  • 后端解决跨域

    对于跨域 相信同学们都有所了解 前端的跨域的若干种方式 大家也都知道 什么 JSONP iframe domain 等等 但是我们今天的主题 不是前端跨域 而是后端跨域 一旦提及到跨域 就会想到同源策略 那我们就先来回顾跨域和同源策略 什么
  • upload-labs第五关 pass-05 大小写绕过

    六 pass 05 大小写绕过 源码 is upload false msg null if isset POST submit if file exists UPLOAD ADDR deny ext array php php5 php4
  • 封装浏览器外壳

    Net本身包含WebBrower控件 可惜内核是IE http www cnblogs com M Silencer p 5846494 html 参考以上文章 通过一些控件可以再窗体中嵌入webkit内核的浏览器 目前在尝试CefShar
  • 快手广告推广效果由哪些因素决定?快手广告能满足哪些推广目标?

    快手广告用户与你的行业用户一致快手用户为三线城市 95后年轻用户为主 同时其用户人群也在大城市进行渗透 那么快手广告推广效果由哪些因素决定 快手广告能满足哪些推广目标 一 快手广告推广效果由哪些因素决定 1 广告的推广效果可以分为曝光效果
  • 大数据代表技术:Hadoop、Spark、Flink、Beam

    大数据代表技术 Hadoop Spark Flink Beam Hadoop 从2005年到2015年 说到大数据都是讲hadoop Hadoop是一整套的技术框架 不是一个单一软件 它是一个生态系统 Hadoop有两大核心 第一个是它解决
  • ubuntu系统安装pangolin

    ubuntu 安装 pangolin 1 安装pangolin依赖项以及安装过程中用到的工具 2 创建安装目录 3 下载pangolin源文件 4 安装pangolin 1 安装pangolin依赖项以及安装过程中用到的工具 ctrl al
  • LeetCode_BinaryTree_1129. Shortest Path with Alternating Colors 颜色交替的最短路径【BFS求最短路径】【java】【中等】

    一 题目描述 英文描述 You are given an integer n the number of nodes in a directed graph where the nodes are labeled from 0 to n 1
  • Vue面试题(一)

    目录 一 vue2和vue3的区别 二 mixin混入对象 三 hooks 特点 四 keep alive 五 生命周期 六 el template render 七 vue router 有哪几种导航钩子 路由守卫 八 HTTP和TCP的
  • CVPR‘2023 即插即用系列!

    Title BiFormer Vision Transformer with Bi Level Routing Attention Paper https arxiv org pdf 2303 08810 pdf Code https gi
  • 电商入门_仓库管理系统wms

    在2010电商WMS第一个阶段 那时的双十一就是各个仓库的噩梦 库区不够用 WMS系统瘫痪 拣货人员都被埋在商品里 往往半个月之后才能发出订单 那时京东的亚洲一号仓刚开始立项 大家还半信半疑 大部分电商库房后台还是处于小作坊状况 纯粹靠人工
  • react动态给组件添加事件_React实战—组件行为:React中的事件(4)

    网页是组件构成的 组件是一系列标签形成的单一功能 所以考虑组件无非也就三件事 结构 表现 和行为 结构JSX搞定了 当然JSX不仅仅干这个 表现是CSS的事儿 我们重点说下行为 也就是事件和钩子 事件好说 就是户干了啥事儿 然后有什么样的相
  • Fiddler / Charles - 夜神模拟器证书安装App抓包

    Fiddler Charles 夜神模拟器证书安装App抓包 文章目录 Fiddler Charles 夜神模拟器证书安装App抓包 前言 一 软件安装 1 Openssl安装 1 1下载安装 1 2配置环境变量 1 3查看openssl版
  • 基于AWS的云服务架构最佳实践 #CSDN博文精选# #IT# #云服务实践#

    大家好 小C将继续与你们见面 带来精选的CSDN博文 在这里 你将收获 将系统化学习理论运用于实践 系统学习IT技术 学习内容涵盖数据库 软件测试 主流框架 领域驱动设计和第三方生态等 离全栈工程师更近一步 精心整理的CSDN技术大咖博文
  • Java版工程项目管理系统源码 工程项目源码

    数 据 库 MySQL 开发语言 Java 开发工具 MyEclipse 源码类型 WebForm 以甲方项目管理为中心 包括项目启动 计划 执行 控制与收尾阶段的全生命周期管理 并对范围 预算 进度 质量 资源 风险等管理要素进行控制与预
  • 06FFMPEG的AVCodecContext结构体分析

    06FFMPEG的AVCodecContext结构体分析 概述 该结构体位于libavcodec库中的avcodec h中 1 AVCodecContext编解码上下文结构体 位于libavcodec库里 AVFormatContext A