フィールドオーダーが予め分かっている場合に、テキストファイルに正しいフィールドオーダーを記載することでどのインターレス解除フィルタよりも高速に逆テレシネ、プログレッシブ化できるfieldhintフィルタの使い方。いわゆる逆テレシネフィルタである。

間引くフレームも分かるのでdecimateフィルタではなくtrimフィルタを使うことでより正確に処理ができる。フィールドを選択できるのがfieldhintフィルタでフレームを選択するのがselectフィルタ。固定周期なら一度の指定で済むが途中で周期が変わると ffmpeg だけでは場所の特定が難しい。weaveフィルタでフィールドをフレームに並べてshuffleframesフィルタで一定周期のフレームを間引ける。

基本コマンド

単純なプログレッシブ化
ffmpeg -i input -vf fieldhint=hint.txt:relative output
ffmpeg -i input -vf fieldhint=hint.txt:1 output
ffplay -i input -vf fieldhint=hint.txt:1

ntsc 29.976 フレームレートの動画をtrimフィルタを併用して5フレーム中2フレーム目を間引く例(n は 0 スタート)。trimフィルタで間引く場合はfpsフィルタで正しいフレームレートを指定しないと再び重複フレームが作られる
ffmpeg -i input -vf fieldhint=hint.txt:relative,select='mod(n-1,5)',fps=24000/1001 output

trim フィルタの使い方
ffmpeg で使える評価式

ffmpeg – remove sequentially duplicate frames – Stack Overflowよりtrimフィルタを使わずにmpdecimate, decimateフィルタを代わりに使う。

ffmpeg -i input -vf decimate output
ffmpeg -i input -vf mpdecimate,setpts=N/FRAME_RATE/TB output

公式ドキュメント:FFmpeg Filters Documentation : fieldhint

オプション

  • hint[string]
    フィールド指定ファイルを指定する。.txtや.csvファイルを使う
    既定値はないので必ず指定する
  • mode[int]
    フィールド指定ファイルのフレーム番号の指定方法
    • 0, absolute:絶対フレーム番号指定。既定値
      hintファイルの指定値:現在フレーム番号から前後1フレーム
    • 1, relative:相対フレーム番号指定
      hintファイルの指定値:-1, 0, 1
    • 2, pattern:相対フレーム番号指定で最終行まで進むと冒頭に戻ってループする。2022年3月15日に追加
      hintファイルの指定値:-1, 0, 1

hintファイルの書き方

出力フレーム数が hintファイルのフレーム数に収まっていないとエラーになるので余裕を持って記入しておく。2つの数字を指定した後に+,を指定することで+ならインターレス、ならプログレッシブのフラグを立てられるがつけなくてもよい。2つの数字でトップフィールドファーストなら最初の数字がトップフィールド、カンマをつけて、次の数字がボトムフィールドになる。片方の数値を書かない場合は1フィールドで1フレームを出力する(用途不明)。また行頭#,;でコメントを記入できる。

既定値はabsolute(絶対フレーム数)だが hintファイルはrelative(相対フレーム数)のほうが書きやすい。また、最初から最後まで縞が出る間隔が変わらないならpattern、途中で変わりその場所を特定できるならabsoluteが書きやすい。

relative向けの hintファイルの例。該当フィールドで0ならそのフィールドに、-1 なら1つ前のフィールドに、1なら1つ先のフィールドを出力する

pattern向けの hintファイルの例。

absolute向けの hintファイルの例

重複フレームと trim の関係

あるのかどうかは知らないが間引く最初の1フレームだけインターレースの場合は、片フィールドしかないのでフィールドをずらさずに先にカットtrim=start_frame=1する。ffmpeg のログ出力は 0フレームスタートだが、1フレームスタートの方が感覚的にわかりやすい。映像がすでにプログレッシブで重複フレームがある場合は、間引くフレームの該当フレームを調べる。ボトムフィールドは相対値で表している。

ffmpeg で時間単位やフレーム単位でカットする方法
trim フィルタの使い方

23プルダウンや32プルダウンは以下を参照。
エンコ入門 – 第2回 プルダウン – エンコ

0フレームスタートの例。

ボトムフィールド 縞フレーム trimコマンド 間引くフレーム 備考
00-1-1000-1-10 2378 mod(n-2,5) 27 23プルダウン
0-1-1000-1-100 1267 mod(n-1,5) 16 32プルダウン
-1-1000-1-1000 0156 mod(n,5) 05
-1000-1-1000-1 04590 mod(n-4,5) 49
000-1-1000-1-1 3489 mod(n-3,5) 38

1フレームスタートの例

ボトムフィールド 縞フレーム trimコマンド 間引くフレーム 備考
00-1-1000-1-10 3489 mod(n-2,5) 38 23プルダウン
0-1-1000-1-100 2378 mod(n-1,5) 27 32プルダウン
-1-1000-1-1000 2367 mod(n,5) 16
-1000-1-1000-1 1560 mod(n-4,5) 50
000-1-1000-1-1 4590 mod(n-3,5) 49

