Control de cambios de flujo

En este tema se describe cómo una transformación de Media Foundation (MFT) debe controlar los cambios de formato durante el streaming.

Importante

Este tema no se aplica a los codificadores. Los codificadores no deben propagar los cambios de formato, como se describe en este tema. Los codificadores solo deben aceptar un tipo de entrada que coincida con el tipo de salida configurado actualmente.

 

Información general sobre los cambios de formato

Por lo general, hay dos razones por las que un formato puede cambiar durante el streaming.

  • El cliente puede cambiar a una secuencia con un nuevo formato. Por ejemplo, en la televisión digital, esto puede ocurrir debido a un cambio de canal.
  • En algunos formatos de vídeo, como H.264, la secuencia de bits puede indicar un cambio de formato. Estos cambios pueden incluir cambios en la dominación de campos, la resolución de vídeo o la relación de aspecto de píxeles.

Si el tipo de codificación cambia, es posible que el cliente tenga que quitar el MFT de la canalización y reemplazarlo por otro MFT. (Por ejemplo, es posible que el cliente tenga que intercambiar en un nuevo descodificador). En este tema no se trata esa situación. En este tema solo se trata el caso en el que el MFT actual puede controlar el nuevo formato.

Si el formato cambia, el MFT podría requerir un nuevo tipo de entrada, un nuevo tipo de salida o ambos.

  • El cliente inicia los cambios en el tipo de entrada. Un MFT nunca cambia su propio tipo de entrada.
  • MFT inicia los cambios en el tipo de salida. El MFT indica que requiere un nuevo tipo de salida y el cliente negocia el nuevo tipo de salida con el MFT.

Por lo tanto, son posibles tres casos distintos:

  • El cliente establece un nuevo tipo de entrada. El MFT consume el nuevo formato, sin ningún cambio en su tipo de salida.
  • El cliente establece un nuevo tipo de entrada y desencadena un cambio en el tipo de salida.
  • El tipo de entrada no cambia, pero MFT detecta un cambio de formato en la secuencia de bits, que requiere un nuevo tipo de salida.

Implementación de cambios de formato

En el resto de este tema se describe cómo el cliente debe procesar un cambio de formato y cómo implementar los cambios de formato en un MFT.

Tipo de salida

Cualquier MFT puede iniciar un cambio en su tipo de salida, como se indica a continuación:

  1. El cliente llama a IMFTransform::P rocessOutput. El MFT responde de la siguiente manera:
    1. El MFT no genera un ejemplo de salida en ProcessOutput.
    2. El MFT establece la marca MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE en el miembro dwStatus de la estructura MFT_OUTPUT_DATA_BUFFER .
    3. El método ProcessOutput devuelve el código de error MF_E_TRANSFORM_STREAM_CHANGE.
  2. El cliente llama a IMFTransform::GetOutputAvailableType. Este método devuelve un conjunto actualizado de tipos de salida.
  3. El cliente llama a SetOutputType para establecer un nuevo tipo de salida.
  4. El cliente reanuda la llamada a ProcessInput/ProcessOutput.

Tipo de entrada

El cliente inicia los cambios en el tipo de entrada, nunca mediante MFT. Si cambia el tipo de entrada, podría desencadenar un cambio en el tipo de salida.

La secuencia exacta de eventos depende del valor del atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE .

Value Descripción
FALSE Antes de que el cliente establezca un nuevo tipo de entrada, debe purgar el MFT.
TRUE El cliente puede establecer un nuevo tipo de entrada sin purgar el MFT.

 

