1

Я использую ffmpeg для извлечения 3 кадров в секунду с помощью этой команды

ffmpeg -i input.flv -f image2 -vf fps=fps=3 out%d.png

Мне интересно, если я устанавливаю значение fps, то как ffmpeg выбирает 3 кадра в секунду. Это случайный или первые 3 кадра в эту секунду? Любая помощь?

1 ответ1

3

Это достигается путем изменения масштаба отметки времени из входной временной базы (т. Е. FPS в виде дроби, например, 24 кадра в секунду станет 1/24) в выходную временную базу.

Сначала устанавливается временная база на основе запрошенного FPS:

link->time_base = av_inv_q(s->framerate);

При фильтрации количество выходных кадров рассчитывается на основе количества входных кадров в буфере, масштабируя это число между двумя временными базами, так что в основном кадры × ввод / вывод. Обратите внимание, что buf->pts - s->first_pts видимому, представляет собой количество кадров, а не фактическую разницу во времени PTS.

/* number of output frames */
delta = av_rescale_q_rnd(buf->pts - s->first_pts, inlink->time_base,
                         outlink->time_base, s->rounding) - s->frames_out ;

Так, например, при временной базе ввода 0,042 (24 кадра в секунду), выходе 0,33 (3 кадра в секунду), и у вас есть 12 кадров ввода в буфере, вы получите 12 × 0,042 / 0,33 кадра, который округляется до ближайшего ближайшего целое число 2 - таким образом, два кадра должны быть сгенерированы. Если у вас 24 кадра, вы получите, конечно, три кадра. Для 35 кадров во входном буфере вы получите четыре выходных кадра.

Если эта дельта меньше 1, кадры в буфере могут быть отброшены, поскольку в этом временном интервале кадр не требуется. Если, с другой стороны, дельта больше единицы, это количество кадров, которое необходимо вывести для входного буфера.

Для новых кадров значение PTS масштабируется на основе времени ввода и вывода:

buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base,
                                outlink->time_base) + s->frames_out;

На практике это означает, что вам придется смотреть на PTS вашего входного видео, делать расчеты того, сколько кадров в секунду может иметь ваш вывод, а затем распределять их равномерно, отбрасывая кадры по мере необходимости. Если вы хотите быть очень точным, я бы порекомендовал отладку исходного кода с помощью нескольких тестовых видео.

Боюсь, я не могу придумать более практичного решения, чем ответ, который я опубликовал здесь недавно, в котором я объясняю, как показать PTS каждого кадра в видео, частота кадров которого была изменена:

ffmpeg -i input.mp4 -t 10 -filter:v "fps=fps=25, showinfo" -f null - 2>&1 grep pts_time | awk '{print $6}' | cut -d: -f2

Эти временные метки принадлежат каждому выходному кадру и соответствующему ему входному времени PTS.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .