Что означает «Прошлая продолжительность 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, см.:


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».


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.