FFmpeg использует слишком много памяти при повторении разделения, выбора, наложения

#performance #video #ffmpeg #scripting #video-processing

#Производительность #Видео #ffmpeg #сценарии #обработка видео

Вопрос:

Я бегу

 ffmpeg -i input.mp4 -filter_complex_script script.txt output.mp4
  

со следующим минимальным примером сценария:

 split[tmp],
select='between(t,1,2)',
select='between(n,0,1)',
[tmp]overlay=enable='between(t,1,2)':eof_action=repeat,
split[tmp],
select='between(t,3,4)',
select='between(n,0,1)',
[tmp]overlay=enable='between(t,3,4)':eof_action=repeat
  

Что я хочу сделать, так это взять 1 кадр в определенной позиции и повторять его в течение определенной продолжительности, в основном «приостанавливая» видео, при перезаписи, чтобы сохранить ту же выходную длину. В примере я делаю это дважды: я использую split[tmp] для получения второго входного потока для работы, выбираю время в позиции 00:01 с select='between(t,1,2)' помощью , выбираю первый кадр из этой позиции с select='between(n,0,1)' помощью и, наконец, накладываю этот кадр на ввод. Это повторяется во второй раз в позиции 00:03. Я протестировал это, и это делает именно то, что я ищу.

Однако в моем реальном скрипте я повторяю это около 1000 раз для разных позиций в потоке (и для более коротких периодов, чем 1 секунда), что приводит к нехватке памяти. Что я делаю не так? Что я могу сделать для оптимизации?

Ответ №1:

Фильтры в ffmpeg работают в основном с кадрами, а не с потоком. Таким образом, каждый фильтр выбора будет оценивать каждый кадр, даже если вы знаете, что только несколько кадров в начале будут иметь право на выбор. Выполнение этого 1000 раз не является ресурсоемким.

Для вашего варианта использования вам не нужна большая часть этого. Подойдет только один фильтр выбора.

select='if(eq(n,0),1,not((between(t,1.0,1.999) between(t,3.0,3.999) between(t,5.0,5.999))*eq(floor(t),floor(prev_selected_t))))'

Это позволит сохранить все кадры за пределами диапазонов [1-1.999], [3-3.999] и [5-5.999] и первые кадры внутри этих диапазонов. Если ваш формат вывода требует постоянной частоты кадров, ffmpeg будет дублировать кадры для заполнения пробелов во временных метках.