FFmpeg:h264_qsv 比 libx264 慢(实时缓冲区太满)

FFmpeg:h264_qsv 比 libx264 慢(实时缓冲区太满)

我使用的配置:Windows 10 IoT、Intel Celeron N3350E(带 Intel HD Graphics)。

运行此行:

ffmpeg -f dshow -i video="USB Video":audio="USB Digital Audio" -c:v libx264 -crf 30 -preset ultrafast out.mp4

CPU 使用率(由 FFmpeg 提供):60-80%,GPU 使用率:0

仅当总 CPU 使用率(连同其他应用程序)上升到接近 100% 时才会出现“实时缓冲区太满”错误。

运行此行(其示例来自 trac.ffmpeg.org):

ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -f dshow -i video="USB Video":audio="USB Digital Audio" -vf hwupload=extra_hw_frames=64,format=qsv -c:v h264_qsv -preset veryfast out.mp4

CPU 使用率(由 FFmpeg 提供):接近 50%,GPU 使用率:接近 50%

但是,即使总 CPU 使用率(所有应用程序)低于 100%(接近 80%),也会出现“实时缓冲区太满”错误。

为什么使用 QSV 的 FFmpeg 在仍有空闲处理器资源的情况下却没有时间对视频进行编码?

Log level: 48
Command line:
ffmpeg -init_hw_device "qsv=hw" -filter_hw_device hw -f dshow -i "video=USB Video:audio=USB Digital Audio" -vf "hwupload=extra_hw_frames=64,format=qsv" -c:v h264_qsv -preset veryfast "out.mp4" -report
ffmpeg version 5.0-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 11.2.0 (Rev5, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Splitting the commandline.
Reading option '-init_hw_device' ... matched as option 'init_hw_device' (initialise hardware device) with argument 'qsv=hw'.
Reading option '-filter_hw_device' ... matched as option 'filter_hw_device' (set hardware device used when filtering) with argument 'hw'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'dshow'.
Reading option '-i' ... matched as input url with argument 'video=USB Video:audio=USB Digital Audio'.
Reading option '-vf' ... matched as option 'vf' (set video filters) with argument 'hwupload=extra_hw_frames=64,format=qsv'.
Reading option '-c:v' ... matched as option 'c' (codec name) with argument 'h264_qsv'.
Reading option '-preset' ... matched as AVOption 'preset' with argument 'veryfast'.
Reading option 'out.mp4' ... matched as output url.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option init_hw_device (initialise hardware device) with argument qsv=hw.
WARNING: defaulting child_device_type to AV_HWDEVICE_TYPE_DXVA2 for compatibility with old commandlines. This behaviour will be removed in the future. Please explicitly set device type via "-init_hw_device" option.
[AVHWDeviceContext @ 0000021f51ffe280] Using D3D9Ex device.
[AVHWDeviceContext @ 0000021f51ffdf80] Initialize MFX session: API version is 1.35, implementation version is 1.35
Applying option filter_hw_device (set hardware device used when filtering) with argument hw.
Applying option report (generate a report) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input url video=USB Video:audio=USB Digital Audio.
Applying option f (force format) with argument dshow.
Successfully parsed a group of options.
Opening an input file: video=USB Video:audio=USB Digital Audio.
[dshow @ 0000021f52001a40] Selecting pin Record on video
[dshow @ 0000021f52001a40] not reusing previous graph capture filter @device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{27F9D9B9-5F34-4AAE-9F7D-0F4573844D9E} != @device_pnp_\\?\usb#vid_534d&pid_2109&mi_00#6&3443966d&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global
[dshow @ 0000021f52001a40] Selecting pin Capture on audio only
[dshow @ 0000021f52001a40] passing through packet of type video size   147499 timestamp 2766116729774 orig timestamp 2766116729774 graph timestamp 2766116730000 diff 226 USB Video
[mjpeg @ 0000021f5200d400] marker=d8 avail_size_in_buf=147497
[mjpeg @ 0000021f5200d400] marker parser used 0 bytes (0 bits)
[mjpeg @ 0000021f5200d400] marker=db avail_size_in_buf=147495
[mjpeg @ 0000021f5200d400] index=0
[mjpeg @ 0000021f5200d400] qscale[0]: 3
[mjpeg @ 0000021f5200d400] marker parser used 67 bytes (536 bits)
[mjpeg @ 0000021f5200d400] marker=db avail_size_in_buf=147426
[mjpeg @ 0000021f5200d400] index=1
[mjpeg @ 0000021f5200d400] qscale[1]: 6
[mjpeg @ 0000021f5200d400] marker parser used 67 bytes (536 bits)
[mjpeg @ 0000021f5200d400] marker=c0 avail_size_in_buf=147357
[mjpeg @ 0000021f5200d400] Changing bps from 0 to 8
[mjpeg @ 0000021f5200d400] sof0: picture: 1920x1080
[mjpeg @ 0000021f5200d400] component 0 2:1 id: 0 quant:0
[mjpeg @ 0000021f5200d400] component 1 1:1 id: 1 quant:1
[mjpeg @ 0000021f5200d400] component 2 1:1 id: 2 quant:1
[mjpeg @ 0000021f5200d400] pix fmt id 21111100
[mjpeg @ 0000021f5200d400] Format yuvj422p chosen by get_format().
[mjpeg @ 0000021f5200d400] marker parser used 17 bytes (136 bits)
[mjpeg @ 0000021f5200d400] marker=c4 avail_size_in_buf=147338
[mjpeg @ 0000021f5200d400] marker parser used 0 bytes (0 bits)
[mjpeg @ 0000021f5200d400] marker=c4 avail_size_in_buf=147305
[mjpeg @ 0000021f5200d400] marker parser used 0 bytes (0 bits)
[mjpeg @ 0000021f5200d400] marker=c4 avail_size_in_buf=147122
[mjpeg @ 0000021f5200d400] marker parser used 0 bytes (0 bits)
[mjpeg @ 0000021f5200d400] marker=c4 avail_size_in_buf=147089
[mjpeg @ 0000021f5200d400] marker parser used 0 bytes (0 bits)
[mjpeg @ 0000021f5200d400] escaping removed 2575 bytes
[mjpeg @ 0000021f5200d400] marker=da avail_size_in_buf=146906
[mjpeg @ 0000021f5200d400] marker parser used 144331 bytes (1154648 bits)
[mjpeg @ 0000021f5200d400] marker=d9 avail_size_in_buf=0
[mjpeg @ 0000021f5200d400] decode frame unused 0 bytes
[dshow @ 0000021f52001a40] passing through packet of type video size   146001 timestamp 2766117063107 orig timestamp 2766117063107 graph timestamp 2766117210000 diff 146893 USB Video

...

[dshow @ 0000021f52001a40] passing through packet of type video size   145557 timestamp 2766120729770 orig timestamp 2766120729770 graph timestamp 2766120730000 diff 230 USB Video
[dshow @ 0000021f52001a40] passing through packet of type audio size    88200 timestamp 2766115720000 orig timestamp 2766115720000 graph timestamp 2766120880000 diff 5160000 USB Digital Audio
[dshow @ 0000021f52001a40] All info found
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, dshow, from 'video=USB Video:audio=USB Digital Audio':
  Duration: N/A, start: 276611.572000, bitrate: N/A
  Stream #0:0, 13, 1/10000000: Video: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj422p(pc, bt470bg/bt709/unknown), 1920x1080, 30 fps, 30 tbr, 10000k tbn
  Stream #0:1, 1, 1/10000000: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Successfully opened the file.
Parsing a group of options: output url out.mp4.
Applying option vf (set video filters) with argument hwupload=extra_hw_frames=64,format=qsv.
Applying option c:v (codec name) with argument h264_qsv.
Successfully parsed a group of options.
Opening an output file: out.mp4.
[file @ 0000021f5b636ac0] Setting default whitelist 'file,crypto,data'
Successfully opened the file.
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (h264_qsv))
  Stream #0:1 -> #0:1 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