Un MFT expone este atributo a través de su método IMFTransform::GetAttributes . El valor predeterminado de este atributo es FALSE; si el MFT no establece el atributo, trate el valor como FALSE.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE es FALSE

  1. El cliente envía el mensaje MFT_MESSAGE_COMMAND_DRAIN .
  2. El cliente purga el MFT llamando a IMFTransform::P rocessOutput hasta que ProcessOutput devuelva MF_E_TRANSFORM_NEED_MORE_INPUT.
  3. El cliente llama a IMFTransform::SetInputType para establecer el nuevo tipo de entrada.
  4. El MFT valida el tipo de entrada. Si el tipo no es válido, SetInputType devuelve MF_E_INVALIDMEDIATYPE u otro código de error. De lo contrario, SetInputType devuelve S_OK.
  5. Suponiendo que el tipo de entrada es válido, MFT evalúa si el tipo de salida también cambia. Si no es así, el streaming continúa y no se requiere ninguna otra acción.
  6. Si el tipo de salida cambia:
    1. MFT invalida su tipo de medio de salida actual y actualiza la lista de tipos de medios de salida disponibles.
    2. La siguiente llamada a ProcessOutput devuelve MF_E_TRANSFORM_STREAM_CHANGE, como se describe en la sección anterior.
    3. El cliente llama a IMFTransform::GetOutputAvailableType para obtener la lista actualizada de tipos de salida.
    4. El cliente llama a SetOutputType.

MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE es TRUE

  1. El cliente llama a IMFTransform::SetInputType para establecer el nuevo tipo de entrada.
  2. El MFT valida el tipo de entrada. Si el tipo no es válido, SetInputType devuelve MF_E_INVALIDMEDIATYPE u otro código de error. De lo contrario, SetInputType devuelve S_OK.
  3. Suponiendo que el tipo de entrada es válido, MFT evalúa si el tipo de salida también cambia. Si no es así, el streaming continúa y no se requiere ninguna otra acción.
  4. Antes de que cambie el tipo de salida, MFT debe procesar las muestras de entrada almacenadas en caché, como se indica a continuación:
    1. MFT no invalida su tipo de salida actual.
    2. El MFT genera tanto resultado como pueda de las muestras de entrada almacenadas en caché.
    3. Es opcional si MFT acepta nuevas muestras de entrada mientras procesa las muestras almacenadas en caché. Si es así, las nuevas muestras de entrada usarán el nuevo formato de entrada, por lo que MFT debe realizar un seguimiento del punto cuando el formato haya cambiado.
  5. Después de que el MFT procese todas las muestras que recibió antes de que el tipo de entrada cambiara, IMFTransform::P rocessOutput devuelve MF_E_TRANSFORM_STREAM_CHANGE.
  6. MFT invalida su tipo de salida actual y actualiza la lista de tipos de medios de salida disponibles.
  7. El cliente negocia el nuevo tipo de salida, como se ha descrito anteriormente.

Las MFT asincrónicas deben devolver el valor TRUE para el atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE . Al usar un MFT asincrónico, el cliente puede suponer que el atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE está establecido en TRUE.

Cuando MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE es TRUE, la principal diferencia es que el cliente no es necesario purgar el MFT antes de establecer un nuevo tipo de entrada. Como resultado, el tipo de entrada podría cambiar mientras el MFT se mantiene en muestras de entrada. Es importante que el MFT no simplemente quite estas muestras. Además, el tipo de salida no puede cambiar hasta que MFT procesa todos sus datos almacenados en caché.

El párrafo anterior se aplica especialmente a los descodificadores de vídeo, que pueden recibir fotogramas entre codificados fuera del orden temporal y, por tanto, deben almacenarlos en caché. Si un MFT no almacena en caché las muestras de entrada, el purgado es esencialmente una operación sin operación. En ese caso, el MFT puede establecer MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE en FALSE (o dejar el atributo sin establecer).

Además, tenga en cuenta que se espera que cada MFT controle los cambios de formato correctamente después de purgarse. El atributo MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE indica si MFT admite cambios de formato sin purgar.

Cambio en el modo de intercalación

Los cambios en el modo de entrelazado de vídeo son un caso especial, ya que no invalidan el tipo de medio actual. En su lugar, el modo de interlace se especifica para cada fotograma de vídeo estableciendo atributos en el ejemplo multimedia. Un vídeo MFT debe comprobar cada muestra de entrada para comprobar la presencia de estas marcas.

El modo de interlace puede cambiar cuando la dominación de campo cambia de campo superior a campo inferior, o cuando el vídeo cambia entre imágenes progresivas e entrelazadas.

Para obtener más información, vea Interlace Flags on Samples (Interlace Flags on Samples).

Escritura de un MFT personalizado