Лучший способ перечислить все доступные видеокодеки в Windows?
-
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
Проблема, с которой я столкнулся, заключается в том, что не существует надежного способа захвата всех декодеров, доступных в системе.Например:
- Вы можете перечислить все декомпрессоры с помощью DirectShow, но это ничего не скажет о компрессорах (кодировщиках).
- Вы можете перечислить все компоненты Video For Windows, но не получите указания, являются ли они кодировщиками или декодерами.
- Существуют фильтры 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.