Ich möchte also einen Frame von einem Video zu einer bestimmten Zeit mit libav für die Verwendung als Thumbnail aufnehmen.
>Was ich benutze ist der folgende Code. Es kompiliert und funktioniert gut (in Bezug auf das Abrufen eines Bildes überhaupt), aber ich habe es schwer, es zu das richtige Bild abrufen .
Ich kann mich einfach nicht mit der klaren Logik von Libav auseinandersetzen, die offensichtlich mehrere Zeitbasen pro Video verwendet. Speziell herausfinden, welche Funktionen welche Art von Zeitbasis erwarten / zurückgeben.
Die Unterlagen waren leider im Grunde überhaupt keine Hilfe. SO zur Rettung?
%Vor%Wenn ich dies mit einer Testfilmdatei ausführe, bekomme ich diese Ausgabe:
%Vor%Die Zeiten stimmen nicht überein. Was ist denn hier los? Was mache ich falsch?
Als ich nach Hinweisen suchte, stolperte ich über diese diese Aussage von der libav-users-Mailingliste ...
[...] packet PTS / DTS sind in Einheiten der Zeitbasis des Formats context, / Der AVFrame- & gt; pts Wert ist in Einheiten der Zeitbasis des Codec-Kontexts .
Mit anderen Worten, der Container kann (und normalerweise) einen anderen haben time_base als der Codec. Die meisten libav Spieler stören nicht mit dem Codecs time_base oder pts, da nicht alle Codecs einen, sondern den meisten haben Container tun. (Aus diesem Grund sagt das Dranger-Tutorial, AVFrame- & gt; pts zu ignorieren)
... was mich noch mehr verwirrte, da ich in den offiziellen Dokumenten keine solche Erwähnung finden konnte.
Wie auch immer, ich habe ersetzt ...
%Vor%... mit ...
%Vor%... und die Ausgabe hat sich geändert ...
%Vor%Immer noch keine Übereinstimmung. Was ist los?
Es ist meistens so:
Die Stream-Zeitbasis ist das, was Sie wirklich interessiert. Es ist, was die Paket-Zeitstempel sind, und auch pkt_pts
auf dem Ausgabe-Frame (da es nur aus dem entsprechenden Paket kopiert wurde).
Die Codec-Zeitbasis ist (wenn überhaupt) nur die Umkehrung der Bildrate, die in die Header der Codec-Ebene geschrieben werden könnte. Es kann in Fällen nützlich sein, in denen keine Container-Timing-Informationen vorhanden sind (z. B. beim Lesen von Rohvideo), aber ansonsten ignoriert werden können.
AVFrame.pkt_pts ist der Zeitstempel des Pakets, das in diesen Frame decodiert wurde. Wie bereits gesagt, es ist nur eine direkte Kopie aus dem Paket, also ist es in der Stream-Zeitbasis. Dies ist das Feld, das Sie verwenden möchten (wenn der Container Zeitstempel hat).
AVFrame.pts ist niemals auf etwas Nützliches eingestellt, wenn es dekodiert wird, ignoriere es (es könnte in Zukunft pkt_pts
ersetzen, um das ganze Durcheinander weniger verwirrend zu machen, aber im Moment ist es aus historischen Gründen so meistens).
Die Dauer des Formatkontexts ist in AV_TIME_BASE
(d. h. Mikrosekunden). Es kann sich in keiner Stream-Zeitbasis befinden, da Sie drei Bazillion-Streams mit jeweils einer eigenen Zeitbasis haben können.
Das Problem, das beim Anzeigen eines anderen Zeitstempels nach dem Suchen auftritt, ist einfach, dass search nicht genau ist . In den meisten Fällen können Sie nur nach dem engsten Schlüsselbild suchen, daher ist es üblich, einige Sekunden zu sparen. Das Entschlüsseln und Verwerfen der nicht benötigten Frames muss manuell erfolgen.