加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在Windows上枚举所有可用视频编解码器的最佳方法?

发布时间:2020-12-14 02:52:51 所属栏目:Windows 来源:网络整理
导读:我正在寻找一种在 Windows XP / Vista机器上枚举所有视频编解码器的好方法. 我需要向用户呈现一组视频编解码器,包括压缩器和解压缩器.输出看起来像 Available DecodersDiVX Version 6.0XVIDMotion JPEGCompanyX's MPEG-2 DecoderWindows Media Video**Availa
我正在寻找一种在 Windows XP / Vista机器上枚举所有视频编解码器的好方法.

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

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

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

>您可以使用DirectShow枚举所有解压缩程序,但这不会告诉您有关压缩程序(编码器)的任何信息.
>您可以枚举所有Video For Windows组件,但没有迹象表明这些是编码器还是解码器.
> DirectShow过滤器可以很好地完成这项工作(例如Motion JPEG过滤器),但没有迹象表明特定的DirectShow过滤器是“视频解码器”.

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

解决方法

这最好由DirectShow处理.

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

HRESULT extractFriendlyName( IMoniker* pMk,std::wstring& str )
{
  assert( pMk != 0 );
  IPropertyBag* pBag = 0;
  HRESULT hr = pMk->BindToStorage(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;
}

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

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

MSDN第Filter Categories页列出了所有其他“官方”类别.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读