FFmpeg behält die Farben nach der Größenänderung nicht bei

Ich möchte ein 4K-mkv-Video mit ffmpeg version 3.4.6-0ubuntu0.18.04.1Ubuntu 18.04 auf 1920 × 1080 skalieren. Die Originaldatei hat folgende Eigenschaften:

Input #0, matroska,webm
encoder         : libebml v1.3.9 + libmatroska v1.5.2
Stream #0:0(eng): Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)

Diese Version von FFmpegunterstützt möglicherweise nicht x265. Ich habe eine neue Version aus dem aktuellen Git-Repository kompiliert und explizit aktiviertx265 . Nun ffmpeg -hide_banner -pix_fmtshat in seiner Ausgabe:

FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL
-----
IO... yuv420p10le            3            15

Dieses Format sollte nun sowohl für die Kodierung als auch für die Dekodierung unterstützt werden. Ich habe es versucht:

ffmpeg -i original_file.mkv -c:v libx265 -pix_fmt + -vf scale=1920:1080 -colorspace bt709 -c:a copy test_output.mkv

Dies erzeugt:

Input #0, matroska,webm, from 'test_output.mkv':
  Metadata:
    ENCODER         : Lavf58.35.100
    Stream #0:0(eng): Video: hevc (Main 10), yuv420p10le(tv, bt709/unknown/unknown), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 23.98 tbc (default)

Scheint also ok zu sein. Die Farben scheinen jedoch test_output.mkvimmer noch die Hälfte der Intensität des Originals zu haben, als ob das 4K-Video mit einer grauen Ebene überlagert würde. Ich habe die Datei sowohl mit vlcals auch geöffnet mpv, ohne Unterschied.

  1. Wie bewahrt man die Originalfarben so weit wie möglich?

  2. Wenn es möglich ist, würde ich auch gerne die Bitrate senken, aber mein Versuch

    ffmpeg -i original_file.mkv -s 1920x1080 -b 1700 output.mkv
    

    produzierte ein solides, nur graues Video mit einigen sich bewegenden Quadraten.


Ich bekomme immer diese Meldung:

[matroska,webm @ 0x55a5507ad100] Could not find codec parameters for stream 1 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
Consider increasing the value for the 'analyzeduration' and 'probesize' options

FFmpegbuild from source hat die folgende Konfiguration:

ffmpeg version N-95768-gd831edc387 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --enable-gpl --enable-libx264 --enable-libx265
libavutil      56. 36.100 / 56. 36.100
libavcodec     58. 62.100 / 58. 62.100
libavformat    58. 35.100 / 58. 35.100
libavdevice    58.  9.101 / 58.  9.101
libavfilter     7. 66.100 /  7. 66.100
libswscale      5.  6.100 /  5.  6.100
libswresample   3.  6.100 /  3.  6.100
libpostproc    55.  6.100 / 55.  6.100

Antworten (2)

Anzeige 1:

-pix_fmt yuv420p10leVersuchen Sie, die Option hinzuzufügen (z. B. vor -vf). Oder nur, -pix_fmt +um dasselbe Pixelformat wie das Eingabevideo zu verwenden.

Wenn es nicht hilft, haben Sie offensichtlich eine ungeeignete, wenn auch häufigere FFmpeg-Version – nur für 8-Bit-Farben. (Ihr Originalvideo verwendet 10-Bit-Farben, und FFmpeg versucht in diesem Fall, das beste 8-Bit-Pixelformat zu verwenden – natürlich mit der Verschlechterung der Farben.)

FFmpeg kann für 8-Bit-Farben oder für 10-Bit-Farben oder – in letzter Zeit – für beide (für Ihr HEVC-codiertes Video) erstellt werden.

Sie müssen also eine Version für 8-/10- oder 10-Bit-Farbtiefe erstellen (oder auf andere Weise erhalten).

Anzeige 2:

Die Bitrate 1700ist sehr niedrig – nur 1700 Bit pro Sekunde, dh etwa 212 Byte pro Sekunde.

Um eine so niedrige Bitrate zu erreichen und gleichzeitig Ihre 23.98Frames pro Sekunde zu erreichen, ist der Encoder mit einer durchschnittlichen Größe für 1 Frame von etwa 212 / 24 = 9 Bytes begrenzt!

Hast du ein Bild von so einem kleinen Speicher gesehen? Es hat fast keine Informationen, daher das graue Bild.

Sie wollten wahrscheinlich 1700.000 (Kilobit pro Sekunde) – oder wahrscheinlicher – 170.000:

-b:v 170k

Korrigieren Sie also Ihren Befehl auf diese Weise.


Nachtrag zu Anzeige 1:

