Können die ffmpeg av libs einen genauen PTS zurückgeben?

Ich arbeite mit einem MPEG-Stream, der eine IBBP ... GOP-Sequenz verwendet. Die (DTS, PTS) -Werte, die für die ersten 4 AV-Pakete zurückgegeben werden, sind wie folgt: I = (0,3) B = (1,1) B = (2,2) P = (3,6)

Der PTS auf dem I-Frame sieht aus, als wäre er legitim, aber dann kann der PTS auf den B-Frames nicht richtig sein, da die B-Frames nicht vor dem I-Frame angezeigt werden sollten, wie ihre PTS-Werte anzeigen. Ich habe auch versucht, die Pakete zu entschlüsseln und den pts-Wert im resultierenden AVFrame zu verwenden, setzen Sie, dass PTS immer auf Null gesetzt wird.

Gibt es eine Möglichkeit, eine genaue PTS aus ffmpeg zu bekommen? Wenn nicht, was ist dann der beste Weg, Audio zu synchronisieren?

0

2 Antworten

Ich denke, dass ich aufgrund eines Kommentars in http://www.dranger.com herausgefunden habe, was passiert. com/ffmpeg/tutorial05.html :

ffmpeg ordnet die Pakete neu an, so dass die DTS des Pakets, das von avcodec_decode_video() verarbeitet wird, immer das gleiche ist wie das PTS des Rahmens, den es zurückgibt

Übersetzung: Wenn ich ein Paket in avcodec_decode_video() füttere, das einen PTS von 12 hat, wird avcodec_decode_video() den dekodierten Rahmen, der in diesem Paket enthalten ist, nicht zurückgeben, bis ich ihm ein späteres Paket mit einem DTS von 12. Wenn der PTS des Pakets derselbe wie sein DTS ist, dann ist das gegebene Paket dasselbe wie der zurückgegebene Rahmen. Wenn der PTS des Pakets 2 Frames später als sein DTS ist, wird avcodec_decode_video() den Frame verzögern und nicht zurückgeben, bis ich 2 weitere Pakete bereitstelle.

Aufgrund dieses Verhaltens vermute ich, dass av_read_frame() möglicherweise die Pakete von IPBB zu IBBP umordnet, so dass avcodec_decode_video() nur die P-Frames für 3 Frames anstelle von 5 puffern muss. Zum Beispiel die Differenz zwischen der Eingabe und die Ausgabe des P-Rahmens mit dieser Reihenfolge ist 3 (6 - 3):

|                  I B B P B B P
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

vs eine Differenz von 5 mit der Standard-Bestellung (6 - 1):

|                  I P B B P B B
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

but that is pure conjecture.

0
hinzugefügt

Ich bin ziemlich sicher, dass Sie genaue Werte erhalten. Es könnte helfen, wenn Sie einen MPEG-Stream als, na ja, einen Stream. In diesem Fall wäre vor der IBBPBB, die Sie dort sehen, normalerweise eine andere GOP. Vielleicht so etwas (mit derselben Notation wie die ursprüngliche Frage):

P(-3,-2)  B(-2,-1)  B(-1,0)

Grundsätzlich basieren die B-Frames nach den I-Frames auf dem I-Frame und der letzte P-Frame auf der previous GOP.

Während es logisch ist, dass ein Video damit beginnt:

Start GOP: IPBBPBBPBB...

Später muss es sein

Start GOP: IBBPBBPBBPBB
Start GOP: IBBPBBPBBPBB
Start GOP: IBB... 

Denken Sie daran, dass das Decodieren eines beliebigen B-Frames einen vollständigen Frame davor und danach erfordert. Daher sollte jedes Paar von B-Frames vor dem I- oder P-Frame angezeigt werden, unmittelbar davor in der Datei.

FFMPEG könnte den "Spezialfall" der ersten GOP einfach vergessen haben.

Da die ersten beiden B-Frames keinen vorherigen Frame zum Manipulieren haben, sollten Sie in der Lage sein, sie sicher zu verwerfen. Setzen Sie einfach Ihre Zeitstempel vom ersten I-Frame um und passen Sie den Audio-Stream um denselben Betrag an.

Ob dies tatsächlich zu einem Verlust von Frames führt, hängt von der Implementierung von FFMPEG ab. Im schlimmsten Fall verlieren Sie jedoch 83 Millisekunden (2 Frames bei 24 Frames/Sek.).

0
hinzugefügt
Diese Art von Hacks (akzeptieren den Verlust von 2 Frames) sind ... Hacky :) Schade Dokumentation zu schreiben ist so langweilig, dass fast niemand stört.
hinzugefügt der Autor Roman Starkov, Quelle