Frage

Ich suche nach einer guten Möglichkeit, alle Video-Codecs auf einem Windows XP/Vista-Computer aufzulisten.

Ich muss dem Benutzer eine Reihe von Video-Codecs präsentieren, einschließlich der Kompressoren und Dekomprimierer.Die Ausgabe würde in etwa so aussehen

Available Decoders
DiVX Version 6.0
XVID
Motion JPEG
CompanyX's MPEG-2 Decoder
Windows Media Video

**Available Encoders**
DiVX Version 6.0
Windows Media Video

Das Problem, auf das ich stoße, besteht darin, dass es keine zuverlässige Möglichkeit gibt, alle für das System verfügbaren Decoder zu erfassen.Zum Beispiel:

  1. Sie können alle Dekomprimierer mit DirectShow auflisten, aber das sagt Ihnen nichts über die Kompressoren (Encoder).
  2. Sie können alle Video For Windows-Komponenten aufzählen, erhalten jedoch keinen Hinweis darauf, ob es sich um Encoder oder Decoder handelt.
  3. Es gibt DirectShow-Filter, die diese Aufgabe möglicherweise perfekt für Sie erledigen (z. B. Motion JPEG-Filter), aber es gibt keinen Hinweis darauf, dass es sich bei einem bestimmten DirectShow-Filter um einen „Videodecoder“ handelt.

Hat jemand mithilfe einer der Windows-APIs eine allgemeine Lösung für dieses Problem gefunden?Funktioniert Windows Vista Media Foundation-API eines dieser Probleme lösen?

War es hilfreich?

Lösung

Dies wird am besten von DirectShow erledigt.

DirectShow ist derzeit Teil des Plattform-SDK.

HRESULT extractFriendlyName( IMoniker* pMk, std::wstring& str )
{
  assert( pMk != 0 );
  IPropertyBag* pBag = 0;
  HRESULT hr = pMk->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag );
  if( FAILED( hr ) || pBag == 0 )
  {
    return hr;
  }
  VARIANT var;
  var.vt = VT_BSTR;
  hr = pBag->Read(L"FriendlyName", &var, NULL);
  if( SUCCEEDED( hr ) && var.bstrVal != 0 )
  {
    str = reinterpret_cast<wchar_t*>( var.bstrVal );
    SysFreeString(var.bstrVal);
  }
  pBag->Release();
  return hr;
}


HRESULT enumerateDShowFilterList( const CLSID& category )
{
  HRESULT rval = S_OK;
  HRESULT hr;
  ICreateDevEnum* pCreateDevEnum = 0; // volatile, will be destroyed at the end
  hr = ::CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>( &pCreateDevEnum ) );

  assert( SUCCEEDED( hr ) && pCreateDevEnum != 0 );
  if( FAILED( hr ) || pCreateDevEnum == 0 )
  {
    return hr;
  }

  IEnumMoniker* pEm = 0;
  hr = pCreateDevEnum->CreateClassEnumerator( category, &pEm, 0 );

  // If hr == S_FALSE, no error is occured. In this case pEm is NULL, because
  // a filter does not exist e.g no video capture devives are connected to
  // the computer or no codecs are installed.
  assert( SUCCEEDED( hr ) && ((hr == S_OK && pEm != 0 ) || hr == S_FALSE) );
  if( FAILED( hr ) )
  {
    pCreateDevEnum->Release();
    return hr;
  }

  if( hr == S_OK && pEm != 0 ) // In this case pEm is != NULL
  {
    pEm->Reset();
    ULONG cFetched;
    IMoniker* pM = 0;
    while( pEm->Next(1, &pM, &cFetched) == S_OK && pM != 0 )
    {
       std::wstring str;

       if( SUCCEEDED( extractFriendlyName( pM, str ) )
       {
          // str contains the friendly name of the filter
          // pM->BindToObject creates the filter
          std::wcout << str << std::endl;
       }

       pM->Release();
    }
    pEm->Release();
  }
  pCreateDevEnum->Release();
  return rval;
}

Der folgende Aufruf listet alle Videokompressoren in der Konsole auf:

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

Die MSDN-Seite Kategorien filtern listet alle anderen „offiziellen“ Kategorien auf.

Ich hoffe, das ist ein guter Ausgangspunkt für Sie.

Andere Tipps

Die obige Antwort berücksichtigt keine Dekomprimierer.Es gibt keine CLSID_VideoDecompressorCategory.Gibt es eine Möglichkeit, einen Filter zu fragen, ob es sich um einen Videodekomprimierer handelt?

Nicht, dass ich davon Wüste.

Die meisten Filter in dieser Liste sind Codecs, enthalten also sowohl einen Encoder als auch einen Decoder.

Die Filter in der

CLSID_ActiveMovieCategories

sind Wrapper um die installierten VfW-Filter.

(Einige Softwareunternehmen erstellen ihre eigenen Kategorien, sodass es auf einigen Computern möglicherweise „nicht offizielle“ Kategorien gibt.)

Wenn Sie alle installierten Kategorien sehen möchten, verwenden Sie GraphEdit, das mit dem DirectShow SDK geliefert wird.

GraphEdit selbst ist ein großartiges Tool, um zu sehen, was DirectShow unter der Haube macht.Vielleicht ist dies also eine Quelle für weitere Informationen über die Filter (und ihre Interaktionen) in Ihrem System.

Noch ein Punkt, den ich vergessen habe.

Die Windows Media Foundation ist ein Toolkit zur Verwendung von WMV/WMA.Es bietet nicht alle Dinge, die DirectShow unterstützt.Es ist eigentlich nur ein SDK für Windows Media.Es gibt Bindungen in WMV/WMA an DirectShow, sodass Sie WM*-Dateien/Streams in DirectShow-Anwendungen verwenden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top