cur_dts is invalid st:0 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[mjpeg @ 0000021f520c43c0] marker=d8 avail_size_in_buf=147497

...

[dshow @ 0000021f52001a40] real-time buffer [USB Video] [video input] too full or near too full (85% of size: 3041280 [rtbufsize parameter])! frame dropped!
[mjpeg @ 0000021f520c43c0] marker parser used 142451 bytes (1139601 bits)
[mjpeg @ 0000021f520c43c0] marker=d9 avail_size_in_buf=0
[mjpeg @ 0000021f520c43c0] decode frame unused 0 bytes
[dshow @ 0000021f52001a40] passing through packet of type video size   144436 timestamp 2766128063096 orig timestamp 2766128063096 graph timestamp 2766128090000 diff 26904 USB Video
[dshow @ 0000021f52001a40] real-time buffer [USB Video] [video input] too full or near too full (85% of size: 3041280 [rtbufsize parameter])! frame dropped!
cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
cur_dts is invalid st:1 (0) [init:0 i_done:0 finish:0] (this is harmless if it occurs once at the start per stream)
[graph_1_in_0_1 @ 0000021f520704c0] Setting 'time_base' to value '1/44100'
[graph_1_in_0_1 @ 0000021f520704c0] Setting 'sample_rate' to value '44100'
[graph_1_in_0_1 @ 0000021f520704c0] Setting 'sample_fmt' to value 's16'
[graph_1_in_0_1 @ 0000021f520704c0] Setting 'channel_layout' to value '0x3'
[graph_1_in_0_1 @ 0000021f520704c0] tb:1/44100 samplefmt:s16 samplerate:44100 chlayout:0x3
[format_out_0_1 @ 0000021f5b66ee00] Setting 'sample_fmts' to value 'fltp'
[format_out_0_1 @ 0000021f5b66ee00] Setting 'sample_rates' to value '96000|88200|64000|48000|44100|32000|24000|22050|16000|12000|11025|8000|7350'
[format_out_0_1 @ 0000021f5b66ee00] auto-inserting filter 'auto_aresample_0' between the filter 'Parsed_anull_0' and the filter 'format_out_0_1'
[AVFilterGraph @ 0000021f5b7ce080] query_formats: 4 queried, 6 merged, 3 already done, 0 delayed
[auto_aresample_0 @ 0000021f5b784b00] [SWR @ 0000021f5b57fb80] Using s16p internally between filters
[auto_aresample_0 @ 0000021f5b784b00] ch:2 chl:stereo fmt:s16 r:44100Hz -> ch:2 chl:stereo fmt:fltp r:44100Hz
Output #0, mp4, to 'C:\Users\FFmpeg\Desktop\out.mp4':
  Metadata:
    encoder         : Lavf59.16.100
  Stream #0:0, 0, 1/10000000: Video: h264 (avc1 / 0x31637661), qsv(pc, gbr/bt709/unknown, progressive), 1920x1080, q=2-31, 1000 kb/s, 30 fps, 10000k tbn
    Metadata:
      encoder         : Lavc59.18.100 h264_qsv
    Side data:
      cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: N/A
  Stream #0:1, 0, 1/44100: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc59.18.100 aac
