Лучший способ перечислить все доступные видеокодеки в Windows?

StackOverflow https://stackoverflow.com/questions/30539

  •  09-06-2019
  •  | 
  •  

Вопрос

Я ищу хороший способ перечислить все видеокодеки на компьютере с 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

Проблема, с которой я столкнулся, заключается в том, что не существует надежного способа захвата всех декодеров, доступных в системе.Например:

  1. Вы можете перечислить все декомпрессоры с помощью DirectShow, но это ничего не скажет о компрессорах (кодировщиках).
  2. Вы можете перечислить все компоненты Video For Windows, но не получите указания, являются ли они кодировщиками или декодерами.
  3. Существуют фильтры DirectShow, которые могут отлично выполнить эту работу (например, фильтр Motion JPEG), но нет никаких указаний на то, что конкретный фильтр DirectShow является «видеодекодером».

Кто-нибудь нашел обобщенное решение этой проблемы с использованием любого из API-интерфейсов Windows?Есть ли Windows Vista API Фонда СМИ решить любую из этих проблем?

Это было полезно?

Решение

Лучше всего с этим справляется 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;
}

Следующий вызов перечисляет все видеокомпрессоры на консоли:

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

Страница MSDN Фильтровать категории перечисляет все остальные «официальные» категории.

Я надеюсь, что это хорошая отправная точка для вас.

Другие советы

Ответ выше не учитывает декомпрессоры.CLSID_VideoDecompressorCategory отсутствует.Можно ли узнать у фильтра, является ли он видеодекомпрессором?

Не то, что я знаю из.

Большинство фильтров в этом списке являются кодеками, поэтому содержат как кодер, так и декодер.

Фильтры в.

CLSID_ActiveMovieCategories

являются обертками вокруг установленных фильтров VfW.

(Некоторые компании-разработчики программного обеспечения создают свои собственные категории, поэтому на некоторых машинах могут быть «неофициальные» категории.)

Если вы хотите просмотреть все установленные категории, используйте GraphEdit, который поставляется с DirectShow SDK.

GraphEdit сам по себе является отличным инструментом для просмотра того, что делает DirectShow «под капотом».Так что, возможно, это может стать источником дополнительной информации о фильтрах (и их взаимодействии) в вашей системе.

Еще один момент, который я забыл.

Windows Media Foundation — это набор инструментов для использования WMV/WMA.Он не предоставляет всего, что поддерживает DirectShow.На самом деле это всего лишь SDK для Windows Media.В WMV/WMA есть привязки к DirectShow, поэтому вы можете использовать файлы/потоки WM* в приложениях DirectShow.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top