tipos - ¿Pueden los ffmpeg av libs devolver un PTS preciso?
riesgos electricos seguridad e higiene (3)
Estoy trabajando con una secuencia de mpeg que usa una secuencia IBBP ... GOP. Los valores (DTS, PTS) devueltos para los primeros 4 AVPackets son los siguientes: I = (0,3) B = (1,1) B = (2,2) P = (3,6)
El PTS en el cuadro I parece legítimo, pero el PTS en los cuadros B no puede ser correcto, ya que los cuadros B no deberían mostrarse antes del cuadro I como lo indican sus valores PTS. También intenté decodificar los paquetes y usar el valor pts en el AVFrame resultante, puse que el PTS siempre se establece en cero.
¿Hay alguna forma de obtener un PTS exacto de ffmpeg? Si no, ¿cuál es la mejor manera de sincronizar el audio?
Ok, rasca mi respuesta confusa anterior.
Para una película de IBBPBBI, es de esperar que los PTS se vean así (en orden de decodificación)
0, 3, 1, 2, 6, 4, 5, ...
correspondiente a los marcos
I, P, B, B, I, B, B, ...
Parece que le falta un I al comienzo de la secuencia, pero las marcas de tiempo se ven correctas.
Creo que finalmente descubrí lo que sucede a partir de un comentario hecho en http://www.dranger.com/ffmpeg/tutorial05.html :
ffmpeg reordena los paquetes para que el DTS del paquete procesado por avcodec_decode_video () siempre sea el mismo que el PTS del marco que devuelve
Traducción: Si introduzco un paquete en avcodec_decode_video () que tiene un PTS de 12, avcodec_decode_video () no devolverá el marco decodificado contenido en ese paquete hasta que lo alimente un paquete posterior que tenga un DTS de 12. Si el PTS del paquete es al igual que su DTS, entonces el paquete dado es el mismo que el marco devuelto. Si el PTS del paquete es 2 fotogramas más tarde que su DTS, entonces avcodec_decode_video () retrasará el fotograma y no lo devolverá hasta que proporcione 2 paquetes más.
En función de este comportamiento, supongo que av_read_frame () tal vez reordene los paquetes de IPBB a IBBP, de modo que avcodec_decode_video () solo tenga que almacenar en búfer los cuadros P para 3 cuadros en lugar de 5. Por ejemplo, la diferencia entre la entrada y la salida del cuadro P con este orden es 3 (6 - 3):
| I B B P B B P
| DTS: 0 1 2 3 4 5 6
| decode() result: I B B P
frente a una diferencia de 5 con el orden estándar (6 - 1):
| I P B B P B B
| DTS: 0 1 2 3 4 5 6
| decode() result: I B B P
<encogerse /> pero eso es pura conjetura.
Estoy bastante seguro de que está obteniendo valores precisos. Podría ser útil si piensas en una transmisión MPEG como, bueno, una transmisión. En ese caso, antes del IBBPBB que ves normalmente habría otro GOP. Tal vez algo así (usando la misma notación que la pregunta original):
P(-3,-2) B(-2,-1) B(-1,0)
Básicamente, los cuadros B después de los cuadros I se basan en el cuadro I y el último cuadro P del GOP anterior .
Si bien tiene sentido lógico que un video comience con esto:
Start GOP: IPBBPBBPBB...
Más tarde debe ser
Start GOP: IBBPBBPBBPBB
Start GOP: IBBPBBPBBPBB
Start GOP: IBB...
Recuerde que decodificar cualquier cuadro B requiere un cuadro completo antes y después de él. Por lo tanto, cada par de fotogramas B debe mostrarse antes del fotograma I o P justo antes de este en el archivo.
FFMPEG puede haber olvidado el "caso especial" del primer GOP.
Como los primeros dos fotogramas B no tienen un fotograma previo para manipular, debe poder descartarlos con seguridad. Simplemente restaure sus marcas de tiempo del primer fotograma I y ajuste la transmisión de audio la misma cantidad.
Si esto realmente dará como resultado una pérdida de fotogramas dependerá de la implementación de FFMPEG, pero el peor escenario es que pierda 83 milisegundos (2 fotogramas a 24 fotogramas por segundo).