2008-08-27 9 views
5

Estoy buscando una buena manera de enumerar todos los códecs de video en una máquina con Windows XP/Vista.¿La mejor manera de enumerar todos los códecs de video disponibles en Windows?

Necesito presentar al usuario un conjunto de códecs de video, incluidos los compresores y descompresores. La salida sería 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 

El problema que estoy funcionando con en es que no hay manera 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 se indica si estos son codificadores o decodificadores.
  3. Hay filtros DirectShow que pueden hacer el trabajo por usted perfectamente (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 general para este problema usando cualquiera de las API de Windows? ¿El Windows Vista Media Foundation API resuelve alguno de estos problemas?

Respuesta

6

DirectShow lo maneja mejor.

DirectShow es actualmente parte de la plataforma 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; 
} 

La llamada siguiente enumera todos los compresores de vídeo en la consola:

enumerateDShowFilterList(CLSID_VideoCompressorCategory); 

La página de MSDN Filter Categories listas de todas las demás categorías 'oficiales'.

Espero que sea un buen punto de partida para usted.

+0

Podría agregar lo siguiente: http://msdn.microsoft.com/en-us/library/windows/desktop/dd375655(v=vs.85).aspx ". En la parte inferior de la página, sugiere que la categoría CLSID_LegacyAmFilterCategory sería la que contiene DMO accesible por DirectShow como descompresores de audio y descompresores de video. – sboisse

2

La respuesta anterior no tiene en cuenta los descompresores. No hay CLSID_VideoDecompressorCategory. ¿Es la forma de solicitar un filtro si es un descompresor de video?

No es 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 de la

CLSID_ActiveMovieCategories 

son envolturas alrededor de los filtros instalados VfW.

(Algunas compañías de software a crear sus propias categorías, lo que puede haber categorías 'no oficiales' en algunas máquinas)

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

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

1

Otro punto que olvidé.

Windows Media Foundation es un conjunto de herramientas para usar WMV/WMA. No proporciona todas las cosas que DirectShow admite. En realidad, es solo un SDK para Windows Media. Hay enlaces en WMV/WMA a DirectShow, para que pueda usar archivos/secuencias WM * en aplicaciones DirectShow.

Cuestiones relacionadas