niiyan's blog

niiyanの個人ブログ。

FilterRange で最終フレームまでを範囲に指定すると 1 フレーム水増しされる件

Leben ist vorbei \(^o^)/: FilterRange を読んで、自分が改造したもののことを思い出したので、もう一回、確認の意味で調べてみました。プチ更新情報に、この件についての記述があるので、約 4 年前のネタになります……。

検証

以下のようなスクリプトを作成します。

# ソース
ColorBars(320,240).Trim(0,9) # 10 フレームのみ
# フレーム番号の追加
ScriptClip("Subtitle(String(current_frame), size=120, align=5)")
# FilterRange
FilterRange(7, 9, "Invert()") # 最終フレームまで

FilterRange 適用前は

このようなクリップだったのが、FilterRange 適用後は

こうなります。やはり最後の 1 フレームが水増しされています。そして、水増しされたフレームは、フィルタ適用前のものです。

原因と対策

c3 = clip.trim(end + 1, 0)

オリジナルの FilterRange では、ここで end + 1 から 0(0 は最後までを意味する)を選択しているのですが、end が最終フレームの場合、c3 には最終フレームが入ります。

c = end == 0 ? c : c + c3

そして、end が最終フレームの番号と一致しても end == 0 の条件にはあてはまらないので、c に c3 (つまり最終フレーム)を結合したクリップを返します。これが 1 フレーム水増しされる原因です。

これを防ぐには、最低限、end が最終フレームの場合にも c のみを返すように条件を追加すればいいことになります。最終フレームかどうかの判定には、FrameCount() 関数を使用するとよいでしょう。

改造版

AviSynth Wiki - FilterRange に改造版をアップしました。以前、改造したものより、さらに手を加えてあります。もう少しうまく書けそうですな気もしますが、今日のところはこれで。