FFMPEG 4.0 saltando marcos

Hoy me di cuenta de que cuando uso ffmpeg 4.0 estable para decodificar algunos archivos TS en y4m o ffv1, ocasionalmente se saltan algunos cuadros. Mi archivo de entrada tiene todos los fotogramas grabados en la imagen y estoy extrayendo algunos fotogramas a intervalos regulares. A veces funciona bien sin ningún cuadro saltado, pero a veces salta uno o dos cuadros. Estoy usando el siguiente comando para decodificar mi entrada:

ffmpeg -i input.ts -vsync 0 output.y4m

y estoy extrayendo los marcos usando:

ffmpeg -ss xxx -i output.y4m -vframes 1 xxx.png

Estoy sustituyendo xxx con 0, 100, 200, etc. y, a veces, veo que se pierden 1-2-3 fotogramas, lo que es muy molesto porque estoy tratando de evaluar el PSNR después y esto estropea toda la evaluación del PSNR/SSIM.

[EDITAR] He ejecutado el comando que sugirió @Gyan:

ffmpeg -v 99 -loglevel 99 -i test.ts \
-c:v rawvideo -vsync 0 \
-enc_time_base 1/1000 output.nut &> test.log

Y aquí está el archivo de registro test.log

Respuestas (1)

Y4M no tiene marcas de tiempo, solo velocidad de fotogramas en su encabezado. Entonces, si su fuente tiene alguna variabilidad en su velocidad de fotogramas, verá un cambio en la marca de tiempo aparente en el Y4M.

p.ej

n     src     y4m
0       0       0
1    0.04    0.04 
2    0.07    0.08
3    0.12    0.12
4    0.21    0.16
5    0.24    0.20
6    0.27    0.24 
...

Durante un largo período, estas perturbaciones pueden sumarse. Aquí, el marco #6 en src está en TS de src #5 en Y4M.

Editar : el archivo TS de muestra tiene marcas de tiempo VFR.

Usar -c:v rawvideo -vsync 0 -vf setpts=N/FRAME_RATE/TB -any guardar en .nut.

Probé su solución y la ejecuté, ffmpeg -i input.ts -c:v rawvideo -vsync 0 -enc_time_base 1/1000 output.nutpero desafortunadamente pierdo un cuadro cada ~ 1000 cuadros y esta es una pérdida bastante constante. Intenté agregar -an, eliminar -enc-time-basepero siempre deja caer un cuadro cada ~ 1000 cuadros. De hecho, ffmpeg 3.2.4 funciona mejor en este sentido y no pierde fotogramas con la misma entrada.
Comparte el registro completo de tu comando.
He subido el archivo test.log usando un enlace de wetransfer. Es bastante voluminoso: 19Mb y mi secuencia de video original tiene ~37000 fotogramas. El enlace y el comando se podían ver en mi publicación original, en la sección EDITAR.
¿Puedes compartir el archivo fuente?
puedes descargarlo desde aquí @Gyan
¿Puedes subirlo a otro lado? Wetransfer es muy lento. Drive o Dropbox, etc.
No se puede reproducir. Corrí ffmpeg -i input.ts -vsync 0 output.y4my luego ffmpeg -ss xxx -i output.y4m -vframes 1 xxx.pngy ffmpeg -ss xxx -i input.ts -vframes 1 xxx-ts.pngpara comparar. Obtengo el mismo marco para 5-6 valores que probé. ¿Puedes identificar algunos ssvalores que muestren el problema?
Si está usando: ffmpeg -i test.ts -c:v rawvideo -vsync 0 -enc_time_base 1/1000 output.nutObtengo aproximadamente una caída de fotogramas cada 1000 fotogramas. Puede intentar extraer los fotogramas cada 3000 fotogramas (60 segundos). Creo que la duración total es de 5 minutos, por lo que puede usar -ss 0 - para obtener el primer cuadro de la secuencia y luego -ss 60, -ss 120, -ss 180, -ss 240, -ss 300. Con ffmpeg -i input.ts -vsync 0 output.y4mestoy obteniendo más caídas aleatorias, a veces es solo un cuadro durante toda la duración, a veces más. Tenga en cuenta que en realidad el archivo está en bucle y hay un marco omitido: 14998.
Puede confirmar fácilmente comparando el número de fotograma grabado de los fotogramas extraídos y debería tener exactamente 3000 fotogramas de diferencia entre los fotogramas exportados en caso de que utilice -ss 0, -ss 60, etc.
Ver cmd editado.
Gracias @Gyan, revisaré más tarde el comando actualizado, pero la velocidad de fotogramas variable no explica por qué el ffmpeg -i input.ts -vsync 0 output.y4mcomando a veces saltaba uno o dos fotogramas o, a veces, funcionaba perfectamente bien. ¿Cómo comprobó también el archivo para VFR y CFR? ¿Hay un comando en ffprobe para verificarlo?
Hay un filtro agregado recientemente: vfrdet . Para la muestra, muestra VFR:0.400005 (15185/22777) min: 1801 max: 3604). El 40% de los fotogramas tienen una duración no estándar. Todos deberían tener 1800 unidades en este archivo.
Tienes toda la razón, @Gyan, probé tu comando y funciona muy bien, también probé el detvfrfiltro y me mostró la desviación. Me pregunto por qué el archivo TS tiene VFR, ya que lo grabé con ffmpeg y estoy bastante seguro de que la entrada tiene CFR. ¿Debo usar -reel comando de grabación en este caso para preservar la velocidad de fotogramas de entrada (duración)? ¿Puede sugerir también un comando de grabación que no corte el relleno nulo (relleno) del TS?
TS es un contenedor VFR, por lo que en la salida debe agregar -vsync cfry también -rsi ese valor es diferente de los fps de entrada nominales.
¿Y qué pasa con la preservación del relleno nulo en la salida? De forma predeterminada, ffmpeg está borrando todos los PID nulos, lo que está creando errores de PCR en la transmisión grabada, ¿es posible conservarlos?
¿Te refieres al crear el TS o al transferir a NUT?
¿Cuándo estoy haciendo la grabación de TS? ¿Hay alguna manera de decirle a ffmpeg que no recorte el relleno nulo?
¿Ha agregado -muxrate?
suponiendo que estoy haciendo una grabación de TS desde Internet, ¿debo probar primero la tasa de MUX y luego configurarla en el comando de grabación? Y si es así, ¿cómo puedo sondear la tasa mux con ffmpeg? ¿Y qué sucede si el flujo de entrada no es CBR sino VBR con tasa de bits variable pero aún así algo de relleno de almohadilla nula?