Share via


ビデオ出力フォーマットの設定

キャプチャ デバイスは一定範囲の出力フォーマットをサポートできる。たとえば、デバイスは 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 のメンバ MinFrameIntervalMaxFrameInterval は各ビデオ フレームの最小の長さと最大の長さである。次の式を使って、これらの値をフレーム レートに変換できる。

frames per second = 10,000,000 / frame duration

特定のフレーム レートを要求するには、メディア タイプにある構造体 VIDEOINFOHEADERVIDEOINFOHEADER2AvgTimePerFrame の値を変更する。デバイスは最小値と最大値の間で可能なすべての値はサポートしていないことがあるため、ドライバは使用可能な最も近い値を使う。ドライバが実際に使った値を調べるには、SetFormat を呼び出した後に IAMStreamConfig::GetFormat を呼び出す。

一部のドライバは MaxFrameInterval の値として MAXLONGLONG (0x7FFFFFFFFFFFFFFF) を報告することがあるが、これは実際には最大時間幅がないことを意味する。しかし、場合によってはアプリケーションに 1 fps など、最小フレーム レートを設定する必要がある。

参照