X264参数设置需要注意以下几点:
(1)profile
通过x264_param_apply_profile设置 baseline,main 还是 high 编码
(2) 编码复杂度
param.i_level_idc = 30
(3) 图像质量控制
param.rc.f_rf_constant =25 // rc.f_rf_constant是实际质量,越小越清晰
param.rc.f_rf_constant_max= 45 // 图像质量的最大值
经常碰到的问题:
(1) 码率控制不准
用crf模式,不管怎么设置也无法控制实际码率,换成平均码率即可
param.rc.i_rc_method = X264_RC_ABR;//参数i_rc_method表示码率控制,CQP(恒定质量),CRF(恒定码率),ABR(平均码率)
param.rc.i_vbv_max_bitrate=(int)((m_bitRate*1.2)/1000) ; // 平均码率模式下,最大瞬时码率,默认0(与-B设置相同)
param.rc.i_bitrate =(int)m_bitRate/1000;
(2) I帧间隔不定
原因是x264会根据视频的运动场景,自动为你添加额外的I帧,所以会导致你编出来的视频关键帧间隔不是你设置的长度
可以通过设置i_scenecut_threshold 为0 来关闭这个功能即可实现 I帧等间隔
(3) 编码延时
在使用中,开始总是会有编码延迟,导致我本地编码立即解码回放后也存在巨大的视频延迟,
后来发现设置x264_param_default_preset(¶m,"fast" , "zerolatency" );后就能即时编码了。
主要是zerolatency该参数。
(4) 编码速度不够
可以通过设置param.i_threads可指定线程数(多个slice可以并发编码), 默认是0(系统自发选择线程数)
多线程编码生成的帧是会存在多个slice的,后续送给RTMP发送时要注意封包格式
一个Flv video tag只能发一帧数据(包含多个slice) , 格式为: TAG header + nal 0 len + nal 0 data + nal 1len + nal 1 data + …
可以通过i_slice_count 来限制一帧里面的slice 数量
以下是我的x264配置:
x264_param_t params;
if( x264_param_default_preset( ¶ms, "fast", "zerolatency" ) < 0 ){
MYLOGE("x264_param_default_preset fail");
return NULL;
}
params.i_csp = X264_CSP_NV21;
params.i_width = width;
params.i_height = height;
params.b_repeat_headers = 0;
params.b_annexb = 1;
params.i_threads=1;
params.i_fps_num = fps;
params.i_fps_den = 1;
params.i_keyint_max = idrInternal * fps;
params.rc.f_rf_constant = 25;
params.rc.f_rf_constant_max = 45;
params.rc.i_rc_method = X264_RC_ABR;
params.rc.i_vbv_max_bitrate=(int)((bps * 1.2)/1000) ;
params.i_scenecut_threshold = 0;
params.rc.i_bitrate = (int)bps/1000;
/* Apply profile restrictions. */
if( x264_param_apply_profile( ¶ms, "baseline" ) < 0 ){
MYLOGE("x264_param_apply_profile fail");
return NULL;
}
params.i_level_idc=30;
x264_t* handler = x264_encoder_open(¶ms);
if(!handler){
MYLOGE("x264_encoder_open fail");
return NULL;
}