Ich transkodiere Echtzeitaufnahmen einer Überwachungskamera von MJPEG in MPEG2, indem ich verwende ffmpeg
.
Leider kann die Maschine, die die Transkodierung durchführt, nicht wirklich mithalten (100 % CPU-Auslastung), aber es ist „gut genug“ und ich habe nichts dagegen, wenn ab und zu ein Bild verloren geht. Aber aus irgendeinem Grund gehen ffmpeg
keine Bilder verloren, sodass der Speicherverbrauch immer weiter zunimmt, da der Prozess hinter den eingehenden Bildern zurückbleibt, und dann geht der Maschine der Speicher aus und das Video wird stark beschädigt.
Gibt es eine Möglichkeit, ffmpeg
Frames aggressiver zu löschen? Die Probleme treten auf, wenn die Speichernutzung 1,9 GB erreicht. Ich habe also versucht, monit
den Vorgang neu zu starten, wenn der Speicher über 1,5 GB steigt. Dann wird er jedoch alle 10 Minuten neu gestartet, was die gewünschte Länge von 15 Minuten für jede transkodierte Datei unterbricht.
Dies ist der Befehl, den ich verwende:
ffmpeg -overrun_nonfatal 1 -y -i udp://1.2.3.4
-c mpeg2video -b:v 2M -vf transpose=2
-preset ultrafast -an -r 30
out.mkv
Laut der Manpage -r
kann die Option als Ausgabeoption zum Löschen von Frames verwendet werden. Ich mache das jedoch und es scheint, dass nur Frames gelöscht werden, um sie an die Ausgabe-Framerate anzupassen (hier 30 fps), und nicht, um mit dem Eingabestream mitzuhalten.
Die -vsync
Option scheint auch etwas Ähnliches zu tun, indem sie versucht, eine Bildrate anzupassen, anstatt das Puffern zu minimieren.
-frame_drop_threshold
sieht vielversprechender aus, aber auch hier scheint es eher darum zu gehen, Frames zu löschen, um mit den Zeitstempeln Schritt zu halten, als zu versuchen, mit der Echtzeitkodierung Schritt zu halten.
Gibt es eine andere Option, die ich verwenden kann, ffmpeg
um Frames nach Bedarf zu löschen, damit nicht so viel Speicher verbraucht wird? Ich nehme an, dass dies in den Optionen für Echtzeit/Streaming/geringe Latenz zu finden ist, aber ich kann scheinbar nichts finden!
Antwort1
Ich habe festgestellt, dass dies in meiner Umgebung ein Problem darstellt, wenn ich von der Kamera aufnehme und FULL HD streame. Wenn das Netzwerk auf einen Engpass stößt, füllt sich ffmpeg rtbufsize ziemlich schnell und ffmpeg beginnt, Frames zu verlieren. Das klingt nach der Lösung für Ihr Problem.
Die Bibliothek libavformat bietet einige allgemeine globale Optionen, die für alle Muxer und Demuxer festgelegt werden können:
rtbufsize
Ganzzahl (Eingabe)Legen Sie den maximalen Speicher fest, der zum Puffern von Echtzeit-Frames verwendet wird.
Quelle:Dokumentation der FFmpeg-Formate
Angenommen, Sie möchten einen auf 150 MB begrenzten Puffer, versuchen Sie Folgendes:
ffmpeg -rtbufsize 150M -overrun_nonfatal 1 -y -i udp://1.2.3.4 -c mpeg2video -b:v 2M -vf transpose=2 -preset ultrafast -an -r 30 out.mkv
Das heißt, wenn die Maschine nicht mithalten kann, beginnt sie, die eingehenden Daten in den RAM zu füllen und füllt so den Puffer. Wenn dieser das Limit erreicht, beginnt er, viele Frames zu verlieren.