A melhor maneira para enumerar todos os codecs de vídeo disponíveis no Windows?
-
09-06-2019 - |
Pergunta
Eu estou procurando uma boa maneira para enumerar todos os codecs de Vídeo no Windows XP/Vista máquina.
Eu preciso apresentar ao usuário um conjunto de codecs de vídeo, incluindo o compactadores e descompactadores.A saída deve se parecer com algo como
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
O problema que eu tenho é de que não há nenhuma maneira confiável para capturar todos os decodificadores disponível para o sistema.Por exemplo:
- Você pode enumerar todos os descompactadores usando o DirectShow, mas este diz nada sobre o compressores (encoders).
- Você pode enumerar todas as Vídeo Para componentes do Windows, mas você não receber nenhuma indicação se estes são os encoders ou decodificadores.
- Existem filtros de DirectShow que pode fazer o trabalho para você perfeitamente bem (Motion JPEG filtro, por exemplo), mas não há nenhuma indicação de que um determinado filtro do DirectShow é um "decodificador de vídeo".
Alguém já encontrou um generaliza solução para este problema utilizando qualquer uma das APIs do Windows?O Windows Vista Media Foundation API resolver estes problemas?
Solução
Este é o melhor tratado pelo DirectShow.
O DirectShow é atualmente uma parte do 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;
}
A chamada seguinte enumera todos os compressores de vídeo para a consola :
enumerateDShowFilterList( CLSID_VideoCompressorCategory );
A página da MSDN Filtro De Categorias lista de todos os outros 'oficial' categorias.
Espero que seja um bom ponto de partida para você.
Outras dicas
A resposta acima não conta para descompactadores.Não há CLSID_VideoDecompressorCategory.É o são uma forma de pedir um filtro se ele é um descompactador de vídeo?
Não que eu saiba.
A maioria dos filtros nesta lista são os codecs, portanto, conter um decodificador e codificador.
Os filtros no
CLSID_ActiveMovieCategories
são wrappers em todo o VfW filtros instalados.
(Algumas empresas de software a criar suas próprias categorias, portanto, pode haver 'não oficial' categorias em algumas máquinas)
Se você quiser ver todas as categorias instaladas, use o GraphEdit que é fornecido com o DirectShow SDK.
GraphEdit em si é uma ótima ferramenta para ver o que DirectShow faz sob o capô.Então, talvez o que pode ser uma fonte de mais informações sobre os filtros (e suas interações) em seu sistema.
Outro ponto que eu esqueci.
O Windows Media Foundation é um kit de ferramentas para o uso WMV/WMA.Ele não fornece todas as coisas que DirectShow oferece suporte.Ele é realmente apenas um SDK para Windows Media.Existem ligações em WMV/WMA para o DirectShow, de modo que você pode usar WM* arquivos/fluxos no DirectShow aplicações.