Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to enumerate all available video codecs on Windows?

I'm looking for a good way to enumerate all the Video codecs on a Windows XP/Vista machine.

I need present the user with a set of video codecs, including the compressors and decompressors. The output would look something like

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

The problem that I am running into is that there is no reliable way to to capture all of the decoders available to the system. For instance:

  1. You can enumerate all the decompressors using DirectShow, but this tells you nothing about the compressors (encoders).
  2. You can enumerate all the Video For Windows components, but you get no indication if these are encoders or decoders.
  3. There are DirectShow filters that may do the job for you perfectly well (Motion JPEG filter for example), but there is no indication that a particular DirectShow filter is a "video decoder".

Has anyone found a generalizes solution for this problem using any of the Windows APIs? Does the Windows Vista Media Foundation API solve any of these issues?

like image 641
Nick Haddad Avatar asked Aug 27 '08 16:08

Nick Haddad


People also ask

How do you find out what Video Codecs are installed?

To determine what codec was used with a specific file, play the file in the Player, if possible. While the file is playing, right-click the file in the library, and then select Properties. On the File tab, look at the Audio codec and Video codec sections. Use a non-Microsoft codec identification tool.

How do I find Video Codecs in Windows 10?

Type System Information in the Windows 10 search bar and click on the app to launch it. Now, expand the Components section on the left pane. Then expand the Multimedia section. In the Multimedia section, you will find Audio Codecs and Video Codecs.

Does Windows 10 need Video Codecs?

For built-in support, you'll need the codecs. These aren't included with the latest versions of Windows 10 but must be installed from the Microsoft Store. These codecs are also required for encoding video in HEVC (H. 265) format in applications that use Windows 10's system codecs.


1 Answers

This is best handled by DirectShow.

DirectShow is currently a part of the 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;
}

The following call enumerates all video compressors to the console :

enumerateDShowFilterList( CLSID_VideoCompressorCategory );

The MSDN page Filter Categories lists all other 'official' categories.

I hope that is a good starting point for you.

like image 173
Christopher Avatar answered Sep 20 '22 07:09

Christopher