Ich versuche, ein .mp4-Video aus einer Reihe von Frames mit FFMPEG unter Verwendung des libx264-Codecs zu codieren.
Dies ist der Befehl, den ich ausführe:
/usr/local/bin/ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4
Ich erhalte manchmal den folgenden Fehler:
[libx264 @ 0xa3b85a0] height not divisible by 2 (520x369)
Nach einigem Hin und Her scheint das Problem etwas mit dem Skalierungsalgorithmus zu tun zu haben und kann durch Hinzufügen eines -vf-Arguments behoben werden.
In meinem Fall möchte ich jedoch keine Skalierung durchführen. Idealerweise möchte ich die Abmessungen genau so halten wie die Rahmen. Irgendein Rat? Gibt es ein Seitenverhältnis, das h264 erzwingt?
-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
: Dies ist nicht einmal eine der Antworten. Die richtige Antwort auf die Frage aller anderen ist die von LordNeckbeard."scale="
stattdessen verwenden,"pad="
wenn er / sie keine farbigen Füllpixel möchte?Antworten:
Die Antwort auf die ursprüngliche Frage, die das Video nicht skalieren möchte, lautet:
Befehl:
Grundsätzlich benötigt .h264 gerade Abmessungen, damit dieser Filter:
Sie können die Farbe der Polsterung ändern, indem Sie Filterparameter hinzufügen
:color=white
. Siehe die Dokumentation des Pads .quelle
-vf pad="width=iw:height=ih+1:x=0:y=0:color=white"
. Die Dokumentation zum ffmpeg-Pad finden Sie hier: ffmpeg.org/ffmpeg-filters.html#pad-1 .-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
.Benutz einfach
-2
Aus der Dokumentation zum Skalenfilter :
Beispiele
Set Breite bis 1280, und die Höhe wird automatisch das Seitenverhältnis zu erhalten , berechnet werden, und die Höhe , die durch 2 teilbar sein wird:
Wie oben, jedoch mit einer angegebenen Höhe. Die Breite muss vom Filter behandelt werden:
"teilbar durch 2"
Wie von x264 gefordert, wird für YUV 4: 2: 0-Chroma-Subsampled-Ausgänge das "durch 2 teilbare für Breite und Höhe" benötigt. 4: 2: 2 würde "durch 2 durch Breite teilbar" benötigen, und 4: 4: 4 hat diese Einschränkungen nicht. Die meisten nicht auf FFmpeg basierenden Player können jedoch nur 4: 2: 0 ordnungsgemäß dekodieren. Daher
ffmpeg
werden bei der-pix_fmt yuv420p
Ausgabe von H.264-Videos häufig Befehle mit dieser Option angezeigt.Vorbehalt
Leider können Sie nicht
-2
sowohl für die Breite als auch für die Höhe verwenden. Wenn Sie jedoch bereits eine Dimension angegeben haben,-2
ist die Verwendung eine einfache Lösung.quelle
-vf scale=-2:-2
nicht? In meinem Fall möchte ich die ursprüngliche Dateigröße so weit wie möglich beibehalten. Was für mich funktioniert hat war-vf scale=-2:ih
. Aber es funktioniert nicht, wenn beide h / w ungleichmäßig sind.-2
hängt vom deklarierten Wert der anderen Dimension ab.Size values less than -1 are not acceptable.
Aber die Antwort von @Zbyszek funktionierte perfekt.ffmpeg
. Sie können einen statischen Build herunterladen .Wenn Sie eine Ausgabebreite einstellen möchten und eine Ausgabe mit demselben Verhältnis wie das Original haben möchten
und um nicht mit diesem Problem zu fallen, können Sie verwenden
(Nur für Leute, die suchen, wie man das mit Skalierung macht)
quelle
scale="trunc(oh*a/2)*2:720"
Das Problem bei den
scale
Lösungen hier ist, dass sie das Quellbild / -video verzerren, was fast nie das ist, was Sie wollen.Stattdessen habe ich festgestellt, dass die beste Lösung darin besteht, der ungeraden Dimension ein 1-Pixel-Pad hinzuzufügen. (Standardmäßig ist das Pading schwarz und schwer zu bemerken.)
Das Problem mit den anderen
pad
Lösungen ist, dass sie nicht über beliebige Dimensionen verallgemeinern, weil sie immer auffüllen.Diese Lösung fügt Höhe und / oder Breite nur dann ein 1-Pixel-Pad hinzu, wenn sie ungerade sind:
Dies ist ideal, weil es immer das Richtige tut, auch wenn keine Polsterung erforderlich ist.
quelle
scale=iw+mod(iw,2):ih+mod(ih,2):flags=neighbor
. Dies kann jede Dimension bei Bedarf nur um 1 erhöhen und die letzte Zeile / Spalte duplizieren.Dies liegt wahrscheinlich an der Tatsache, dass H264-Videos vor dem Anwenden der Komprimierung normalerweise als 4: 2: 0 von RGB in YUV-Speicher konvertiert werden (obwohl die Formatkonvertierung selbst ein verlustbehafteter Komprimierungsalgorithmus ist, der zu 50% Speicherplatzersparnis führt).
YUV-420 beginnt mit einem RGB-Bild (Rot, Grün, Blau) und konvertiert es in YUV (im Grunde ein Intensitätskanal und zwei "Farbton" -Kanäle). Die Farbtonkanäle werden dann unterabgetastet, indem für jedes 2 × 2-Quadrat dieses Farbtons eine Farbtonabtastung erstellt wird.
Wenn Sie eine ungerade Anzahl von RGB-Pixeln entweder horizontal oder vertikal haben, haben Sie unvollständige Daten für die letzte Pixelspalte oder -zeile im unterabgetasteten Farbtonraum des YUV-Rahmens.
quelle
LordNeckbeard hat sehr schnell die richtige Antwort
Vergessen Sie für Android nicht hinzufügen
quelle
--disable-asm
in seinem x264-Build-Skript verwendet wird . Dies führt zu unnötiger und erheblicher Langsamkeit (Sie können das ffmpeg-Protokoll überprüfen und wenn es anzeigtusing cpu capabilties: none!
, ist das schlecht). Ich bin mir nicht sicher, warum sie das hinzugefügt haben, aber ich bin kein Android-Entwickler.Sie können auch die
bitand
Funktion anstelle vontrunc
:Bitand (x, 65534)
werde das gleiche tun wie
trunc(x/2)*2
und es ist meiner Meinung nach transparenter.(Betrachten Sie 65534 hier als magische Zahl;))
Meine Aufgabe war es, viele Videodateien automatisch auf die halbe Auflösung zu skalieren .
scale=-2,ih/2
führen zu leicht unscharfen BildernGrund:
scale
skaliert die tatsächlichen RahmenabmessungenLösung:
Erläuterung:
setsar=1
bedeutet, dass output_dimensions jetzt endgültig sind und keine Korrektur des Seitenverhältnisses angewendet werden sollteJemand könnte dies hilfreich finden.
quelle