戻る

Windows DDKで w2k なドライバを描こう

Sony DFW-VL500 + DirectX 8.0 (DirectShow) ・・・で,どうやって?


7月20日
White Balanceが調節できないとか,APIに金を取るとか・・・うーん, なかなか決め手となるドライバがないな.Unixだと register に書き込むとこ ろまで raw1394_writeな感じで簡単に触れるのに・・・Windowsで1394のパケッ トやdcamのレジスタをいじるには一体どうしたらええねん!?
それに,そもそもWindowsのドライバの中身はどうなっとんねん!?
・・・どうも,Windows は Linux のように小回りが 効かないし,内側が見えん
・・・ああ,やっぱりLinuxにしようか(21時20ぷん)・・・

いや,ここで引き返しては,「極めるVisual C++」を買った意味がないやんけ. やっぱこの夏でDirectShowを極めよう.ここはいっちょ自分でドライバを描くでー (21時21ぷん)
何を思ったかDDKをダウンロードしにいく(21時25ぷん)
・・・といってもdocumentを見てみると,ドライバを一から書けるとは到底思えん.うーん, 困った・・・(22時30ぷん)
ん?よくみると sonydcam なるサンプルがあるやんか.これは使えそうやな.よ しまずは,サンプルをコンパイルしてみよう(23時00ぷん).


[キーワード] Windows2000 DDK (Driver Development Kits), WDM (Windows Driver Model), KS (Kernel Streaming), KSProxy, DirectShow, 1394 Trade Association IIDC 1394 Digital Camera Spec.

  1. Windows DDK (Driver Development Kits) のインストール
    1. ダウンロード
    2. サンプルのビルド
  2. Window2000 WDM Driver 概要
  3. 1394-base VideoCapture Driver [sonydcam.sys] 概要
  4. サンプルを眺める [src\wdm\videocap\1394dcam]
    特に,CameraControlとVideoProcAmpに関しては
    1. CapProp.h : Device.c, CapProp.c の プロトタイプ宣言
    2. DcamDef.h: レジスタ空間,プロパティの 構造体定義,フレームレート等の定義 (1394dcam spec.準拠)
    3. PropData.h:
    4. Device.c : レジスタのread/write(device.c)
    5. CapProp.c: プロパティのget/set
    を参照する.カメラspecificなパラメータは,DcamDef.h, PropData.h と CapProp.cで扱う.(DcamDef.h は古いspec準拠であるため多少変更が必 要.)
    VideoFormatに関しては
    1. StrmData.h
    を参照する.
  5. プロパティをいじる
    1. プロパティの追加
    2. ホワイトバランス
  6. カスタムプロパティセットとインタフェース
  7. ビデオモードをいじる
    1. mode3 (640 x 480)でとりたい!
    2. フレームレート


Windows DDK (Driver Development Kits) のインストール

ダウンロード

http://www.microsoft.com/ddk/ よりたどる.
非常にたどりにくいのだが,要は
http://www.microsoft.com/ddk/W2kDDK.asp#Download
で,License Agreement を読み,そして[I Accept this License Agreement for the Windows DDK] というボタンを押す。一見画像 と見粉うほどだが,丁寧にテーブルで組んである・・・よけいわからんちゅーね ん!(おれだけ?)さらにボタン部分はJavaScriptを使うようになっていて,画 像の上においてもカーソルが変わらない・・・(ノ-_-)ノ ~┻━┻ うがー

サンプルのビルド

  1. スタート → プログラム → Development Kits → Windows 2000 DDK → Checked(もしくは Free) Build Environment を選択
  2. cd %NTDDK%\src
  3. build -cZ
  4. 数十分待つ


Window2000 WDM Driver 概要

User-mode driver と Kernel-mode driver

User-mode drivers
デバイス依存のWin32, MS-DOSアプリケーションや,他の protected subsystem's driver
Kernel-mode drivers
Windows NT excutiveの一部として動くdriver

Windows2000 driverといえば,Windows2000で動く全ての kernel-mode driverを指す.これは WDM とそれ以外に分けられる.
kernel-mode の driver には

