AVStream 코덱의 동적 형식 변경 지원

실행 중인 미디어 스트림에서 동적 형식 변경이 발생하면 시스템에서 제공하는 Devproxy 모듈이 캡처 핀과 협상하여 새 형식이 허용되는지 여부를 결정합니다.

다음 이벤트 시퀀스는 동적 형식 변경이 미디어 원본에서 시작될 때 발생합니다.

  1. 드라이버는 입력 KS 핀이 새 미디어 형식을 지원하는지 여부를 확인하는 KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT 요청을 받습니다. 드라이버는 이 속성을 지원해야 합니다.

  2. 입력 핀이 새 미디어 형식을 지원하는 경우 KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT 처리기는 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를 호출해야 합니다.