ビデオ出力形式を構成する
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
注意
このトピックで説明する機能は非推奨です。 キャプチャ デバイスの出力形式を構成するには、アプリケーションで pmt パラメーターで IAMStreamConfig::GetFormat によって返されるAM_MEDIA_TYPE構造を使用する必要があります。
キャプチャ デバイスは、さまざまな出力形式をサポートできます。 たとえば、デバイスで 16 ビット RGB、32 ビット RGB、YUYV がサポートされている場合があります。 これらの各形式内で、デバイスはさまざまなフレーム サイズをサポートできます。
WDM デバイスでは、 IAMStreamConfig インターフェイスを使用して、デバイスでサポートされている形式を報告し、形式を設定します。 (レガシ VFW デバイスの場合は、「VFW キャプチャ ダイアログ ボックスを表示する」の説明に従って、[ ビデオ形式の VFW] ダイアログ ボックスを使用します)。 IAMStreamConfig インターフェイスは、キャプチャ フィルターのキャプチャ ピン、プレビュー ピン、またはその両方で公開されます。 インターフェイス ポインターを取得するには、 ICaptureGraphBuilder2::FindInterface メソッドを使用します。
IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
&PIN_CATEGORY_PREVIEW, // Preview pin.
0, // Any media type.
pCap, // Pointer to the capture filter.
IID_IAMStreamConfig, (void**)&pConfig);
デバイスには、サポートされているメディアの種類の一覧があります。 メディアの種類ごとに、デバイスには一連の機能も用意されています。 これには、その形式で使用できるフレーム サイズの範囲、デバイスがイメージをどの程度拡大または縮小できるか、フレーム レートの範囲が含まれます。
メディアの種類の数を取得するには、 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);
// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
// Use the video capabilities structure.
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))
{
/* Examine the format, and possibly use it. */
// Delete the media type when you are done.
DeleteMediaType(pmtConfig);
}
}
GetStreamCaps メソッドに構造体がどのように割り当てられるかに注意してください。 メソッドはメディアの種類の構造を割り当てますが、呼び出し元は機能構造を割り当てます。 機能構造をバイト配列ポインターに強制します。 メディアの種類が完了したら、メディアの種類のフォーマット ブロックと共に、 AM_MEDIA_TYPE 構造体を削除します。
GetStreamCaps メソッドで返される形式を使用するようにデバイスを構成できます。 メディアの種類を指定して IAMStreamConfig::SetFormat を呼び出すだけです。
hr = pConfig->SetFormat(pmtConfig);
ピンが接続されていない場合、接続時にこの形式の使用が試みられます。 ピンが既に接続されている場合は、新しい形式を使用して再接続を試みます。 いずれの場合も、ダウンストリーム フィルターで形式が拒否される可能性があります。
メディアの種類は、 SetFormat メソッドに渡す前に変更することもできます。 ここで、 VIDEO_STREAM_CONFIG_CAPS 構造が入ります。 メディアの種類を変更するためのすべての有効な方法について説明します。 この情報を使用するには、その特定のメディアの種類の詳細を理解する必要があります。
たとえば、 GetStreamCaps から 24 ビット RGB 形式が返され、フレーム サイズは 320 x 240 ピクセルであるとします。 この情報を取得するには、メディアタイプの主なタイプ、サブタイプ、およびフォーマットブロックを調べることができます。
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 contains the detailed format information.
LONG lWidth = pVih->bmiHeader.biWidth;
LONG lHeight = pVih->bmiHeader.biHeight;
}
VIDEO_STREAM_CONFIG_CAPS構造体は、このメディア タイプに使用できる最小および最大の幅と高さを提供します。 また、幅または高さを調整できる増分を定義する "ステップ" サイズも提供されます。 たとえば、デバイスは次を返す場合があります。
- MinOutputSize: 160 x 120
- MaxOutputSize: 320 x 240
- OutputGranularityX: 8 ピクセル (水平ステップ サイズ)
- OutputGranularityY: 8 ピクセル (垂直ステップ サイズ)
これらの数値を指定すると、幅を範囲内の任意の値 (160、168、176、..) に設定できます。304、312、320)、および範囲 (120、128、136、...104, 112, 120). このプロセスを説明する図を次に示します。
新しいフレーム サイズを設定するには、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 など) を適用する必要がある場合があります。
関連トピック