更多音視頻知識請點(diǎn)擊:專注音視頻開發(fā)
參考
研究了一下x264編碼延時(shí).
方法是加log在x264.c
static int encode( x264_param_t *param, cli_opt_t *opt )
{
...
i_frame_size = encode_frame( h, opt->hout, &pic, &last_dts );
if( i_frame_size == 0) // delay frames
fprintf( stderr, "output zero %d\n", i_frame );
...
}
統(tǒng)計(jì)了一下囤捻,發(fā)現(xiàn)x264編碼延時(shí)幀數(shù)符合下面的公式臼朗。
h->frames.i_delay =
param->i_sync_lookahead + // 前向考慮幀數(shù)
max ( param->i_bframe, // B幀數(shù)量
param->rc.i_lookahead) + // 碼率控制前向考慮幀數(shù)
param->i_threads - 1. // 并行編碼幀數(shù)
延遲有兩種:
- 編碼前延時(shí)(當(dāng)前幀沒有編碼,需要buffer更多幀后才能開始編碼蝎土,比如要編碼B幀视哑,需要后面的P幀來了才能編碼)。
這種延時(shí)出口在 encoder.c, x264_encoder_encode函數(shù)
if( h->frames.i_input <= h->frames.i_delay + 1 - h->i_thread_frames )
{
/* Nothing yet to encode, waiting for filling of buffers */
pic_out->i_type = X264_TYPE_AUTO;
return 0;
}
i_sync_lookahead, i_bframe, rc.i_lookahead 都會在此影響延時(shí)誊涯。
- 編碼后延時(shí)(當(dāng)前幀已經(jīng)編碼挡毅,但后續(xù)幀還沒編碼,只好先退出)暴构。
這種延時(shí)出口在 encoder.c, x264_encoder_frame_end函數(shù)
if( !h->out.i_nal )
{
pic_out->i_type = X264_TYPE_AUTO;
return 0;
}
這部分延時(shí)是因?yàn)閤264并行幀編碼引起的跪呈。
x264并行幀編碼每一次都是把一個(gè)幀組(i_threads個(gè)并行處理幀)處理完后,再處理下一個(gè)幀組取逾。
博主評論
這也解析了為什么即使沒有b幀耗绿,但不設(shè)置zerolatency時(shí)也出現(xiàn)了編碼延遲。
根據(jù)公式看到減少幀延時(shí)的方法砾隅,也就是(zerolatency 設(shè)置)
param->rc.i_lookahead = 0;
param->i_sync_lookahead = 0;
param->i_bframe = 0;
param->b_sliced_threads = 1;
param->b_vfr_input = 0;
param->rc.b_mb_tree = 0;
- 這個(gè)設(shè)置h->frames.i_delay = 0误阻。但其中param->b_sliced_threads = 1 的設(shè)置值得懷疑。
- 當(dāng)b_sliced_threads = 1時(shí)晴埂,x264放棄幀并行編碼究反,這必然會影響編碼速度。
- 一個(gè)折中的辦法是設(shè)置b_sliced_threads = 0(為0時(shí)x264自動(dòng)計(jì)算線程)儒洛,其他按照zerolatency 設(shè)置精耐。
這樣h->frames.i_delay = param->i_threads - 1。
x264根據(jù)CPU自動(dòng)計(jì)算i_threads琅锻,一般為6/8. 這樣的幀群延遲大概是1/3-1/2秒黍氮。
看具體系統(tǒng)的需要能否滿足唐含。
注:即使設(shè)置了zerolatency,但將i_bframe改為>0則同樣會出現(xiàn)編碼前的延遲沫浆。
疑惑
這樣看x264并行幀編碼寫的還不是很自適應(yīng)捷枯。
如果能夠讓i_threads在編碼起始階段隨著輸入幀數(shù)的增加而增加,那樣就可以徹底解決編碼群延時(shí)的問題了专执。
博主評論:但具體怎么去實(shí)施還是有些難度淮捆。