ゲーム配信などでレイアウトを決めるときに映像が全く変わらない部分。例えばRTAのチャートの部分とか、レトロゲームを模したフレームとかそういったところの品質を下げられる。対応コーデックは H.264、H.265、VP8、VP9 など。AV1のエンコーダ(libsvtav1、libaom-av1、librav1e)は現状対応していない。ROIは(Region of Interest)の略。インターレースのフレームは「interlaced_frame not supported for ROI encoding yet, skipping ROI」で対応していない。

効果のあるエンコーダ。AMDのamfは対応しているらしいが未確認。

関連フィルタ

基本コマンド

全画面の品質を0.2悪くする。
ffmpeg -i input -vf addroi=x=0:y=0:w=iw:h=ih:qoffset=1/5 -c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k -c:a copy output
ffmpeg -i input -vf addroi=0:0:iw:ih:1/5 -c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k -c:a copy output

左上0:0座標から右と下に100ピクセルの領域に0.2品質を悪くする。
ffmpeg -i input -vf addroi=x=0:y=0:w=100:h=100:qoffset=1/5 -c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k -c:a copy output
ffmpeg -i input -vf addroi=0:0:100:100:1/5 -c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k -c:a copy output

2回フィルタを当てれば2カ所の品質を変えられる。以下の例は左3分の1の品質を0.5良くし、右3分の1の品質を0.5悪くする。
ffmpeg -i input -vf addroi=0:0:iw/3:ih:-1/2,addroi=2*iw/3:0:iw/3:ih:1/2 -c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k -c:a copy output

映像全体を指定する。この場合は8ビット深度なら51を分母に、10ビット深度なら63を分母に指定すると-crf変更と同じような効果になる。
ffmpeg -i input -vf "addroi=0:0:iw:ih:-2/51" -c:v libx264 -crf 25 -c:a copy output

コーデック別のオプション例。VP9 はROI is only enabled when aq_mode is 0, cpu_used >= 5 and deadline is REALTIMEとなるので以下のようになる。-crf単体でもフィルタは使えるが、-crfで品質指定しビットレート固定して品質の比較をしやすくしている。厳密にビットレートをそろえるなら2パスエンコード-pass 1、2するが VP8 は-crfが使えず、VP9 は-quality realtimeで2パスエンコードができない。

-c:v libx264 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k
-c:v libx265 -crf 25 -b:v 800k -bufsize 800k -maxrate 800k
-c:v libvpx -crf 25 -b:v 800k -bufsize 800k -minrate 800k -maxrate 800k
-c:v libvpx-vp9 -aq-mode 0 -cpu-used 5 -quality realtime -crf 25 -b:v 800k -bufsize 800k -minrate 800k -maxrate 800k

1440×1080の映像に左右の黒枠のついた1920×1080で、左右の黒枠にaddroiフィルタを当てて品質を下げる。
ffmpeg -i input -vf "addroi=0:0:224:ih:40/51,addroi=1696:0:224:ih:40/51" -c:v libx264 -crf 23 -c:a copy output

黒枠部分をそのままフィルタを当てるのではなくcropフィルタで取り除いた後、padフィルタで黒枠をつけなおしてその部分にaddroiフィルタを当てる。
ffmpeg -i input -vf "crop=1440:1080:240:0,pad=1920:1080:x=-1,addroi=0:0:224:ih:40/51,addroi=1696:0:224:ih:40/51" -c:v libx264 -crf 23 -c:a copy output

特定のフレーム間の品質を変えるならsegmentフィルタ、メタデータの結果でフィルタするならmetadataフィルタ、フレームの種類、映像の変化率によって品質を変えるならselectフィルタを使う。その他条件で変えるにはmetaタグを参照。

先にclear=1を当てると特定の領域の設定をリセットできるが、リセットした区画に再度qoffsetを指定しても効果がない。

ffmpeg -f lavfi -i testsrc2=d=10 -vf addroi=0:0:iw/2:ih:0:1,addroi=0:0:iw:ih:1 -c:v libx264 -crf 23 output.mp4

全画面以外で座標指定して品質を変え複数解像度にリサイズするときは出力ごと、またはリサイズごとにフィルタを当てないとオリジナルの解像度の指定座標で品質が変わる。

意図した場所の品質が変わらない。
ffmpeg -f lavfi -i testsrc2=d=5:s=1920x1080 -filter_complex addroi=0:0:iw/2:ih:1,split[1],scale=1280:720[0];[1]scale=1024:576[1] -map [0] -c:v libx264 -crf 23 output0.mp4 -map [1] -c:v libx264 -crf 23 output1.mp4

scaleフィルタの後にshowinfoフィルタをつけると side data – Regions Of Interest(ROI) information:に座標とqp offsetの値が見られる。

index: 0, region: (0, 0) -> (960, 1080), qp offset: 1/1.

出力ごとにフィルタを当てる。
ffmpeg -f lavfi -i testsrc2=d=5:s=1920x1080 -vf scale=1280:720,addroi=0:0:iw/2:ih:1 -c:v libx264 -crf 23 output0.mp4 -vf scale=1024:576,addroi=0:0:iw/2:ih:1 -c:v libx264 -crf 23 output1.mp4

リサイズごとにフィルタを当てる。
ffmpeg -f lavfi -i testsrc2=d=5:s=1920x1080 -filter_complex split[1],scale=1280:720,addroi=0:0:iw/2:ih:1[0];[1]scale=1024:576,addroi=0:0:iw/2:ih:1[1] -map [0] -c:v libx264 -crf 23 output0.mp4 -map [1] -c:v libx264 -crf 23 output1.mp4

addroiフィルタの指定座標を目視で確認するならdrawboxフィルタが1から4引数まで同じ指定方式なのでフィルタを書き換えて、5引数に色名、6引数にfillを指定する。

ffplay -i input -vf drawbox=0:0:iw/3:ih:black@0.5:fill,drawbox=2*iw/3:0:iw/3:ih:black@0.5:fill

映像に枠をつける drawbox

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

オプション

領域指定はぴったりの範囲ではなく16の倍数で目的の範囲より一回り小さい値を指定する。qoffsetの値は映像のビット深度で品質指定crfの影響が異なり、10bit深度なら 51 から -12 までの範囲である(51 – -12)の 63 を 1 とし、8bit深度では 51 から 0 までの範囲の (51 – 0)の 51 を 1 とする。単色で全く映像が変わらないならqoffset=1でよいが、色が複雑なら 0.1 くらいから調整してみる。w、hのピクセル指定はリサイズした後の解像度で指定する。

clearせずに2回以上フィルタを使い複数の場所でqoffsetを指定しても同じ区画は最初のqoffsetしか効果がない。

  • x[string]
    領域指定の横座標
  • y[string]
    領域指定の縦座標
  • w[string]
    指定範囲の横のピクセル数。xを指定して右端まで指定するときはiwからxの指定した値を引く
  • h[string]
    指定範囲の縦のピクセル数。yを指定して最下部まで指定するときはihからyの指定した値を引く
  • qoffset[rational]
    品質指定のオフセット値。負の値で品質を上げ、正の値で品質を下げる。小数でも可能
    既定値:-1/10
    範囲:-1から1まで
  • clear[boolean]
    clearを指定した以降のフィルタの効果をqoffsetで指定した値にする。2つ続けてclearすると後の設定を優先する
    既定値:0

コメントを残す

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

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