====== DirectShow:IAMCrossbarのバグ(?)回避方法 ====== ===== 概要 ===== DirectShowを利用すると簡単にTVやカメラの映像をPCへ取り込むことが出来ます。\\ ただし、複数台を同時に制御しようとすると\\ **『最初に認識されるキャプチャカード(またはカメラ)しか入出力のコントロールが出来ない』**\\ という問題に直面するかもしれません。\\ 少し詳しく書くと、複数あるキャプチャデバイスの任意の1つから取得したIAMCrossbarのRouteメソッドで\\ 入力元を切り替えると、その対象デバイスではなくインデックス0に相当するデバイスの入力が常に設定されてしまいます。\\ __※玄人指向の[[http://www.kuroutoshikou.com/products/tvcuner/saa7130-b.html|SAA7130-TVPCI/B]]を3枚刺した時に 遭遇した現象なので他の種類のデバイスでは起こらないかもしれません__\\ この問題は学生時代(2006年頃)に遭遇しました。原因を探るべくDDKにあるキャプチャカードのサンプルコードを査読しました。\\ その結果、ドライバの実装の問題によって発生する問題ではないようで「IAMCrossbarコンポーネントのバグ」ではないかという結論に至りました。\\ 以下では回避方法とIAMCrossbarの代替実装のサンプルを提示します。\\ ===== 回避方法 ===== IAMCrossbarではなく、IKsControlを使用します。\\ IKsControlはキャプチャデバイスの入出力ピンを設定するWDMドライバのインターフェイスです。\\ WDM仕様のキャプチャデバイスでの実装要求となっているので、キャプチャデバイスに対してQueryInterface()を行うことで\\ このインターフェイスを取得することが出来るはずです。\\ なお、IKsControlインターフェイスを利用するにはKs.hが必要です。これはWindows DDK for Windows 2003 SP1に含まれています。\\ 詳しくは見れていませんが、最近のWindows SDKにも含まれているようです。\\ ===== サンプルコード ===== IKsControlをIAMCrossbarを経由して扱えるようにしたCXbarクラスをサンプルとして置いておきます。 サンプル: {{:programing:xbar.zip|xbar.zip}} // 使用例 HRESULT GetAMCrossbar() { HRESULT hr; IKsControl *pKsControl = NULL; IAMCrossbar *pCrossbar = NULL; // IKsControl又はIAMCrossbarを取得 hr = m_pSourceF->QueryInterface(IID_IKsControl, (void **)&pKsControl); if ( SUCCEEDED(hr) ) { hr = CXBar::CreateInstance(pKsControl, &pCrossbar); ATLASSERT(SUCCEEDED(hr)); pKsControl->Release(); } else { hr = m_pSourceF->QueryInterface(IID_IAMCrossbar, (void **)&pCrossbar); } m_pCrossbar.Attach(pCrossbar); return hr; } {{tag>Programing}}