Guide pratique pour définir le format de capture vidéo

Un périphérique de capture vidéo peut prendre en charge plusieurs formats de capture. Les formats diffèrent généralement par le type de compression, l’espace de couleur (YUV ou RVB), la taille d’image ou la fréquence d’images.

La liste des formats pris en charge est contenue dans le descripteur de présentation. Pour plus d’informations, consultez Descripteurs de présentation.

Pour énumérer les formats pris en charge :

  1. Créez la source multimédia pour l’appareil de capture. Consultez Énumération des appareils de capture vidéo.
  2. Appelez IMFMediaSource::CreatePresentationDescriptor sur la source multimédia pour obtenir le descripteur de présentation.
  3. Appelez IMFPresentationDescriptor::GetStreamDescriptorByIndex pour obtenir le descripteur de flux pour le flux vidéo.
  4. Appelez IMFStreamDescriptor::GetMediaTypeHandler sur le descripteur de flux.
  5. Appelez IMFMediaTypeHandler::GetMediaTypeCount pour obtenir le nombre de formats pris en charge.
  6. Dans une boucle, appelez IMFMediaTypeHandler::GetMediaTypeByIndex pour obtenir chaque format. Le format est représenté par un type de média. Pour plus d’informations, consultez Types de médias vidéo.

L’exemple suivant énumère les formats de capture d’un appareil :

HRESULT EnumerateCaptureFormats(IMFMediaSource *pSource)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cTypes = 0;
    hr = pHandler->GetMediaTypeCount(&cTypes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cTypes; i++)
    {
        hr = pHandler->GetMediaTypeByIndex(i, &pType);
        if (FAILED(hr))
        {
            goto done;
        }

        LogMediaType(pType);
        OutputDebugString(L"\n");

        SafeRelease(&pType);
    }

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

La LogMediaType fonction utilisée dans cet exemple est répertoriée dans la rubrique Code de débogage du type de média.

Pour définir le format de capture :

  1. Obtenez un pointeur vers l’interface IMFMediaTypeHandler , comme indiqué dans l’exemple précédent.
  2. Appelez IMFMediaTypeHandler::GetMediaTypeByIndex pour obtenir le format souhaité, spécifié par index.
  3. Appelez IMFMediaTypeHandler::SetCurrentMediaType pour définir le format.

Si vous ne définissez pas le format de capture, l’appareil utilisera son format par défaut.

L’exemple suivant définit le format de capture :

HRESULT SetDeviceFormat(IMFMediaSource *pSource, DWORD dwFormatIndex)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->GetMediaTypeByIndex(dwFormatIndex, &pType);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->SetCurrentMediaType(pType);

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

L’ordre dans lequel les formats sont retournés dépend de l’appareil. En règle générale, ils sont regroupés en premier par type de compression ou espace de couleur ; puis de la plus petite taille d’image à la plus grande taille d’image au sein de chaque groupe.

La fréquence d’images est gérée légèrement différemment des autres attributs de format. Pour plus d’informations, consultez Comment définir la fréquence d’images de capture vidéo.

Notes

Sur certains appareils, la liste des formats contient une entrée en double pour chaque format. Par exemple, si l’appareil prend en charge 15 formats de capture distincts, la liste contient 30 entrées. Dans chaque paire, l’un des types de média aura l’attribut MF_MT_AM_FORMAT_TYPE égal à FORMAT_VideoInfo, et l’autre aura MF_MT_AM_FORMAT_TYPE égal à FORMAT_VideoInfo2. (Ces deux valeurs sont définies dans le fichier d’en-tête uuids.h.) Le deuxième type peut également contenir des informations de couleur supplémentaires (informations de couleur étendues) ou afficher une valeur différente pour l’entrelacement (MF_MT_INTERLACE_MODE). Ces types de doublons existent pour prendre en charge les applications DirectShow plus anciennes. Dans une application Media Foundation, vous devez ignorer le type de FORMAT_VideoInfo chaque fois qu’un type de FORMAT_VideoInfo2 en double est répertorié.

 

Capture vidéo