2008-08-27 24 views
5

Je cherche un bon moyen d'énumérer tous les codecs vidéo sur une machine Windows XP/Vista.La meilleure façon d'énumérer tous les codecs vidéo disponibles sur Windows?

J'ai besoin de présenter à l'utilisateur un ensemble de codecs vidéo, y compris les compresseurs et les décompresseurs. La sortie ressemblerait à quelque chose comme

 
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 

Le problème que je suis en cours d'exécution en est qu'il n'y a aucun moyen fiable pour de capturer tous les décodeurs disponibles au système. Par exemple:

  1. Vous pouvez énumérer tous les décompresseurs en utilisant DirectShow, mais cela ne vous dit rien sur les compresseurs (encodeurs).
  2. Vous pouvez énumérer tous les composants Video For Windows, mais vous n'obtenez aucune indication s'il s'agit d'encodeurs ou de décodeurs.
  3. Il existe des filtres DirectShow qui peuvent parfaitement vous convenir (filtre Motion JPEG par exemple), mais rien n'indique qu'un filtre DirectShow particulier soit un "décodeur vidéo".

Est-ce que quelqu'un a trouvé une solution généralisée pour ce problème en utilisant l'une des API Windows? Est-ce que Windows Vista Media Foundation API résout l'un de ces problèmes?

Répondre

6

Ceci est mieux géré par DirectShow.

DirectShow fait actuellement partie de la plate-forme 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; 
} 

L'appel suivant énumère tous les compresseurs vidéo à la console:

enumerateDShowFilterList(CLSID_VideoCompressorCategory); 

La page MSDN Filter Categories répertorie toutes les autres catégories 'officielles'. J'espère que c'est un bon point de départ pour vous.

+0

Je pourrais ajouter ce qui suit: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375655(v=vs.85).aspx ".Au bas de la page, il suggère que la catégorie CLSID_LegacyAmFilterCategory serait celle contenant les DMOs accessibles par DirectShow en tant que décompresseurs audio et décompresseurs vidéo. – sboisse

2

La réponse ci-dessus ne tient pas compte des décompresseurs. Il n'y a pas CLSID_VideoDecompressorCategory. Est-ce que c'est un moyen de demander un filtre s'il s'agit d'un décompresseur vidéo?

Pas que je sache.

La plupart des filtres dans cette liste sont des codecs, donc contiennent à la fois un encodeur et un décodeur.

Les filtres dans le

CLSID_ActiveMovieCategories 

sont transposés sur des filtres installés VFW.

(Certaines sociétés de logiciels créent leurs propres catégories, donc il peut y avoir des catégories « non officielles » sur certaines machines)

Si vous voulez voir toutes les catégories installées, utilisez GraphEdit qui est fourni avec le SDK DirectShow. GraphEdit lui-même est un excellent outil pour voir ce que fait DirectShow sous le capot.Alors peut-être que cela peut être une source de plus d'informations sur les filtres (et leurs interactions) sur votre système.

1

Un autre point que j'ai oublié.

Windows Media Foundation est une boîte à outils pour l'utilisation de WMV/WMA. Il ne fournit pas toutes les fonctionnalités prises en charge par DirectShow. C'est vraiment un SDK pour Windows Media. Il existe des liaisons WMV/WMA à DirectShow, ce qui vous permet d'utiliser des fichiers/flux WM * dans les applications DirectShow.