ついに動画編集の連載も10回目になってしまいましたね。
まさかこんなに続けることになるとは思いもしませんでした。
今回はVideoProcessor(以下VP)で扱う画像に関するお話です。


REAPER上の全トラックを見渡してみて、現在の再生カーソル位置に複数の動画が縦に並んでいる場合を考えてみましょう。この時、例えば一番上のトラックに挿入されたVPスクリプトでは複数の画像を参照出来るようになっています。

VPのAPIではある画像の「次の画像」のハンドルを取得できるようになっているのですが、これは一体何を指しているのでしょうか。などなど、こういった入力画像まわりの事が一見分かりにくいように感じたので、このあたりどうなっているのか少し調べた結果をまとめておきます。

画像コンテナ(推測)

REAPERの動画機能では再生中の位置に応じて何枚もの画像が構築され、これが複数のVPによってアクセスされるといった構造になっているようです。REAPER内部の画像コンテナがあるようで、そこに現在のフレームで使用される画像が全て追加されていくようです。

どういう画像が追加されていくかというと、現在のフレームにおける「動画の現在の画像」「Itemに挿したVP処理後の画像」「Trackに挿したVP処理後の画像」などです。FXに複数のVPを挿していれば、それらの処理後の画像が全てコンテナ内に追加されていくことになります。

VPの処理内においても一時的に使用する画像を確保・解放(gfx_img_alloc(), gfx_img_free())ができますが、これもこの画像コンテナとのやりとりになります。最大で扱える画像枚数は全部で32個までのようです。

あるVPを処理するタイミングでは、その下にあるトラック群で作られた画像が全てコンテナに含まれるので、それらを利用して画像効果を作れるという感じです。このようにVPは他のTrackの動画やVPと連携した処理が行える点が特徴の1つになっていると言えるでしょう。

※このへんはAPIを使った結果を見ての推定なので、間違ってたらごめんなさい

画像ハンドルについて

画像を扱うには画像ハンドルという整数の番号を使ってアクセスします。
ハンドルの番号には一応規則性がありますが、どの動画・VPが何番なのかということを本来意識する必要はありません。刻々と再生位置での動画・VPの個数が変わっていくので、決め打ちの番号でアクセスするのは危険です(後述するAPIを使うことになる)。

また、画像ハンドルの0番はある意味特殊なもので、そのVPの直前までに生成された結果の画像になっています。なので、多くのVPプリセットではこれを使って画像エフェクトを実装しています。

画像ハンドルを取得するAPI

現在のVPの処理を行う時点で存在する画像の個数は input_count() で取得できます。ただし、個数が分かるだけで、どの画像がどれなのかはこれだけでは特定できません。

次は動画処理を行っているトラック数、これを取得するには input_track_count() を使用します。ただしここで言う「トラック数」にはVP自身のいるトラックを含まず、これより下側に位置するトラック数のうち動画処理を行わないトラックは除外されたトラック数が返ってきます。

ここでさらに input_track_exact_count() では、上記のトラック数に似ていますが動画処理を行わないトラックも含まれたトラック数が返ってきます。VPを処理している次のトラックから、動画処理をしている最も下に位置するトラックまでのトラック数、という感じです(後で出てくる図を参考に)。

ここまでで個数が3種類出てきましたが、普通に各トラックの画像を取得したければ、例えば
numTrack = input_track_count();
という感じで有効なトラック数を取得します。
numTrack=3 だったら、0~2のインデックスで
img = input_track( index );
としてやれば img に現在使われている各動画トラック処理後の画像が取得できます。

input_track_exact( index ) では input_track_exact_count()-1 までのインデックスを指定出来ますが、動画処理を含まないトラックを指定すると、その旨を表す値(-1000)が返ってきます。また、input_track_exact_count()以上の値のインデックスを渡すと、これも範囲外を示す値(-10000)が返ってきます。

では同じトラック上で重なっている複数の動画の画像にアクセスするにはどうすればいいかというと、 input_next_item( img ) を使用します。ある画像ハンドルを渡すと、次の画像ハンドルを返してくれます。そのトラック上に次がなければ、次のトラックへ進んでいくことになります。

input_next_track( img ) というものもありますが、これはトラック単位で次のものを探すものになります。ひとつのトラック上で複数の動画が重なっていても、次のトラックへ進むという感じです。

実際の例で挙動を確認

ここで実際に例を見てみましょう。
現在再生カーソルはアイテム[1]とアイテム[2]が重なっているところにいます。
各アイテムにはFXにVPが2つあり、色変えと文字表示(アイテム[1]なら (1) と表示)をしています。
トラック1には下の方の図に示す画像を表示するVPスクリプトを挿入しています。
トラック4には "ABC" という文字を表示するVPがセットしてあります。

以下ではトラック1のTrackFXで実行しているVPスクリプトにおける値を説明します。下図に再生位置やVideoWindowの表示例を示してあります。

VP_Img01
 ↓ Track1のVPでVideoWindowに表示している画像です
VP_Img02
  • 全画像数: input_count() = 7(画像ハンドルは0~6までが有効)
  • 有効トラック数: input_track_count() = 1
  • トラック数(exact): input_track_exact_count() = 3
  • 最終画像ハンドル 0 をスタートと考えると、画像0の次の画像(Item単位)は画像3、画像3の次は画像6(画像ハンドル値は下にあるVideoWindowの図の下方の画像それぞれに対応しています。図の赤線で囲ったNextImg(Item)などの値が、ある画像の次の画像ハンドルを示しています)
  • 上記に出てこない、画像1, 2, 4, 5は何かというと、このフレームに存在する各VPが出力した画像のようです。動画のオリジナル画像(2, 5)、それを色変えした画像(1, 4)、さらにテキストを乗せた画像(0, 3)、の3つが各ItemのVPで生成されていると考えればわかりやすいですね。
だいぶ数字だらけで眩暈がしそうですが、「へー、そうなんだー」くらいにとらえてもらえればよいかと。こういったVPのAPIを使う時の参考にしてもらえれば幸いです。


今回の検証では、動画の画像を加工する際に必要になる画像まわりの仕組みについて、いろいろと理解出来てよかったです。