Что означает «Прошлая продолжительность X.XXX слишком велика»?

150

При кодировании H.264 с использованием ffmpeg я получаю массовые предупреждения следующего типа:

Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large

Что они имеют в виду? Я не нашел ничего ясного в Интернете или в документации ffmpeg.

Эрик
источник
2
Направляйте вопросы о ffmpeg на бета-версию video.stackexchange.com . См. Описание тега ffmpeg.
Ondra ižka
36
@Ondra Еще одна стековая биржа? Меня путают эти 100+ дочерних сайтов, я не уверен, что это положительное направление, в котором движется stackexchange.
mxmlnkn
1
@mxmlnkn Я согласен, это заставляет вас тосковать по более простым временам ... :)
Эрик,
5
Я думаю, что это. StackOverflow предназначен для программирования, а не для программирования. Есть сайт вопросов и ответов по обработке видео, это вопрос по обработке видео. Что не понимать?
Ondra
Также прочтите описание тега.
Ондра Жижка

Ответы:

24

Я получал тысячи этих предупреждений с определенным кодом. Я уменьшал видео 1080p до 480p. В точке редактирования, где было какое-то сомнительное видео из-за дефекта исходного лазерного диска, эти сообщения начали появляться, а затем появлялись, я думаю, для каждого последующего кадра. Они продолжали и продолжали, как этот короткий отрывок:

Past duration 0.901115 too large=  535031kB time=00:54:15.06 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 31 times
Past duration 0.901115 too large=  535031kB time=00:54:15.62 bitrate=1346.3kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 34 times
Past duration 0.901115 too large=  535031kB time=00:54:16.21 bitrate=1346.0kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 36 times
Past duration 0.901115 too large=  535338kB time=00:54:16.83 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 39 times

Первоначальный вызов ffmpeg был таким:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv

Следуя рекомендациям здесь, я сначала добавил -framerate 60000/1001 на вход. Это ничего не улучшило. Я сохранил -framerate и добавил к выводу -r 60000/1001. Это все равно ничего не улучшило. Сохранив оба, я наконец добавил -async 1 -vsync 1. В результате я получил одно предупреждение, и все. Этот призыв был:

ffmpeg -i input.mp4 -framerate 60000/1001 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -r 60000/1001 -async 1 -vsync 1

Единственное отличие, которое я обнаружил в подробном дампе от MediaInfo, - это удаление этой строки, обнаруженной в исходном вызове, но не во втором:

Delay relative to video                  : -33ms

Однако я проверил синхронизацию аудио и видео в начале и в конце файлов, и не было заметной разницы в синхронизации между двумя файлами. Их время работы также было таким же, но оно измерялось только с точностью до секунды в VLC. Поэтому я проверил количество кадров с помощью ffmpeg вот так:

ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -

и ищем "frame = #" ближе к концу вывода.

Оказывается, исходное видео было длиной 375226 кадров, исходный вызов дал 375195 кадров, а второй вызов дал 375200. Таким образом, второй вызов с гораздо меньшим количеством предупреждений также потерял на 5 кадров меньше.

Последующее тестирование показало, что -framerate и -r не нужны, и достаточно использовать два флага синхронизации. Это дало результаты, идентичные результатам второго вызова выше, поэтому третий и самый простой вызов, который я обнаружил для решения проблемы, таков:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -async 1 -vsync 1

И еще один файл впоследствии выдал кучу этих предупреждений даже с флагами синхронизации, но добавление обратно флагов скорости «исправило» это (выдало только два предупреждения вместо тысяч). Поэтому иногда второй вызов срабатывает, а третий - нет. Для моих непосредственных целей я остановлюсь на втором вызове и надеюсь, что он решит большинство этих проблем.

Все это было с ffmpeg версии 4.0.

Ларри
источник
2
Спасибо тебе за это! После нескольких дней проблем -async 1 -vsync 1исправил это для меня.
Offek
1
Спасибо за этот анализ @larryy очень полезно
deepelement
Спасибо за подробный ответ. Не могли бы вы также объяснить, что на самом деле делают эти флаги синхронизации?
Фриц
91

Один из сопровождающих для проекта DVDStyler на SourceForge сказал это об этом:

В версиях FFMpeg после 15 января 2015 г. это предупреждение часто отображается. Он был добавлен, чтобы предупредить о возможных искажениях регулятора скорости, иначе это не причинит никакого вреда.

Джош Дэвис
источник
«искажение управления скоростью» связано с кодированием (в основном видео) и не имеет отношения к этому предупреждению, которое касается того, не отличается ли выходная временная метка слишком сильно (относительно) по сравнению с входной временной меткой
Гиан
Первые несколько раз я получал предупреждение, что я прервал преобразование, но этот совет заставил меня запустить его, и через некоторое время предупреждения прекратились, и преобразование завершилось успешно. Спасибо.
IRTFM
59

