Вопрос или проблема
Я использую конфигурацию: 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
Использование ЦП (по данным FFmpeg): 60-80%, использование ГП: 0
Ошибка “реального времени буфер слишком полон” появляется только тогда, когда общее использование ЦП (вместе с другими приложениями) достигает почти 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
Использование ЦП (по данным FFmpeg): около 50%, использование ГП: около 50%
Но ошибка “реального времени буфер слишком полон” возникает даже тогда, когда общее использование ЦП (всех приложений) меньше 100% (около 80%).
Почему FFmpeg с QSV не успевает кодировать видео, несмотря на то, что процессорные ресурсы все еще свободны?
Уровень журнала: 48
Командная строка:
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 5.0-full_build-www.gyan.dev Copyright (c) 2000-2022 разработчики FFmpeg
собран с помощью gcc 11.2.0 (Rev5, созданный проектом MSYS2)
конфигурация: --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
Разделение командной строки.
Чтение параметра '-init_hw_device' ... соответствует параметру 'init_hw_device' (инициализация аппаратного устройства) с аргументом 'qsv=hw'.
Чтение параметра '-filter_hw_device' ... соответствует параметру 'filter_hw_device' (установить аппаратное устройство, используемое при фильтрации) с аргументом 'hw'.
Чтение параметра '-f' ... соответствует параметру 'f' (принудительный формат) с аргументом 'dshow'.
Чтение параметра '-i' ... соответствует URL входного потока с аргументом 'video=USB Video:audio=USB Digital Audio'.
Чтение параметра '-vf' ... соответствует параметру 'vf' (установить видеофильтры) с аргументом 'hwupload=extra_hw_frames=64,format=qsv'.
Чтение параметра '-c:v' ... соответствует параметру 'c' (имя кодека) с аргументом 'h264_qsv'.
Чтение параметра '-preset' ... соответствует параметру AVOption 'preset' с аргументом 'veryfast'.
Чтение параметра 'out.mp4' ... соответствует URL выходного потока.
Чтение параметра '-report' ... соответствует параметру 'report' (генерировать отчет) с аргументом '1'.
Завершение разделения командной строки.
Парсинг группы параметров: глобальные .
Применение параметра init_hw_device (инициализация аппаратного устройства) с аргументом qsv=hw.
ПРЕДУПРЕЖДЕНИЕ: тип дочернего устройства по умолчанию устанавливается в AV_HWDEVICE_TYPE_DXVA2 для совместимости со старыми командными строками. Это поведение будет удалено в будущем. Пожалуйста, явно укажите тип устройства через параметр "-init_hw_device".
[AVHWDeviceContext @ 0000021f51ffe280] Использование устройства D3D9Ex.
[AVHWDeviceContext @ 0000021f51ffdf80] Инициализация MFX сессии: API версия 1.35, версия реализации 1.35
Применение параметра filter_hw_device (установить аппаратное устройство, используемое при фильтрации) с аргументом hw.
Применение параметра report (генерировать отчет) с аргументом 1.
Успешный парсинг группы параметров.
Парсинг группы параметров: входной URL video=USB Video:audio=USB Digital Audio.
Применение параметра f (принудительный формат) с аргументом dshow.
Успешный парсинг группы параметров.
Открытие входного файла: video=USB Video:audio=USB Digital Audio.
[dshow @ 0000021f52001a40] Выбор пина Record на видео
[dshow @ 0000021f52001a40] не повторное использование предыдущего графа захватного фильтра @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] Выбор пина Capture только для аудио
[dshow @ 0000021f52001a40] передача пакета типа видео размером 147499 временной метки 2766116729774 оригинальная временная метка 2766116729774 временная метка графа 2766116730000 разница 226 USB Video
[mjpeg @ 0000021f5200d400] маркер=d8 доступный размер в буфере=147497
[mjpeg @ 0000021f5200d400] маркер парсер использовал 0 байт (0 бит)
[mjpeg @ 0000021f5200d400] маркер=db доступный размер в буфере=147495
[mjpeg @ 0000021f5200d400] индекс=0
[mjpeg @ 0000021f5200d400] qscale[0]: 3
[mjpeg @ 0000021f5200d400] маркер парсер использовал 67 байт (536 бит)
[mjpeg @ 0000021f5200d400] маркер=db доступный размер в буфере=147426
[mjpeg @ 0000021f5200d400] индекс=1
[mjpeg @ 0000021f5200d400] qscale[1]: 6
[mjpeg @ 0000021f5200d400] маркер парсер использовал 67 байт (536 бит)
[mjpeg @ 0000021f5200d400] маркер=c0 доступный размер в буфере=147357
[mjpeg @ 0000021f5200d400] Изменение bps с 0 до 8
[mjpeg @ 0000021f5200d400] sof0: изображение: 1920x1080
[mjpeg @ 0000021f5200d400] компонент 0 2:1 id: 0 quant:0
[mjpeg @ 0000021f5200d400] компонент 1 1:1 id: 1 quant:1
[mjpeg @ 0000021f5200d400] компонент 2 1:1 id: 2 quant:1
[mjpeg @ 0000021f5200d400] id формата pix 21111100
[mjpeg @ 0000021f5200d400] Формат yuvj422p выбран через get_format().
[mjpeg @ 0000021f5200d400] маркер парсер использовал 17 байт (136 бит)
[mjpeg @ 0000021f5200d400] маркер=c4 доступный размер в буфере=147338
[mjpeg @ 0000021f5200d400] маркер парсер использовал 0 байт (0 бит)
[mjpeg @ 0000021f5200d400] маркер=c4 доступный размер в буфере=147305
[mjpeg @ 0000021f5200d400] маркер парсер использовал 0 байт (0 бит)
[mjpeg @ 0000021f5200d400] маркер=c4 доступный размер в буфере=147122
[mjpeg @ 0000021f5200d400] маркер парсер использовал 0 байт (0 бит)
[mjpeg @ 0000021f5200d400] маркер=c4 доступный размер в буфере=147089
[mjpeg @ 0000021f5200d400] маркер парсер использовал 0 байт (0 бит)
[mjpeg @ 0000021f5200d400] escaping removed 2575 bytes
[mjpeg @ 0000021f5200d400] маркер=da доступный размер в буфере=146906
[mjpeg @ 0000021f5200d400] маркер парсер использовал 144331 байта (1154648 бит)
[mjpeg @ 0000021f5200d400] маркер=d9 доступный размер в буфере=0
[mjpeg @ 0000021f5200d400] декодированная рамка не использована 0 байт
[dshow @ 0000021f52001a40] передача пакета типа видео размером 146001 временной метки 2766117063107 оригинальная временная метка 2766117063107 временная метка графа 2766117210000 разница 146893 USB Video
...
[dshow @ 0000021f52001a40] передача пакета типа видео размером 145557 временной метки 2766120729770 оригинальная временная метка 2766120729770 временная метка графа 2766120730000 разница 230 USB Video
[dshow @ 0000021f52001a40] Вся информация найдена
Предположенная конфигурация канала для входного потока #0.1: стерео
Вход #0, dshow, из 'video=USB Video:audio=USB Digital Audio':
Длительность: N/A, начало: 276611.572000, битрейт: N/A
Поток #0:0, 13, 1/10000000: Видео: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj422p(pc, bt470bg/bt709/unknown), 1920x1080, 30 fps, 30 tbr, 10000k tbn
Поток #0:1, 1, 1/10000000: Аудио: pcm_s16le, 44100 Hz, стерео, s16, 1411 кбит/с
Успешно открыт файл.
Парсинг группы параметров: выходной URL out.mp4.
Применение параметра vf (установить видеофильтры) с аргументом hwupload=extra_hw_frames=64,format=qsv.
Применение параметра c:v (имя кодека) с аргументом h264_qsv.
Успешный парсинг группы параметров.
Открытие выходного файла: out.mp4.
[file @ 0000021f5b636ac0] Установка белого списка по умолчанию 'file,crypto,data'
Успешно открыт файл.
Отображение потоков:
Поток #0:0 -> #0:0 (mjpeg (родной) -> h264 (h264_qsv))
Поток #0:1 -> #0:1 (pcm_s16le (родной) -> aac (родной))
Нажмите [q], чтобы остановить, [?] для справки
cur_dts недопустим st:0 (0) [init:0 i_done:0 finish:0] (это безвредно, если происходит один раз в начале каждого потока)
[mjpeg @ 0000021f520c43c0] маркер=d8 доступный размер в буфере=147497
...
[dshow @ 0000021f52001a40] буфер реального времени [USB Video] слишком полон или почти полон (85% от размера: 3041280 [параметр rtbufsize])! кадр сброшен!
[mjpeg @ 0000021f520c43c0] маркер парсер использовал 142451 байта (1139601 бит)
[mjpeg @ 0000021f520c43c0] маркер=d9 доступный размер в буфере=0
[mjpeg @ 0000021f520c43c0] декодированная рамка не использована 0 байт
[dshow @ 0000021f52001a40] передача пакета типа видео размером 144436 временной метки 2766128063096 оригинальная временная метка 2766128063096 временная метка графа 2766128090000 разница 26904 USB Video
[dshow @ 0000021f52001a40] буфер реального времени [USB Video] слишком полон или почти полон (85% от размера: 3041280 [параметр rtbufsize])! кадр сброшен!
cur_dts недопустим st:0 (0) [init:1 i_done:0 finish:0] (это безвредно, если происходит один раз в начале каждого потока)
cur_dts недопустим st:1 (0) [init:0 i_done:0 finish:0] (это безвредно, если происходит один раз в начале каждого потока)
[graph_1_in_0_1 @ 0000021f520704c0] Установка 'time_base' в значение '1/44100'
[graph_1_in_0_1 @ 0000021f520704c0] Установка 'sample_rate' в значение '44100'
[graph_1_in_0_1 @ 0000021f520704c0] Установка 'sample_fmt' в значение 's16'
[graph_1_in_0_1 @ 0000021f520704c0] Установка 'channel_layout' в значение '0x3'
[graph_1_in_0_1 @ 0000021f520704c0] tb:1/44100 samplefmt:s16 samplerate:44100 chlayout:0x3
[format_out_0_1 @ 0000021f5b66ee00] Установка 'sample_fmts' в значение 'fltp'
[format_out_0_1 @ 0000021f5b66ee00] Установка 'sample_rates' в значение '96000|88200|64000|48000|44100|32000|24000|22050|16000|12000|11025|8000|7350'
[format_out_0_1 @ 0000021f5b66ee00] авто-вставка фильтра 'auto_aresample_0' между фильтром 'Parsed_anull_0' и фильтром 'format_out_0_1'
[AVFilterGraph @ 0000021f5b7ce080] query_formats: 4 запросов, 6 объединены, 3 уже выполнены, 0 задержано
[auto_aresample_0 @ 0000021f5b784b00] [SWR @ 0000021f5b57fb80] Использование s16p внутри фильтров
[auto_aresample_0 @ 0000021f5b784b00] ch:2 chl:стерео fmt:s16 r:44100Hz -> ch:2 chl:стерео fmt:fltp r:44100Hz
Выход #0, mp4, в 'C:\Users\FFmpeg\Desktop\out.mp4':
Метаданные:
кодировщик : Lavf59.16.100
Поток #0:0, 0, 1/10000000: Видео: h264 (avc1 / 0x31637661), qsv(pc, gbr/bt709/unknown, прогрессивный), 1920x1080, q=2-31, 1000 кбит/с, 30 fps, 10000k tbn
Метаданные:
кодировщик : Lavc59.18.100 h264_qsv
Дополнительные данные:
cpb: максимальная/минимальная/средняя битрейт: 0/0/1000000 размер буфера: 0 vbv_delay: N/A
Поток #0:1, 0, 1/44100: Аудио: aac (LC) (mp4a / 0x6134706D), 44100 Hz, стерео, fltp, 128 кбит/с
Метаданные:
кодировщик : Lavc59.18.100 aac
[dshow @ 0000021f52001a40] передача пакета типа видео размером 143852 временной метки 2766128396429 оригинальная временная метка 2766128396429 временная метка графа 2766128410000 разница 13571 USB Video
[dshow @ 0000021f52001a40] передача пакета типа видео размером 144527 временной метки 2766128729762 оригинальная временная метка 2766128729762 временная метка графа 2766128760000 разница 30238 USB Video
frame= 16 fps=0.0 q=45.0 size= 0kB time=00:00:00.44 битрейт= 0.9kbits/s dup=3 drop=0 speed=0.613x
...
[q] команда получена. Выход.
Пожалуйста, увеличьте значения параметров -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
Устранение неполадок:
Если сможете, проверьте режимы устройства USB Video с помощью ffmpeg:
ffmpeg -f dshow -list_options true -i video="USB Video"
А затем вручную сопоставьте действительные параметры, полученные из вышеприведенного вывода, в ffmpeg. Например, чтобы захватить 1080p видео со скоростью 30 кадров в секунду с образца камеры, вы можете использовать:
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
Это может помочь снизить любые накладные расходы на обработку, выбрав вручную разрешения и кодеки, которые напрямую поддерживаются захватывающим устройством. Смотрите этот ответ для получения дополнительных советов по этому вопросу.
Затем повторно протестируйте и дайте обратную связь.
Ответ или решение
Решение проблемы: «FFmpeg: h264_qsv медленнее, чем libx264 (ошибка переполнения реального времени)»
Введение
Проблема медленной работы кодека h264_qsv
по сравнению с libx264
в FFmpeg может возникнуть по разным причинам, даже при наличии доступных ресурсов процессора. Пользователи могут столкнуться с сообщением об ошибке "реальное время буфер переполнен", особенно когда общее использование CPU достигает 100%. В данном ответе рассматриваются возможные причины данной ситуации и предлагаются рекомендации по оптимизации.
Описание конфигурации и проблематики
Вы используете систему на базе Windows 10 IoT с процессором Intel Celeron N3350E и программой FFmpeg для захвата видео с USB-устройств. Ваша первая команда, использующая кодек libx264
, указывает на высокую загрузку CPU (60-80%) и отсутствие загрузки GPU (0%). Применение команды, использующей h264_qsv
, приводит к снижению загрузки CPU до 50% и увеличению загрузки GPU до 50%, но ошибка "реальное время буфер переполнен" продолжает возникать, даже при общем использовании CPU менее 100%.
Возможные причины медленной работы h264_qsv
-
Настройки буфера занятости: Ошибка о переполнении буфера может указывать на недостаток ресурсов, выделенных для обработки видеопотока. Если количество кадров, поступающих от устройства захвата, превышает пропускную способность обработки, возникает ошибка.
-
Совместимость устройства захвата: Не все устройства захвата оптимально работают с определенными форматами видео или частотой кадров. Возможно, кодек
h264_qsv
требует другой конфигурации ввода, чемlibx264
. -
Неправильные параметры кодировки: Использование неверных параметров кодирования также может повлиять на производительность. Оптимальные параметры кодирования и настройки фильтров могут существенно улучшить ситуацию.
Рекомендации и оптимизация
Для решения вышеописанных проблем рекомендуется внести изменения в ваши команды. Приведенные ниже настройки учитывают определенные аспекты, такие как увеличение возможностей буфера и управление очередями потоков.
-
Увеличение параметров
-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 -f dshow -list_options true -i video="USB Video"
Определите, какие параметры поддерживаются, и при необходимости адаптируйте команду кодирования с использованием этих параметров.
-
Ручная установка параметров ввода: Если ваше устройство поддерживает возможность ручного указания разрешения и частоты кадров, это может уменьшить вычислительные нагрузки. Например:
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
Заключение
Эти шаги могут существенно повысить производительность вашего кодирования с использованием h264_qsv
и снизить вероятность ошибок, связанных с переполнением буфера. Если проблема не устраняется после этой оптимизации, могут потребоваться дополнительные исследования совместимости вашего оборудования или тестирование с другими источниками видеопотока.