Cur*_*Guo 7 encoding ffmpeg libx264
我正在使用ffmpeg libx264来编码从x11实时捕获的720p屏幕,其fps为30.当我使用-tune zerolatency参数时,每帧的平均编码时间可以与配置文件基线一样大到12ms.
在研究了ffmpeg x264源代码之后,我发现导致如此长编码时间的关键参数是切片线程,它通过-tune zerolatency启用.使用-x264-params slic-threads = 0禁用后,编码时间可低至2ms
禁用切片线程后,CPU使用率将为40%,而启用时仅为20%.
有人可以解释这个切片线程的细节吗?特别是在实时编码中(假设没有帧被缓冲以进行编码.仅在捕获帧时进行编码).
aer*_*tal 11
该文件表明,基于帧的线程具有比片为基础的更好的吞吐量.它还指出,由于编码器的部分串行,后者不能很好地扩展.
加速与veryfast配置文件的编码线程(非实时):
threads speedup psnr
slice frame slice frame
x264 --preset veryfast --tune psnr --crf 30
1: 1.00x 1.00x +0.000 +0.000
2: 1.41x 2.29x -0.005 -0.002
3: 1.70x 3.65x -0.035 +0.000
4: 1.96x 3.97x -0.029 -0.001
5: 2.10x 3.98x -0.047 -0.002
6: 2.29x 3.97x -0.060 +0.001
7: 2.36x 3.98x -0.057 -0.001
8: 2.43x 3.98x -0.067 -0.001
9: 3.96x +0.000
10: 3.99x +0.000
11: 4.00x +0.001
12: 4.00x +0.001
Run Code Online (Sandbox Code Playgroud)
主要区别似乎是帧线程增加了帧延迟,因为需要使用不同的帧,而在基于切片的线程的情况下,所有线程都在同一帧上工作.在实时编码中,它需要等待更多帧到达以填充管道而不是离线.
正常螺纹,也称为基于框架的螺纹,使用巧妙的交错框架系统进行并行.但它需要付出代价:如前所述,每个额外的线程都需要一层延迟.基于切片的线程没有这样的问题:每个帧被分成片,每个片在一个核上编码,然后将结果打包在一起以形成最终帧.由于各种原因,它的最大效率要低得多,但它至少允许一些并行性而不会增加延迟.
来自:x264开发者的日记
无切片线程:具有2个线程的示例.开始编码帧#0.当它完成一半时,开始编码帧#1.线程#1现在只能访问其参考帧的上半部分,因为其余部分尚未编码.所以它必须限制运动搜索范围.但这可能没问题(除非你在一个小框架上使用大量的线程),因为很少有这么长的垂直运动矢量.片刻之后,两个线程都编码了一行宏块,因此线程#1仍然使用运动范围= +/- 1/2帧高度.稍后,线程#0完成帧#0,并继续前进到帧#2.线程#0现在获得运动限制,线程#1不受限制.
来自:http://web.archive.org/web/20150307123140/http : //akuvian.org/src/x264/sliceless_threads.txt
因此,有意义的是启用sliced-threads,-tune zereolatency因为您需要尽快发送帧,而不是有效地编码它们(性能和质量明智).
相反,使用太多线程会影响性能,因为维护它们的开销可能会超过潜在的收益.