¿Qué significa 'Duración pasada X.XXX demasiado grande'?

142

Al codificar H.264 con ffmpeg, recibo el siguiente tipo de advertencias en masa:

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

¿Qué quieren decir? No he encontrado nada claro en línea o en la documentación de ffmpeg.

Erik
fuente
2
Dirija las preguntas de ffmpeg a video.stackexchange.com beta. Ver la descripción de la etiqueta ffmpeg.
Ondra Žižka
34
@Ondra ¿Incluso otro intercambio de pila? Me estoy confundiendo con esos más de 100 subsitios, no estoy seguro de si esa es una dirección positiva a la que se dirige el intercambio de pila.
mxmlnkn
1
@mxmlnkn Estoy de acuerdo, te hace anhelar tiempos más simples ... :)
Erik
44
Creo que es. StackOverflow es para programar, esto no es programar. Hay un sitio de preguntas y respuestas para el procesamiento de video, esta es una pregunta sobre el procesamiento de video. ¿Qué no hay que entender?
Ondra Žižka
Lea también la descripción de la etiqueta.
Ondra Žižka

Respuestas:

23

Estaba recibiendo miles de estas advertencias con una codificación particular. Estaba reduciendo el tamaño del video de 1080p a 480p. En un punto de edición, donde había un video dudoso debido a un defecto en el disco láser de origen, estos mensajes comenzaron a aparecer y luego aparecieron, creo, para cada cuadro a partir de entonces. Siguieron y siguieron, como este breve extracto:

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

La invocación original de ffmpeg fue esta:

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

Siguiendo las sugerencias aquí, primero agregué -framerate 60000/1001 a la entrada. Eso no mejoró nada. Retuve -framerate y agregué -r 60000/1001 a la salida. Eso todavía no mejoró nada. Reteniendo ambos, finalmente agregué -async 1 -vsync 1. Esto resultó en que recibí una sola advertencia, y eso es todo. Esa invocación fue:

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

La única diferencia que encontré en un volcado detallado de MediaInfo fue la eliminación de esta línea encontrada en la invocación original pero no en la segunda:

Delay relative to video                  : -33ms

Sin embargo, verifiqué la sincronización de A / V cerca del comienzo de los archivos y cerca del final, y no hubo diferencias apreciables en la sincronización entre los dos archivos. Sus tiempos de ejecución también fueron los mismos, pero eso solo se midió al segundo más cercano, en VLC. Así que verifiqué los recuentos de cuadros usando ffmpeg así:

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

y buscando "frame = #" cerca del final de la salida.

Resulta que el video fuente tenía 375226 cuadros de largo, la invocación original produjo 375195 cuadros, y la segunda invocación produjo 375200. Entonces, la segunda invocación, con muchos menos mensajes de advertencia, también dejó caer 5 cuadros menos.

Las pruebas posteriores mostraron que -framerate y -r eran innecesarios, y solo usar los dos indicadores de sincronización era suficiente. Esto produjo resultados idénticos a la segunda invocación anterior, por lo que la tercera y más simple invocación que encontré para resolver el problema es esta:

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

Y otro archivo posteriormente produjo un montón de estas advertencias incluso con los indicadores de sincronización, pero al agregar nuevamente los indicadores de velocidad "lo arregló" (solo produjo dos en lugar de miles de advertencias). Entonces, a veces la segunda invocación funciona cuando la tercera no. Para mis propósitos inmediatos, me voy a conformar con la segunda invocación y espero que solucione la mayoría de estos problemas.

Todo esto con la versión 4.0 de ffmpeg.

larryy
fuente
2
¡Gracias por esto! Después de días de tener problemas, lo -async 1 -vsync 1arregló para mí.
Offek
1
Gracias por este análisis @larryy muy útil
deepelement
90

Uno de los encargados del proyecto DVDStyler en SourceForge dijo esto al respecto:

Las versiones de FFMpeg posteriores al 15 de enero de 2015 a menudo muestran esta advertencia. Se ha agregado para advertir sobre la posible distorsión del control de velocidad, de lo contrario no causa ningún daño.

