Pregunta

Estoy buscando una buena manera de enumerar todos los códecs de vídeo en una máquina con Windows XP/Vista.

Necesito presentarle al usuario un conjunto de códecs de vídeo, incluidos los compresores y descompresores.La salida se vería así

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

El problema con el que me encuentro es que no existe una forma confiable de capturar todos los decodificadores disponibles para el sistema.Por ejemplo:

  1. Puede enumerar todos los descompresores usando DirectShow, pero esto no le dice nada sobre los compresores (codificadores).
  2. Puede enumerar todos los componentes de Video para Windows, pero no obtiene ninguna indicación si se trata de codificadores o decodificadores.
  3. Hay filtros DirectShow que pueden hacer el trabajo perfectamente por usted (filtro Motion JPEG, por ejemplo), pero no hay ninguna indicación de que un filtro DirectShow en particular sea un "decodificador de video".

¿Alguien ha encontrado una solución generalizada para este problema utilizando alguna de las API de Windows?¿Windows Vista? API de la Fundación de Medios resolver alguno de estos problemas?

¿Fue útil?

Solución

Esto se maneja mejor con DirectShow.

DirectShow forma parte actualmente del SDK de la plataforma.

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;
}

La siguiente llamada enumera todos los compresores de video para la consola:

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

La página de MSDN Filtrar categorías enumera todas las demás categorías "oficiales".

Espero que sea un buen punto de partida para ti.

Otros consejos

La respuesta anterior no tiene en cuenta los descompresores.No existe CLSID_VideoDecompressorCategory.¿Es esta una forma de preguntarle a un filtro si es un descompresor de video?

No que yo sepa.

La mayoría de los filtros de esta lista son códecs, por lo que contienen un codificador y un decodificador.

Los filtros en el

CLSID_ActiveMovieCategories

Hay envoltorios alrededor de los filtros VfW instalados.

(Algunas empresas de software crean sus propias categorías, por lo que puede haber categorías "no oficiales" en algunas máquinas)

Si desea ver todas las categorías instaladas, utilice GraphEdit que se suministra con DirectShow SDK.

GraphEdit en sí es una gran herramienta para ver qué hace DirectShow bajo el capó.Entonces, tal vez esa sea una fuente de más información sobre los filtros (y sus interacciones) en su sistema.

Otro punto que olvidé.

Windows Media Foundation es un conjunto de herramientas para utilizar WMV/WMA.No proporciona todo lo que admite DirectShow.En realidad, es sólo un SDK para Windows Media.Hay enlaces en WMV/WMA a DirectShow, para que pueda usar archivos/transmisiones WM* en aplicaciones DirectShow.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top