Highest-level drivers
FAT, NTFS,CDFS File System Drivers(FSDs)
Intermediate drivers
PnP function/filter drivers
PnP software bus drivers (WDM driver はこれらのサブセット)
Lowest-level drivers
PnP hardware bus drivers
Legacy device drivers
の3タイプがある.(へルプ参照)
ここで扱うWDM driverは Intermediate levelに属し, 他のOS (Windows98/Meなど)とのソースレベルでの互換性をあげるため に出てきたらしい.上記のように,全てのWDMはPnP対応である.

WDM driver

Windows2000 I/O モデル

I/O Manager
kernel-mode のドライバにインタフェースを提供し,I/O リクエストを行 う.
I/O system services
I/O Manager が user-mode のsubsystem に提供するサービス群で, user-mode の subsytemはI/O system serviceを用いて I/O リクエストを行う.
IRP (I/O Request Packets)
I/O Manager が kernel-mode driver とやり取りするためのパケット.

Kernel Streaming (KS) driver

ストリームデータのデバイスを扱う WDM driverである.以下4タイプのドライバ に分類される.
Filters
デバイスの機能をカプセル化
Pins
デバイス上の I/O チャネルを表す
Clocks
on-board clock への問い合わせ等を管理
Allocators
on-board memory などのマネジメント

Stream Class driver と Minidriver

Microsoftは,KS driver を一から書く煩雑さ(cross-platform対応等)を避けるために, Stream Class driver [stream.sys] + デバイス固有のMinidriver (Miniclass driver)という組み合わせを用意している.(ただし,Auido 関係は audio class driver/audio miniport driverの組み合わせ)

ルーチン命名規則
Io---- I/O Manager Routines
Ke---- Kernel Routines
Rtl---- Run-time Library Routines
Ke---- Kernel Routines
Ke---- Kernel Routines


1394-base VideoCapture Driver 概要

プロパティ等をいじるだけであれば,ここは飛ばしてもええけど,少なくとも流 れは押さえておく必要があると思われる.

キーワード

DDKのドキュメントを読む限り,流れはとりあえず,こんな感じのようやけど. (図は合っているかどうかは分かりません.もしご存じの方で誤りに気づかれ ましたら,お知らせいただければ幸いです.)

このうち,stream.sys や ksproxy.ax は Microsoft 側から提供され,自分で書くの は(というか手を加えるのは) minidriver である SonyDCam.sys の部分.

Stream Classからの(?)IRPにおける major function.


プロパティをいじる

DcamDef.h
PropData.h
CapProp.h

プロパティの追加

DcamDef.h

  1. DCAM_EXTENSION構造体 の VideoProcAmp, CameraControls に変数を追加

KSPROPERTY

PropData.h

各プロパティについてアイテムを定義

  1. LONG xxxDefault
    デフォルト値の定義
  2. KSPROPERTY_STEPPING_LONG xxxRangeAndStep
    パラメタの範囲とステップ幅を定義
  3. KSPROPERTY_MEMBERLIST xxxMemberList(今はKSPROPERTY_MEMBERLISTの配列である)
    xxxRangeAndStep, xxxDefaulをそれぞれメンバリストへッダ(KSPROPERTY_MEMBERSHEADER)として 追加
  4. KSPROPERTY_VALUES xxxValues
    xxxMemberListを用いて値(Value)を定義
  5. DEFINE_KSPROPERTY_ITEM
    xxxValueを用いて アイテム(Item)を定義

各プロパティセットについてプロパティテーブルを定義

DEFINE_KSPROPERTY_TABLE(VideoProcAmpProperties/CameraControlProperties) へ プロパティに対応するDEFINE_KSPROPERTY_ITEMを追加

プロパティテーブルをプロパティセットテーブルへ追加

アダプタのサポートするプロパティセット(今はVideoProcAmpPropertiesとCameraControlProperties)を追加する
DEFINE_KSPROPERTY_SET_TABLE(AdapterPropertyTables)

Device.c, CapProp.c

