アットウィキロゴ
ノート > DirectShow 入門 > SampleGrabberでWebカメラから取得した画像をテクスチャとして貼り付ける

SampleGrabberでWebカメラから取得した画像をテクスチャとして貼り付けるプログラムに付いて
解説したい所ですが、ひとまず荒川の身に起こっている事態について話させてください。

解決しました

SVNの trunk/directx/ 内にある
TextureFromSampleGrabber2
のslnファイルをダブルクリックしてVisual Studioを起動させてください。

ポイントとなったところを3つメモしておきます。

村山くんからのアドバイス

MEDIASUBTYPE_ARGB32 を使用して、
併記してあるサンプルで a,r,g,b を足したものを
テクスチャの領域へコピーすればOK

pBuffer の並び順

テクスチャへの貼り付けはアドバイスで何とかなったのですが、
その内容が、上下と左右がそれぞれ逆でした。

どうやら、pBufferには1画面の内容が一番最後(右下)から入っているようだったので、
pBufferのポインタのアドレスを一番最後まで進めた後、
ポインタのアドレスをデクリメントしていくようにしました。

pTexture の解放

表示自体は上の2つのポイントでできましたが、
今度はメモリリークが起こっているようでした。

思えば、元々のプログラムは
「スプライトにお弁当のテクスチャを貼りつけて以後更新しない」
というものだったので、テクスチャオブジェクト pTexture の解放は
プログラム最後に FreeDx() 内で一回だけ行われるのみでした。

今回はテクスチャオブジェクトは CreateTextureSampleGrabber() により
何度も作成されているので、DrawSprite() の最後で SAFE_RELEASE(pTexture) を実行して
適時解放するようにしました。


現段階のプログラム

Subversionの trunk/directx 以下に
TextureFromSampleGrabber
というプロジェクトフォルダーがありますので、
その中にあるソリューションファイルをダブルクリックして
Visual Studio を起動させてください。

問題点

SampleGrabberから取得したバッファを
正しくテクスチャへ渡せていないような気がします。

SampleGrabberでWebカメラから画像を取得している部分

ShowXFile_test20100510.cpp
こちらのソースファイルの 493行目辺り(DrawSprite関数内)の下記の部分です

pMediaControl->GetState(INFINITE, &fs); // ある一定時間待たないと、GetCurrentBufferで VFW_E_WRONG_STATE を起こす
hr = pSampleGrabber->GetCurrentBuffer(&nBufferSize, pBuffer); // nBufferSize の大きさで pBuffer に現在のカメラの画像を渡す
  • 最初の行は GetCurrentBuffer() で取得するための待ち時間です
  • 2行目で具体的に nBufferSize の大きさで pBuffer に画像を渡します

テクスチャのために変換してテクスチャに渡しているつもりの部分

CreateTextureSampleGrabber.cpp
こちらのソースファイルの 45行目辺りの下記の部分です

data = 0;

/* コメントがズラズラ */

//pBuffer から RGB を取り出しているつもり
//だがしかし、「b = ~」の処理でメモリ違反を起こしてしまう
b = ((unsigned char*)(pBuffer + Width * y))[x * 3];		//B
data += b;
g = ((unsigned char*)(pBuffer + Width * y))[x * 3 + 1];	//G
g <<= 8;
data += g;
r = ((unsigned char*)(pBuffer + Width * y))[x * 3 + 2];	//R
r <<= 16;
data += r;

/* コメントがズラズラ */

*to++ = data; //テクスチャに変換した値を渡す
  • 最初の行「b = ((unsigned char*) ~」でメモリ違反を起こして止まってしまう

to は29行目辺りで下記のように定義されている
unsigned long *to = (unsigned long*)pLockedRect.pBits;

pLockedRect は14行目辺りでこのように定義されている
//ロック
D3DLOCKED_RECT pLockedRect;
hr = (*ppTexture)->LockRect(0, &pLockedRect, NULL, 0);
if(FAILED(hr)){
	return hr;
}
  • テクスチャをロックしておいて、テクスチャの変更には pLockRect から行う様子



何かコメントをあげる
最終更新:2010年05月25日 19:28