X264码率控制流程分析

本文深入剖析了x264的码率控制流程,包括初始化、根据复杂度获取QP值、编码过程中的比特控制等关键步骤。实验部分对比了不同码率控制模型(CQP、CRF)以及多pass编码的效果,展示了码率控制对视频压缩质量和效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

码率控制的理论知识:

码率控制的目的和意义:
图像通信中码率控制的目的:通过调节编码参数,控制单位时间内的编码视频流的数据量,以使产生的比特流符合各种应用的需求。视频压缩的效率和视频内容有很大的关系,对于变化多样的画面,视频编码的输出的码流变化较大,在信道环境不好的时候就容易导致解码端显示的质量的不稳定。

率失真理论:
由于传输带宽和存储空间的限制,视频应用对压缩比有较高的要求。而无损编码较低的压缩比无法满足视频在实际应用中的需求。但如果给视频引入一定程度的失真,通常可以获得较高的压缩比。
率失真理论对有损压缩编码下的失真和编码性能之间的关系的描述,为码率控制的研究提供了坚实的理论依据。率失真理论主旨是描述编码失真度和编码数据速率的关系。该理论建立在图像是连续的基础上的,在有限数据速率下,由于存在量化误差,必然存在失真。当使用有损编码方法时,重建图像g(x,y)和原始图像f(x,y)之间存在差异,失真度D的函数形式在理论上是可以根据需要自由选取的,在图像编码中,D常用均方差形式表示的,典型的率失真曲线。R(D)为D的凸减函数。
对于怎么选择哪个函数的率失真效果更好,则是比较哪个函数的率失真函数更为接近典型的率失真函数的曲线。

x264码率控制方法:采用的码率控制算法并没有采用拉格朗日代价函数来控制编码,而是使用一种更简单的方法,即利用半精度帧的SATD(sum of absolute transformed difference)作为模式选择的依据。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。SATD是将残差经哈达曼变换4*4块的预测残差绝对值总和。自适应宏块层码率控制策略:X264的宏块没有任何码率控制的机制,其在帧层得到一个QP后,属于该帧的所有宏块都用着统一的QP进行量化。

码率控制性能测度:
1、比特率误差|ABR-TBR|/TBR ,越小越好。
2、编码器性能。
3、缓冲区满度与TBL的匹配程度。
4、跳帧数。
5、PSNR波动越小越好。


x264中码率控制的流程(对于重点函数在下面有注释):

1.在进行编码时,Encode--->x264_encoder_open(主要是进行参数的修订设置,进行初始化)---->x264_ratecontrol_new
2.encode--->Encode_frame--->x264_encoder_encode--->x264_ratecontrol_slice_type
3.encode--->Encode_frame--->x264_encoder_encode--->x264_ratecontrol_start**************
4.encode--->Encode_frame--->x264_encoder_encode--->x264_ratecontrol_qp
5.encode--->Encode_frame--->x264_encoder_encode--->x264_slices_write--->x264_slice_write
--->x264_ratecontrol_mb********************
6.encode--->Encode_frame--->x264_encoder_encode--->x264_ratecontrol_end(在编完一帧过后)
7.在编完过后,encode--->x264_encoder_close---->ratecontrol summary/x264_ratecontrol_delete


函数注释:

在编码中所用的编码方式:
#define X264_RC_CQP                  0
#define X264_RC_CRF                  1
#define X264_RC_ABR                  2

1.
x264_ratecontrol_new( x264_t *h )
{   // 获取RC方式,FPS,bitrate,rc->buffer_rate,rc->buffer_size
// 在码率控制的时候会出现2pass,参数的初始化
rc = h->rc;
rc->b_abr = h->param.rc.i_rc_method != X264_RC_CQP && !h->param.rc.b_stat_read;
rc->b_2pass = h->param.rc.i_rc_method == X264_RC_ABR && h->param.rc.b_stat_read;
..........
if( h->param.rc.b_mb_tree )//这里设置mb_tree
{
h->param.rc.f_pb_factor = 1;
rc->qcompress = 1;
}
else
rc->qcompress = h->param.rc.f_qcompress;

..............
rc->ip_offset = 6.0 * log(h->param.rc.f_ip_factor) / log(2.0);
rc->pb_offset = 6.0 * log(h->param.rc.f_pb_factor) / log(2.0);
rc->qp_constant[SLICE_TYPE_P] = h->param.rc.i_qp_constant;
rc->qp_constant[SLICE_TYPE_I] = x264_clip3( h->param.rc.i_qp_constant - rc->ip_offset + 0.5, 0, 51 );
rc->qp_constant[SLICE_TYPE_B] = x264_clip3( h->param.rc.i_qp_constant + rc->pb_offset + 0.5, 0, 51 );

}

2.
int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
{
//根据不同类型来获取不同的qp_constant
h->param.rc.i_qp_constant = (h->stat.i_frame_count[SLICE_TYPE_P] == 0) ? 24
: 1 + h->stat.f_frame_qp[SLICE_TYPE_P] / h->stat.i_frame_count[SLICE_TYPE_P];
rc->qp_constant[SLICE_TYPE_P] = x264_clip3( h->param.rc.i_qp_constant, 0, 51 );
rc->qp_constant[SLICE_TYPE_I] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) / fabs( h->param.rc.f_ip_factor )) + 0.5 ), 0, 51 );
rc->qp_constant[SLICE_TYPE_B] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) * fabs( h->param.rc.f_pb_factor )) + 0.5 ), 0, 51 );
}

3.
x264_ratecontrol_start( h, h->f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值