メディアの種類について (DirectShow)

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

DirectShow はモジュール式であるため、フィルター グラフの各ポイントでデータの形式を記述する方法が必要です。 たとえば、AVI 再生を考えてみましょう。 データは、RIFF チャンクのストリームとしてグラフに入ります。 これらはビデオストリームとオーディオストリームに解析されます。 ビデオ ストリームは、おそらく圧縮されたビデオ フレームで構成されます。 デコード後、ビデオ ストリームは一連の非圧縮ビットマップです。 オーディオ ストリームも同様のプロセスを経ます。

メディアの種類: DirectShow が形式を表す方法

メディアの種類は、デジタル メディア形式を記述するための汎用的で拡張可能な方法です。 2 つのフィルターが接続すると、メディアの種類に同意します。 メディアの種類は、アップストリーム フィルターがダウンストリーム フィルターに配信するデータの種類と、データの物理的なレイアウトを識別します。 2 つのフィルターがメディアの種類に同意できない場合、それらは接続されません。

一部のアプリケーションでは、メディアの種類について心配する必要はありません。 たとえば、ファイルの再生では、DirectShow はすべての詳細を処理します。 他の種類のアプリケーションでは、メディアの種類を直接操作する必要がある場合があります。

メディアの種類は、 AM_MEDIA_TYPE 構造体を使用して定義されます。 この構造体には、次の情報が含まれています。

  • メジャー型: メジャー型は、データの全体的なカテゴリを定義する GUID です。 主な種類には、ビデオ、オーディオ、解析されていないバイト ストリーム、MIDI データなどがあります。

  • サブタイプ: サブタイプは別の GUID であり、形式をさらに定義します。 たとえば、ビデオ メジャー型内には、RGB-24、RGB-32、UYVY などのサブタイプがあります。 オーディオ内には、PCM オーディオ、MPEG-1 ペイロードなどがあります。 サブタイプはメジャー型よりも多くの情報を提供しますが、形式に関するすべての情報を定義しているわけではありません。 たとえば、ビデオ サブタイプでは、イメージ サイズやフレーム レートは定義されません。 これらは、以下で説明するフォーマット ブロックによって定義されます。

  • 書式ブロック: 書式ブロックは、形式を詳細に記述するデータブロックです。 フォーマット ブロックは、 AM_MEDIA_TYPE 構造体とは別に割り当てられます。 AM_MEDIA_TYPE構造体の pbFormat メンバーは、書式ブロックを指します。

    フォーマット ブロックのレイアウトはメディアの種類によって変わるため、 pbFormat メンバーは void* と入力されます。 たとえば、PCM オーディオでは WAVEFORMATEX 構造体が使用されます。 ビデオでは、 VIDEOINFOHEADER や VIDEOINFOHEADER2 など、さまざまな構造 が使用されますAM_MEDIA_TYPE構造体の formattype メンバーは、書式ブロックに含まれる構造体を指定する GUID です。 各書式構造には GUID が割り当てられます。 cbFormat メンバーは、書式ブロックのサイズを指定します。 pbFormat ポインターを逆参照する前に、常にこれらの値をチェックします。

フォーマット ブロックが入力されている場合、メジャー型とサブタイプには冗長な情報が含まれます。 ただし、主要な型とサブタイプは、完全な書式ブロックなしで形式を識別する便利な方法を提供します。 たとえば、イメージ サイズやフレーム レートなど、 VIDEOINFOHEADER 構造体に必要なすべての情報を知らなくても、汎用の 24 ビット RGB 形式 (MEDIASUBTYPE_RGB24) を指定できます。

たとえば、フィルターでは、次のコードを使用してメディアの種類をチェックできます。

HRESULT CheckMediaType(AM_MEDIA_TYPE *pmt)
{
    if (pmt == NULL) return E_POINTER;

    // Check the major type. We're looking for video.
    if (pmt->majortype != MEDIATYPE_Video)
    {
        return VFW_E_INVALIDMEDIATYPE;
    }

    // Check the subtype. We're looking for 24-bit RGB.
    if (pmt->subtype != MEDIASUBTYPE_RGB24)
    {
        return VFW_E_INVALIDMEDIATYPE;
    }

    // Check the format type and the size of the format block.
    if ((pmt->formattype == FORMAT_VideoInfo) &&
         (pmt->cbFormat >= sizeof(VIDEOINFOHEADER) &&
         (pmt->pbFormat != NULL))
    {
        // Now it's safe to coerce the format block pointer to the
        // correct structure, as defined by the formattype GUID.
        VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    
        // Examine pVIH (not shown). If it looks OK, return S_OK.
        return S_OK;
    }

    return VFW_E_INVALIDMEDIATYPE;
}

AM_MEDIA_TYPE構造体には、いくつかの省略可能なフィールドも含まれています。 これらは追加情報を提供するために使用できますが、フィルターを使用する必要はありません。

  • lSampleSize。 このフィールドが 0 以外の場合は、各サンプルのサイズが定義されます。 0 の場合は、サンプル サイズがサンプルからサンプルに変更される可能性があることを示します。
  • bFixedSizeSamples。 このブール値フラグが TRUE の場合は、 lSampleSize の値が有効であることを意味します。 それ以外の場合は、 lSampleSize を無視する必要があります。
  • bTemporalCompression。 このブール値フラグが FALSE の場合は、すべてのフレームがキー フレームであることを意味します。

フィルター グラフとそのコンポーネント