verlustfreies Video mit FFmpeg ffv1 auf JPEG-Bildern wird nicht komprimiert, sondern erweitert

1018
user1373984

Ist es für FFmpeg / ffv1.3 / mkv möglich, ein verlustfreies Video zu erstellen, das nicht größer ist als die Summe seiner Teile (und wenn ja, wie) und wenn nicht, was ist eine gute Alternative, um an die Größe heranzukommen? Das Video muss verlustfrei sein.

Ich versuche, FFmpeg zu verwenden, um eine mkv mit ffv1.3 auf einem Satz ähnlicher JPEG-Bilder (Bilder von einer Webcam) zu erstellen. Ich kann das Video jedoch mindestens 2 mal so groß wie die Sammlung von JPEG-Bildern erstellen. Ich hätte ungefähr die gleiche Kompression oder besser erwartet.

Ich verstehe, dass JPEG allein für die Komprimierung optimiert ist. Eine große Anzahl sehr ähnlicher Bilder sollte jedoch weiter komprimiert werden können, oder in diesem Fall ähnlich wie die Originalbilder.

Die Befehle, die ich zum Erstellen der Datei verwende, sind:

ffmpeg -pattern_type glob -i '* .jpg' -vcodec ffv1 -level 3 -an -pass 1 -passlogfile passlog -f matroska / dev / null

ffmpeg -pattern_type glob -i '* .jpg' -vcodec ffv1 -level 3 -an -pass 2 -passlogfile passlog -f matroska ~ / foo.mkv

Die Eingabedateien haben eine Gesamtlänge von 24M, aber das Ergebnis ist 96M (je du -h).

Die Ergebnisse aus dem zweiten Durchgang:

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.6 (Debian 4.6.3-14+rpi1) configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff libavutil 55. 19.100 / 55. 19.100 libavcodec 57. 28.103 / 57. 28.103 libavformat 57. 28.101 / 57. 28.101 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 39.102 / 6. 39.102 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.101 / 2. 0.101 Input #0, image2, from '*.jpg': Duration: 00:00:21.32, start: 0.000000, bitrate: N/A Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc File '/home/pi/foo.mkv' already exists. Overwrite ? [y/N] y [swscaler @ 0x3671f30] deprecated pixel format used, make sure you did set range correctly Output #0, matroska, to '/home/pi/foo.mkv': Metadata: encoder : Lavf57.28.101 Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv422p, 640x480, q=2-31, pass 2, 200 kb/s, 25 fps, 1k tbn, 25 tbc Metadata: encoder : Lavc57.28.103 ffv1 Stream mapping: Stream #0:0 -> #0:0 (mjpeg (native) -> ffv1 (native)) Press [q] to stop, [?] for help frame= 533 fps=4.2 q=-0.0 Lsize= 97815kB time=00:00:21.32 bitrate=37584.4kbits/s speed=0.168x video:97808kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.006607% 

Jedes JPEG hat ungefähr 43143 Bytes (pro ls -al), aber mit dem folgenden Befehl gibt das Tool an, dass jedes Bild 614400 Bytes ist (sowohl im Video als auch in den unabhängigen JPEG-Images). Ich würde davon ausgehen, dass dies die Größe des Bildes (640x480x2) ist.

ffmpeg -pattern_type glob -i '* .jpg' -f framemd5 -

Die folgenden Ergebnisse beziehen sich auf die Bilder, die gleichen Größen werden für den MKV angegeben.

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.6 (Debian 4.6.3-14+rpi1) configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff libavutil 55. 19.100 / 55. 19.100 libavcodec 57. 28.103 / 57. 28.103 libavformat 57. 28.101 / 57. 28.101 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 39.102 / 6. 39.102 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.101 / 2. 0.101 Input #0, image2, from '*.jpg': Duration: 00:00:21.32, start: 0.000000, bitrate: N/A Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc #format: frame checksums #version: 1 #hash: MD5 #software: Lavf57.28.101 #tb 0: 1/25 #stream#, dts, pts, duration, size, hash Output #0, framemd5, to 'pipe:': Metadata: encoder : Lavf57.28.101 Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuvj422p, 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc Metadata: encoder : Lavc57.28.103 rawvideo Stream mapping: Stream #0:0 -> #0:0 (mjpeg (native) -> rawvideo (native)) Press [q] to stop, [?] for help 0, 0, 0, 1, 614400, 2148ff8b95296f4bacc1099d13235063 0, 1, 1, 1, 614400, da330e2acd2f7d7a1e79fe79fccc90cf 0, 2, 2, 1, 614400, f55563c13a9f232ce32419fa26e37214 0, 3, 3, 1, 614400, c53d994fff0a9b26529fa8763deae520 

BEARBEITEN: Die beste Komprimierung (und gute Geschwindigkeit) stammte aus einem Container der JPEG-Bilder:

ffmpeg -pattern_type glob -i '* .jpg' -vcodec kopiert -an -f matroska ~ / foo.mkv

Die resultierende Datei betrug etwas mehr als 24 Millionen (gegenüber den 96 Millionen ffv1). Auch die dekomprimierten JPEG-Bilder waren 312M, in beiden Fällen wurden sie ziemlich gut komprimiert. Wenn ich mit etwas anderem als einem jpeg angefangen hätte, wäre ffv1 ideal gewesen, aber in meinem Fall wäre das verlustbehaftete jpeg auch die verlustfreien Anfangsbilder.

1
Standardmäßig wird für die [Bilddatei demuxer] (http://ffmpeg.org/ffmpeg-formats.html#image2-1) eine Bildrate von 25 verwendet. Wenn Sie dies ändern möchten, verwenden Sie die Eingabeoption `-framerate` ( und zusätzlich die `-r`-Ausgabeoption, wenn Sie die Eingabe-Frame-Rate variieren wollen. Sie können die JPG-Bilder mit "jpegtran" vorverarbeiten, um eine verlustfreie Optimierung durchzuführen (siehe [Beispiel] (http://stackoverflow.com/a/32151594/1109017), wobei eine Bash "for-Schleife" verwendet wird), bevor Sie mit "ffmpeg" muxen. Ihre Ergebnisse können je nach den JPG-Dateien variieren. LordNeckbeard vor 8 Jahren 0

1 Antwort auf die Frage

0
Tandy Freeman

Im Allgemeinen habe ich festgestellt, dass die Kodierung verlustbehafteter Videos mit einem verlustfreien Codec zu einer größeren Datei führt. FFmpeg muss Ihre Eingabe dekomprimieren, bevor sie in ffv1 kodiert werden kann, sodass sie von der unkomprimierten Version Ihrer JPEG-Dateien aus funktioniert. Der Vorgang wird hier beschrieben: https://ffmpeg.org/ffmpeg.html#Detailed-description

Der Link lieferte die Informationen, die ich brauchte. Da das JPEG-Format dekomprimiert wird, wird es durch ffv1 nicht so klein komprimiert. Leider erklärt dies nicht, warum einzelne JPEG-Bilder besser komprimiert werden als die Mehrfach-Bildkomprimierung durch ffv1, aber es ist immer noch eine Tatsache. user1373984 vor 8 Jahren 0
Wenn ich Sie richtig verstehe, fragen Sie sich, warum -vcodec copy eine kleinere Datei als -vcodec ffv1 erzeugt hat? Dies ist darauf zurückzuführen, dass Ihre JPEG-Dateien nicht neu codiert werden, sondern lediglich die Streams kopiert werden. Deshalb ist es so schnell, der Engpass ist, wie schnell Ihre Festplatte kopieren / einfügen kann. Tandy Freeman vor 8 Jahren 0