フィールドオーダーが予め分かっている場合に、テキストファイルに正しいフィールドオーダーを記載することでどのインターレス解除フィルタよりも高速にプログレッシブ化できるfieldhint
フィルタの使い方。いわゆる手動インターレース解除フィルタである。
間引くフレームも分かるのでdecimate
フィルタではなくtrim
フィルタを使うことでより正確に処理ができる。フィールドを選択できるのがfieldhint
フィルタでフレームを選択するのがselect
フィルタ。固定周期なら一度の指定で済むが途中で周期が変わると ffmpeg だけでは場所の特定が難しい。一定周期で間引くなら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
ffmpeg – remove sequentially duplicate frames – Stack Overflowよりtrim
フィルタを使わずにmpdecimate, decimate
フィルタを代わりに使う。
ffmpeg -i input -vf mpdecimate output
ffmpeg -i input -vf decimate,setpts=N/24/TB output
公式ドキュメント:FFmpeg Filters Documentation : fieldhint
オプション
- hint[string]
フィールド指定ファイルを指定する。.txt や .csv でファイルを保存する
既定値はないので必ず指定する - mode[int] フィールド指定ファイルのフレーム番号の指定方法
- 0, absolute:絶対フレーム番号指定。既定値
hintファイルの指定値:現在フレーム番号から前後1フレーム - 1, relative:相対フレーム番号指定
hintファイルの指定値:-1, 0, 1
- 0, absolute:絶対フレーム番号指定。既定値
hintファイルの書き方
出力フレーム数が hintファイルのフレーム数に収まっていないとエラーになるので余裕を持って記入しておく。2つの数字を指定した後に+,–を指定することで+ならインターレス、–ならプログレッシブのフラグを立てられるがつけなくてもよい。2つの数字で最初の数字がトップフィールド、カンマをつけて、次の数字がボトムフィールドになる。片方の数値を書かない場合は1フィールドで1フレームを出力する(用途不明)。また行頭に#,;でコメントを記入できる。
既定値はabsolute(絶対フレーム数)だが hintファイルはrelative(相対フレーム数)のほうが書きやすい。また、最初から最後まで縞が出る間隔が変わらないならrelative、途中で変わりその場所を特定できるならabsoluteが書きやすい。
relative向けの hintファイルの例。該当フィールドで0ならそのフィールドに、-1 なら1つ前のフィールドに、1なら1つ先のフィールドを出力する
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 |
運用例
idet
フィルタのrepeated.current_frameでneither,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
ffmpeg fieldhint filter. relative 23pulldown file : gist.github.com