FFmpeg BMP zu YUV x264 Farbverschiebung

Wenn ich eine bestimmte Sequenz von BMP-Bilddateien in AVC/H.264 codiere, werden die Farben verschoben. Warum passiert das?

Aber wenn ich die BMPs in PNGs konvertiere, bevor ich ffmpeg ausführe, erscheint die Videokonvertierung korrekt. Mein Quellmaterial ist in BMPs und würde es vorziehen, nicht alles manuell in PNGs zu konvertieren, um die Problemumgehung durchzuführen.


Für den Zweck dieser Frage habe ich die Bildfolge genommen und sie in diesen verwendeten Hauptfarben zusammengefasst:

Geben Sie hier die Bildbeschreibung ein

Erster Codierungsversuch (das reine Weiß wird merklich grün):ffmpeg -i 000.bmp -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 first.mp4

Geben Sie hier die Bildbeschreibung ein

Zweiter Versuch (noch schlimmer):ffmpeg -i 000.bmp -vf "colormatrix=bt601:bt709" -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 second.mp4

Geben Sie hier die Bildbeschreibung ein

Dritter Versuch (zu hell):ffmpeg -i 000.bmp -vf "scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709" -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 third.mp4

Geben Sie hier die Bildbeschreibung ein

Die Verwendung einer PNG-Version desselben Eingabebilds funktioniert jedoch hervorragend:ffmpeg -i 000.png -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 fourth.mp4

Geben Sie hier die Bildbeschreibung ein


Ich verwende den neuesten FFmpeg Windows x86-64-Build (2016-11-22 Git d316b21):

C:\Temp> ffmpeg.exe -version
ffmpeg version N-82597-gd316b21 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2
    --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig
    --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray
    --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme
    --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame
    --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264
    --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger
    --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora
    --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis
    --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264
    --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma
    --enable-decklink --enable-zlib
libavutil      55. 40.100 / 55. 40.100
libavcodec     57. 66.106 / 57. 66.106
libavformat    57. 58.100 / 57. 58.100
libavdevice    57.  2.100 / 57.  2.100
libavfilter     6. 67.100 /  6. 67.100
libswscale      4.  3.101 /  4.  3.101
libswresample   2.  4.100 /  2.  4.100
libpostproc    54.  2.100 / 54.  2.100

Um meine Frage neu zu formulieren, wie kann ich die Sequenz von BMP-Bildern ohne unerwünschte Farbverschiebungen in ein H.264-Video konvertieren?

Ich bin mir nicht sicher, also bitte bestätigen, bevor ich dies als Antwort betrachte. Bitte versuchen Sie es mit '-vcodec libx264rgb' anstelle von '-vcodec libx264'
Angesichts der Tatsache, dass es im Titel der Frage um eine Farbverschiebung bei der Codierung in das YUV-Format geht, wie wird die Codierung in RGB das Problem lösen? Hier geht es darum, die Attribute der Quelle korrekt und vollständig anzugeben, damit swscale sie korrekt transformieren kann. Außerdem muss der Ausgabestrom für faule/schlampige Spieler markiert werden.
Zum OP. Wie hast du BMPs in PNG konvertiert? Und wie wurden die BMPs generiert?
@Mulvya Für mein MCVE in dieser Frage habe ich die BMPs von Hand in MS Paint generiert. Ich habe mit IrfanView in PNG konvertiert. Wenn Sie sich die Dateien in einem Hex-Editor ansehen, hat das BMP kein Farbprofil oder zugehörige Metadaten. Dem PNG scheint standardmäßig ein gAMA-Chunk und ein sRGB-Chunk hinzugefügt zu sein.
@RawBean Interessanter Vorschlag. Mit (minus -pix_fmt-vcodec libx264rgb -profile:v high444 ) erhalte ich ein Video mit perfekten Farben ohne Abweichung. Es ist jedoch nur in MPC-HC spielbar, nicht in Windows Explorer oder Mozilla Firefox. Ich denke, es wäre gut, im H.264-Hauptprofil zu bleiben.
@RawBean Nachdem ich mehrere Stunden lang verschiedene Dinge libx264rgbausprobiert hatte, wurde libx264das Problem für mich behoben. Vielen Dank!!

Antworten (1)

Anscheinend setzt FFmpeg die Eingabefarbattribute nicht korrekt für die BMP-Eingabe (wahrscheinlich, weil die Datei diese Metadaten nicht enthält) und der BMP-Decoder prüft nicht auf manuell markierte Attribute. Wir können es jedoch mit dem Formatfilter erzwingen.

ffmpeg -i 000.bmp -vf format=rgb24 -pix_fmt yuv420p -vcodec libx264 -profile:v main -crf 16 first.mp4
Das funktioniert perfekt! Es erhält das gleiche Ergebnis wie die Verwendung einer PNG-Eingabe. Ich danke dir sehr! Trotzdem ist das irgendwie verrückt, weil BMP-Dateien nur RGB24 sein können, sonst nichts ...
Je nach Decoder können BMPs ein Pixelformat einer 8-Bit-Palette oder 5-Bit-RGB oder 6-Bit-G..usw. haben (auch Alpha). Aber ja, Farbraum ist RGB. Der Decoder stammt ursprünglich aus dem Jahr 2005 und seine Aufgabe besteht darin, die an Filter weitergegebene AVFrame-Struktur mit relevanten Attributen zu füllen. Da sich BMP nicht viel geändert hat und nicht viel verwendet wird, hat sich niemand die Mühe gemacht, den Code mit neuen hinzugefügten Flags nachzurüsten.