題 在不丟失有用幀的情況下降低視頻幀速率


我有一個來自安全攝像頭的視頻,最初以低幀速率錄製,可能是15 fps,也許是10 fps,甚至可能更低。此後它被其他人轉換為25 fps(不改變持續時間)。我假設已經添加了額外的重複幀,並且可能這也略微扭曲了原始幀的顯示時間。

我想用ffmpeg將視頻重新編碼為原始幀速率,而不丟棄任何一個 有用 實際運動的幀。如果我只是使用 fps 過濾它不會選擇它保留哪些幀,我認為由於舍入錯誤,它可能最終保留一些重複的幀並永久丟失有用的幀,使事情變得更糟。無論如何,我不知道告訴過濾器的號碼是什麼,因為我不確切知道原始幀率是多少!

如何使用ffmpeg繼續修復此視頻?

ffmpeg -i "orig.mp4" -an -vcodec h264 -vf "fps=???" "fixed.mp4"

3
2018-02-18 15:49


起源


它似乎不太可能完成,特別是如果你不知道轉換器使用的確切“算法”。聽起來有點像下拉問題。 - Tom Yan


答案:


我設法修復了我的文件。我找到了 mpdecimate 過濾器,從視頻流中刪除重複或接近重複的幀。首先我試過:

ffmpeg -loglevel debug -i orig.mp4 -an -vf "mpdecimate" test.mp4

我補充道 -loglevel debug 在轉碼過程中獲取更多信息。信息顯示了什麼 mpdecimate 正在做框架,這是很多很多這種模式:

lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44032 pts_time:3.44 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44544 pts_time:3.48 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45056 pts_time:3.52 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45568 pts_time:3.56 drop_count:4
781>=hi keep pts:46080 pts_time:3.6 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:46592 pts_time:3.64 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47104 pts_time:3.68 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47616 pts_time:3.72 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:48128 pts_time:3.76 drop_count:4
821>=hi keep pts:48640 pts_time:3.8 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49152 pts_time:3.84 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49664 pts_time:3.88 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50176 pts_time:3.92 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50688 pts_time:3.96 drop_count:4
793>=hi keep pts:51200 pts_time:4 drop_count:-1

即,它一直連續丟失4幀作為重複並保持每5秒。這表明原始幀率是現在的1/5。 我很幸運! 由於視頻的當前25 fps是原始幀速率的倍數,因此保持和丟棄的幀的時間未對準應該沒有問題。因此,我重新編寫了原始視頻,而不是更複雜 -vf "fps=5",輸出似乎很好。只是為了確定,我通過輸出管道輸出 mpdecimate 過濾,並將所有剩餘幀檢測為“保持”。所以原始文件並沒有像我想像的那麼混亂。


4
2018-02-18 19:42





如果額外的幀是重複的而不是插值,那麼以下可能有效:

ffmpeg -i orig.mp4 -an -vf "select='gt(scene\,0.001)',setpts=N/(10*TB)" -r 10 fixed.mp4

我們的想法是選擇不與前一幀重複的所有幀。然後根據指定的輸出速率重新生成PTS。您可能需要向上或向下調整場景值以使檢測過濾器正確。如果視頻顯示比實時更快或更慢,則分別降低或提高速率(和設定分母值)。


2
2018-02-18 18:23



我認為這可行,但我發現很難正確調整它。我最終找到了“mpdecimate”過濾器並使用了它,因為它似乎給每個幀一個更明確的“欺騙或不重複”結果。 - Boann