Question

Je recherche un bon moyen d'énumérer tous les codecs vidéo sur une machine Windows XP/Vista.

Je dois présenter à l'utilisateur un ensemble de codecs vidéo, y compris les compresseurs et 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 rencontre est qu'il n'existe aucun moyen fiable de capturer tous les décodeurs disponibles sur le système.Par exemple:

  1. Vous pouvez énumérer tous les décompresseurs à l'aide de 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 faire le travail pour vous (filtre Motion JPEG par exemple), mais rien n'indique qu'un filtre DirectShow particulier est un "décodeur vidéo".

Quelqu'un a-t-il trouvé une solution généralisée à ce problème en utilisant l'une des API Windows ?Est-ce que Windows Vista API de la Fondation Media résoudre l'un de ces problèmes ?

Était-ce utile?

La solution

Ceci est mieux géré par DirectShow.

DirectShow fait actuellement partie du SDK de la plateforme.

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 sur la console :

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

La page MSDN Filtrer les catégories répertorie toutes les autres catégories « officielles ».

J'espère que c'est un bon point de départ pour vous.

Autres conseils

La réponse ci-dessus ne prend pas en compte les décompresseurs.Il n’existe pas de CLSID_VideoDecompressorCategory.Existe-t-il un moyen de demander à un filtre s'il s'agit d'un décompresseur vidéo ?

Pas que je sache de.

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

Les filtres dans le

CLSID_ActiveMovieCategories

sont des enveloppes autour des filtres VfW installés.

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

Si vous souhaitez voir toutes les catégories installées, utilisez GraphEdit fourni avec le SDK DirectShow.

GraphEdit lui-même est un excellent outil pour voir ce que DirectShow fait sous le capot.Alors peut-être que cela pourrait être une source d'informations supplémentaires sur les filtres (et leurs interactions) sur votre système.

Un autre point que j'ai oublié.

La Windows Media Foundation est une boîte à outils permettant d'utiliser WMV/WMA.Il ne fournit pas tout ce que DirectShow prend en charge.Il ne s'agit en réalité que d'un SDK pour Windows Media.Il existe des liaisons entre WMV/WMA et DirectShow, afin que vous puissiez utiliser les fichiers/flux WM* dans les applications DirectShow.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top