ビデオ出力フォーマットの設定
キャプチャ デバイスは一定範囲の出力フォーマットをサポートできる。たとえば、デバイスは 16 ビット RGB、32 ビット RGB、および YUYV をサポートすることがある。これらの各フォーマット内で、デバイスは一定範囲のフレーム サイズをサポートできる。
WDM デバイスで、IAMStreamConfig インターフェイスはデバイスがサポートするフォーマットを報告し、そのフォーマットを設定するときに使われる。 (従来の VFW デバイスには、「VFW キャプチャ ダイアログ ボックスの表示」で説明しているように、[ビデオ フォーマット VFW] ダイアログ ボックスを使う。) IAMStreamConfig インターフェイスは、キャプチャ フィルタのキャプチャ ピン、プレビュー ピン、または両方のピンで公開される。インターフェイス ポインタを取得するには、ICaptureGraphBuilder2::FindInterface メソッドを使う。
IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
&PIN_CATEGORY_PREVIEW, // プレビュー ピン。
0, // すべてのメディア タイプ。
pCap, // キャプチャ フィルタへのポインタ。
IID_IAMStreamConfig, (void**)&pConfig);
デバイスは、サポートしているメディア タイプの一覧を備えている。デバイスは、メディア タイプごとに 1 組の能力も提供する。その中には、対象フォーマットで利用できるフレーム サイズの範囲、デバイスが画像を伸縮できる程度、フレーム レートの範囲などが含まれる。
メディア タイプの数を取得するには、IAMStreamConfig::GetNumberOfCapabilities メソッドを呼び出す。メソッドは 2 つの値を返す。
- メディア タイプの数
- 能力情報が入った構造体のサイズ
サイズ値が必要となるのは、オーディオとビデオの両方に IAMStreamConfig インターフェイスが使われるためである (さらに、他のメディア タイプにも拡張される可能性がある)。ビデオには VIDEO_STREAM_CONFIG_CAPS 構造体を使って能力を記述し、オーディオには AUDIO_STREAM_CONFIG_CAPS 構造体を使う。
メディア タイプを列挙するには、0 から始まるインデックスを使って IAMStreamConfig::GetStreamCaps メソッドを呼び出す。GetStreamCaps メソッドはメディア タイプと対応する能力構造体を返す。
int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);
// サイズを調べ、正しい構造体を渡すことを確認する。
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)
{
// ビデオ能力構造体を使う。
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE *pmtConfig;
hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
if (SUCCEEDED(hr))
{
/* フォーマットを調べ、場合によっては使う。 */
// 完了したら、メディア タイプを削除する。
DeleteMediaType(pmtConfig);
}
}
構造体がどのように GetStreamCaps メソッドに割り当てられているかに注意すること。メソッドはメディア タイプ構造体を割り当て、呼び出し元は能力構造体を割り当てる。 能力構造体は強制的にバイト配列ポインタにする。メディア タイプの処理が終わった後、メディア タイプのフォーマット ブロックと共に AM_MEDIA_TYPE 構造体を削除する。
GetStreamCaps メソッドで返されたフォーマットをデバイスが使うように設定できる。それには、メディア タイプを使って IAMStreamConfig::SetFormat を呼び出す。
hr = pConfig->SetFormat(pmtConfig);
ピンが接続していない場合、接続するときにこのフォーマットを使おうとする。ピンが既に接続している場合、新しいフォーマットを使って再接続しようとする。どちらの場合も、ダウンストリーム フィルタはフォーマットを拒絶する可能性がある。
また、メディア タイプは SetFormat メソッドに渡す前に変更することもできる。ここで、VIDEO_STREAM_CONFIG_CAPS 構造体を利用することになる。この構造体は、メディア タイプを変更するすべての有効な方法を記述する。この情報を使うには、対象メディア タイプの詳細を理解する必要がある。
たとえば、GetStreamCaps は 320 × 240 ピクセルのフレーム サイズを持つ 24 ビット RGB フォーマットを返す。この情報を取得するには、メディア タイプのメジャー タイプ、サブタイプ、およびフォーマット ブロックを調べる。
if ((pmtConfig.majortype == MEDIATYPE_Video) &&
(pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
(pmtConfig.formattype == FORMAT_VideoInfo) &&
(pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
(pmtConfig.pbFormat != NULL))
{
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
// pVih には詳細なフォーマット情報が含まれている。
LONG lWidth = pVih->bmiHeader.biWidth;
LONG lHeight = pVih->bmiHeader.biHeight;
}
VIDEO_STREAM_CONFIG_CAPS 構造体は、このメディア タイプに使える最小と最大の幅と高さを示す。また、"ステップ" サイズも示す。ステップ サイズは、幅または高さを調整できるインクリメントの値を定義する。たとえば、デバイスは次の値を返すことがある。
- MinOutputSize: 160 × 120
- MaxOutputSize: 320 × 240
- OutputGranularityX:8 ピクセル (水平ステップ サイズ)
- OutputGranularityY:8 ピクセル (垂直ステップ サイズ)
これらの数値が与えられると、幅は範囲内 (160、168、176、... 304、312、320) の任意の値に、高さは範囲内 (120、128、136、... 224、232、240) の任意の値に設定できる。
新しいフレーム サイズを設定するには、GetStreamCaps に返される AM_MEDIA_TYPE 構造体を直接変更する。
pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);
次に、前に説明したように、メディア タイプを SetFormat メソッドに渡す。
VIDEO_STREAM_CONFIG_CAPS のメンバ MinFrameInterval と MaxFrameInterval は各ビデオ フレームの最小の長さと最大の長さである。次の式を使って、これらの値をフレーム レートに変換できる。
frames per second = 10,000,000 / frame duration
特定のフレーム レートを要求するには、メディア タイプにある構造体 VIDEOINFOHEADER か VIDEOINFOHEADER2 の AvgTimePerFrame の値を変更する。デバイスは最小値と最大値の間で可能なすべての値はサポートしていないことがあるため、ドライバは使用可能な最も近い値を使う。ドライバが実際に使った値を調べるには、SetFormat を呼び出した後に IAMStreamConfig::GetFormat を呼び出す。
一部のドライバは MaxFrameInterval の値として MAXLONGLONG (0x7FFFFFFFFFFFFFFF) を報告することがあるが、これは実際には最大時間幅がないことを意味する。しかし、場合によってはアプリケーションに 1 fps など、最小フレーム レートを設定する必要がある。
参照