SSブログ

aravis解析 その7 [aravis]

GObjectは複雑で難しいということは身にしみてよくわかった。この程度の知識でaravisのソースが読めるのかどうかはわからないけど読んでみることにする。まずaravis全体の構造を知るために主要なオブジェクトをざっくりみる。

4.3  aravisの主要なオブジェクトの概観

4.3.1  ArvCamera

カメラの入り口オブジェクト。インスタンス変数に
typedef struct _ArvCameraPrivate ArvCameraPrivate;

struct _ArvCamera {
        GObject             object;
        ArvCameraPrivate    *priv;
};

struct _ArvCameraPrivate {
        ArvDevice    *device;
        ArvGc        *genicam;

        // その他
};
を持っている。カメラの属性の読み書きはArvDeviceにリダイレクトしている。Gen<i>CamノードツリーのArvGcもArvDeviceから得ていて、単にキャッシュしているだけのようである。

4.3.2  ArvDevice

カメラへのコマンドを受けるオブジェクト。抽象クラスでサブクラスの
  • ArvFakeDevice
  • ArvGvDevice
  • ArvUvDevice
のどれかが実体になる。ArvDeviceはカメラのfeatureを読み書きするけど、それはArvGcのfeatureノードをとってきてそれに対して読み書きすることで実現している。

ArvGvDeviceではGigEにあるheartbeat(UDPでの切断検出のため一定周期で確認フレームを送る)信号のために専用のthreadを起こしてそこで作業している。

4.3.3  ArvInterface

インターフェイスハードウェアの抽象クラス。device_idsという配列を持っていてデバイスを列挙すると配列にその情報を保持する。サブクラスに
  • ArvFakeInterface
  • ArvGvInterface
  • ArvUvInterface
があって、列挙の実作業はサブクラスが行う。

4.3.4  arvsystem

arvsystem.cはオブジェクトを定義していない。staticにArvInterfaceの配列
typedef struct {
    const char  *interface_id;
    gboolean    is_available;
    ArvInterface *     (*get_interface_instance) (void);
    void         (*destroy_interface_instance) (void);
} ArvInterfaceInfos;

ArvInterfaceInfos interfaces[] = {
    {
        .interface_id = "Fake",
        .is_available = FALSE,
        .get_interface_instance = arv_fake_interface_get_instance,
        .destroy_interface_instance =  arv_fake_interface_destroy_instance
    },
#ifdef ARAVIS_BUILD_USB
    {    
        .interface_id = "USB3Vision",
        .is_available = TRUE,
        .get_interface_instance = arv_uv_interface_get_instance,
        .destroy_interface_instance = arv_uv_interface_destroy_instance
    },
#endif
    {
        .interface_id = "GigEVision",
        .is_available = TRUE,
        .get_interface_instance = arv_gv_interface_get_instance,
        .destroy_interface_instance = arv_gv_interface_destroy_instance
    }
};
を(static宣言されてないけど)持って、インターフェイスのenable/disableとデバイス列挙とArvDeviceの生成をする。またstaticにmutexを持っていてArvInterfaceをいじるときはロックしている。

デバイス列挙などの作業はArvInterfaceのオブジェクトにリダイレクトしている。

4.3.5  ArvStream

カメラからのデータ転送を制御するオブジェクト。これも抽象クラスで
  • ArvFakeStream
  • ArvGvStream
  • ArvUvStream
のサブクラスがある。データの受け取りは専用スレッドで行う。サブクラス側はタイミングクリティカルな作業になるので、ソースの字面も随分違った雰囲気になっている。

ArvStreamには非同期キュー(メッセージを非同期にやり取りする)が2本とmutexがあって何に使っているかというと、ArvBufferのポインタを詰め込んでリングバッファ動作を実現している。一方のキューからArvBufferを取り出してカメラからのデータを書き込み、全部埋まったらもう一方のキューに押し込む。

空のArvBufferがキューになくなったらunderrunのエラーが発生する。underrunの回数を数えていて統計情報として読み出せるようになっている。これ、underrunが一定時間続いたら何らかのアクションを起こすようにしたほうがいいな。underrunが増えるということはArvBufferをpopする側の処理がフレームレートより遅いということなので、underrunが増え出したら増える一方だろう。

4.3.6  ArvBuffer

フレームバッファオブジェクト。payloadのタイプごとにサブクラスがありそうだと思ったんだけどそうなってなかった。これは特に変わったことはしていない。preallocatedポインタを持っていて、インスタンスを作るときメモリ領域が渡されてきたらインスタンス破棄ではそのメモリを解放しないようになっている。

4.3.7  ArvGc

Gen<i>Camのノードツリー全体を表すオブジェクト。ArvGcはArvDomDocumentのサブクラスになっている。
ArvDomなんとかというクラスがいくつかあって
  • ArvDomNode
  • ArvDomElement
  • ArvDomDocument
  • ArvDomCharacerdata
  • ArvDomText
などで一般的なXMLのノードをオブジェクトにしている。XMLのパースはlibxml2を使ってarvdomparserで定義された関数で行なっている。arvdomparserそのものはオブジェクトではない。

ArvDomElementのサブクラスとしてArvGcNodeがあってさらにそのサブクラスとしてGen<i>Camの属性を持った
  • ArvGcPropertyNode
  • ArvGcFeatureNode
が定義されている。さらにGen<i>Camのfeatureの型ごとにArvGcFeatureNodeのサブクラスと、feature以外のノードであるプロパティとしてArvGcPropertyNodeのサブクラスがある。

ArvGcFeatureNodeのサブクラスとしてArvGcPortがあって、ArvDeviceがこれを呼んで実際のカメラレジスタの読み書きを行っている。

4.3.8  GVCP、GVSP、UVCP、UVSP

GigEとUSB3のコマンドフレームを作るのがGVCP、UVCP、応答フレームを読んでデータに再構成するのがGVSP、UVSP。これはオブジェクトにはなってなくて、関数群。仕様通りになってるだけで難しいことはしていない。

4.3.9  ArvZip

最近のカメラのGen<i>Cam記述ファイルは肥大化していて、多くが圧縮されてカメラに格納されている。その圧縮を解くのがこのオブジェクトで、zlibを使っている。

読めなくはないな。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。