我正在將安全攝影機的即時鏡頭從 MJPEG 轉碼為 MPEG2,使用ffmpeg
.
不幸的是,進行轉碼的機器無法真正跟上(100% CPU 使用率),但它“足夠好”,我不介意偶爾丟幀。但由於某種原因,ffmpeg
沒有丟棄任何幀,因此隨著進程滯後於傳入幀,內存使用量不斷增加,然後機器內存不足,視頻開始嚴重損壞。
有什麼方法可以告訴ffmpeg
我們更積極地丟幀嗎?當記憶體使用量達到 1.9GB 時就會出現問題,因此我嘗試在monit
記憶體超過 1.5GB 時重新啟動該進程,但隨後它每 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
我發現這對我的環境來說是一個問題,當從相機捕獲並串流全高清時,當網路遇到一些瓶頸時,ffmpeg rtbufsize 很快就會填充,並且 ffmpeg 開始丟幀。這聽起來像是您問題的解決方案。
libavformat 函式庫提供了一些通用的全域選項,可以在所有 muxers 和 demuxersock 上設定:
rtbufsize
整數(輸入)設定用於緩衝即時幀的最大記憶體。
來源:FFmpeg 格式文檔
假設您想要 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,從而填充緩衝區,當緩衝區達到限制時,它將開始嚴重丟幀。