枚举Windows上所有可用视频编解码器的最佳方法? [英] Best way to enumerate all available video codecs on Windows?

查看:224
本文介绍了枚举Windows上所有可用视频编解码器的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找枚举Windows XP/Vista计算机上所有视频编解码器的好方法.

I'm looking for a good way to enumerate all the Video codecs on a Windows XP/Vista machine.

我需要向用户提供一组视频编解码器,包括压缩器和解压缩器.输出看起来像

I need present the user with a set of video codecs, including the compressors and decompressors. The output would look something like


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

我遇到的问题是,没有可靠的方法来捕获系统可用的所有解码器.例如:

The problem that I am running into is that there is no reliable way to to capture all of the decoders available to the system. For instance:

  1. 您可以使用DirectShow枚举所有解压缩器,但这对压缩器(编码器)一无所知.
  2. 您可以枚举Windows的所有Video组件,但是没有指示它们是编码器还是解码器.
  3. 有些DirectShow过滤器可以很好地为您完成工作(例如,Motion JPEG过滤器),但没有迹象表明特定的DirectShow过滤器是视频解码器".

有人使用任何Windows API找到了针对此问题的通用解决方案吗? Windows Vista Media Foundation API 是否可以解决这些问题?

Has anyone found a generalizes solution for this problem using any of the Windows APIs? Does the Windows Vista Media Foundation API solve any of these issues?

推荐答案

这最好由DirectShow处理.

This is best handled by DirectShow.

DirectShow当前是平台SDK的一部分.

DirectShow is currently a part of the platform 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;
}

以下调用将所有视频压缩器枚举到控制台:

The following call enumerates all video compressors to the console :

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

MSDN页面过滤器类别列出了所有其他官方"类别.

The MSDN page Filter Categories lists all other 'official' categories.

我希望这对您来说是一个很好的起点.

I hope that is a good starting point for you.

这篇关于枚举Windows上所有可用视频编解码器的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