next up previous
Next: MalibSource Up: 各クラスの概要 Previous: MalibFrame

Subsections

MalibHolder

一枚以上の画像(MalibFrame)を保持する抽象クラスである。 画像データ処理の実際は、図3.4に示すブロック図に基づいて 行なわれる。 MalibHolder クラスのサブクラスとして、さらに 後段のフィルタへ接続することが可能となるバッファクラス (MalibBuffer)と、最終的なアウトプットを 生成するデスティネーションクラス(MalibGtkDisplayなど)が個別に実装される。
  
Figure 3.4: データ構造と処理の流れ
\includegraphics[scale=0.8]{images/dataflow.eps}

メンバ

MalibHolder のメンバ変数を表3.2に示す。 この中で、注意すべきはフレームテーブルへのポインタ frames である。 フレームテーブルは、フレームオブジェクト(MalibFrame)へのポインタの 配列として実現されるので、frames の型は MalibFrame** となる。
 
 
Table 3.2: MalibHolderのメンバ変数
size フレームテーブルのサイズ
current_idx 現在アクティブなフレームテーブル番号
frames フレームテーブルへのポインタ
source 入力ソースオブジェクトへのポインタ

なおフレームテーブルは MalibFrame オブジェクトへのポインタの配列となって いるので、データ構造的には各フレームのサイズやモデルが異なる場合も 許容できる。

メンバ変数framesのデータ型がMalibFrameの配列、 すなわちMalibFrame*型とせず、さらにそのポインタへのポインタ (MalibFrame**型)となっている理由は、 将来の拡張として MalibFrame を継承するサブクラスが用意された場合にも そのまま対応することができるようにとの配慮したためである。

現在の実装では、運用上の制約としてひとつのフレーム列に連なるフレームは 全て同じ種類のフレームであることを暗黙の条件として付与していることに注意 する。すなわち実際には、MalibFrame の関数 malib_frame_alloc_data_area() において、図3.5 に示すデータ構造が形成される。

  
Figure 3.5: バッファに付随するフレームテーブルおよび実データ構造
\includegraphics{images/bufandframedatastructure.eps}

本クラスのメンバ関数のうち注意すべきものは、次に述べる 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() も また同様である。

   
アクティブなフレームの更新と新規画像の取得

MalibHolder はバーチャルメンバ関数として、現在アクティブなフレーム をひとつ進める関数 malib_holder_increment_frame() を持つ。 本関数は、図3.4に示す一連の処理フローにおける処理の エントリポイントとしての重要な意味を担っている。

現在アクティブなフレームをひとつ進めると、新たにアクティブになるフレーム には新しい画像データを格納することになる。各サブクラスで 定義される 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)。

  
Figure 3.6: データ構造と処理の流れ
\includegraphics{images/recursiveprocess.eps}

リファレンスカウンティング

なお上記の一連の処理において、[*]ページで述べたとお りのリファレンスカウンティングによる同期性の確保が行なわれる。

MalibHoldermalib_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())という手順となる。



Jun IIO
2001-06-14