関数
Get系 Set系
CSRレジスタのR/W DCamReadRegister DCamWriteRegister
各プロパティについて DCamGetProperty DCamSetProperty
オートモード DCamSetAutoMode
値の範囲 DCamGetRange
プロパティセットVideoProcAmpについて AdapterGetVideoProcAmpProperty AdapterSetVideoProcProperty
プロパティセットCameraControlについて AdapterGetCameraControlProperty AdapterSetCameraControlProperty
全てのプロパティセットについて AdapterGetProperty AdapterSetProperty
レジストリキー生成 CreateRegistrySingle, CreateRegistrySubKey
GetRegistryKeyValue SetRegistryKeyValue
GetPropertyValuesFromRegistry SetPropertyValuesToRegistry
SetCurrentDevicePropertyValues
InitializePropertyArray(中で GetPropertyValuesFromRegistryが呼ばれる)

青色は [DCamPkt.c]で用いられる関数.
AdapterGetProperty, AdapterSetProperty は DCamReceivePacket(pSRB) で 用いられる. SetPropertyValuesToRegistry,SetCurrentDevicePropertyValues, InitializePropertyArrayなどはドライバの初期化/終了時にレジストリの read/writeを行う(プロパティ値の保存).

カスタムプロパティセット

デバイスによっては, PROPSETID_VIDCAP_CAMERACONTROL や PROPSETID_VIDCAP_VIDEOPROCAMP では 対応しきれないプロパティ(1394 spec に新たに追加され たものや,カメラ独自のプロパティ)がある.既存の(標準の)プロパティセッ トに対しカスタムなプロパティを追加し,プロパティセットをカスタマイズする ことができる.
このようなプロパティは,kernel-mode driverレベルではKSPROPERTYとして追加できるが, user-mode のアプリケーションへはどのようにインタフェースを提供すればええ のか?

ドライバレベル

カスタムプロパティセットに対してGUIDを生成

Guidgen.exeを実行(パスはMicrosoft Visual StudioのCommonなど). 用途に適したGUID Formatを指定し,"Copy"を押すことによってクリップボードへコピーできる.
IMPLEMENT_OLECREATE(...)用
// {49BFAC9A-947D-4c12-8A09-3619C28C692A}
IMPLEMENT_OLECREATE(<>, <>, 
0x49bfac9a, 0x947d, 0x4c12, 0x8a, 0x9, 0x36, 0x19, 0xc2, 0x8c, 0x69, 0x2a);
DEFINE_GUID(...)用
// {49BFAC9A-947D-4c12-8A09-3619C28C692A}
DEFINE_GUID(<>, 
0x49bfac9a, 0x947d, 0x4c12, 0x8a, 0x9, 0x36, 0x19, 0xc2, 0x8c, 0x69, 0x2a);
static const GUID 用
// {49BFAC9A-947D-4c12-8A09-3619C28C692A}
static const GUID <> = 
{ 0x49bfac9a, 0x947d, 0x4c12, { 0x8a, 0x9, 0x36, 0x19, 0xc2, 0x8c, 0x69, 0x2a } };
レジストリフォーマット用
{49BFAC9A-947D-4c12-8A09-3619C28C692A}

今必要なのはレジストリフォーマット用です.

ドライバのプロパティセットに追加

user-modeにてカスタムCOMインタフェースを作成する

ksproxyにおいて IAMxxxxx を実装する.

ビデオモードをいじる

モード3 (640 x 480) でとりたい!

dcamのmode1から4まではすでに strmdata.h で定義されているが,dcampkt.c に おいて TIカメラのみ使えるようになっている. これを全てのカメラでも使えるように,dcampkt.c の 654, 656, 657をコメントアウトする.
    //
    // Until we build the format table dynamically,
    // we need to hardcode this.
    //
    //  TI 1394 DCam supports all modes of video format 0 (uncompressed).
    //
//    if(RtlCompareMemory(pDevExt->pchVendorName, "TI", 2) == 2) 
        StreamInfo->NumberOfFormatArrayEntries = NUM_DCAM_STREAM_FORMATS;
//    else
//        StreamInfo->NumberOfFormatArrayEntries = 1;  // 320x240 UYVY

    StreamInfo->StreamFormatsArray = &DCAM_StreamFormats[0];
これでbuildした後ドライバを更新すれば,出力ピンのプロパティから640x480 (mode3)も選べる様になる.
戻る

Created 2001/07/26 川嶋 宏彰 Hiroaki KAWASHIMA
Last Modified 2001/07/27
Copyright 2001 Hiroaki KAWASHIMA. All rights reserved.