Android手机H264软编码参数优化

做了一段时间的视频后,最先碰到的是花屏,解码端丢包的花屏,先是通过抓取编码后的BITMAP,发现解码出来就是花屏的,所以考虑优化编码来减少因为丢包产生的花屏;另外调整丢包策略规避解码花屏的问题.

1、X264编码参数调整:

H264 FF_PROFILE_H264_BASELINE、 FF_PROFILE_H264_MAIN两种编码差异,其中最明显的差异是profile_idc_baseline没有B帧,而profile_idc_main带B帧,这个差异体现在解码时,带B帧的不仅依赖之前的帧,还依赖之后到来的帧,通常在实时视频类应用中不建议带B帧的编码。

质量和码率控制:

最开始也是用bit_rate 来控制:


encoder.context->bit_rate = (self->encoder.max_bw_kpbs * 1024);// bps

bit_rate是平均码率,总是达不到理想的结果(包括编码后的视频帧大小和质量),后来查看网上关于移动设备X264编码优化,提到了通过CRF来控制质量和码率,认为: x264默认是使用”crf”压缩算法,  默认值为23, 代表了编码速度,画质与码流的均衡.并且对各种取值做了编码大小和帧率的比较: 

ultrafast baseline crf 28
encoded 467 frames, 58.94 fps, 515.58 kb/s 2006474

superfast baseline crf 26
encoded 467 frames, 41.73 fps, 460.02 kb/s 1790244

superfast baseline crf 28
encoded 467 frames, 43.64 fps, 366.28 kb/s 1425436

配置crf

if((ret = av_opt_set_double(self->encoder.context->priv_data, "crf", (double)30, 0))){
            TSK_DEBUG_ERROR("Failed to set x264 crf 28.0");
	    return;
}
//ultrafast veryfast superfast
if((ret = av_opt_set(self->encoder.context->priv_data, "preset", "superfast", 0))){
	TSK_DEBUG_ERROR("Failed to set x264 preset to veryfast");
}


编码后视频NALU单元大小控制:

encoder.context->rtp_payload_size = H264_RTP_PAYLOAD_SIZE;//H264_RTP_PAYLOAD_SIZE大小为1300
if((ret = av_opt_set_int(self->encoder.context->priv_data, "slice-max-size", H264_RTP_PAYLOAD_SIZE, 0))){
	TSK_DEBUG_ERROR("Failed to set x264 slice-max-size to %d", H264_RTP_PAYLOAD_SIZE);
}


两个I帧之间帧个数的控制:

encoder.context->gop_size = TMEDIA_CODEC_VIDEO(self)->out.fps * TDAV_H264_GOP_SIZE_IN_SECONDS


2、丢包策略:

基于BP的H264编码,P帧只依赖之前的帧就能解码,所以出现丢包时的处理策略会比较简单,如果发现有P帧丢了,则丢弃后面的所有P帧,直到有I帧到来;如果是I帧丢了,则丢弃I帧及之后的P帧,直到有I帧到来。 

你可能感兴趣的:(流媒体)