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

Video 枚举Windows上所有可用视频编解码器的最佳方法?,video,directshow,media,codec,Video,Directshow,Media,Codec,我正在寻找一种很好的方法来列举WindowsXP/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 可用解码器 DiVX版本

我正在寻找一种很好的方法来列举WindowsXP/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 可用解码器 DiVX版本6.0 十六 帧每秒 公司的MPEG-2解码器 Windows Media视频 **可用编码器** DiVX版本6.0 Windows Media视频 我遇到的问题是,没有可靠的方法来捕获系统可用的所有解码器。例如:

  • 您可以使用DirectShow枚举所有的解压器,但这并没有告诉您有关压缩器(编码器)的任何信息
  • 您可以枚举Windows的所有视频组件,但无法指示这些组件是编码器还是解码器
  • 有一些DirectShow过滤器可以很好地完成这项工作(例如,运动JPEG过滤器),但没有迹象表明特定的DirectShow过滤器是“视频解码器”

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

    这最好由DirectShow来处理

    DirectShow目前是平台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;
    }
    
    MSDN页面列出了所有其他“官方”类别

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

    上面的答案不包括解压器。没有CLSID\u视频解压缩类别。这是一种询问过滤器是否为视频解压器的方法吗

    据我所知不是这样。

    此列表中的大多数过滤器都是编解码器,因此同时包含编码器和解码器

    空气中的过滤器

    CLSID_ActiveMovieCategories
    
    VfW过滤器周围是否安装了包装器

    (一些软件公司创建自己的类别,因此在某些机器上可能存在“非官方”类别)

    如果要查看所有已安装的类别,请使用DirectShow SDK附带的GraphEdit


    GraphEdit本身就是一个很好的工具,可以查看DirectShow在幕后的工作。因此,这可能是关于系统上的过滤器(及其交互)的更多信息的来源。

    我忘记了另一点

    Windows Media基金会是使用WMV/WMA的工具包。它并没有提供DirectShow支持的所有功能。它实际上只是一个适用于Windows Media的SDK。 WMV/WMA中有到DirectShow的绑定,因此您可以在DirectShow应用程序中使用WM*文件/流。

    我可能会添加以下内容:“。在页面底部,它建议类别CLSID_LegacyAmFilterCategory将包含DirectShow可作为音频解压缩器和视频解压缩器访问的DMO。
    CLSID_ActiveMovieCategories