patternモードとshuffleframesフィルタの関係

23プルダウンで2番目の重複フレームを間引く。

fieldhint 0,0
0,0
0,-1
0,-1
0,0
0,0
0,-1
0,-1
0,0
0,0
0,-1
0,-1
0,0
0,0
0,0
0,-1
0,0
0,0
0,0
0,-1
shuffleframes 0 1 -1 3 4 0 -1 2 3 4 -1 1 2 3 4 0 1 2 3 -1
重複フレーム 1, 2 0, 1 4, 0 3, 4

運用例

idetフィルタのrepeated.current_frameneither,neither,top,neither,bottomが来る最初のフレーム番号から1を引いた値をtrimフィルタの開始フレームに指定する。フレーム番号はメモ帳以外のエディタでよく見られる行番号を参考にするか、lavfi.idet.repeated.neitherを参考にする。コマーシャル含めて一括でフィルタを当てると途中で縞の場所が変わってプログレッシブ化に失敗するパートがでることもある。

通常ならこのコマンドのログを見比べる。

ffprobe -v error -f lavfi -i movie=input.ts,idet -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.idet.repeated.current_frame,lavfi.idet.repeated.neither -of csv > output.csv

ffprobe -v error -f lavfi -i movie=input.ts,idet -select_streams v:0 -show_entries packet=pts_time -show_entries packet_tags=lavfi.idet.repeated.current_frame,lavfi.idet.repeated.neither -of json > output.json

音声の開始サンプルはmediainfoの音声遅延(Delay relative to video)を調べて、例えば、48kHzで音声遅延が-362msでtrimフィルタの開始フレームが354の30/1.001fpsの場合、

サンプルレート*(遅延の正負逆の値+trimのフレーム数/(動画のフレームレート))
48000*(0.362+354/(30/1.001))

インターレース解除はfieldhintフィルタで23プルダウンして、trimフィルタで間引く。mediainfo の遅延は ffmpeg では計算方法が見つかっていない。

ffmpeg -i input.ts -vf trim=start_frame=353,setpts=PTS-STARTPTS,fieldhint=23.csv:1,select='mod(n-2,5)',fps=24000/1001 -af atrim=start_sample=584342,asetpts=PTS-STARTPTS -c:v libx264 -c:a aac -sn output.mp4

patternの利用例。pattern.txtの行をずらしながらshuffleframesフィルタの間引くフィルタを指定するとうまく処理できる。-rで出力フレーム数を指定しないと改めて元のフレームレートで重複フレームが挿入される。
ffmpeg -i input.ts -vf "setpts=PTS-STARTPTS,fieldhint=pattern.txt:pattern,shuffleframes=-1 1 2 3 4" -r 24000/1001 -c:v hevc_nvenc -c:a aac -sn output.mp4

patternで5通りのファイルを容易に比較できるので数十秒比較してSingle frame detection Progressiveの一番大きな値のrelative.txtがおそらく正解。

ffmpeg -i input.ts -vf setpts=PTS-STARTPTS,fieldhint=pattern0.txt:pattern,idet -an -t 30 -f null -
ffmpeg -i input.ts -vf setpts=PTS-STARTPTS,fieldhint=pattern1.txt:pattern,idet -an -t 30 -f null -
ffmpeg -i input.ts -vf setpts=PTS-STARTPTS,fieldhint=pattern2.txt:pattern,idet -an -t 30 -f null -
ffmpeg -i input.ts -vf setpts=PTS-STARTPTS,fieldhint=pattern3.txt:pattern,idet -an -t 30 -f null -
ffmpeg -i input.ts -vf setpts=PTS-STARTPTS,fieldhint=pattern4.txt:pattern,idet -an -t 30 -f null -

重複フレームをブレンドする

重複フレームをtblendフィルタで平均して2番目のフレームを間引く。
ffmpeg -i input.ts -vf "setpts=PTS-STARTPTS,fieldhint=pattern.txt:pattern,split[1],shuffleframes=0 -1 -1 3 4[0];[1]tblend=all_mode=average,shuffleframes=-1 1 -1 -1 -1,[0]interleave" -r 24000/1001 -c:v hevc_nvenc -c:a aac -sn output.mp4

fieldhint 0,0
0,0
0,-1
0,-1
0,0
0,0
0,-1
0,-1
0,0
0,0
0,-1
0,-1
0,0
0,0
0,0
0,-1
0,0
0,0
0,0
0,-1
shuffleframes 0 -1 -1 3 4 -1 -1 2 3 4 -1 1 2 3 -1 0 1 2 -1 -1
tblend後のshuffleframes -1 1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 4 -1 -1 -1 3 -1
重複フレーム 1, 2 0, 1 4, 0 3, 4

AviSynthで複数の映像を使う場合。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)