Domanda

Sto cercando un buon modo per enumerare tutti i codec video su una macchina Windows XP/Vista.

Devo presentare all'utente una serie di codec video, inclusi compressori e decompressori.L'output sarebbe simile a

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

Il problema che sto riscontrando è che non esiste un modo affidabile per acquisire tutti i decoder disponibili nel sistema.Ad esempio:

  1. Puoi enumerare tutti i decompressori utilizzando DirectShow, ma questo non ti dice nulla sui compressori (codificatori).
  2. È possibile enumerare tutti i componenti Video For Windows, ma non si ottiene alcuna indicazione se si tratta di codificatori o decodificatori.
  3. Esistono filtri DirectShow che potrebbero svolgere perfettamente il lavoro per te (ad esempio il filtro Motion JPEG), ma non vi è alcuna indicazione che un particolare filtro DirectShow sia un "decodificatore video".

Qualcuno ha trovato una soluzione generalizzata per questo problema utilizzando una delle API di Windows?Funziona con Windows Vista API Media Foundation risolvere qualcuno di questi problemi?

È stato utile?

Soluzione

Questo viene gestito al meglio da DirectShow.

DirectShow fa attualmente parte della piattaforma 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 chiamata seguente enumera tutti i compressori video sulla console:

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

La pagina MSDN Filtra categorie elenca tutte le altre categorie "ufficiali".

Spero che sia un buon punto di partenza per te.

Altri suggerimenti

La risposta sopra non tiene conto dei decompressori.Non esiste CLSID_VideoDecompressorCategory.Esiste un modo per chiedere a un filtro se si tratta di un decompressore video?

Non che io sappia.

La maggior parte dei filtri in questo elenco sono codec, quindi contengono sia un codificatore che un decodificatore.

I filtri in

CLSID_ActiveMovieCategories

sono wrapper attorno ai filtri VfW installati.

(Alcune società di software creano le proprie categorie, quindi su alcune macchine potrebbero esserci categorie "non ufficiali")

Se desideri visualizzare tutte le categorie installate, utilizza GraphEdit fornito con DirectShow SDK.

GraphEdit stesso è un ottimo strumento per vedere cosa fa DirectShow dietro le quinte.Quindi forse potrebbe essere una fonte di ulteriori informazioni sui filtri (e le loro interazioni) sul tuo sistema.

Un altro punto che ho dimenticato.

Windows Media Foundation è un toolkit per l'utilizzo di WMV/WMA.Non fornisce tutte le cose supportate da DirectShow.In realtà è solo un SDK per Windows Media.Sono presenti collegamenti in WMV/WMA a DirectShow, in modo da poter utilizzare file/flussi WM* nelle applicazioni DirectShow.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top