一定のフレーム間隔で重複フレームを間引くdecimate
フィルタと、前フレームとあまり変化のないフレームを間引くmpdecimate
フィルタの使い方。
Windows の ffmpeg で生放送する方法で書いていた内容をこちらに引っ越し内容を修正した。
一定周期のフレームを間引くフィルタにshuffleframes
フィルタがある。
指定フレーム毎に順番を入れ換える shuffleframes
Remove sequentially duplicate frames when using FFmpeg – Stack Overflow
decimate
間引くフレームは2番目の重複フレームで、PTSを修正し元のフレームレートよりも少なく出力する。
基本コマンド
日本の映像データは一般的に5フレーム毎に1フレーム間引けば重複フレームがなくなるので既定値のままでよい。
ffmpeg -i input -vf decimate=cycle=5:dupthresh=1.1:scthresh=15:blockx=32:blocky=32:ppsrc=0:chroma=1 -c:a copy output
ffplay -i input -vf decimate
ppsrc=1を使いlutyuv
フィルタで少し明るくする。
ffmpeg -i input -vf split[1],lutyuv=y=gammaval(1/1.1)[0];[0][1]decimate=ppsrc=1 -c:a copy output
ffplay -i input -vf split[1],lutyuv=y=gammaval(1/1.1)[0];[0][1]decimate=ppsrc=1
公式ドキュメント:FFmpeg Filters Documentation : decimate
オプション
- cycle[int]
間引く1フレームを決めるフレーム周期の指定
既定値:5
範囲:2から25まで - dupthresh[double]
重複フレームを検出するしきい値の指定
既定値:1.1
範囲:0から100まで - scthresh[double]
シーンチェンジの閾値の設定
既定値:15
範囲:0から100まで - blockx, blocky[int]
計算に使うx軸とy軸のブロックサイズを指定する。値が大きいほどノイズの抑制になるが小さな動きの検出は悪くなる。2の累乗でなければならない
既定値:32
範囲:4から512まで - ppsrc[boolean]
あらかじめデノイズなどを行った1入力目の映像から重複フレームを調べ、2入力目の映像に1入力目の重複を調べた結果を反映させる。実際のフレーム間引きには1入力目のフィルタの影響はない
既定値:0(無効) - chroma[boolean]
重複フレームを検出する計算に彩度を考慮する
既定値:1(有効) - mixed[boolean]
映像に間引くのと間引かないのが両方含まれるときの設定
既定値:0(無効)
mixedの挙動について
アニメだと初期のノイタミナのOPクレジットや一部のトランジション、販促などのスクロールテロップ、OPEDのクレジットなどが片フィールドやインターレースになっていないときに、それ以外の本編のフレームレートと異なるときに使う。
24と30の最小公倍数の120にフレームレートを合わせて、24の部分は5フレームごとに動き、30の部分は4フレームごとに動く。
ffmpeg -i input.ts -map 0:v -c:v libx264 -vf fps=fps=30000/1001,fieldmatch,decimate=mixed=1,fps=fps=120000/1001 -preset slow -crf 18 output.mp4
- フレームレートを変更するfps
- 前後フィールドを考慮して逆テレシネするfieldmatch
- [FFmpeg-devel] [PATCH] lavfi/vf_decimate: add mixed option to process input only partially to be decimated
mpdecimate
重複フレームを間引き、PTSは修正せずに可変フレームレートで出力する。-vsyncか、setpts、fps
フィルタを併用しないと間引いたフレームに再び元のフレームレートに合わせてフレームを複製するので意図した挙動にならない。似た映像を間引きdecimate
フィルタのように一定間隔の重複フレームを間引くには扱いにくい。
-vsyncの内容はffmpeg でのフレームレート設定の違い | 可変フレームレートの項目で説明している。-vsyncでエラーがでるときは-fps_modeにかえる。
基本コマンド
固定間隔ではない重複フレームを間引いたのをそのまま再生するには重複フレームが元のフレームレートに合わせて複製されるので有用ではない。
ffmpeg -i input -vf mpdecimate=max=0:hi=768:lo=320:frac=0.33,setpts=N/FRAME_RATE/TB -vsync vfr -c:a copy output.mp4
メタデータ出力に対応していないのでnull出力したログで調べる必要がある。
ffmpeg -loglevel level+debug -i input -vf mpdecimate -an -sn -dn -f null - 2>&1 | grep -e Parsed_mpdecimate | grep -e drop_count
- Is there an ffmpeg incantation that replaces duplicate frames : ffmpeg
- FFmpeg Mpdecimate filter for Dummies – Trembit
- ffprobe – Reporting duplicated frames with FFmpeg – Stack Overflow
公式ドキュメント:FFmpeg Filters Documentation : mpdecimate
オプション
- max[int]
連続して間引くフレーム間隔の指定。正の値ならフレーム間隔の最大値。負の値なら間引く1フレームを決めるフレーム間隔の最小値。0は最初のフレームを除きすべての重複フレームを間引く。具体例は後述
既定値:0
範囲:INT_MINからINT_MAXまで - hi[int]
間引くしきい値の指定。8×8ピクセルを1単位としてこの値の上限を間引く候補とする
既定値:768(8x8x12)
範囲:INT_MINからINT_MAXまで - lo[int]
間引くしきい値の指定。8×8ピクセルを1単位としてこの値の下限を間引く候補とする
既定値:320(8x8x5)
範囲:INT_MINからINT_MAXまで - frac[float]
探索する1フレーム画像の割合
既定値:0.33
範囲:0から1まで
maxの挙動について
黒単色24フレームレートで10秒の動画をテストに使い、それぞれmaxに値を代入する。代入する値をnとすると以下のような出力フレームになる。
0を指定すると1フレームだけ出力する。
ffmpeg -f lavfi -i color=r=24:d=10 -vf mpdecimate=max=0,setpts=N/FRAME_RATE/TB -vsync vfr -c:v ffv1 color.mkv
正の値を指定する。割合は1/(n+1)でnは1以上とする。
ffmpeg -f lavfi -i color=r=24:d=10 -vf mpdecimate=max=1,setpts=N/FRAME_RATE/TB -vsync vfr -c:v ffv1 color.mkv
nの値 | 出力フレーム数 | 割合 |
1 | 120 | 1/2 |
2 | 80 | 1/3 |
3 | 60 | 1/4 |
5 | 40 | 1/6 |
10 | 22 | 1/11 |
負の値を指定する。割合は-(n+1)/nでnは-2以下とする。
ffmpeg -f lavfi -i color=r=24:d=10 -vf mpdecimate=max=1,setpts=N/FRAME_RATE/TB -vsync vfr -c:v ffv1 color.mkv
nの値 | 出力フレーム数 | 割合 |
-1 | 120 | 1/2 |
-2 | 120 | 1/2 |
-3 | 160 | 2/3 |
-5 | 192 | 4/5 |
-10 | 216 | 9/10 |