Impostazione dei tipi di supporti in un oggetto DMO

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Prima che un DMO possa elaborare qualsiasi dato, il client deve impostare il tipo di supporto per ogni flusso. Esiste un'eccezione secondaria a questa regola. Vedere Flussi facoltativi. Per trovare il numero di flussi, chiamare il metodo IMediaObject::GetStreamCount :

DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);

Questo metodo restituisce due valori, il numero di input e il numero di output. Questi valori sono fissi per la durata dell'oggetto DMO.

Tipi preferiti

Per ogni flusso, DMO assegna un elenco di possibili tipi di supporti, in ordine di preferenza. Ad esempio, i tipi preferiti potrebbero essere RGB a 32 bit, RGB a 24 bit e RGB a 16 bit, in tale ordine. Quando il client imposta i tipi di supporto, può usare questi elenchi come hint. Per recuperare un tipo preferito per un flusso, chiamare il metodo IMediaObject::GetInputType o IMediaObject::GetOutputType . Specificare il numero di flusso e un valore di indice per il tipo (a partire da zero). Ad esempio, il codice seguente recupera il primo tipo preferito dal primo flusso di input:

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);
}

Per enumerare tutti i tipi di supporti preferiti in un determinato flusso, usare un ciclo che incrementa l'indice del tipo fino a quando il metodo non restituisce DMO_E_NO_MORE_ITEMS, come illustrato nell'esempio seguente:

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;
}

Tenere presente quanto segue sui tipi preferiti:

  • L'oggetto DMO potrebbe restituire un tipo senza blocco di formato. Ad esempio, un DMO può specificare un tipo di video, ad esempio RGB a 24 bit, senza specificare la larghezza e l'altezza dell'immagine. Quando si imposta il tipo, tuttavia, è necessario fornire un blocco di formato completo. Alcuni tipi di supporti, ad esempio MIDI, non richiedono mai un blocco di formato, nel qual caso questa osservazione non si applica.
  • DMO non è necessario per supportare ogni combinazione di tipi preferiti restituiti. Ad esempio, se un DMO ha due flussi e ogni flusso ha quattro tipi preferiti, sono disponibili 16 possibili combinazioni, ma non tutte sono valide.
  • Quando il client imposta il tipo di supporto per un flusso, il DMO potrebbe aggiornare i tipi preferiti per altri flussi in modo che riflettano il nuovo stato. Non è tuttavia necessario farlo.
  • Per alcuni flussi, DMO potrebbe non offrire alcun tipo preferito. In genere, un DMO deve offrire almeno alcuni tipi preferiti in alcuni flussi.
  • DMO non è necessario per offrire un elenco completo dei tipi di supporti che può accettare. Potrebbero essere presenti tipi "non annullati" supportati dall'oggetto DMO, ma che non sono disponibili come tipi preferiti.

In breve, il client deve considerare i tipi preferiti solo come linee guida. L'unico modo per sapere quali tipi sono supportati consiste nel testarli, come descritto nella sezione successiva.

Impostazione del tipo di supporto in un flusso

Utilizzare i metodi IMediaObject::SetInputType e IMediaObject::SetOutputType per impostare il tipo per ogni flusso. È necessario fornire una struttura DMO_MEDIA_TYPE contenente una descrizione completa del tipo di supporto. L'esempio seguente imposta il tipo di supporto nel flusso di input 0, usando audio PCM stereo a 44,1 kHz a 16 bit:

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);
}

Per testare un tipo di supporto senza impostarlo, chiamare SetInputType o SetOutputType con il flag DMO_SET_TYPEF_TEST_ONLY. Il metodo restituisce S_OK se il tipo è accettabile o S_FALSE in caso contrario:

if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)
{
    // Media type is OK.
}

Poiché le impostazioni in un flusso possono influire su un altro flusso, potrebbe essere necessario cancellare il tipo di supporto di un flusso. A tale scopo, chiamare SetInputType o SetOutputType con il flag DMO_SET_TYPEF_CLEAR.

Per un decodificatore DMO, il client in genere imposta innanzitutto il tipo di input e quindi sceglie un tipo di output. Per un codificatore DMO, il client imposterà prima il tipo di output e quindi il tipo di input.

Hosting diretto di un oggetto DMO