码率控制的理论知识:
码率控制的目的和意义:
图像通信中码率控制的目的:通过调节编码参数,控制单位时间内的编码视频流的数据量,以使产生的比特流符合各种应用的需求。视频压缩的效率和视频内容有很大的关系,对于变化多样的画面,视频编码的输出的码流变化较大,在信道环境不好的时候就容易导致解码端显示的质量的不稳定。
率失真理论:
由于传输带宽和存储空间的限制,视频应用对压缩比有较高的要求。而无损编码较低的压缩比无法满足视频在实际应用中的需求。但如果给视频引入一定程度的失真,通常可以获得较高的压缩比。
率失真理论对有损压缩编码下的失真和编码性能之间的关系的描述,为码率控制的研究提供了坚实的理论依据。率失真理论主旨是描述编码失真度和编码数据速率的关系。该理论建立在图像是连续的基础上的,在有限数据速率下,由于存在量化误差,必然存在失真。当使用有损编码方法时,重建图像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
X264码率控制流程分析
最新推荐文章于 2024-06-24 20:44:41 发布