zoukankan      html  css  js  c++  java
  • X264-libx264编码库

    X264编码库libx264实现真正的视频编解码,该编解码算法是基于块的混合编码技术,即帧内/帧间预测,然后对预测值变换、量化,最后熵编码所得。

    编码帧的类型分为I帧(x264_type_i)、P帧(x264_type_p)、B帧(x264_type_b),在H264中叫做图像片Slice。

    X264把整帧图像看作一个Slice,片中有slice_type_i、slice_type_p、slice_type_b之分。

    I帧只有slice_type_i,P帧有slice_type_i、slice_type_p,B帧三种片都有。

    X264的H264视频编码过程可以分为三个步骤:首先根据规则判定当前帧的编码类型,如果是B帧,要缓冲存放、获取;然后对待编码图像进行帧内预测、帧间预测、整数DCT变换、量化和熵编码;最后把压缩的H264数据进行NAL层打包输出。

    X264编码器有关的重要结构体:

    x264_image_t:实际参与编码的编码帧图像信息。

    typedef struct
    {
    	int i_csp;          //图像空间颜色
    	int i_plane;        //图像平面数目
    	int i_stride[4];    //每个图像平面的跨度,也就是每一行数据的字节数
    	uint8_t *plane[4];  //每个图像平面存放数据的起始地址,plane[0]是Y平面,plane[1]是U平面,plane[2]是V平面
    }x264_image_t;          //待编码的图像
    

    x264_picture_t:x264编码器定义便于控制的图像帧,描述一帧的特征。包含x264_image_t和x264_param_t结构体。

    typedef struct
    {
    	int   i_type;            //帧的类型,初始化为auto,在编码过程自行控制
    	int   i_qpplus1;         //此参数减1代表当前帧的量化参数值
    	int   i_pic_struct;      //帧的结构类型
    	int   b_keyframe;        //输出是否是关键帧
    	int64_t   i_pts;         //一帧的显示时间戳
    	int64_t   i_dts;         //输出解码时间戳
    
    	x264_param_t    *param;          
    	x264_image_t     img;           
    	x264_image_properties_t    prop;
    	x264_hrd_t    hrd_timing;      
    	void    *opaque;               
    } x264_picture_t;            //x264编码视频帧
    

    x264_param_t:初始化编码器。

    typedef struct
    {
    	unsigned int cpu;       //CPU 标志位 
    	int  i_threads;         //并行编码多帧
    	int  b_sliced_threads;  //如果设置为false,一个slice只编码成一个NALU,默认值是true
    	int  b_deterministic;   //是否允许非确定性时线程优化
    	int  b_cpu_independent; //强制采用典型行为,而不是采用独立于CPU的优化算法
    	int  i_sync_lookahead;  //线程超前缓存帧数
    	int  i_width;           //视频图像的宽
    	int  i_height;          //视频图像的高
    	int  i_csp;             //色彩空间设置,仅支持I420
    	int  i_level_idc;       //编码复杂度
    	int  i_frame_total;     //编码帧的总数, 不知道默认为0即可
    
    	struct
    	{
    		int  i_sar_height;    //样本宽高比的高度
    		int  i_sar_width;     //样本宽高比的宽度
    		int  i_vidformat;     //视频在编码/数字化之前是什么类型,默认"undef(不设置)"
    		int  b_fullrange;     //样本亮度和色度的计算方式,默认"off"
    		int  i_colorprim;     //原始色度格式,默认"undef"
    		int  i_transfer;      //转换方式,默认"undef"
    		int  i_colmatrix;     //设置从RGB计算得到亮度和色度所用的矩阵系数,默认"undef"
    		int  i_chroma_loc;    //设置色度采样位置,范围0~5,默认0
    	} vui;                    //vui参数集 : 视频可用性信息、视频标准化选项 
    
    
    	//比特流参数 
    	int  i_frame_reference;          //最大参考帧数目
    	int  i_dpb_size;                 //Decoded picture buffer size
    	int  i_keyint_max;               //设定IDR帧之间的最间隔,在此间隔设置IDR关键帧
    	int  i_keyint_min;               //设定IDR帧之间的最小间隔, 场景切换小于此值编码位I帧, 而不是 IDR帧
    	int  i_scenecut_threshold;       //场景切换阈值,插入I帧
    	int  b_intra_refresh;            //是否使用周期帧内刷新替代IDR帧
    	int  i_bframe;                   //两个参考帧之间的B帧数目
    	int  i_bframe_adaptive;          //自适应B帧判定, 可选取值:X264_B_ADAPT_FAST等
    	int  i_bframe_bias;              //控制B帧替代P帧的概率,范围-100 ~ +100,该值越高越容易插入B帧,默认0
    	int  i_bframe_pyramid;           //允许部分B帧为参考帧,可选取值:0=off,  1=strict hierarchical,  2=normal
    	int  b_open_gop;                 //帧间的预测都是在GOP中进行,后一个GOP会参考前一个GOP的信息
    	int  b_bluray_compat;            //支持蓝光碟
    	int  b_deblocking_filter;        //去块滤波开关
    	int  i_deblocking_filter_alphac0;//[-6, 6] -6 light filter, 6 strong
    	int  i_deblocking_filter_beta;   //[-6, 6] 同上
    	int  b_cabac;                    //自适应算术编码cabac开关
    	int  i_cabac_init_idc;           //给出算术编码初始化时表格的选择
    	int  b_interlaced;               //隔行扫描
    	int  b_constrained_intra;
    	int  i_cqm_preset;               //自定义量化矩阵(CQM), 初始化量化模式为flat
    	char *psz_cqm_file;              //读取JM格式的外部量化矩阵文件,忽略其他cqm选项
    	uint8_t  cqm_4iy[16];            //used only if i_cqm_preset == X264_CQM_CUSTOM  
    	uint8_t  cqm_4py[16];
    	uint8_t  cqm_4ic[16];
    	uint8_t  cqm_4pc[16];
    	uint8_t  cqm_8iy[64];
    	uint8_t  cqm_8py[64];
    	uint8_t  cqm_8ic[64];
    	uint8_t  cqm_8pc[64];
    
    	void(*pf_log)(void *, int i_level, const char *psz, va_list);     //日志函数
    	void  *p_log_private;
    	int    i_log_level;             //日志级别,不需要打印编码信息时直接注释掉即可
    	int    b_visualize;             //是否显示日志
    	char   *psz_dump_yuv;           //重建帧的文件名
    
    	struct
    	{
    		unsigned int intra;         //帧内分区
    		unsigned int inter;         //帧间分区
    		int  b_transform_8x8;
    		int  i_weighted_pred;       //P帧权重
    		int  b_weighted_bipred;     //B帧隐式加权
    		int  i_direct_mv_pred;      //时间空间运动向量预测模式
    		int  i_chroma_qp_offset;    //色度量化步长偏移量
    		int  i_me_method;           //运动估计算法 (X264_ME_*)
    		int  i_me_range;            //整像素运动估计搜索范围 (from predicted mv) 
    		int  i_mv_range;            //运动矢量最大长度. -1 = auto, based on level
    		int  i_mv_range_thread;     //线程之间的最小运动向量缓冲.  -1 = auto, based on number of threads.
    		int  i_subpel_refine;       //亚像素运动估计质量
    		int  b_chroma_me;           //亚像素色度运动估计和P帧的模式选择
    		int  b_mixed_references;    //允许每个宏块的分区有它自己的参考号
    		int  i_trellis;             //Trellis量化提高效率,对每个8x8的块寻找合适的量化值
    		int  b_fast_pskip;          //快速P帧跳过检测
    		int  b_dct_decimate;        //P帧变换系数阈值
    		int  i_noise_reduction;     //自适应伪盲区
    		int  b_psy;                 //Psy优化开关,可能会增强细节
    		float  f_psy_rd;            //Psy RD强度
    		float  f_psy_trellis;       //Psy Trellis强度
    		int  i_luma_deadzone[2];    //亮度量化中使用的盲区大小,{ 帧间, 帧内 }
    		int  b_psnr;                //计算和打印PSNR信息
    		int  b_ssim;                //计算和打印SSIM信息
    	} analyse;                      //编码分析参数
    
    	struct
    	{
    		int  i_rc_method;         //码率控制方式:X264_RC_CQP恒定质量,X264_RC_CRF恒定码率,  X264_RC_ABR平均码率
    		int  i_qp_constant;       //指定P帧的量化值,0 - 51,0表示无损
    		int  i_qp_min;            //允许的最小量化值,默认10
    		int  i_qp_max;            //允许的最大量化值,默认51
    		int  i_qp_step;           //量化步长,即相邻两帧之间量化值之差的最大值
    		int   i_bitrate;          //平均码率大小
    		float  f_rf_constant;     //1pass VBR, nominal QP. 实际质量,值越大图像越花,越小越清晰
    		float  f_rf_constant_max; //最大码率因子                           
    		float  f_rate_tolerance;  //允许的误差
    		int    i_vbv_max_bitrate; //平均码率模式下,最大瞬时码率,默认0
    		int    i_vbv_buffer_size; //码率控制缓冲区的大小,单位kbit,默认0
    		float  f_vbv_buffer_init; //设置码率控制缓冲区(VBV)缓冲达到多满(百分比),才开始回放,范围0~1.0,默认0.9
    		float  f_ip_factor;       //I帧和P帧之间的量化因子(QP)比值,默认1.4
    		float  f_pb_factor;       //P帧和B帧之间的量化因子(QP)比值,默认1.3
    		int   i_aq_mode;          //自适应量化(AQ)模式。0:关闭AQ;1:允许AQ在整个视频中和帧内重新分配码;2:自方差AQ(实验阶段),尝试逐帧调整强度。
    		float  f_aq_strength;     //AQ强度,减少平趟和纹理区域的块效应和模糊度
    		int   b_mb_tree;          //是否开启基于macroblock的qp控制方法
    		int   i_lookahead;        //决定mbtree向前预测的帧数
    		int   b_stat_write;       //是否将统计数据写入到文件psz_stat_out中
    		char  *psz_stat_out;      //输出文件用于保存第一次编码统计数据
    		int   b_stat_read;        //是否从文件psz_stat_in中读入统计数据
    		char  *psz_stat_in;       //输入文件存有第一次编码的统计数据
    		float  f_qcompress;       //量化曲线(quantizer curve)压缩因子。0.0 => 恒定比特率,1.0 => 恒定量化值
    		float  f_qblur;           //时间上模糊量化,减少QP的波动(after curve compression)
    		float  f_complexity_blur; //时间上模糊复杂性,减少QP的波动(before curve compression)
    		x264_zone_t *zones;       //码率控制覆盖
    		int    i_zones;           //number of zone_t's
    		char  *psz_zones;         //指定区的另一种方法
    	} rc;                         //码率控制参数
    
    	//Muxing复用参数 
    	int  b_aud;                //生成访问单元分隔符
    	int  b_repeat_headers;     //是否复制sps和pps放在每个关键帧的前面
    	int  b_annexb;             //值为true,则NALU之前是4字节前缀码0x00000001;值为false,则NALU之前的4个字节为NALU长度
    	int  i_sps_id;             //sps和pps的id号
    	int  b_vfr_input;          //VFR输入。1 :时间基和时间戳用于码率控制  0 :仅帧率用于码率控制
    	uint32_t  i_fps_num;       //帧率的分子
    	uint32_t  i_fps_den;       //帧率的分母
    	uint32_t  i_timebase_num;  //时间基的分子
    	uint32_t  i_timebase_den;  //时间基的分母
    	int  b_pulldown;
    	int  b_pic_struct;         //强制在Picture Timing SEI传送pic_struct. 默认是未开启
    	int b_fake_interlaced;
    	int  i_slice_max_size;     //每个slice的最大字节数,包括预计的NAL开销
    	int  i_slice_max_mbs;      //每个slice的最大宏块数,重写i_slice_count
    	int  i_slice_count;        //每帧slice的数目,每个slice必须是矩形
    } x264_param_t;
    

    x264_nal_t:x264_nal_t里的数据在下一次调用x264_encoder_encode之后就无效了,因此要在调用或者使用之前使用它。

    typedef struct
    {
    	int  i_ref_idc;        // Nal的优先级
    	int  i_type;           // Nal的类型
    	int  b_long_startcode; // 是否采用长前缀码0x00000001
    	int  i_first_mb;       // 如果Nal为一条带,则表示该条带第一个宏块的指数
    	int  i_last_mb;        // 如果Nal为一条带,则表示该条带最后一个宏块的指数
    	int  i_payload;        // payload 的字节大小
    	uint8_t *p_payload;    // 存放编码后的数据,已经封装成Nal单元
    } x264_nal_t;
    

    X264编码器有关的功能函数:

    功能函数包括VCL编码和NAL打包。

    VCL编码函数包括:

        创建编码器x264_encoder_open();

        编码图像x264_encoder_encode();

        关闭编码器x264_encoder_close();

    NAL打包函数:

        x264_nal_encode();

    //x264_picture_alloc:申请一帧图像空间,需要调用x264_picture_clean释放申请的内存
    void x264_picture_alloc(x264_picture_t *pic, int i_csp, int i_width, int i_height);
    //x264_picture_clean:释放x264_picture_alloc申请的有关资源,视频结构体是x264_picture_t
    void x264_picture_clean(x264_picture_t *pic);
    
    //x264_encoder_open:创建编码器句柄,读入x264_param_t的所有参数
    x264_t *x264_encoder_open(x264_param_t*);
    //x264_encoder_headers:写SPS和PPS数据
    int x264_encoder_headers(x264_t*, x264_nal_t**, int*);
    
    //x264_encoder_encode:编码一帧图像
    int x264_encoder_encode(x264_t *, x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,x264_picture_t *pic_out);
    //x264_encoder_close:关闭编码器句柄
    void x264_encoder_close(x264_t*);
     
     
     
  • 相关阅读:
    http://www.kankanews.com/ICkengine/archives/18078.shtml
    c# ArrayList 的排序问题!
    MVC各种传值方式
    MVC3学习第五章 排山倒海第一变母版页,模型
    MVC3学习第三章 剑出鞘之前奏控制器,URL路由
    MVC3学习第二章 剑出鞘之看剑vs2010安装MVC3和建立你的第一个MVC3项目
    MVC3学习第四章 剑出鞘之后续MVC3的新特性之Razor视图解析
    MVC3学习第一章 掀起它的盖头来
    有关匿名函数执行与传参
    ubuntu12.04安装jdk7u79linuxi586.tar.gz
  • 原文地址:https://www.cnblogs.com/xue0708/p/11962248.html
Copyright © 2011-2022 走看看