[dshow @ 0000021f52001a40] passing through packet of type video size   143852 timestamp 2766128396429 orig timestamp 2766128396429 graph timestamp 2766128410000 diff 13571 USB Video
[dshow @ 0000021f52001a40] passing through packet of type video size   144527 timestamp 2766128729762 orig timestamp 2766128729762 graph timestamp 2766128760000 diff 30238 USB Video
frame=   16 fps=0.0 q=45.0 size=       0kB time=00:00:00.44 bitrate=   0.9kbits/s dup=3 drop=0 speed=0.613x    

...

[q] command received. Exiting.

答案1

-rtbufsize请增加和-thread_queue_size(每个输入)参数的值并重新测试。

对于您的命令,请按照建议的值进行调整:

ffmpeg -y -rtbufsize 2048M -init_hw_device qsv=hw
-filter_hw_device hw -f dshow -thread_queue_size 4096 
-i video="USB Video":audio="USB Digital Audio" 
-vf "hwupload=extra_hw_frames=64,format=qsv"
-c:v h264_qsv -preset veryfast out.mp4

故障排除:

如果可以的话,使用 ffmpeg 探测 USB 视频捕获设备的设备模式:

ffmpeg -f dshow -list_options true -i video="USB Video"

然后将从上述输出中得出的有效选项手动映射到 ffmpeg。例如,要从样本相机以 30 fps 捕获 1080p 视频,您可以使用:

ffmpeg -y -rtbufsize 2048M -init_hw_device qsv=hw
-filter_hw_device hw -f dshow -thread_queue_size 4096
-video_size 1920x1080 -framerate 30 -vcodec mjpeg 
-i video="USB Video":audio="USB Digital Audio" 
-vf "hwupload=extra_hw_frames=64,format=qsv"
-c:v h264_qsv -preset veryfast out.mp4

通过手动选择捕获设备直接支持的分辨率和编解码器,这可能有助于减少任何处理开销。请参阅回答有关同一问题的更多指示。

然后重新测试并报告。

相关内容