セキュリティカメラからのリアルタイム映像を、 を使用して MJPEG から MPEG2 にトランスコードしていますffmpeg
。
残念ながら、トランスコーディングを実行するマシンは実際には追いつくことができません (CPU 使用率 100%)。しかし、それは「十分」であり、時々フレームがドロップされても気になりません。しかし、何らかの理由でffmpeg
フレームがドロップされないため、プロセスが受信フレームより遅れてメモリ使用量が増加し続け、マシンのメモリが不足し、ビデオがひどく破損し始めます。
もっと積極的にフレームをドロップする方法はありますかffmpeg
? 問題はメモリ使用量が 1.9 GB に達したときに発生するため、monit
メモリが 1.5 GB を超えたときにプロセスを再起動するように試みましたが、その後 10 分ごとに再起動され、各トランスコードされたファイルの推奨される 15 分の長さが破られます。
私が使用しているコマンドは次のとおりです:
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
マニュアルページには、この-r
オプションはフレームをドロップするための出力オプションとして使用できると書かれていますが、私がこれを実行したところ、入力ストリームに追いつくためにフレームをドロップするのではなく、出力フレームレート (ここでは 30fps) に一致するようにフレームをドロップするだけであるようです。
この-vsync
オプションも同様のことを行うようで、バッファリングを最小限に抑えるのではなく、フレームレートを一致させようとします。
-frame_drop_threshold
より有望に見えますが、これもまた、リアルタイム エンコーディングに追いつこうとするよりも、タイムスタンプに追いつくためにフレームをドロップすることに関するもののようです。
メモリを大量に消費しないように、必要に応じてフレームをドロップするように指示する他のオプションはありますかffmpeg
? これは、リアルタイム/ストリーミング/低遅延オプションにあると思いますが、何も見つからないようです。
答え1
私の環境では、カメラからキャプチャして FULL HD をストリーミングするときにこれが問題になることがわかりました。ネットワークがボトルネックになると、ffmpeg rtbufsize がすぐにいっぱいになり、ffmpeg がフレームをドロップし始めます。これは、問題の解決策のように思えます。
libavformat ライブラリは、すべての muxer および demuxersock に設定できるいくつかの汎用グローバル オプションを提供します。
rtbufsize
整数(入力)リアルタイム フレームのバッファリングに使用される最大メモリを設定します。
150 MB の制限バッファが必要な場合は、次を試してください。
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
つまり、マシンが追いつけない間は、受信データを RAM に書き込み始め、バッファがいっぱいになり、限界に達するとフレームが大量にドロップされ始めます。