背景
- 最近使用FFmpeg编码时(264,265的软编和NVIDIA硬编)有不同程序的缓存。具体表现就是调用avcodec_send_frame多次后才能调用avcodec_receive_packet一次。自测x264缓存了40帧,h264_nvenc未做缓存,h264_nvenc编码8K时也有缓存。
- 目的是降低编码延时,如果缓存40帧,帧率25的情况下接近2s了,不能接受。
结论
- 通过改变编码器线程数,多线程编码类型。(未起作用)
因为之前有过启用多线程编码,编码器会做缓存的经验,大概缓存个数跟线程数相关,如果设置了 thread为auto的话,这个线程数跟CPU的核数相关。但是把AVCodecContext的thread_count设置为1,thread_type设置为FF_THREAD_SLICE后测试发现并未起作用。 - 增加tune和preset参数(成功)
av_opt_set(m_av_codec_ctx->priv_data, "tune", "zerolatency", 0); av_opt_set(m_av_codec_ctx->priv_data, "preset", "superfast", 0);
技术细节
-
以前做推流时候为了降低延迟,不使用B帧,设置tune为zerolatency,preset为superfast,当时没有详细分析,误以为是对协议中封包逻辑有影响,或者因为编码器的改动影响到解码器的解码等。产生这样的想法原因是编码复用代码一起写了,难免思维有误差。
-
那这两个参数影响了编码器的那些编码参数呢?我们从执行x264.exe --fullhelp,过滤下关键字。
--preset <string> Use a preset to select encoding settings [medium] Overridden by user settings. - superfast: --no-mbtree --me dia --no-mixed-refs --partitions i8x8,i4x4 --rc-lookahead 0 --ref 1 --subme 1 --trellis 0 --weightp 1 - veryfast: --no-mixed-refs --rc-lookahead 10 --ref 1 --subme 2 --trellis 0 --weightp 1 --tune <string> Tune the settings for a particular type of source or situation Overridden by user settings. Multiple tunings are separated by commas. Only one psy tuning can be used at a time. - zerolatency: --bframes 0 --force-cfr --no-mbtree --sync-lookahead 0 --sliced-threads --rc-lookahead 0
为了方便阅读,我只贴了这两个参数,详细的参数表在文章尾部。
观察一下他们都有lookahead这个参数,且都设置为0。再看superfast和veryfast,look_ahead值不同。
lookahead这个参数大有来头,它的作用是确定当前编码的帧是哪种类型(IBP等),但是需要根据前面的帧来判断,参考帧越多,得出的结论越准确。 -
所以将look_ahead设置为0了,自然缓存帧数也就降下来了,但是带来的负面影响是编码效率会降低。
参考文章
x264码率控制 关键字: x264 lookahead
低延时编码 关键字:编码延时主要来源三个方面:B 帧、Lookahead 以及 Frame thread
x264编码参数详细解释
ref 引用帧个数
subme 压缩像素估计复杂度
详细参数表
--preset <string> Use a preset to select encoding settings [medium]
Overridden by user settings.
- ultrafast:
--no-8x8dct --aq-mode 0 --b-adapt 0
--bframes 0 --no-cabac --no-deblock
--no-mbtree --me dia --no-mixed-refs
--partitions none --rc-lookahead 0 --ref 1
--scenecut 0 --subme 0 --trellis 0
--no-weightb --weightp 0
- superfast:
--no-mbtree --me dia --no-mixed-refs
--partitions i8x8,i4x4 --rc-lookahead 0
--ref 1 --subme 1 --trellis 0 --weightp 1
- veryfast:
--no-mixed-refs --rc-lookahead 10
--ref 1 --subme 2 --trellis 0 --weightp 1
- faster:
--no-mixed-refs --rc-lookahead 20
--ref 2 --subme 4 --weightp 1
- fast:
--rc-lookahead 30 --ref 2 --subme 6
--weightp 1
- medium:
Default settings apply.
- slow:
--direct auto --rc-lookahead 50 --ref 5
--subme 8 --trellis 2
- slower:
--b-adapt 2 --direct auto --me umh
--partitions all --rc-lookahead 60
--ref 8 --subme 9 --trellis 2
- veryslow:
--b-adapt 2 --bframes 8 --direct auto
--me umh --merange 24 --partitions all
--ref 16 --subme 10 --trellis 2
--rc-lookahead 60
- placebo:
--bframes 16 --b-adapt 2 --direct auto
--slow-firstpass --no-fast-pskip
--me tesa --merange 24 --partitions all
--rc-lookahead 60 --ref 16 --subme 11
--trellis 2
--tune <string> Tune the settings for a particular type of source
or situation
Overridden by user settings.
Multiple tunings are separated by commas.
Only one psy tuning can be used at a time.
- film (psy tuning):
--deblock -1:-1 --psy-rd <unset>:0.15
- animation (psy tuning):
--bframes {+2} --deblock 1:1
--psy-rd 0.4:<unset> --aq-strength 0.6
--ref {Double if >1 else 1}
- grain (psy tuning):
--aq-strength 0.5 --no-dct-decimate
--deadzone-inter 6 --deadzone-intra 6
--deblock -2:-2 --ipratio 1.1
--pbratio 1.1 --psy-rd <unset>:0.25
--qcomp 0.8
- stillimage (psy tuning):
--aq-strength 1.2 --deblock -3:-3
--psy-rd 2.0:0.7
- psnr (psy tuning):
--aq-mode 0 --no-psy
- ssim (psy tuning):
--aq-mode 2 --no-psy
- fastdecode:
--no-cabac --no-deblock --no-weightb
--weightp 0
- zerolatency:
--bframes 0 --force-cfr --no-mbtree
--sync-lookahead 0 --sliced-threads
--rc-lookahead 0
--slow-firstpass Don't force these faster settings with --pass 1:
--no-8x8dct --me dia --partitions none
--ref 1 --subme {2 if >2 else unchanged}
--trellis 0 --fast-pskip