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幀到來。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章