Josh Davis
fuente
la 'distorsión de control de velocidad' está relacionada con la codificación (principalmente de video) y no tiene relación con esta advertencia, que se trata de si la marca de tiempo de salida difiere demasiado (relativamente) en comparación con la marca de tiempo de entrada
Gyan
Las primeras veces que recibí la advertencia terminé la conversión, pero este consejo me hizo dejarla correr y las advertencias se detuvieron después de un tiempo y la conversión se completó con éxito. Gracias.
IRTFM
58

Este mensaje de advertencia aparece cuando se trata de codificar una fuente de alta velocidad de cuadros a una salida de baja velocidad de cuadros, lo que significa que los cuadros deben descartarse.


Tuve este error porque quería convertir una serie de imágenes en un video:

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

El problema parece ser que si no se proporciona una velocidad de cuadro para la entrada, se supone una velocidad de cuadro de 25 fps:

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

Esto también se puede ver en el número total de cuadros codificados. Tenía 400 imágenes, pero el comando anterior solo codificó 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%

Los mensajes de error desaparecen al establecer la velocidad de fotogramas de entrada si la velocidad de fotogramas de salida. La velocidad de fotogramas de salida se elegirá automáticamente para que sea la de la entrada. Además en las últimas versiones de ffmpeg hay que tener cuidado, porque al usar imágenes PNG con el -ila opción o bien image2o v4l2formato de entrada, usted tiene que usar -framerateen lugar de -r, consulte la documentación de la -ropción .

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

También es posible especificar la velocidad de fotogramas de entrada y salida por separado:

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

En este caso, solo se codificarán 161/400 cuadros. Los otros cuadros provisionales se descartarán. También el mensaje de error desaparece, supongo que para no ralentizar ffmpeg enviando spam a stdout, vea:

mxmlnkn
fuente
3
"porque solo cuando se usan imágenes PNG con la opción -i, debe usar -framerate en lugar de -r" - esto resolvió mi problema por completo, ¡gracias!
Anónimo
1
Al tratar de convertir un wmv a mp4, el uso -rfuncionó donde el uso -framerateno lo hizo.
1934286
+1 y le sugiero que mueva su "resumen" en la parte superior. Más, ya que resolvió mi caso de convertir imágenes a video e intentar aumentar la velocidad de fotogramas de salida y acelerar la salida también. Empecé de esto 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"a esto sin más advertencias 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"(tenga en cuenta lo -framerate 50agregado como entrada)
el-teedee
49

Mirando el código fuente observar , parece ser que la diferencia entre el tiempo de presentación (pts) en la secuencia de entrada difiere de la de la secuencia de salida en más de un límite fijo establecido en 0.6.

Fragmentos de la fuente:

    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;
    }

Esto es solo un vistazo rápido, así que siéntase libre de cavar más profundo.

Erik
fuente
¿Hay algo que podamos hacer para "solucionar" este problema o establecer explícitamente los puntos de salida?
Baodad
1
No recuerdo los detalles que rodean este problema, pero si por "arreglar" te refieres a deshacerte de la advertencia, entonces, según el código anterior, podrías buscar la opción format_video_sync = VSYNC_DROPo format_video_sync = VSYNC_PASSTHROUGHver si uno de ellos es viable en tu caso de uso.
Erik
Gracias. Descubrí que la configuración de la velocidad de fotogramas explícitamente usando el -rinterruptor "reparó" estas advertencias.
Baodad
1
Solo algo por experiencia personal: tuve el problema de spam de mensajes de "duración pasada" y lo arreglé forzando la velocidad de cuadros de entrada con -r 25, pero luego comencé a sincronizar mucho el audio. La eliminación de la opción -r y el uso de "-async 1 -vsync 1" para evitar la desincronización de audio ha evitado el problema de audio, pero el spam de "duración pasada" parece haber desaparecido también.
Jason Lang
En v 4.1 y posterior, el nivel de registro se ha actualizado, por lo que no aparecerá en el nivel de registro predeterminado.
Gyan
1

El comando en realidad debería ser:

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

No hay un prefijo "-" para el parámetro "silencioso", ya que no es una opción, sino un valor para la opción "-loglevel".

Gordon McCrae
fuente