Partager via


Choix d’un filtre de compression

[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.]

Plusieurs types de composants logiciels peuvent effectuer une compression vidéo ou audio, par exemple :

  • Filtres DirectShow natifs
  • Codecs VCM (Video Compression Manager)
  • Codecs ACM (Audio Compression Manager)
  • Objets multimédias DirectX (DMO)

Dans DirectShow, les codecs VCM sont encapsulés par le filtre de compression AVI, et les codecs ACM sont encapsulés par le filtre wrapper ACM. Les objets de gestion de base de données sont encapsulés par le filtre wrapper DMO. L’énumérateur de périphériques système fournit un moyen cohérent d’énumérer et de créer l’un de ces types de compresseurs, sans se soucier du modèle sous-jacent.

Pour plus d’informations sur l’énumérateur d’appareil système, consultez Utilisation de l’énumérateur d’appareil système. En bref, tous les filtres DirectShow sont classés par catégorie et chaque catégorie est identifiée par un GUID. Pour les compresseurs vidéo, le GUID de catégorie est CLSID_VideoCompressorCategory. Pour les compresseurs audio, il est CLSID_AudioCompressorCategory. Pour énumérer une catégorie particulière, l’énumérateur d’appareil système crée un objet énumérateur qui prend en charge l’interface IEnumMoniker . L’application utilise cette interface pour récupérer les monikers d’appareil, où chaque moniker d’appareil représente une instance d’un filtre DirectShow. Vous pouvez utiliser le moniker pour créer le filtre ou pour obtenir le nom convivial de l’appareil sans créer le filtre.

Pour énumérer les compresseurs vidéo ou audio disponibles sur le système de l’utilisateur, procédez comme suit :

  1. Appelez CoCreateInstance pour créer l’énumérateur d’appareil système, qui a un ID de classe de CLSID_SystemDeviceEnum.
  2. Appelez ICreateDevEnum::CreateClassEnumerator avec le GUID de catégorie de filtre. La méthode retourne un pointeur d’interface IEnumMoniker .
  3. Utilisez la méthode IEnumMoniker::Next pour énumérer les monikers d’appareil. Cette méthode retourne une interface IMoniker , qui représente le moniker.

Pour obtenir le nom convivial d’un moniker, procédez comme suit :

  1. Appelez la méthode IMoniker::BindToStorage . Cette méthode retourne un pointeur d’interface IPropertyBag .
  2. Utilisez la méthode IPropertyBag::Read pour lire la propriété FriendlyName .

En règle générale, une application affiche une liste de compresseurs, afin que l’utilisateur puisse en choisir un. Par exemple, le code suivant remplit une zone de liste avec les noms des compresseurs vidéo disponibles.

void OnInitDialog(HWND hDlg)
{
    HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    IEnumMoniker *pEnum = NULL;
    IMoniker *pMoniker = NULL;

    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
        CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, 
        (void**)&pSysDevEnum);
    if (FAILED(hr))
    {
        // Handle the error.
    }    

    hr = pSysDevEnum->CreateClassEnumerator(
             CLSID_VideoCompressorCategory, &pEnum, 0);
    if (hr == S_OK)  // S_FALSE means nothing in this category.
    {
        while (S_OK == pEnum->Next(1, &pMoniker, NULL))
        {
            IPropertyBag *pPropBag = NULL;
            pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
                (void **)&pPropBag);
            VARIANT var;
            VariantInit(&var);
            hr = pPropBag->Read(L"FriendlyName", &var, 0);
            if (SUCCEEDED(hr))
            {
                LRESULT iSel = AddString(GetDlgItem(hDlg, 
                    IDC_CODEC_LIST), var.bstrVal);
            }   
            VariantClear(&var); 
            pPropBag->Release();
            pMoniker->Release();
        }
    }

    SendDlgItemMessage(hDlg, IDC_CODEC_LIST, 
                       LB_SETCURSEL, 0, 0);
    pSysDevEnum->Release();
    pEnum->Release();
}

Pour créer un filtre instance à partir du moniker, appelez la méthode IMoniker::BindToObject. La méthode retourne un pointeur IBaseFilter .

IBaseFilter *pFilter = NULL;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, 
                                       (void**)&pFilter);
if (SUCCEEDED(hr))
{
    // Use the filter. 
    // Remember to release the IBaseFilter interface.
}

Pour les codecs VCM, chaque moniker représente un codec particulier, même si tous les codecs sont encapsulés par le même filtre de compression AVI. L’appel de BindToObject crée une instance de ce filtre, initialisé pour ce codec. Pour cette raison, vous ne pouvez pas appeler CoCreateInstance directement sur le filtre de compression AVI. Vous devez passer par l’énumérateur d’appareil système.

Recompression d’un fichier AVI