niiyan's blog

niiyanの個人ブログ。

CopyFieldCond関数: ConditionalFilterを利用したCopyField拡張版

【2005-10-12 追記】「CopyFieldCond関数(改): フィルタ適用前のフィールドと置換可能に」に新しいバージョンを掲載しています。【追記終わり】

昨日あたりから、2ちゃんねる DTV 板の Avisynth スレッドで、「あるフィールドを別のコピーしたフィールドに入れ替える方法」に関する話題が出ていたので、HowToApplyFilterToManySingleFrames を使って CopyField 関数の拡張版を作ってみました。

HowToApplyFilterToManySingleFrames は、ConditionalFilterConditionalReader を使って、たくさんの単一フレームにフィルタをかけるテクニックです(AviSynth 開発者の sh0dan 氏が提案したもの)。HowToApplyFilterToManySingleFrames でも紹介していますので、参考にしてください。

CopyFieldCond関数

function CopyFieldCond(clip clip, string logfile, bool "debug")
{
# デフォルト値などの指定
global video = clip.SeparateFields() # フィールド分離
global FreezeThis = -1 # これは変更しないこと
debug = default(debug, false) # debugのデフォルトはfalse

# debug==trueの場合: フレーム番号の表示と各フィールドの選択
video = (debug == true) ? video.ScriptClip("Subtitle(String(current_frame))") : video
even = (debug == true) ? video.SelectEven() : NOP
odd = (debug == true) ? video.SelectOdd() : NOP

# ScriptClip: フレームごとに評価
copy = video.ScriptClip("FreezeFrame(current_frame, current_frame, FreezeThis)")

# ConditionalFilter/ConditonalReader: FreezeThisが-1より大きいならcopyから取る
ConditionalFilter(video, copy, video, "FreezeThis", ">", "-1")
ConditionalReader(logfile, "FreezeThis", false)

# debug==trueなら2画面分割表示、さもなければWeave
(debug == true) ? StackVertical(even, odd) : Weave()
}

使い方

1.ログファイル(例: CopyFields.txt)を作成

ログファイル内には、以下の 2 行を記述。

type int
default -1
2.CopyFieldCond を debug モードで使用

debug モードでは、フィールド別に上下 2 画面表示になり、各フィールドの番号が表示されます。

# 例
AviSource("foo.avi") # ソース
AssumeFrameBased().ComplementParity() # フィールドオーダーの指定
CopyFieldCond("CopyFields.txt", true) # debug=trueならdebugモード
3.「コピー先フィールドNo コピー元フィールドNo」の形式で、ログファイルに追記していく
# 例
type int
default -1
2 4
4 6
4.debug モードを解除。
AviSource("foo.avi") # ソース
AssumeFrameBased().ComplementParity() # フィールドオーダーの指定
CopyFieldCond("CopyFields.txt") # または CopyFieldCond("CopyFields.txt", false)

使用例

オリジナル:


debug モード:


フィルタ適用後:


補足

  • 簡単な動作テストはしていますが、いつものように動作無保証です。ログファイルを作成する手間などを考えると、あまり実用的とは言えないかもしれません。
  • 範囲指定も可能です(正常に動作するかどうかは別にして)。範囲指定したい場合は、ログファイルに次のように記述します。
#  1〜2フィールドを3フィールド目に置き換える
R 1 2 3

# 4〜5フィールドを5〜6フィールドに置き換える
I 4 5 5 6