次の方法で共有


AVStream コーデックの動的形式変更のサポート

実行中のメディア ストリームで動的形式変更が発生すると、システム提供の Devproxy モジュールはキャプチャ ピンとネゴシエートして、新しい形式が許容されるかどうかを判断します。

動的形式変更がメディア ソースから発生した場合、次の一連のイベントが発生します。

  1. ドライバーは、KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT要求を受け取り、入力 KS ピンが新しいメディアの種類をサポートしているかどうかを判断します。 ドライバーは、このプロパティをサポートする必要があります。

  2. 入力ピンが新しいメディアの種類をサポートしている場合、KSPROPERTY_CONNECTION_PROPO Standard Edition DATAFORMAT ハンドラーはSTATUS_SUCCESSを返す必要があります。 次に、ドライバーは、現在選択されている出力メディアの種類と提案された入力を使用してストリームを再開できるかどうかを判断します。 「はい」の場合は、ストリームが再開されます。

  3. 入力ピンが新しく提案されたメディアの種類をサポートしていない場合、KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT ハンドラーはエラーを返す必要があります。 その後、HW MFT は、接続されたコンポーネントとメディアの種類を再ネゴシエーションします。

  4. 入力ピンで新しいメディア入力の種類がサポートされているが、KS フィルターで必要な出力メディアの種類が異なる場合、ドライバーは、KSEVENT_DYNAMIC_FORMAT_CHANGEイベントを生成し、このトピックで後述するように、メディアの種類の変更について HW MFT に通知する必要があります。

  5. HW MFT は KSEVENT 通知を受信すると、出力ピンをKSSTATE_RUNからKSSTATE_STOP に切り替えます。

  6. HW MFT は、使用可能なメディアの種類のドライバーを照会し、ドライバーの AVStrMiniIntersectHandlerEx 交差ハンドラーの呼び出しに変換します。 ドライバーは、優先する出力メディアの種類を優先順に報告する必要があります。

  7. ユーザー モード クライアントは、メディアの種類を選択し、HW MFT の出力ピンに新しいメディアの種類を設定します。 これにより、ドライバーのAVStrMiniPinSetDataFormatディスパッチ ルーチンが呼び出されます。 ドライバーが STATUS_SUCCESS を返すことによって形式を受け入れる場合は、新しいメディアの種類でストリーミングが再開されます。 呼び出しが失敗した場合、形式の変更に関連するコンポーネントはメディアの種類を再ネゴシエーションする必要があります。

  8. HW MFT は、接続されているメディアに変更があるかどうかをチェックします。 変更がない場合は、選択されたメディアの種類をピンに設定し、KSSTATE_RUN に配置します。 接続されているメディアに変更がある場合、HW MFT はピンを破棄し、新しく選択したメディアの種類とメディアで再作成します。 その後、MFT はピンを KSSTATE_RUN に入れます。

  9. ストリーミングが再開されます。

特定の状況では、メディア ソースで形式の変更が検出されない場合があります。 たとえば、MPEG2 デコーダーは、形式の変更を見つけるために各パケットをデコードする必要があります。

このような場合、ドライバーは、形式の変更を検出した場合、ハードウェア ドライバーは、動的な形式の変更 KSEVENT を生成する必要があります。 次に、HW MFT は、サポートされているメディアの種類についてピンに対してクエリを実行します。 ピンは、優先するメディアの種類を優先順に返す必要があります。 その後、HW MFT は、前のセクションの手順 4 から 9 で説明した一連のイベントに従います。

ドライバーは、このような形式の変更を処理できない場合は、ストリーミング エラーを返す必要があります。その後、それは MF に伝達されます。

次のコード例は、KSEVENT を使用して新しい動的形式の変更を定義する方法を示しています。

// {162AC456-83D7-4239-96DF-C75FFA138BC6}
#define STATIC_KSEVENTSETID_DynamicFormatChange\
    0x162ac456, 0x83d7, 0x4239, 0x96, 0xdf, 0xc7, 0x5f, 0xfa, 0x13, 0x8b, 0xc6 DEFINE_GUIDSTRUCT("162AC456-83D7-4239-96DF-C75FFA138BC6", KSEVENTSETID_ DynamicFormatChange);
#define KSEVENTSETID_DynamicFormatChange DEFINE_GUIDNAMED(KSEVENTSETID_ DynamicFormatChange)

typedef enum {
KSEVENT_DYNAMIC_FORMAT_CHANGE = 0
};

DEFINE_KSEVENT_TABLE(DynamicFormatChangeEventTable) {
    DEFINE_KSEVENT_ITEM
    (
        KSEVENT_DYNAMIC_FORMAT_CHANGE,
        sizeof(KSEVENTDATA),
        0,   
        NULL,
        NULL,
        NULL
    )
};

KSEVENT_SET PinEventTable[] =
{
    DEFINE_KSEVENT_SET
    (
        &KSEVENTSETID_DynamicFormatChange,
        SIZEOF_ARRAY(DynamicFormatChangeEventTable),
        DynamicFormatChangeEventTable
    )
};

各ピンは、ピン記述子でこのイベントを公開する必要があります。 イベントの種類は KSEVENTF_EVENT_HANDLE です。

ドライバーは、このイベントを生成する前に、現在選択されている入力メディアの種類に基づいて KS ピンの優先メディアの種類を設定する必要があります。 これを行うには、ピンの記述子で_KsEdit関数を使用します。

イベントを生成するには、ドライバーがKsGenerateEventsを呼び出す必要があります。