玖叶教程网

前端编程开发入门

FFmpeg常用结构体分析:AVCodecContext

图上所以为我们内部学习资料,现将部分资料发出如下,后续笔者这里亦有,私信“资料”即可获得完整版。

AVCodecContext

这是编码器上下文的数据结构,包含了解码器需要的参数信息。

如果是单纯使用libavcodec,这部分信息需要调用者进行初始化,如果是整个FFmpeg库,这部分信息在调用av_open_input_file()和 av_find_stream_info()的过程中会根据文件头部信息以及媒体内的头部信息完成初始化。


结构体定义:

typedef struct AVCodecContext{
    const AVClass *av_class;//av_log使用的结构体,通过avcodec_alloc_context3设置
    int log_level_offset;//日志中的级别
    enum AVMediaType codec_type;//参见AVMEDIA_TYPE_xxx
    const struct AVCodec *codec;
    
    enum AVCodecId codec_id;//参见AV_CODEC_ID_xxx
    
    unsigned int codec_tag;//Codec的标记,用来解决一些编码bug
    
    void *priv_data;//私有数据
    
    struct AVCodecInternal *internal;//与priv_data不同,它与某个解码器没有特别关联,用在一般的libavcodec功能
    
    void *opaque;//user私有数据,在编解码时候由用户设置
    
    int64_t bit_rate;//平均比特率
    
    int bit_rate_tolerance;//比特流中允许偏离参考的比特数
    
    int global_quality;//全局Codec质量
    
    int compression_level;
    
    int flags;//参见 AV_CODEC_FLAG_*
    
    int flags2;//参见 AV_CODEC_FLAG2_*
    
    uint8_t *extradata;//一些编码器可用的额外数据,比如哈夫曼码表
                        //如果是通过bitstream reader读取来的,分配的内存是比extradata_size字节数更大的AV_INPUT_BUFFER_PADDING_SIZE来避免一些问题
   int extradata_size;
   
   AVRational time_base;//时间戳
   
   int ticks_per_frame;//默认设置为1,比如 H.264/MPEG-2 设置为2
   
   int delay;//对于视频,解码输出相对于编码输入将会延迟的帧数
                //对于音频,代表在解码器输出有效之前,解码器需要输出的样本数。当seek时候,你需要在你所seek的点之前许多样本数的地方开始解码。
  
   int width,height;//只对视频,图片的宽高。
   
   int coded_width,coded_height;//比特流的宽高
   
   int gop_size;//a group of pictrues中图片的数量
   
   enum AVPixelFormat pix_fmt;//像素格式,参见AV_PIX_FMT_xxx
   
   /**  如果不是NULL,则被调用来绘制一个水平带 */
    void (*draw_horiz_band)(struct AVCodecContext *s,
                            const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
                            int y, int type, int height);
   
    /** 回调协商pixelFormat */
    enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
    
    int max_b_frames;//在非B帧之间的最大B帧数,注意,输出将会相对于输入有max_b_frames+1的延迟
    
    float b_quant_factor;//IP和b帧之间的qscale因子
                        // >0 上一个P帧的quantizer(数字转换器)将会被使用(q = lastp_q * factor + offset)
                        // <0 进行正常的速率控制(q=-normal_q * factor + offset)
    
    float b_quant_offset;//IP和b帧间的qscale偏移
    
    int has_b_frames;//解码器中帧重排序缓冲区的大小
                        //对于MPEG-2为 1 IPB或者 0 低延迟IP
    
    float i_quant_factor;//p帧和(I帧)关键帧之间的qscale因子
                        // >0 上一个p帧的quantizer将被使用(q = lastp_q * factor + offset)
                        // <0 进行正常的速率控制( q = -normal_q * factor + offset)
 
    
    float i_quant_offset;//p帧和关键帧(I帧)之间的qscale偏移
    
    float lumi_masking;//照度掩蔽 (0->disabled)
    
    float temporal_cplx_masking;//临时复杂性掩蔽(0->disabled)
    
    float spatial_cplx_masking;//空间复杂性掩蔽(0->disabled)
    
    float p_masking;// p块掩蔽(0->disabled)
    
    float dark_masking;// 黑暗掩蔽(0->disabled)
    
    int slice_count;//slice(图像细分)总和
    
    int *slice_offset;//帧中的图像细分偏移量(以字节为单位)
    
    AVRational sample_aspect_ratio;//样本宽高比,像素宽度除以像素高度
    
    int me_cmp;//运动估计比较功能
    
    int me_sub_cmp;//亚像素运动估计比较功能
    
    int mb_cmp;//暂不支持
    
    int ildct_cmp;//交错DCT比较功能
    //省略宏定义
    
    int dia_size;// ME diamond 的大小和形状
    
    int last_predictor_count;//前期MV预测量(2a+1的平方)
    
    int me_pre_cmp;//运动估计比较功能
    
    int pre_dia_size;//ME 准备的diamond的大小和形状
    
    int me_subpel_quality;
    
    int slice_flags;//slice标识
    
    int mb_decision;//macroblock decision宏块类型选择
    //省略宏定义
 
    uint16_t *intra_matix;//自定义内部量化矩阵
    
    uint16_t *inter_matrix;//自定义内部量化矩阵
    
    int intra_dc_precision;//内部系数的精度- 8
    
    int skip_top;//顶部被跳过的宏块行数
    
    int skip_bottom;//底部被跳过的宏块行数
    
    int mb_lmin;
    int mb_lmax;
    
    int bidir_refine;
    
    int keyint_min;// GOP最小size
    
    int refs;//number of reference frames参考系数,参考帧的数目
    
    int mv0_threshold;
    
    enum AVColorPrimaries color_primaries;//色度坐标
    
    enum AVColorTransferCharacteristic color_trc;//颜色传输特性
    
    enum AVColorSpace colorspace;//YUV颜色空间类型
    
    enum AVColorRange color_range;//用于存储颜色范围MPEG vs JPEG YUV range
    
    enum AVChromaLocation chroma_sample_location;//色度样本的位置
    
    int slices;//图像细分数量,用于并行解码
    
    enum AVFieldOrder field_order;
    
    /** 以下用于音频相关操作 */
    
    int sample_rate; ///< samples per second
    int channels;    ///< number of audio channels
    
    enum AVSampleFormat sample_fmt;  ///< sample format
    
    int frame_size;//音频每个信道的采样数
    
    int frame_number;//帧计数器
    
    int block_align;//用在一些基于MAV的音频解码器,表示常量或者已知的每个包中的字节数
    
    int cutoff;//音频截止带宽 0表示自动
    
    uint64_t channel_layout;//信道布局
    
    uint64_t request_channel_layout;//如果可以,请求解码器使用此通道布局(默认为0)
    
    enum AVAudioServiceType audio_service_type;//音频流传递的服务类型
    
    enum AVSampleFormat request_sample_fmt;//所需的样本格式
    
    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);//获取Buffer的回调函数
    
    int refcounted_frames;//通过avcodec_decode_video2和avcodec_decod_audio4返回的解码后的帧数
    
    /** 编码参数 */
    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)
    
    int qmin;//最小量化器
    int qmax;//最大量化器
    int max_qdiff;//帧之间的最大量化器差异
    
    int rc_buffer_size;//解码器比特流缓冲区大小
    
    int rc_override_count;
    RcOverride *rc_override;
    
    int64_t rc_max_rate;//最大比特率
    int64_t rc_min_rate;//最小比特率
    
    float rc_max_available_vbv_use;//Ratecontrol尝试在最大情况下使用,即可以在没有下溢的情况下使用的内容
    
    float rc_min_vbv_overflow_use;//Ratecontrol尝试在最大情况下使用,即可以在没有上溢的情况下使用的内容
    int rc_initial_buffer_occupancy;//译码开始前应装入rc缓冲区的位的数目。
    
    char *stats_out;//pass1编码统计输出缓冲区,编码时由libavcodec设置
    
    char *stats_in;//pass2编码统计输入缓冲区,应该将来自pass1的stats_out的连接内容放在这里,由user来分配内存、设置、释放
    
    int workaround_bugs;//解决编码器中有时无法自动检测到的bug
    //省略宏定义
    
    int strict_std_compliance;//严格遵循标准,比如MPEG-4等
    //省略宏定义
    
    int error_concealment;//错误隐藏的标识
    //省略宏定义
 
    int debug;
    //省略宏定义
    int debug_mv;
    
    int err_recognition;//错误认识;可能会将一些有效的部分错误地检测为错误
    
    int64_t reordered_opaque;//将在avframe . reordered_中重新排序和输出的不透明64位数字(通常为PTS)
    
    struct AVHWAccel *hwaccel;//硬件加速结构体
    
    void *hwaccel_context;//硬件加速Context上下文环境
    
    int thread_count;//线程个数,取决于有多少个独立任务在执行
    
    int thread_type;//使用哪些多线程方法
    
    int active_thread_type;//哪些多线程方法正在被使用
    
    int thread_safe_callbacks;//如果使用默认的get_buffer(),则忽略它。
    
    //编解码器可以调用它来执行几个独立的东西,它只会在完成所有任务后返回
    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
 
    //编解码器可以调用它来执行几个独立的东西,它只会在完成所有任务后返回
    int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
 
    int nsse_weight;
    
    int profile;
    //省略宏定义
    
    int level;
    //省略宏定义
    
    enum AVDiscard skip_frame;//跳过选定帧的解码操作
    
    uint8_t *subtitle_header;//字幕头
    int subtitle_header_size;//字幕头的大小
    
    AVRational framerate;//压缩码流中存储的帧率
    
    AVRational pkt_timebase;//pkt_dts和pkt_pts的时间基数
    
    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
    
    
    char *codec_whitelist;//可用编解码器的白名单
    
    //省略了部分属性
   
}AVCodecContext;