Sie verwenden das (standardmäßige) 4:2:0-Chroma-Subsampling (mit unvermeidlicher Farb- und Kontrastverschlechterung).
Probieren Sie die maximale Qualität aus, also 4:4:4 (kein Subsampling) oder — falls Ihnen das ausreicht — 4:2:2.

Um dies zu erreichen, verwenden -pix_fmt yuv444p10leund ändern Sie das Videoprofil auf main444-10 (mit Option -profile:v main444-10).

Vielen Dank für all die sehr nützlichen Erklärungen. Ich habe es mit einer aus der Quelle kompilierten Version (mit aktiviertem x265) FFmpegund auch mit einer gepackten neueren Version versucht. Auch wenn (in beiden Fällen) verwendet wird -pix_fmt yuv420p10le, ist das Problem dasselbe. Überprüfen Sie die Fehlermeldung, die ich in der Frage hinzugefügt habe, ob sie nützlich ist. FFmpegErstellt außerdem x264standardmäßig eine Ausgabe; HEVCWie kann man stattdessen das Original bewahren ?
Verwenden Sie ffmpeg -hide_banner -pix_fmts, um zu sehen, ob Sie das Pixelformat yuv420p10le in Ihrem Build haben. Wenn nicht, unterstützt Ihr Build keine 10-Bit-Farbtiefe. Fügen Sie -c:v libx265Ihren Befehlen hinzu, um die HEVC-Ausgabe zu erhalten. Die an Ihre Frage angehängte Fehlermeldung hat nichts mit Ihren Problemen zu tun.
Ich bin mir bewusst, dass dies sehr schwierig ist. Wie auch immer, Sie finden das gesamte Verfahren, das ich befolgt habe (und seine Ergebnisse), in meiner aktualisierten Frage. Das Problem besteht immer noch, unabhängig vom Format der Ausgabedatei yuv420p10le.
Versuchen Sie, die Option hinzuzufügen -color_range pc(für den vollen Farbbereich 0 bis 255 anstelle von 16 bis 235 für TV).
Ihre Eingabe enthält eine Reihe von nicht standardmäßigen Farbparametern ( bt2020nc/bt2020/smpte2084). Verwenden Sie den Farbraumfilter , um in Standard bt709 zu konvertieren. Der Farbbereich ist hier nicht relevant, und niedrige Bitraten verschlechtern die Bildfarbe, sind in diesem Fall jedoch nicht der Hauptfaktor.
@MarianD -color_range pcÄndert leider nichts am Ergebnis.
@Gyan Ich habe die Frage mit diesem neuen Versuch bearbeitet. Das Video ist immer noch mit "falschen" Farben. Beachten Sie jedoch die tv, bt709/unknown/unknownin der Ausgabe. Vielleicht auch colormatrixund noch etwas muss modifiziert werden? Ich habe versucht, die Option hinzuzufügen -colormatrix bt709, aber dies verursacht einen Fehler: Unrecognized option 'colormatrix'..
Der Farbraumfilter, nicht die Option.
@Gyan Ok. Ich hoffe, die Syntax ist korrekt: Die Verwendung -vf "scale=1920:1080, colorspace=bt709"erzeugt einen Fehler: [Parsed_colorspace_1 @ 0x560001239540] Unsupported input transfer characteristics 16 (smpte2084) Error while filtering: Invalid argument Failed to inject frame into filter network: Invalid argument Error while processing the decoded data for stream #0:0. Dasselbe auch wenn ich nur nutze -vf colorspace=bt709.
Ich werde mich morgen darum kümmern.
Siehe die Aktualisierung meiner Antwort ( Nachtrag zu Anzeige 1 ).

Hier gibt es bereits eine Lösung . Aber ich versuche es kurz zusammenzufassen.

Sie müssen die richtigen Flags für Farbeigenschaften der Originaldatei angeben. Ihre Originaldatei (wie wahrscheinlich viele andere Dateien) hat diese Eigenschaften: yuv420p10le(tv, bt2020nc/bt2020/smpte2084). Sie müssen also jeweils die folgenden Argumente hinzufügen: -pix_fmt, -color_range, -colorspace, -color_primariesund -color_trc. Die letzten vier sind nur Flags (die in Klammern). Wenn Sie die Datei also bereits codiert haben, müssen Sie dies nicht noch einmal tun, sondern fügen Sie einfach die richtigen Flags hinzu. Ihre Argumente sollten dann so aussehen:

-c:v libx265
-pix_fmt +
-color_range tv 
-colorspace bt2020nc
-color_primaries bt2020 
-color_trc smpte2084  
-vf scale=1920:1080

Wie an anderer Stelle erwähnt, bedeutet die Farbformateigenschaft -pix_fmtmit Wert +"dasselbe Pixelformat verwenden", aber Sie können es manuell angeben: -pix_fmt yuv420p10le.