- Вопрос или проблема
- Ответ или решение
- Управление потоками и буферизацией в FFMPEG: Оптимальная конфигурация с использованием -thread_queue_size и pipe:
- Параметр -thread_queue_size
- Эффективная архивация и низкая задержка
- Оценка эффективности и контроль за ресурсами
- Точки синхронизации и временные метки
- Заключение
Вопрос или проблема
Я обнаружил значение thread_queue_size, которое, кажется, работает на моей системе для этого случая использования, но я буду тестировать больше (или повторять тесты), чтобы помочь делу, если кто-то сможет что-то подсказать. Пожалуйста, дайте совет. Спасибо, Марк.
thread_queue_size 24883200 (чтобы избежать “Блокировки очереди сообщений потока”)
Командная строка – VapourSynth (VSPIPE) передает сырые кадры, а FFMPEG извлекает аудио и субтитры из конкатенации VOB-файлов, таким образом:
VSPIPE --y4m C:\AVout\VTS_04_1(210820-023517.49).mkv.vpy - | FFMPEG -thread_queue_size 24883200 -i pipe: -i "concat:h:\VIDEO_TS\VTS_04_1.VOB|h:\VIDEO_TS\VTS_04_2.VOB|h:\VIDEO_TS\VTS_04_3.VOB|h:\VIDEO_TS\VTS_04_4.VOB|h:\VIDEO_TS\VTS_04_5.VOB|h:\VIDEO_TS\VTS_04_6.VOB" -filter_complex "[0:v]settb=expr=1/120,setpts=expr=N,setdar=16/9,setsar=32/27[v];[1:a:0]atempo=1.001[a0];[1:a:1]atempo=1.001[a1];[1:a:2]atempo=1.001[a2];[1:a:3]atempo=1.001[a3];[1:a:4]atempo=1.001[a4]" -map "[v]" -map "[a0]" -map "[a1]" -map "[a2]" -map "[a3]" -map "[a4]" -map 1:s -codec:v libx265 -x265-params "crf=18:qcomp=0.80:sao=no:strong-intra-smoothing=no" -codec:a:0 ac3 -codec:a:1 ac3 -codec:a:2 ac3 -codec:a:3 ac3 -codec:a:4 ac3 -codec:s copy -r 120 C:\AVout\VTS_04_1(210820-023517.49).mkv
Результат:
1, Транскодирование проходило со скоростью около speed=0.5.
2, В то время как оно выполнялось, VSPIPE доминировал над 8 потоками (в 2 раза по сравнению с FFMPEG), а “Системный резерв” (сумма используемой ОЗУ + используемой страницы) достиг максимума в 126.3 ГБ после постоянного роста.
3, Консольный вывод обратил внимание на “Ошибка: вызов fwrite() не удался при записи кадра: 331449, плоскость 2, errno: 22”. Трудно судить наверняка, но казалось, что сообщение об ошибке печаталось в тот же момент, когда “Системный резерв” достиг максимума. При воспроизведении видео зависает в тот момент: кадр 331449 (46:02.072) — должно быть 939036 кадров (2:10:25.305).
thread_queue_size 2048
Командная строка снова VapourSynth (VSPIPE), передающая сырые кадры и т.д. (но на этот раз с “-thread_queue_size 2048”) таким образом:
VSPIPE --y4m C:\AVout\VTS_04_1(210820-042617.65).mkv.vpy - | FFMPEG -thread_queue_size 2048 -i pipe: -i "concat:h:\VIDEO_TS\VTS_04_1.VOB|h:\VIDEO_TS\VTS_04_2.VOB|h:\VIDEO_TS\VTS_04_3.VOB|h:\VIDEO_TS\VTS_04_4.VOB|h:\VIDEO_TS\VTS_04_5.VOB|h:\VIDEO_TS\VTS_04_6.VOB" -filter_complex "[0:v]settb=expr=1/120,setpts=expr=N,setdar=16/9,setsar=32/27[v];[1:a:0]atempo=1.001[a0];[1:a:1]atempo=1.001[a1];[1:a:2]atempo=1.001[a2];[1:a:3]atempo=1.001[a3];[1:a:4]atempo=1.001[a4]" -map "[v]" -map "[a0]" -map "[a1]" -map "[a2]" -map "[a3]" -map "[a4]" -map 1:s -codec:v libx265 -x265-params "crf=18:qcomp=0.80:sao=no:strong-intra-smoothing=no" -codec:a:0 ac3 -codec:a:1 ac3 -codec:a:2 ac3 -codec:a:3 ac3 -codec:a:4 ac3 -codec:s copy -r 120 C:\AVout\VTS_04_1(210820-042617.65).mkv
Результат:
1, Транскодирование проходило со скоростью около speed=1.0 с “Блокировкой очереди сообщений потока; рассмотрите возможность увеличения параметра thread_queue_size (текущее значение: 2048)”.
2, В то время как VSPIPE выполнялся, именно FFMPEG (а не VSPIPE) доминировал (в 5 раз по сравнению с VSPIPE), и “Системный резерв” повысился, а затем стабилизировался всего на 5.9 ГБ.
3, С воспроизведением все в порядке.
Дополнительные запуски
Я уменьшил плохой thread_queue_size до 12441600, затем снова уменьшил его до 6220800 и т.д., в то время как я наблюдал за “Системным резервом” в каждом запуске. С каждым запуском, по мере снижения значения thread_queue_size, я увидел, что “Системный резерв” и использование ЦП начали уравновешиваться между VSPIPE и FFMPEG.
Итог
При “-thread_queue_size 48600” я снова начал получать “Блокировку очереди сообщений потока; рассмотрите возможность увеличения параметра thread_queue_size (текущее значение: 48600)”, и все стабилизировалось: FFMPEG и VSPIPE поменялись местами в доминировании над использованием ЦП (при этом FFMPEG теперь доминировал), и “Системный резерв” линейно увеличился до 28.5 ГБ и затем стабилизировался.
Мне кажется, что “Блокировка очереди сообщений потока” – это хорошая вещь — канал, который не будет переполнен, если (или когда) он будет работать долго. Есть ли лучший способ это обеспечить, кроме как корректировкой thread_queue_size?
Еще один момент, который я не понимаю: почему я продолжаю получать уведомления “Начало нового кластера из-за метки времени” — я предполагаю, что это от кодировщика — когда я сам записываю метки времени (через “settb=expr=1/120,setpts=expr=N”)?
Примечания:
Весь код и файлы находятся на твердотельном RAID0, Windows10, 4 двухъядерных процессора (8 потоков), 3.6 ГГц, 32 ГБ ОЗУ + 100ГиБ pagefile.sys.
Инструмент, используемый для мониторинга использования ЦП и “Системного резерва”: Sysinternals, Process Explorer v16.21.
Из https://ffmpeg.org/ffmpeg.html
-thread_queue_size size (входной)
Эта опция устанавливает максимальное количество очередных пакетов при чтении из файла или устройства. При потоках с низкой задержкой / высокой частотой пакеты могут быть отброшены, если их не прочитают вовремя; установка этого значения может заставить ffmpeg использовать отдельный входной поток и читать пакеты по мере их поступления. По умолчанию ffmpeg делает это только в том случае, если указано несколько входов.
Еще одна подсказка
В то время как оно выполнялось, VSPIPE доминировал над 8 потоками (в 2 раза по сравнению с FFMPEG), а "Системный резерв" (сумма используемой ОЗУ + используемой страницы) достиг максимума в 126.3 ГБ после постоянного роста.
Это проблема буферизации – ffmpeg не может обрабатывать кадры так быстро, как они поступают. Мы можем попробовать 3 решения.
a. Запишите на другой SSD/HDD, отличной от SSD/HDD входного файла. Это исключит скорости записи как параметр сбоя.
b. Поскольку вы используете Windows – начните процесс как
start /b /high "cmd"
c. Существует большая разница в скорости между именованными каналами и использованием анонимных каналов в Windows.
Из – http://trac.ffmpeg.org/ticket/986
стандартный ввод Windows очень медленный. Поэтому я переключился на именованные каналы. Это в 10 раз быстрее, чем стандартный ввод (pipe:).
Замените входы анонимных каналов -
и -i pipe:
на
-i \\.\pipe\pipename out.mkv
В Windows нет официальной утилиты cmd – вы можете использовать эту – github.com/psmay/windows-named-pipe-utils
Ответ или решение
Управление потоками и буферизацией в FFMPEG: Оптимальная конфигурация с использованием -thread_queue_size
и pipe:
Проблема, с которой вы столкнулись, является весьма распространенной при использовании FFMPEG
и VapourSynth
для обработки видео в реальном времени. Ваша задача заключается в оптимизации работы потоков и предотвращении блокировок в очередях сообщений, что может существенно влиять на производительность и качество выходного контента. В этом ответе мы рассмотрим ключевые аспекты работы с параметрами -thread_queue_size
и управлением трубами (pipe:
) для достижения лучшего результата.
Параметр -thread_queue_size
Параметр -thread_queue_size
задает максимальное количество пакетов, которое может быть подготовлено к передаче в поток обработчика. Это особенно важно при работе с высокоскоростными потоками или видео в реальном времени, когда пакеты должны обрабатываться без задержек. Как вы заметили, увеличение этого параметра до значения 24883200
(примерно 24 МБ) позволяло избежать блокировок, но вы столкнулись с чрезмерным использованием памяти (System Commit достигал 126.3 ГБ).
Проблема, которую вы описываете, может быть признаком недостаточной производительности обработки в реальном времени. Низкие значения -thread_queue_size
, например, 2048
или 48600
, могут привести к тому, что FFMPEG
не сможет обрабатывать данные так быстро, как они поступают, особенно если ваша система предлагает ограниченные ресурсы для обработки (в данном случае это 32 ГБ ОЗУ).
Эффективная архивация и низкая задержка
Для оптимизации пропускной способности и снижения использования памяти можно рассмотреть несколько рекомендаций:
-
Используйте другой диск для ввода-вывода: Если ваша система допускает, попробуйте указать другой SSD/HDD для ввода, чтобы минимизировать время доступа к диску.
-
Измените уровень приоритета процесса: Запуская процесс с помощью
start /b /high "cmd"
, вы можете обеспечить приоритет выполнения, что увеличит шансы на более быструю обработку пакетов. -
Именованные трубы: Вместо использования анонимных труб (например,
-i pipe:
), рассмотрите возможность использования именованных труб, которые предлагают значительно более высокую скорость передачи. Пример использования именованной трубы:-i \\.\pipe\pipename
Для создания именованных труб в Windows можно использовать утилиты, доступные на GitHub, такие как
windows-named-pipe-utils
.
Оценка эффективности и контроль за ресурсами
Ваши тесты с изменением значения параметра -thread_queue_size
, а также мониторинг использования памяти и процессора являются важными шагами для нахождения оптимального решения. Обратите внимание на следующие моменты:
- Анализируйте, когда именно происходят блокировки и на каком этапе.
- Убедитесь, что у вас достаточно процессорных ресурсов для обработки видео без задержек. Возможно, стоит использовать более мощный процессор или распределять нагрузку на несколько машин.
Точки синхронизации и временные метки
Относительно сообщений об ошибках, связанных с "Starting new cluster due to timestamp," это может указывать на то, что кодек или механизм записи не способен синхронизировать временные метки потоков, даже когда вы сами задаете временные метки. Параметры settb
и setpts
могут не приводить к ожидаемым результатам, если на входе для FFMPEG
время уже обрабатывается. Попробуйте проверять временные метки потоков на входе и убедитесь, что они не конфликтуют.
Заключение
Наилучший способ управления потоками в FFMPEG
заключается в сбалансированном подходе к конфигурации параметров, выбора оборудования и методов обработки данных. Постоянные испытания различных конфигураций с использованием как анонимных, так и именованных труб, помогут улучшить скорость транскодирования и минимизировать потребление ресурсов, достигая тем самым желаемого качества видео.