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*);
 
 
 

X264-libx264编码库的更多相关文章

  1. 视频编解码---x264用于编码,ffmpeg用于解码

    项目要用到视频编解码,最近半个月都在搞,说实话真是走了很多弯路,浪费了很多时间.将自己的最终成果记录于此,期望会给其他人提供些许帮助. 参考教程: http://ffmpeg.org/trac/ffm ...

  2. Libx264 编码错误 Input picture width(320) is greater than stride (0)

    Ffmpeg libx264编码出现 Input picture width(320) is greater than stride (0),问题出在视频格式不正确. libx264 编码要求输入源的 ...

  3. FFmpeg X264 H264编码指南[译]

    本文目标:如何创建一个高质量的H.264视频 x264 是一个 H.264 编码器. 通常有2种码率控制(rate control)模式:Constant Rate Factor (CRF) or T ...

  4. libIconv.lib编码库的生成和使用

    iconv是将一种编码格式转换为另一种编码格式的开源库,例如可以把Windows环境下通用的ASCii(中文是GB2312)编码转换为国际通用的Unicode编码 iconv最新版本只支持MingW和 ...

  5. 几组不错的X264自定义编码<转>

    转帖地址:http://tieba.baidu.com/p/4201033507 一般直播时使用A设定即可.你尝试设置并找出你最满意的设定 A为最需最低CPU资源,E为最高. A8x8dct=1 aq ...

  6. ndk编译libx264生成库

    编译脚本如下: TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64 function build_x26 ...

  7. FFmpeg编码扩展之————编码库的扩展(libfdk-aac)

    ffmpeg windows版没有libfdk-acc 请求该地址下载:http://tmod.nmm-hd.org/FFmpeg/

  8. Arm-Linux 移植 FFMPEG库 + x264

      背景: ffmpeg 中带有264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx26 ...

  9. arm linux 移植 ffmpeg 库 + x264

    背景 Ffmpeg 中带有h264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx264. ...

随机推荐

  1. [日常] 使用TCPDUMP和Ethereal抓包分析HTTP请求中的异常情况

    在测试功能的过程中,出现这样一种现象.前端js发起ajax请求后,在浏览器的审查元素网络状态中可以看到status为pending,等15秒以后js会把当前超时的请求取消掉,变成了红色的cancel. ...

  2. 渗透测试学习 十七、 XSS跨站脚本漏洞详解

      一般用途:拿cookie进后台,将后台地址一起发送过来 特点:挖掘困难,绕过困难  大纲: XSS漏洞基础讲解 XSS漏洞发掘与绕过 XSS漏洞的综合利用 XSS漏洞基础讲解 XSS介绍: 跨站脚 ...

  3. strcpy&memcpy&memmove

    strcpy extern char *strcpy(char *dest,char *source); { assert((dest!=NULL)&&(source!=NULL)); ...

  4. Appium自动化WebView中元素的操作

    在App开发过程中,很容易用到第三方的WebView控件,这个属于移动端混合型App.在我们做自动化测试的过程中,就要对这种情况进行处理,最通用的办法就是先将appium切换到webview模式然后按 ...

  5. Centos7防火墙添加端口

    添加 firewall-cmd --zone=public --add-port=80/tcp --permanent   (--permanent永久生效,没有此参数重启后失效) 重新载入 fire ...

  6. 17. 抽象建模能力&发散思维能力&综合(5)

    抽象建模能力 题一:[扑克牌顺子] LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽 ...

  7. Vue 使用lodash库减少watch对后台请求压力

    lodash需要新引入 我使用的是npm方式 使用lodash的_.debounce方法 具体代码: <!doctype html> <html lang="en" ...

  8. ORB-SLAM2初步(Tracking.cpp)

    今天主要是分析一下Tracking.cpp这个文件,它是实现跟踪过程的主要文件,这里主要针对单目,并且只是截取了部分代码片段. 一.跟踪过程分析 首先构造函数中使用初始化列表对跟踪状态mState(N ...

  9. let/const特性

        let: 1.声明的变量不存在预解析: console.log(a); let a=1; 2.变量名不允许重复(在同一作用域下): { let a=1; let a=2; console.lo ...

  10. Elasticsearch搜索调优权威指南 (2/3)

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/AAkVdzmkgdBisuQZldsnvg 英文原文:https://qbox.io/blog/el ...