Condividi tramite


Impostazione dei tipi di media in un DMO

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Cattura Audio/Video in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice utilizzi MediaPlayer, IMFMediaEngine e Acquisizione audio/video nell'ambito di Media Foundation anziché 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 media per ogni flusso. (C'è 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 l'intera durata del DMO.

tipi preferiti

Per ogni flusso, DMO assegna un elenco di possibili tipi di media, 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 cliente imposta i tipi di supporti, può usare questi elenchi come suggerimento. Per recuperare un tipo preferito per un flusso, chiamare il metodo IMediaObject::GetInputType o il metodo 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;
}

Si notino i punti seguenti 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 specificare 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.
  • Il DMO non è obbligato a supportare ogni possibile combinazione dei tipi preferiti che restituisce. Ad esempio, se un DMO ha due flussi e ogni flusso ha quattro tipi preferiti, esistono 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 dovrebbe offrire almeno alcune tipologie preferite su alcuni flussi di dati.
  • Il DMO non è tenuto a offrire un elenco completo dei tipi di media che può accettare. Potrebbero esserci tipi "non pubblicizzati" supportati dal DMO, ma non offerti come tipi preferiti.

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

Impostazione del tipo di supporto su un flusso

Utilizzare i metodiIMediaObject::SetInputTypee 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 media 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 media 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 prima il tipo di input e quindi sceglie un tipo di output. Per un codificatore DMO, il client imposta prima il tipo di output e quindi il tipo di input.

l'hosting diretto di un DMO