Это предупреждающее сообщение появляется при попытке кодировать источник с высокой частотой кадров в вывод с низкой частотой кадров, что означает необходимость отбрасывания кадров.


У меня была эта ошибка, потому что я хотел преобразовать серию изображений в видео:

ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv

Проблема, по-видимому, в том, что если для входных данных не указана частота кадров, то предполагается частота кадров 25 кадров в секунду:

Input #0, image2, from 'frames/%04d.bmp':
  Duration: 00:00:15.96, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: bmp, bgra, 920x650, 25 fps, 25 tbr, 25 tbn, 25 tbc

Это также можно увидеть по общему количеству закодированных кадров. У меня было 400 изображений, но приведенная выше команда закодировала только 384:

frame=  384 fps= 68 q=-1.0 Lsize=   10931kB time=00:00:15.91 bitrate=5626.1kbits/s dup=0 drop=15    
video:10928kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033807%

Сообщения об ошибках исчезают, если вместо выходной частоты кадров устанавливается частота кадров на входе. После этого частота кадров вывода будет автоматически выбрана равной частоте кадров ввода. Кроме того, в более новых версиях ffmpeg вам нужно остерегаться, потому что при использовании изображений PNG с -iопцией или, скорее, входным форматом image2или v4l2вы должны использовать -framerateвместо -r, см. Документацию по этой -rопции .

ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv

Также можно указать частоту кадров для ввода и вывода отдельно:

ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv

В этом случае будут закодированы только 161/400 кадров. Остальные промежуточные кадры будут отброшены. Также сообщение об ошибке исчезает, я думаю, чтобы не замедлять ffmpeg, отправляя спам на stdout, см.:

mxmlnkn
источник
3
«потому что только при использовании изображений PNG с параметром -i вы должны использовать -framerate вместо -r» - это полностью решило мою проблему, спасибо!
Anonymous
1
При попытке конвертировать wmv в mp4 использование -rсработало, а использование - -framerateнет.
1934286
+1 и я предлагаю переместить ваше «резюме» наверх. Более того, поскольку он решил мой случай преобразования изображений в видео и попыток увеличить частоту кадров вывода, а также ускорить вывод. Я начал с этого ffmpeg -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"до этого без предупреждения ffmpeg -framerate 50 -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"(обратите внимание на -framerate 50добавленное для ввода)
el-teedee
50

Глядя на исходный код, кажется, что разница между временем представления (pts) во входном потоке отличается от времени в выходном потоке более чем на фиксированный предел, равный 0,6.

Фрагменты из источника:

    delta0 = sync_ipts - ost->sync_opts;
    delta  = delta0 + duration;

...

        if (delta0 < 0 &&
        delta > 0 &&
        format_video_sync != VSYNC_PASSTHROUGH &&
        format_video_sync != VSYNC_DROP) {
        double cor = FFMIN(-delta0, duration);
        if (delta0 < -0.6) {
            av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
        } else
            av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
        sync_ipts += cor;
        duration -= cor;
        delta0 += cor;
    }

Это только беглый взгляд, поэтому не стесняйтесь копать глубже.

Эрик
источник
Что мы можем сделать, чтобы «исправить» эту проблему, или явно установить выходные значения?
Baodad
1
Я не помню подробностей, связанных с этой проблемой, но если под «исправлением» вы имеете в виду избавление от предупреждения, то, основываясь на приведенном выше коде, вы можете изучить вариант format_video_sync = VSYNC_DROPили format_video_sync = VSYNC_PASSTHROUGHпосмотреть, подходит ли один из них для вашего варианта использования.
Эрик
Спасибо. Я обнаружил настройку частоты кадров явно с помощью -rпереключателя «исправил» эти предупреждения.
Baodad 02
1
Просто кое-что из личного опыта: у меня была проблема со спамом сообщений «прошедшей продолжительности», и я исправил ее, установив частоту входных кадров с помощью -r 25, но затем я начал сильно рассинхронизировать звук. Удаление опции -r и использование «-async 1 -vsync 1» для предотвращения рассинхронизации звука предотвратило проблему со звуком, но спам «прошедшей продолжительности», похоже, тоже исчез.
Джейсон Лэнг
В версии 4.1 и новее уровень журнала был обновлен, поэтому он не будет отображаться на уровне журнала по умолчанию.
Гьян
1

На самом деле команда должна быть:

ffmpeg -loglevel quiet -i input_file.xyz ...

У параметра «quiet» нет префикса «-», так как это не опция, а значение для опции «-loglevel».

Гордон МакКрэй
источник