光定义就真是够多的。下面挑一些关键的变量来看看(这里只考虑解码)。


enum AVMediaType codec_type:编解码器的类型(视频,音频...)
struct AVCodec  *codec:采用的解码器AVCodec(H.264,MPEG2...)
int bit_rate:平均比特率
uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)
int width, height:如果是视频的话,代表宽和高
int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
int sample_rate:采样率(音频)
int channels:声道数(音频)
enum AVSampleFormat sample_fmt:采样格式
int profile:型(H.264里面就有,其他编码标准应该也有)
int level:级(和profile差不太多)

在这里需要注意:AVCodecContext中很多的参数是编码的时候使用的,而不是解码的时候使用的。


其实这些参数都比较容易理解。就不多费篇幅了。在这里看一下以下几个参数:


1.codec_type编解码器类型有以下几种:


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.sample_fmt在FFMPEG中音频采样格式有以下几种:

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
};



3.profile在FFMPEG中型有以下几种,可以看出AAC,MPEG2,H.264,VC-1,MPEG4都有型的概念。

#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_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_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_HIGH_422 122
#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
#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



总结;

AVFormatContext描述了一个媒体文件或媒体流的构成和基本信息,位于avformat.h文件中

AVStream 音频流和视频流的一些信息

AVPacket 此结构体包含了压缩数据,音频的话例如mp3 ,AAC,视频的话例如h264,hevc;



发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言