ゲーム配信などでレイアウトを決めるときに映像が全く変わらない部分。例えば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は対応しているらしいが未確認。
- libx264
- libx265
- libvpx(clearが効かない)
- libvpx-vp9(-cpu_usedが5以上)
- h264_amf
- hevc_amf
- h264_qsv:ffmpeg 5.1からの予定
関連フィルタ
基本コマンド
全画面の品質を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タグを参照。
- フィルタ内で分割するsegment、asegment
- メタデータをコンソールに表示する metadata, ametadata
- 特定の映像フレームや音声サンプルを出力するselect, aselect
先に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
公式ドキュメント: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