potatosubさんのブログ読んでたら、yrangemaskなるフィルタを使っているのに気づきました。
わたくし、このフィルタはこれまで知らなかったんですが、ちょっと気になったことがあったので実験してみました。
#test.avs
LoadPlugin("yrangemask.dll")
LoadPlugin("masktools2.dll")
#1920x1080のグラデーション画像10000フレーム
BlankClip(length=10000, width=1920, height=1080, pixel_type="YV12")
mt_lutspa(mode="relative", expr="x 256 *", chroma="128")
#yrangemask(16, 4, 80, 16, true)
mt_yrangemask(16, 4, 80, 16, true)
function mt_yrangemask(clip clip, int "min_y", int "fade_min_y", int "max_y", int "fade_max_y", bool "invert")
{
assert(clip.IsPlanar(), "clip is not planar format")
min = default(min_y, 0)
max = default(max_y, 0)
assert(min >= 0 || min < 256 || max < 256, "Specify in the range from 0 to 255")
assert(min <= max, "min_y must be less than or equal to max_y")
fmin = default(fade_min_y, 0)
fmax = default(fade_max_y, 0)
assert((fmin + fmax) <= (max - min), "'fade_min_y + fade_max_y' should be less than or equal to 'max_y - min_y'")
min = string(min - 1)
max = string(max + 1)
fmin = string(fmin + 1)
fmax = string(fmax)
invert = default(invert, false)
#expr = 255 / (x < max - fmax ? fmin / (x - min) : (fmax + 1) / (max - x))
#expr = invert ? 255 - expr : expr
expr = "255 / (x < " + max + " - " + fmax + " ? " + fmin + " / (x - " + min + ") : (" + fmax + " + 1) / (" + max + " - x))"
expr = (invert ? "255 - " : "") + expr
return clip.mt_lut(mt_polish(expr), chroma="0")
}
で、
$ for i in {1..3}; do avs2pipemod -benchmark test.avs; done
yrangemask mt_yrangemask
1 303.556fps 889.047fps
2 300.232fps 890.155fps
3 301.298fps 891.027fps
------------------------------------
avg 301.695fps 890.076fps
やはり気のせいではなかったようです。
mt_lutは起動時にあらかじめxが0から255までの256パターンの計算を行いLUT(ルックアップテーブル)を作るため、実行中の処理スピードは式がどれだけ複雑になっても変わりません。
LUTのサイズは256バイトですから、L1キャッシュに収まるため高速です。
逆ポーランド記法もmt_polishを使えば覚えなくて済むので、積極的に使ってみることをお勧めします。
追記:2016/01/21 mt_lutの式を簡略化 & invert=trueの場合をちょっと高速化
0 件のコメント:
コメントを投稿