Compatibilidad con DXVA 2.0 en Media Foundation
En este tema se describe cómo admitir directX Video Acceleration (DXVA) 2.0 en una transformación de Media Foundation (MFT) mediante Microsoft Direct3D 9 Específicamente, describe la comunicación entre el descodificador y el representador de vídeo, que está mediado por el cargador de topología. En este tema no se describe cómo implementar la descodificación de DXVA.
En el resto de este tema, el término descodificador hace referencia al descodificador MFT, que recibe vídeo comprimido y genera vídeo sin comprimir. El término dispositivo descodificador hace referencia a un acelerador de vídeo de hardware implementado por el controlador de gráficos.
Sugerencia
Para obtener información sobre la descodificación de vídeo de Microsoft Direct3D 11, vea Compatibilidad con la descodificación de vídeo de Direct3D 11 en Media Foundation.
Nota
Las aplicaciones de la Tienda Windows deben usar Direct3D 11.
Estos son los pasos básicos que debe realizar un descodificador para admitir DXVA 2.0 en Media Foundation:
- Abra un identificador para el dispositivo Direct3D 9.
- Busque una configuración de descodificador DXVA.
- Asigne búferes sin comprimir.
- Descodificar fotogramas.
Estos pasos se describen con más detalle en el resto de este tema.
Apertura de un identificador de dispositivo Direct3D
MFT usa el administrador de dispositivos de Microsoft Direct3D para obtener un identificador para el dispositivo Direct3D 9. Para abrir el identificador del dispositivo, realice los pasos siguientes:
- Exponga el atributo MF_SA_D3D_AWARE con el valor TRUE. El cargador de topología consulta este atributo llamando a IMFTransform::GetAttributes. Al establecer el atributo en TRUE , se notifica al cargador de topología que MFT admite DXVA.
- Cuando comienza la negociación de formato, el cargador de topología llama a IMFTransform::P rocessMessage con el mensaje de MFT_MESSAGE_SET_D3D_MANAGER . El parámetro ulParam es un puntero IUnknown al administrador de dispositivos Direct3D del representador de vídeo. Consulte este puntero para la interfaz IDirect3DDeviceManager9 .
- Llama a IDirect3DDeviceManager9::OpenDeviceHandle para obtener un identificador para el dispositivo Direct3D del representador.
- Llame a IDirect3DDeviceManager9::GetVideoService y pase el identificador del dispositivo. Este método devuelve un puntero a la interfaz IDirectXVideoDecoderService .
- Almacene en caché los punteros y el identificador del dispositivo.
Búsqueda de una configuración de descodificador
El MFT debe encontrar una configuración compatible para el dispositivo de descodificador DXVA. Realice los pasos siguientes dentro del método IMFTransform::SetInputType , después de validar el tipo de entrada:
Llame a IDirectXVideoDecoderService::GetDecoderDeviceGuids. Este método devuelve una matriz de GUID de dispositivo de descodificador.
Recorra en bucle la matriz de GUID de descodificador para buscar las que admite el descodificador. Por ejemplo, para un descodificador MPEG-2, buscaría DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT o DXVA2_ModeMPEG2_VLD.
Cuando encuentre un GUID de dispositivo de descodificador candidato, pase el GUID al método IDirectXVideoDecoderService::GetDecoderRenderTargets . Este método devuelve una matriz de formatos de destino de representación, especificados como valores D3DFORMAT .
Recorra en bucle los formatos de destino de representación y busque un formato admitido por el descodificador.
Llame a IDirectXVideoDecoderService::GetDecoderConfigurations. Pase el mismo GUID del dispositivo de descodificador, junto con una estructura de DXVA2_VideoDesc que describe el formato de salida propuesto. El método devuelve una matriz de estructuras de DXVA2_ConfigPictureDecode . Cada estructura describe una posible configuración para el dispositivo descodificador. Busque una configuración que admita el descodificador.
Almacene el formato de destino de representación y la configuración.
En el método IMFTransform::GetOutputAvailableType , devuelve un formato de vídeo sin comprimir, en función del formato de destino de representación propuesto.
En el método IMFTransform::SetOutputType , compruebe el tipo de medio con el formato de destino de representación.
Reserva a la descodificación de software
Si el MFT no encuentra una configuración de DXVA (por ejemplo, si el controlador de gráficos no tiene las funcionalidades adecuadas), debe devolver el código de error MF_E_UNSUPPORTED_D3D_TYPE de los métodos SetInputType y SetOutputType . El cargador de topología responderá enviando el mensaje MFT_MESSAGE_SET_D3D_MANAGER con el valor NULL para el parámetro ulParam . El MFT debe liberar su puntero a la interfaz IDirect3DDeviceManager9 . Después, el cargador de topología renegociará el tipo de medio y MFT puede usar la descodificación de software.
Asignar búferes sin comprimir
En DXVA 2.0, el descodificador es responsable de asignar superficies de Direct3D para usarlas como búferes de vídeo sin comprimir. El descodificador debe asignar 3 superficies para que el EVR se use para desinterlacar. Este número es fijo, ya que Media Foundation no proporciona una manera para que el EVR especifique cuántas superficies requiere el controlador de gráficos para desinterlacar. Tres superficies deben ser suficientes para cualquier controlador.
En el método IMFTransform::GetOutputStreamInfo , establezca la marca MFT_OUTPUT_STREAM_PROVIDES_SAMPLES en la estructura MFT_OUTPUT_STREAM_INFO . Esta marca notifica a la sesión multimedia que el MFT asigna sus propios ejemplos de salida.
Para crear las superficies, llame a IDirectXVideoAccelerationService::CreateSurface. (La interfaz IDirectXVideoDecoderService hereda este método de IDirectXVideoAccelerationService). Puede hacerlo en SetInputType, después de buscar el formato de destino de representación.
Para cada superficie, llame a MFCreateVideoSampleFromSurface para crear una muestra multimedia que contenga la superficie. El método devuelve un puntero a la interfaz IMFSample .
Descodificación
Para crear el dispositivo descodificador, llame a IDirectXVideoDecoderService::CreateVideoDecoder. El método devuelve un puntero a la interfaz IDirectXVideoDecoder del dispositivo descodificador.
La descodificación debe producirse dentro del método IMFTransform::P rocessOutput . En cada fotograma, llame a IDirect3DDeviceManager9::TestDevice para probar el identificador del dispositivo. Si el dispositivo ha cambiado, el método devuelve DXVA2_E_NEW_VIDEO_DEVICE. Si esto ocurre, haga lo siguiente:
- Cierre el identificador del dispositivo llamando a IDirect3DDeviceManager9::CloseDeviceHandle.
- Libere los punteros IDirectXVideoDecoderService e IDirectXVideoDecoder .
- Abra un nuevo identificador de dispositivo.
- Negocia una nueva configuración de descodificador, como se describe en "Buscar una configuración de descodificador" anteriormente en esta página.
- Cree un nuevo dispositivo de descodificador.
Suponiendo que el identificador del dispositivo es válido, el proceso de descodificación funciona de la siguiente manera:
- Obtiene una superficie disponible que no está en uso actualmente. (Inicialmente todas las superficies están disponibles).
- Consulte el ejemplo de medios para la interfaz IMFTrackedSample .
- Llame a IMFTrackedSample::SetAllocator y proporcione un puntero a la interfaz IMFAsyncCallback , implementada por el descodificador. Cuando el representador de vídeo libera el ejemplo, se invocará la devolución de llamada del descodificador.
- Llame a IDirectXVideoDecoder::BeginFrame.
- Haga lo siguiente una o varias veces:
- Llame a IDirectXVideoDecoder::GetBuffer para obtener un búfer de descodificador DXVA.
- Rellene el búfer.
- Llame a IDirectXVideoDecoder::ReleaseBuffer.
- Llame a IDirectXVideoDecoder::Execute para realizar las operaciones de descodificación en el marco.
DXVA 2.0 usa las mismas estructuras de datos que DXVA 1.0 para las operaciones de descodificación. Para el conjunto original de perfiles DXVA (para H.261, H.263 y MPEG-2), estas estructuras de datos se describen en la especificación DXVA 1.0.
Dentro de cada par de llamadas BeginFrame/Execute , puede llamar a GetBuffer varias veces, pero solo una vez para cada tipo de búfer DXVA. Si lo llama dos veces con el mismo tipo de búfer, sobrescribirá los datos.
Use la devolución de llamada del método SetAllocator (paso 3) para realizar un seguimiento de qué ejemplos están disponibles actualmente y cuáles están en uso.
Temas relacionados