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:

  1. Você pode enumerar todos os descompactadores usando o DirectShow, mas este diz nada sobre o compressores (encoders).
  2. 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.
  3. 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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top