Définition de types de média sur un DMO
[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]
Avant qu’un DMO puisse traiter des données, le client doit définir le type de média pour chaque flux. (Il existe une exception mineure à cette règle ; consultez Flux facultatifs.) Pour rechercher le nombre de flux, appelez la méthode IMediaObject::GetStreamCount :
DWORD cInput = 0, cOutput = 0;
pDMO->GetStreamCount(&cInput, &cOutput);
Cette méthode retourne deux valeurs, le nombre d’entrées et le nombre de sorties. Ces valeurs sont fixes pour la durée de vie du DMO.
Types préférés
Pour chaque flux, le DMO attribue une liste de types de médias possibles, par ordre de préférence. Par exemple, les types préférés peuvent être 32-RVB, RVB 24 bits et RVB 16 bits, dans cet ordre. Lorsque le client définit les types de médias, il peut utiliser ces listes comme indicateur. Pour récupérer un type préféré pour un flux, appelez la méthode IMediaObject::GetInputType ou la méthode IMediaObject::GetOutputType . Spécifiez le numéro de flux et une valeur d’index pour le type (à partir de zéro). Par exemple, le code suivant récupère le premier type préféré à partir du premier flux d’entrée :
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);
}
Pour énumérer tous les types de média préférés sur un flux donné, utilisez une boucle qui incrémente l’index de type jusqu’à ce que la méthode retourne DMO_E_NO_MORE_ITEMS, comme illustré dans l’exemple suivant :
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;
}
Vous devez noter les points suivants concernant les types préférés :
- Le DMO peut retourner un type qui n’a pas de bloc de format. Par exemple, un DMO peut spécifier un type vidéo, tel que RVB 24 bits, sans fournir la largeur et la hauteur de l’image. Toutefois, lorsque vous définissez le type, vous devez fournir un bloc de format complet. (Certains types de médias, tels que MIDI, ne nécessitent jamais de bloc de format, auquel cas cette remarque ne s’applique pas.)
- Le DMO n’est pas requis pour prendre en charge chaque combinaison de types préférés qu’il retourne. Par exemple, si un DMO a deux flux et que chaque flux a quatre types préférés, il existe 16 combinaisons possibles, mais leur validité n’est pas garantie.
- Lorsque le client définit le type de média pour un flux, le DMO peut mettre à jour les types préférés pour d’autres flux afin qu’ils reflètent le nouvel état. Toutefois, elle n’est pas tenue de le faire.
- Pour certains flux, le DMO n’offre peut-être pas les types préférés. En règle générale, un DMO doit offrir au moins certains types préférés sur certains flux.
- Le DMO n’est pas obligé de proposer une liste complète des types de médias qu’il peut accepter. Il peut y avoir des types « nonadvertisés » que le DMO prend en charge, mais n’offre pas comme types préférés.
En bref, le client doit traiter les types préférés comme des instructions uniquement. La seule façon de savoir quels types sont pris en charge est de les tester, comme décrit dans la section suivante.
Définition du type de média sur un flux
Utilisez les méthodes IMediaObject::SetInputType et IMediaObject::SetOutputType pour définir le type pour chaque flux. Vous devez fournir une structure DMO_MEDIA_TYPE qui contient une description complète du type de média. L’exemple suivant définit le type de média sur le flux d’entrée 0, à l’aide de l’audio PCM stéréo 16 bits 44,1 kHz :
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);
}
Pour tester un type de média sans le définir, appelez SetInputType ou SetOutputType avec l’indicateur DMO_SET_TYPEF_TEST_ONLY. La méthode retourne S_OK si le type est acceptable, ou S_FALSE sinon :
if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)
{
// Media type is OK.
}
Étant donné que les paramètres d’un flux peuvent affecter un autre flux, vous devrez peut-être effacer le type de média d’un flux. Pour ce faire, appelez SetInputType ou SetOutputType avec l’indicateur DMO_SET_TYPEF_CLEAR.
Pour un décodeur DMO, le client définit généralement d’abord le type d’entrée, puis choisit un type de sortie. Pour un DMO d’encodeur, le client définit d’abord le type de sortie, puis le type d’entrée.
Rubriques connexes