Manipulando alterações de fluxo

Este tópico descreve como uma MFT (transformação do Media Foundation) deve lidar com as alterações de formato durante o streaming.

Importante

Este tópico não se aplica a codificadores. Os codificadores não devem propagar alterações de formato, conforme descrito neste tópico. Os codificadores só devem aceitar um tipo de entrada que corresponda ao tipo de saída atualmente configurado.

 

Visão geral das alterações de formato

Geralmente, há dois motivos pelos quais um formato pode ser alterado durante o streaming.

  • O cliente pode mudar para um fluxo com um novo formato. Por exemplo, na televisão digital, isso pode ocorrer devido a uma alteração de canal.
  • Em alguns formatos de vídeo, como H.264, o bitstream pode sinalizar uma alteração de formato. Essas alterações podem incluir alterações no domínio do campo, resolução de vídeo ou taxa de proporção de pixel.

Se o tipo de codificação for alterado, talvez o cliente precise remover o MFT do pipeline e substituí-lo por outro MFT. (Por exemplo, o cliente pode precisar trocar em um novo decodificador.) Este tópico não aborda essa situação. Este tópico aborda apenas o caso em que o MFT atual pode lidar com o novo formato.

Se o formato for alterado, o MFT poderá exigir um novo tipo de entrada, um novo tipo de saída ou ambos.

  • As alterações no tipo de entrada são iniciadas pelo cliente. Um MFT nunca altera seu próprio tipo de entrada.
  • As alterações no tipo de saída são iniciadas pelo MFT. O MFT sinaliza que requer um novo tipo de saída e o cliente negocia o novo tipo de saída com o MFT.

Portanto, três casos distintos são possíveis:

  • O cliente define um novo tipo de entrada. O MFT consome o novo formato, sem nenhuma alteração em seu tipo de saída.
  • O cliente define um novo tipo de entrada e isso dispara uma alteração no tipo de saída.
  • O tipo de entrada não é alterado, mas o MFT detecta uma alteração de formato no bitstream, o que requer um novo tipo de saída.

Implementando alterações de formato

O restante deste tópico descreve como o cliente deve processar uma alteração de formato e como implementar alterações de formato em um MFT.

Tipo de saída

Qualquer MFT pode iniciar uma alteração em seu tipo de saída, da seguinte maneira:

  1. O cliente chama IMFTransform::P rocessOutput. O MFT responde da seguinte maneira:
    1. O MFT não produz um exemplo de saída no ProcessOutput.
    2. O MFT define o sinalizador MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE no membro dwStatus da estrutura MFT_OUTPUT_DATA_BUFFER .
    3. O método ProcessOutput retorna o código de erro MF_E_TRANSFORM_STREAM_CHANGE.
  2. O cliente chama IMFTransform::GetOutputAvailableType. Esse método retorna um conjunto atualizado de tipos de saída.
  3. O cliente chama SetOutputType para definir um novo tipo de saída.
  4. O cliente continua chamando ProcessInput/ProcessOutput.

Tipo de entrada

As alterações no tipo de entrada são iniciadas pelo cliente, nunca pelo MFT. Se o tipo de entrada for alterado, ele poderá disparar uma alteração no tipo de saída.

A sequência exata de eventos depende do valor do atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE .

Valor Descrição
FALSE Antes que o cliente defina um novo tipo de entrada, ele deve esvaziar o MFT.
TRUE O cliente pode definir um novo tipo de entrada sem esvaziar o MFT.

 

