fieldhintフィルタで手動インターレース解除しH.264のハードウェアエンコードする。手動インターレース解除するとぎりぎり1倍速以上出るので縞フレームの場所が分かればライブ配信にも使える。patternオプションは2022年3月15日に追加されたものなのでffmpegはソースコードからビルドする。

手動でフィールド処理を行う fieldhint

日常ものならば-b:v 4M指定でもよいが、動きが多いと-b:v 4Mではノイズが多い。1920×1080も-b:v 6M程度は必要かも。フレームタイプのフラグがこのままだとインターレースのままなので、setparamsフィルタでプログレッシブに変更できる。

フィールドタイプや色域を記述するsetparams

コマンドは重複フレームをブレンドする例。

ffmpeg -analyzeduration 10MB -probesize 10MB -i input.ts \
  -vf "setpts=PTS-STARTPTS,fieldhint=pattern2.txt:pattern,split[1],\
  shuffleframes=0 1 2 -1 -1[0];\
  [1]tblend=all_mode=average,shuffleframes=-1 -1 -1 3 -1,
  [0]interleave,setparams=field_mode=prog" \
  -r 24000/1001 -c:v h264_v4l2m2m -num_output_buffers 64 -num_capture_buffers 128 \
  -b:v 4M -c:a copy -bsf:a aac_adtstoasc output.mp4

エンコーダでh264_v4l2m2mをつかうと、なぜか1440×1080の解像度で映像が乱れるのでリサイズしなければならないが、リサイズしてもまだ1倍速以上をキープしていた。

ffmpeg -analyzeduration 10MB -probesize 10MB -i input.ts \
  -vf "setpts=PTS-STARTPTS,fieldhint=pattern2.txt:pattern,split[1],\
  shuffleframes=0 1 2 -1 -1[0];[1]tblend=all_mode=average,shuffleframes=-1 -1 -1 3 -1,\
  [0]interleave,scale=1280:720,setparams=field_mode=prog" \
  -r 24000/1001 -c:v h264_v4l2m2m -num_output_buffers 64 -num_capture_buffers 128 \
  -b:v 4M -c:a copy -bsf:a aac_adtstoasc output.mp4

separatefields、weaveフィルタで代用することもできる。手元で試すとbwdif、decimateフィルタ併用よりフレーム数が少し少ないのが気になった。この原因はshuffleframesが扱うフレーム数によるもので、10フレーム処理するならフィールド分離して2倍フレームになるので下一桁5の倍数フレームないと最後近辺のフレームが抜ける仕様になっている。
-vf "separatefields,shuffleframes=0 1 4 3 6 5 8 9 -1 -1,setfield=tff,weave,setpts=(N*1001)/(24000*TB),setparams=field_mode=prog" -r 24000/1001 -fps_mode cfr

フレーム抜けを抑えるためにtpadフィルタで末尾フレームをコピーして増やす。
-vf "tpad=stop=2:stop_mode=1,separatefields,shuffleframes=0 1 4 3 6 5 8 9 -1 -1,setfield=tff,weave,setpts=(N*1001)/(24000*TB),setparams=field_mode=prog" -r 24000/1001 -fps_mode cfr

ffprobeでフレーム数を調べるにはすぐに終わるメタデータから調べる方法と、
ffprobe -v error -i input -select_streams v:0 -show_entries stream=nb_frames -of csv=p=0

時間のかかる全フレームデコードする方法がある。
ffprobe -v error -i input -select_streams v:0 -show_entries stream=nb_read_frames -count_frames -of csv=p=0

コメントを残す

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

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