カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

メディアタイプの設定

次にDMOの入出力に扱いたいメディアタイプを設定します。DMO_MEDIA_TYPE構造体にメディアタイプとデータフォーマットを設定し、入力側をSetInputType関数、出力側をSetOutputType関数で設定します。

DMO_MEDIA_TYPE構造体

以下にDMO_MEDIA_TYPE構造体を示します。

typedef struct _DMOMediaType {
    GUID     majortype;
    GUID     subtype;
    BOOL     bFixedSizeSamples;
    BOOL     bTemporalCompression;
    ULONG    lSampleSize;
    GUID     formattype;
    IUnknown *pUnk;
    ULONG    cbFormat;
    [size_is(cbFormat)] BYTE * pbFormat;
} DMO_MEDIA_TYPE;

設定すべき項目は以下のとおりです。

ここではオーディオエフェクターの実装を想定しています。ビデオ関連やエンコーダ・デコーダを実装するときは、それに合せた設定が必要です。

majortype

MEDIATYPE_Audioを指定します。

subtype

DMOの入出力は通常PCMを使うのでMEDIASUBTYPE_PCMを指定します。

formattype

PCMを使うのでFORMAT_WaveFormatExを指定します。

pUnk

未使用です。安全のためにNULLを設定します。

pUnkにゴミが入っているとCopyMediaTypeで不具合が起こったというレポートがあります。

cbFormat

WAVEFORMATEX構造体のサイズを指定します。

pbFormat

WAVEFORMATEX構造体へのポインターを指定します。

bFixedSizeSamples

サンプルが固定サイズかどうかを示します。PCMではTRUEとなります。この変数は参照専用です。

bTemporalCompression

ビデオのフレーム間で圧縮フォーマットが利用されているかどうかを示します。この変数は参照専用です。

lSampleSize

サンプルのサイズです。単位はバイトです。

DirectShowでメディアタイプを表現するときAM_MEDIA_TYPE構造体を用います。DMOではDMO_MEDIA_TYPE構造体を用いますが、この2つは同じ内容です。bFixedSizeSamples、bTemporalCompression、lSampleSizeは、DirectShowで用いる変数ですが、構造体の互換性を保つためDMO_MEDIA_TYPEに残されました。DMOを単独で用いるときは利用しません。

以下にメディアタイプを設定する部分のコード(C#での実装例)を示します。

WAVEFORMATEX wfx;
GCHandle gcHandle = GCHandle.Alloc(wfx, GCHandleType.Pinned);

try
{
    mt = new DMOMediaType();
    mt.majortype  = DMOSys.MEDIATYPE_Audio;
    mt.subtype    = DMOSys.MEDIASUBTYPE_PCM;
    mt.formattype = DMOSys.FORMAT_WaveFormatEx;
    mt.cbFormat   = Marshal.SizeOf(typeof(WAVEFORMATEX));
    mt.pbFormat   = gcHandle.AddrOfPinnedObject();
    mt.pUnk       = null;

    result = iObject.SetInputType(0, mt, 0);
    if (result < S_OK)      Marshal.ThrowExceptionForHR(result);

    result = iObject.SetOutputType(0, mt, 0);
    if (result < S_OK)      Marshal.ThrowExceptionForHR(result);
}
catch (Exception e)
{
    Debug.WriteLine(e.Message);
}
finally
{
    gcHandle.Free();
}

wfxはWAVEFORMATEX構造体です。入力するウェーブデータのフォーマットを設定しておきます。

C#では構造体へのポインターを必要とするときは、GCHandle.Alloc関数を用いてガベージコレクションの対象とならない領域を作成し、AddrOfPinnedObject関数を用いて領域のアドレスを取得します。利用が終わったら忘れずにFree関数で領域を開放します。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