Freigeben über


Auswählen eines Komprimierungsfilters

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Verschiedene Arten von Softwarekomponenten können eine Video- oder Audiokomprimierung durchführen, z. B.:

  • Native DirectShow-Filter
  • Video Compression Manager (VCM)-Codecs
  • Audio Compression Manager (ACM)-Codecs
  • DirectX Media Objects (DMOs)

In DirectShow werden VCM-Codecs vom AVI-Kompressorfilter umschlossen, und ACM-Codecs werden vom ACM-Wrapperfilter umschlossen. DMOs werden vom DMO-Wrapperfilter umschlossen. Der Systemgeräte-Enumerator bietet eine konsistente Möglichkeit, einen dieser Kompressortypen aufzuzählen und zu erstellen, ohne sich Gedanken über das zugrunde liegende Modell machen zu müssen.

Ausführliche Informationen zum Systemgeräte-Enumerator finden Sie unter Verwenden des Systemgeräte-Enumerators. Kurz gesagt, alle DirectShow-Filter werden nach Kategorie klassifiziert, und jede Kategorie wird durch eine GUID identifiziert. Für Videokompressoren ist die Kategorie GUID CLSID_VideoCompressorCategory. Für Audiokompressoren ist es CLSID_AudioCompressorCategory. Um eine bestimmte Kategorie aufzulisten, erstellt der Systemgeräteenumerator ein Enumeratorobjekt , das die IEnumMoniker-Schnittstelle unterstützt. Die Anwendung verwendet diese Schnittstelle zum Abrufen von Gerätemonikern, wobei jeder Gerätemoniker eine instance eines DirectShow-Filters darstellt. Sie können den Moniker verwenden, um den Filter zu erstellen oder den Anzeigenamen des Geräts abzurufen, ohne den Filter zu erstellen.

Gehen Sie wie folgt vor, um die video- oder audio-Kompressoren aufzulisten, die auf dem System des Benutzers verfügbar sind:

  1. Rufen Sie CoCreateInstance auf, um den Systemgeräteenumerator zu erstellen, der über die Klassen-ID CLSID_SystemDeviceEnum verfügt.
  2. Rufen Sie ICreateDevEnum::CreateClassEnumerator mit der Filterkategorie-GUID auf. Die -Methode gibt einen IEnumMoniker-Schnittstellenzeiger zurück.
  3. Verwenden Sie die IEnumMoniker::Next-Methode, um die Gerätemoniker aufzulisten. Diese Methode gibt eine IMoniker-Schnittstelle zurück, die den Moniker darstellt.

Gehen Sie wie folgt vor, um den Anzeigenamen von einem Moniker abzurufen:

  1. Rufen Sie die IMoniker::BindToStorage-Methode auf . Diese Methode gibt einen IPropertyBag-Schnittstellenzeiger zurück.
  2. Verwenden Sie die IPropertyBag::Read-Methode , um die FriendlyName-Eigenschaft zu lesen.

In der Regel zeigt eine Anwendung eine Liste von Kompressoren an, sodass der Benutzer einen auswählen kann. Der folgende Code füllt beispielsweise ein Listenfeld mit den Namen der verfügbaren Videokompressoren auf.

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

Um einen Filter instance aus dem Moniker zu erstellen, rufen Sie die IMoniker::BindToObject-Methode auf. Die -Methode gibt einen IBaseFilter-Zeiger zurück.

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

Bei VCM-Codecs stellt jeder Moniker einen bestimmten Codec dar, obwohl alle Codecs vom gleichen AVI-Komprimierungsfilter umschlossen sind. Durch aufrufen von BindToObject wird eine instance dieses Filters erstellt, der für diesen Codec initialisiert wird. Aus diesem Grund können Sie CoCreateInstance nicht direkt im AVI-Komprimierungsfilter aufrufen. Sie müssen den Systemgeräte-Enumerator durchlaufen.

Erneutes Komprimieren einer AVI-Datei