H264编码系列之x264帧编码延迟

2018-11-01  本文已影响92人  C_GO流媒体后台开发

参考

x264帧编码延迟

研究了一下x264编码延时.
方法是加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 );
     ...
 }

统计了一下,发现x264编码延时帧数符合下面的公式。

h->frames.i_delay =
        param->i_sync_lookahead +   // 前向考虑帧数
        max ( param->i_bframe,      // B帧数量
              param->rc.i_lookahead)  + // 码率控制前向考虑帧数
        param->i_threads - 1.           // 并行编码帧数

延迟有两种:

  1. 编码前延时(当前帧没有编码,需要buffer更多帧后才能开始编码,比如要编码B帧,需要后面的P帧来了才能编码)。
    这种延时出口在 encoder.c, x264_encoder_encode函数
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 都会在此影响延时。

  1. 编码后延时(当前帧已经编码,但后续帧还没编码,只好先退出)。
    这种延时出口在 encoder.c, x264_encoder_frame_end函数
    if( !h->out.i_nal )
     {
         pic_out->i_type = X264_TYPE_AUTO;
         return 0;
     }

这部分延时是因为x264并行帧编码引起的。
x264并行帧编码每一次都是把一个帧组(i_threads个并行处理帧)处理完后,再处理下一个帧组。
博主评论

这也解析了为什么即使没有b帧,但不设置zerolatency时也出现了编码延迟。

根据公式看到减少帧延时的方法,也就是(zerolatency 设置)

            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;

注:即使设置了zerolatency,但将i_bframe改为>0则同样会出现编码前的延迟。

疑惑
这样看x264并行帧编码写的还不是很自适应。
如果能够让i_threads在编码起始阶段随着输入帧数的增加而增加,那样就可以彻底解决编码群延时的问题了。

博主评论:但具体怎么去实施还是有些难度。

上一篇下一篇

猜你喜欢

热点阅读