なおフレームテーブルは MalibFrame オブジェクトへのポインタの配列となって いるので、データ構造的には各フレームのサイズやモデルが異なる場合も 許容できる。
メンバ変数framesのデータ型がMalibFrameの配列、 すなわちMalibFrame*型とせず、さらにそのポインタへのポインタ (MalibFrame**型)となっている理由は、 将来の拡張として MalibFrame を継承するサブクラスが用意された場合にも そのまま対応することができるようにとの配慮したためである。
現在の実装では、運用上の制約としてひとつのフレーム列に連なるフレームは
全て同じ種類のフレームであることを暗黙の条件として付与していることに注意
する。すなわち実際には、MalibFrame の関数 malib_frame_alloc_data_area() において、図3.5
に示すデータ構造が形成される。
本クラスのメンバ関数のうち注意すべきものは、次に述べる malib_holder_increment_frame() の他には、 malib_holder_alloc_data_area() および malib_holder_free_data_area() である。これらはフレーム クラスとその実データを格納する領域を確保する場合に利用する。
フレームのサイズやデータ形式については、ホルダクラスは直接の責任を持たない。 これらの情報は、ソースクラスがサンプルフレームを一枚保持する ことで記録される(詳細は後述)。また、フレームのデータ構造の責任は フレームクラス自身が担うので、実際のデータ領域の確保はフレームクラスの バーチャル関数 malib_frame_alloc_data_area() にて行なわれる。
したがって、malib_holder_alloc_data_area() は単に前段の ソースからサンプルフレームを取得し、そのフレームへ領域確保を委譲するだけ である。
データ領域の解放を行なう malib_holder_free_data_area() も また同様である。
現在アクティブなフレームをひとつ進めると、新たにアクティブになるフレーム には新しい画像データを格納することになる。各サブクラスで 定義される malib_holder_increment_frame() の実体においては、 前段のソースクラスに新規フレームを渡し、そこへ新しい データを書き込んでもらうことになる。このデータの書き込みには、 MalibSource クラスのバーチャル関数である malib_source_write_frame_data() を用いる。
前段のソースクラスが始点ではなく、さらに前段の入力を持つフィルタクラスで
あった場合には、malib_source_write_frame_data() の定義に
おいて、前段のバッファクラスに対するフレーム更新の手続き、すなわち
malib_holder_increment_frame() が再帰的に呼び出される。
このような順序を経て、
終端のホルダクラスに対して malib_holder_increment_frame() を
呼び出すことにより、一連のデータ構造列に対して再帰的に処理が進むことになる
(図3.6)。
ページで述べたとお
りのリファレンスカウンティングによる同期性の確保が行なわれる。
MalibHolder の malib_holder_increment_frame() に関しては、 リファレンスカウンタの操作は以下のとおりバーチャル関数を実現している マクロ定義中に埋め込んであり、ユーザあるいは新規にサブクラスを構築する 実装者が意識する必要はない。
#define malib_holder_increment_frame(holder) G_STMT_START { \
if (MALIB_OBJECT_CHECK_NEED_UPDATE(holder)) \
{ \
(* (MALIB_HOLDER_VFUNC_TBL (holder))->increment_frame) \
(holder); \
} \
MALIB_OBJECT_DECREMENT_REFVAR (holder); \
} G_STMT_END
ホルダが行なうリファレンスカウンタ操作は、データを更新する必要が あるかどうか判定し(MALIB_OBJECT_CHECK_NEED_UPDATE())、 その結果により必要に応じて前段のフレームの更新処理を呼ぶ (increment_frame())。 さらに、テンポラリのリファレンスカウンタrefvarの操作を行なう (MALIB_OBJECT_DECREMENT_REFVAR())という手順となる。