Um MFT expõe esse atributo por meio de seu método IMFTransform::GetAttributes . O valor padrão desse atributo é FALSE; se o MFT não definir o atributo, trate o valor como FALSE.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE é FALSE

  1. O cliente envia a mensagem MFT_MESSAGE_COMMAND_DRAIN .
  2. O cliente drena o MFT chamando IMFTransform::P rocessOutput até que ProcessOutput retorne MF_E_TRANSFORM_NEED_MORE_INPUT.
  3. O cliente chama IMFTransform::SetInputType para definir o novo tipo de entrada.
  4. O MFT valida o tipo de entrada. Se o tipo for inválido, SetInputType retornará MF_E_INVALIDMEDIATYPE ou outro código de erro. Caso contrário, SetInputType retornará S_OK.
  5. Supondo que o tipo de entrada seja válido, o MFT avaliará se o tipo de saída também é alterado. Caso contrário, o streaming continuará e nenhuma ação adicional será necessária.
  6. Se o tipo de saída for alterado:
    1. O MFT invalida seu tipo de mídia de saída atual e atualiza a lista de tipos de mídia de saída disponíveis.
    2. A próxima chamada para ProcessOutput retorna MF_E_TRANSFORM_STREAM_CHANGE, conforme descrito na seção anterior.
    3. O cliente chama IMFTransform::GetOutputAvailableType para obter a lista atualizada de tipos de saída.
    4. O cliente chama SetOutputType.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE é TRUE

  1. O cliente chama IMFTransform::SetInputType para definir o novo tipo de entrada.
  2. O MFT valida o tipo de entrada. Se o tipo for inválido, SetInputType retornará MF_E_INVALIDMEDIATYPE ou outro código de erro. Caso contrário, SetInputType retornará S_OK.
  3. Supondo que o tipo de entrada seja válido, o MFT avaliará se o tipo de saída também é alterado. Caso contrário, o streaming continuará e nenhuma ação adicional será necessária.
  4. Antes que o tipo de saída seja alterado, o MFT deve processar todos os exemplos de entrada armazenados em cache, da seguinte maneira:
    1. O MFT não invalida seu tipo de saída atual.
    2. O MFT produz o máximo de saída possível dos exemplos de entrada armazenados em cache.
    3. É opcional se o MFT aceita novos exemplos de entrada enquanto processa os exemplos armazenados em cache. Nesse caso, os novos exemplos de entrada usarão o novo formato de entrada, portanto, o MFT deve acompanhar o ponto quando o formato foi alterado.
  5. Depois que o MFT processa todos os exemplos recebidos antes da alteração do tipo de entrada, imfTransform::P rocessOutput retorna MF_E_TRANSFORM_STREAM_CHANGE.
  6. O MFT invalida seu tipo de saída atual e atualiza a lista de tipos de mídia de saída disponíveis.
  7. O cliente negocia o novo tipo de saída, conforme descrito anteriormente.

MFTs assíncronos devem retornar o valor TRUE para o atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE . Ao usar um MFT assíncrono, o cliente pode assumir que o atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE está definido como TRUE.

Quando MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE é TRUE, a diferença main é que o cliente não é necessário para esvaziar o MFT antes de definir um novo tipo de entrada. Como resultado, o tipo de entrada pode mudar enquanto o MFT está segurando amostras de entrada. É importante que o MFT não simplesmente solte esses exemplos. Além disso, o tipo de saída não pode ser alterado até que o MFT processe todos os seus dados armazenados em cache.

O parágrafo anterior se aplica especialmente aos decodificadores de vídeo, que podem receber quadros intercodificados fora da ordem temporal e, portanto, precisam armazená-los em cache. Se um MFT não armazenar amostras de entrada em cache, o esvaziamento será essencialmente uma operação não operada. Nesse caso, o MFT pode definir MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE como FALSE (ou deixar o atributo não definido).

Além disso, observe que cada MFT deve manipular as alterações de formato corretamente após ser drenado. O atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE indica se o MFT dá suporte a alterações de formato sem esvaziar.

Alteração no modo de entrelaçamento

As alterações no modo de interlacção de vídeo são um caso especial, pois não invalidam o tipo de mídia atual. Em vez disso, o modo de entrelaçamento é especificado para cada quadro de vídeo definindo atributos no exemplo de mídia. Um MFT de vídeo deve marcar cada exemplo de entrada para a presença desses sinalizadores.

O modo de entrelaçamento pode mudar quando o domínio do campo alterna de campo superior para inferior ou quando o vídeo alterna entre imagens progressivas e entrelaçadas.

Para obter mais informações, consulte Interlace Flags on Samples.

Escrevendo um MFT personalizado