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の場合をちょっと高速化