Establecer tipos de medios en un DMO
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.
Para que un DMO pueda procesar cualquier dato, el cliente debe establecer el tipo de medio para cada secuencia. (Hay una excepción secundaria a esta regla; vea Secuencias opcionales). Para buscar el número de secuencias, llame al método IMediaObject::GetStreamCount :
DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);
Este método devuelve dos valores, el número de entradas y el número de salidas. Estos valores se fijan durante la vigencia del DMO.
Tipos preferidos
Para cada secuencia, DMO asigna una lista de posibles tipos de medios, en orden de preferencia. Por ejemplo, los tipos preferidos pueden ser RGB de 32, RGB de 24 bits y RGB de 16 bits, en ese orden. Cuando el cliente establece los tipos de medios, puede usar estas listas como sugerencia. Para recuperar un tipo preferido para una secuencia, llame al método IMediaObject::GetInputType o al método IMediaObject::GetOutputType . Especifique el número de secuencia y un valor de índice para el tipo (a partir de cero). Por ejemplo, el código siguiente recupera el primer tipo preferido del primer flujo de entrada:
DMO_MEDIA_TYPE mt
hr = pDMO->GetInputType(0, 0, &mt)
if (SUCCEEDED(hr))
{
// Examine this media type (not shown).
/* ... */
// Free the format block.
MoFreeMediaType(&mt);
}
Para enumerar todos los tipos de medios preferidos en una secuencia determinada, use un bucle que incremente el índice de tipo hasta que el método devuelva DMO_E_NO_MORE_ITEMS, como se muestra en el ejemplo siguiente:
DMO_MEDIA_TYPE mt;
DWORD dwType = 0;
while (hr = pDMO->GetInputType(0, dwType, &mt), SUCCEEDED(hr))
{
// Examine this media type (not shown).
/* ... */
// Free the format block.
MoFreeMediaType(&mt);
++dwType;
}
Debe tener en cuenta los siguientes puntos sobre los tipos preferidos:
- El DMO podría devolver un tipo que no tiene ningún bloque de formato. Por ejemplo, un DMO podría especificar un tipo de vídeo, como RGB de 24 bits, sin proporcionar el ancho y el alto de la imagen. Sin embargo, al establecer el tipo, debe proporcionar un bloque de formato completo. (Algunos tipos de medios, como MIDI, nunca requieren un bloque de formato, en cuyo caso este comentario no se aplica).
- El DMO no es necesario para admitir todas las combinaciones de tipos preferidos que devuelve. Por ejemplo, si un DMO tiene dos secuencias y cada secuencia tiene cuatro tipos preferidos, hay 16 combinaciones posibles, pero no todas ellas están garantizadas para ser válidas.
- Cuando el cliente establece el tipo de medio para una secuencia, DMO podría actualizar los tipos preferidos para otras secuencias para reflejar el nuevo estado. Sin embargo, no es necesario hacerlo.
- En algunos flujos, es posible que DMO no ofrezca ningún tipo preferido. Normalmente, un DMO debe ofrecer al menos algunos tipos preferidos en algunos flujos.
- El DMO no es necesario para ofrecer una lista completa de los tipos de medios que puede aceptar. Puede haber tipos "no invertidos" que el DMO admite, pero no ofrece como tipos preferidos.
En resumen, el cliente debe tratar los tipos preferidos solo como directrices. La única manera de saber qué tipos se admiten es probarlos, como se describe en la sección siguiente.
Establecer el tipo de medio en una secuencia
Use los métodos IMediaObject::SetInputType e IMediaObject::SetOutputType para establecer el tipo de cada secuencia. Debe proporcionar una estructura DMO_MEDIA_TYPE que contenga una descripción completa del tipo de medio. En el ejemplo siguiente se establece el tipo de medio en la secuencia de entrada 0, con audio PCM estéreo de 44,1 kHz de 16 bits:
DMO_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(DMO_MEDIA_TYPE));
// Allocate memory for the format block.
HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
if (SUCCEEDED(hr))
{
// Set the type GUIDs.
mt.majortype = MEDIATYPE_Audio;
mt.subtype = MEDIASUBTYPE_PCM;
mt.formattype = FORMAT_WaveFormatEx;
// Initialize the format block.
WAVEFORMATEX *pWave = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);
pWave->wFormatTag = WAVE_FORMAT_PCM;
pWave->nChannels = 2;
pWave->nSamplesPerSec = 44100;
pWave->wBitsPerSample = 16;
pWave->nBlockAlign = (pWave->nChannels * pWave->wBitsPerSample) / 8;
pWave->nAvgBytesPerSec = pWave->nSamplesPerSec * pWave->nBlockAlign;
pWave->cbSize = 0;
// Set the media type.
hr = pDMO->SetInputType(0, &mt, 0);
// Release the format block.
MoFreeMediaType(&mt);
}
Para probar un tipo de medio sin establecerlo, llame a SetInputType o SetOutputType con la marca DMO_SET_TYPEF_TEST_ONLY. El método devuelve S_OK si el tipo es aceptable o S_FALSE de lo contrario:
if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)
{
// Media type is OK.
}
Dado que la configuración de una secuencia puede afectar a otra, es posible que tenga que borrar el tipo de medio de una secuencia. Para ello, llame a SetInputType o SetOutputType con la marca DMO_SET_TYPEF_CLEAR.
Para un DMO descodificador, el cliente normalmente establecería primero el tipo de entrada y, a continuación, elegiría un tipo de salida. Para un DMO del codificador, el cliente establecería primero el tipo de salida y, a continuación, el tipo de entrada.
Temas relacionados