Compartilhar via


Suporte a alterações de formato dinâmico em codecs AVStream

Quando ocorre uma alteração de formato dinâmico em um fluxo de mídia em execução, o módulo Devproxy fornecido pelo sistema negocia com o pino de captura para determinar se o novo formato será aceitável.

A seguinte sequência de eventos ocorre quando uma alteração de formato dinâmico se origina da fonte de mídia:

  1. O driver recebe uma solicitação KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT para determinar se o pino KS de entrada dá suporte ao novo tipo de mídia. Os drivers devem dar suporte a essa propriedade.

  2. Se o pin de entrada der suporte ao novo tipo de mídia, o manipulador de KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT deverá retornar STATUS_SUCCESS. Em seguida, o driver determina se ele pode retomar o fluxo usando a entrada proposta junto com os tipos de mídia de saída selecionados no momento. Se sim, o fluxo será retomado.

  3. Se o pin de entrada não der suporte ao tipo de mídia recém-proposto, o manipulador de KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT deverá retornar um erro. O HW MFT renegocia o tipo de mídia com o componente conectado.

  4. Se o pino de entrada der suporte ao novo tipo de entrada de mídia, mas o filtro KS exigir um tipo de mídia de saída diferente, o driver deverá gerar um evento KSEVENT_DYNAMIC_FORMAT_CHANGE , conforme detalhado posteriormente neste tópico, para notificar o MFT do HW sobre a alteração do tipo de mídia.

  5. Quando o MFT do HW recebe a notificação KSEVENT, ele faz a transição do pino de saída de KSSTATE_RUN para KSSTATE_STOP.

  6. Em seguida, o HW MFT consulta o driver para tipos de mídia disponíveis, o que se traduz em uma chamada para o manipulador de interseção AVStrMiniIntersectHandlerEx do driver. O driver deve relatar tipos de mídia de saída preferenciais na ordem de preferência.

  7. O cliente do modo de usuário seleciona um tipo de mídia e define o novo tipo de mídia no pino de saída do HW MFT. Isso resulta em uma chamada para a rotina de expedição AVStrMiniPinSetDataFormat do driver. Se o driver aceitar o formato retornando STATUS_SUCCESS, o streaming será retomado com o novo tipo de mídia. Se a chamada falhar, os componentes envolvidos na alteração de formato deverão renegociar o tipo de mídia.

  8. O HW MFT verifica se há alguma alteração no meio conectado. Se não houver nenhuma alteração, ele definirá o tipo de mídia selecionado no pino e o colocará em KSSTATE_RUN. Se houver uma alteração no meio conectado, o HW MFT destruirá o pino e o recriará com o tipo de mídia e o meio recém-selecionados. Em seguida, o MFT coloca o pino em KSSTATE_RUN.

  9. O streaming é retomado.

Em determinadas situações, uma fonte de mídia pode não detectar uma alteração de formato. Por exemplo, um decodificador MPEG2 teria que decodificar cada pacote para encontrar qualquer alteração de formato.

Nesse caso, se o driver detectar uma alteração de formato, o driver de hardware deverá gerar uma alteração de formato dinâmico KSEVENT. Em seguida, o HW MFT consulta o pino para seus tipos de mídia com suporte. O pino deve retornar os tipos de mídia preferenciais na ordem de preferência. Em seguida, o HW MFT segue a sequência de eventos descrita nas etapas 4 a 9 da seção anterior.

Se o driver não puder lidar com essa alteração de formato, ele deverá retornar um erro de streaming, que é propagado para MF.

O exemplo de código a seguir mostra como definir uma nova alteração de formato dinâmico usando um 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
    )
};

Cada pin deve expor esse evento em seu descritor de pino. O evento é do tipo KSEVENTF_EVENT_HANDLE.

Antes que o driver gere esse evento, ele deve definir os tipos de mídia preferenciais para o pino KS com base no tipo de mídia de entrada selecionado no momento. Você pode fazer isso usando a função _KsEdit no descritor do pino.

Para gerar o evento, os drivers devem chamar KsGenerateEvents.