Ffmpeg4 mit Pyglet integrieren. Was ist die richtige Methode, um Streams mit Alpha zu identifizieren?

403
Neon22

Wir versuchen, ffmpeg4 mit Pyglet zu verbinden.

Es läuft alles sehr gut, aber wir haben ein Problem:

Wenn eine VP9- (oder VP8-) Datei mit ffmpeg4 aus png-Dateien mit Alphas erstellt wird, erhalten wir intern eine Videodatei (webm) mit Alpha. ffmpeg -i image_seq%03d.png -qmin 0 -qmax 50 -crf 5 -b:v 1M output.webm

Beispielvmv-Videos mit Alpha finden Sie auf dieser Seite: https://simpl.info/videoalpha/

Bei der Wiedergabe erhalten wir jedoch kein Alpha, es sei denn, wir überschreiben den Codec als libvpx. (Dasselbe Verhalten kann in der CLI-Version von ffplay demonstriert werden). Wir wickeln ein avutil, avcodec, etc.

Frage: Wie kann man im Code erkennen, dass ein VP8- oder VP9-Stream eine Alphakomponente hat? (So ​​können wir es laden und AVFrame()als RGBA-Textur darauf zugreifen .)

Genauer:

Wir erhalten den FormatContext aus der Datei using AVFormatContextund den Stream AVStreamaus diesem FormatContext.

Dann AVStreambekommen wir den 'codecpar' Parameter.

Aus dem können AVCodecParameterswir die codec_id (167 ist VP9) und andere nützliche Parameter wie bits_per_coded_sample.

Interessanterweise scheinen diese Werte für Streams wie H264 (codec_id = 27) bei 24 Bit korrekt zu sein, werden jedoch für den VP9-Codec mit 0 markiert. Mich zu denken, dies sei nicht der richtige Ort, um den richtigen Wert zu finden.

2

1 Antwort auf die Frage

0
Neon22

OK, der native Codec ist einfach nicht so gut wie der libvpx-Codec, der von den Webm-Peeps geliefert wird. Wenn Sie also diese Alpha-Informationen benötigen, sollten Sie den Codec beim Laden mit dem libvpx-Codec überschreiben.

Wie Sie das tun - siehe hier: https://stackoverflow.com/questions/35340437/how-can-i-use-avformat-open-input-function-ffmpeg

Grundsätzlich muss das dritte Argument avformat_open_input()ein av_find_input_format("libvpx")Typ seinAVInputFormat

Wenn Sie nicht sicher sind, ob es sich um einen VP8,9-Codec im Dateikontext handelt, müssen Sie zuerst die Datei prüfen, den Codec ermitteln und dann in einem tatsächlichen Ladevorgang überschreiben. Informationen dazu finden Sie hier: https://stackoverflow.com/questions/14134589/what-does-the-avformat-open-input-do

Und schließlich - wenn Sie den nativen anstelle des webm-Codecs verwenden möchten, es sei denn, er hat ein Alpha (aber warum), können Sie überprüfen, ob das Alpha-Flag gesetzt ist, indem Sie die Zusatzdaten AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL überprüfen.

Prüfen Sie AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, wenn die side_data mit (uint64_t) 1 beginnt, da sich eine Transparenzebene befindet.

Der allgemeine Konsens besteht jedoch darin, immer den libvpx-Decoder zu verwenden.

Bearbeiten: Weitere Details Die ID des Google VP8-Codecs lautet 139. 167 ist der Google VP9-Codec. Um die libvpx-Versionen zu ersetzen, müssen Sie "libvpx-vp8" und "libvpx-vp9" suchen, z. B. avcodec_find_decoder_by_name ("libvpx-vp9").