2008-08-27 11 views
5

Windows XP/Vista 시스템에서 모든 비디오 코덱을 나열하는 좋은 방법을 찾고 있습니다.Windows에서 사용 가능한 모든 비디오 코덱을 열거하는 가장 좋은 방법은 무엇입니까?

사용자에게 압축기 및 압축 해제기를 포함한 비디오 코덱 세트를 제시해야합니다. 출력은

 
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 

처럼 시스템에 사용할 수있는 디코더를 모두 캡처 할 신뢰할 수있는 방법이 없다는 것입니다으로 실행하고 문제를 보일 것이다. 예를 들면 다음과 같습니다.

  1. 압축 해독기는 모두 DirectShow를 사용하여 열거 할 수 있지만 압축기 (인코더)에 대해서는 알려주지 않습니다.
  2. 모든 Video For Windows 구성 요소를 열거 할 수 있지만 이들이 인코더 또는 디코더인지 여부는 알 수 없습니다.
  3. 완벽하게 잘 작동 할 수있는 DirectShow 필터가 있지만 (예 : 모션 JPEG 필터) 특정 DirectShow 필터가 "비디오 디코더"라는 표시가 없습니다.

누구나 Windows API를 사용하여이 문제에 대한 일반화 해결책을 찾았습니까? Windows Vista Media Foundation API이 이러한 문제를 해결합니까?

답변

6

이것은 DirectShow에서 가장 잘 처리됩니다.

DirectShow는 현재 플랫폼 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; 
} 

다음 호출은 콘솔에 모든 비디오 압축기를 열거 :

enumerateDShowFilterList(CLSID_VideoCompressorCategory); 

MSDN의 페이지를 Filter Categories 목록 다른 모든 '공식'카테고리를.

나는 그것이 당신을위한 좋은 출발점이되기를 바랍니다.

+0

다음을 추가 할 수 있습니다. http://msdn.microsoft.com/en-us/library/windows/desktop/dd375655(v=vs.85).aspx "페이지 맨 아래에 카테고리 CLSID_LegacyAmFilterCategory는 오디오 디 컴프레서 및 비디오 디 컴프레서로서 DirectShow가 액세스 가능한 DMO를 포함한 카테고리가된다. – sboisse

2

위의 대답은 압축 해제기에 대한 설명이 아닙니다. CLSID_VideoDecompressorCategory가 없습니다. 필터가 비디오 압축 해제 기인 경우 필터에 요청하는 방법입니까?

아니요.

이 목록의 필터는 대부분 코덱이므로 인코더와 디코더가 모두 포함되어 있습니다.

CLSID_ActiveMovieCategories 

에서

필터가 설치을 VfW 필터 래퍼입니다.

는 (일부 소프트웨어 회사들은 자신의 범주를 만들고, 그래서 일부 컴퓨터에서 '비 공식적인'카테고리가있을 수 있습니다) 당신이 설치된 모든 카테고리를 볼 수있는 DirectShow를 SDK와 함께 제공됩니다 GraphEdit로 사용하려는 경우

.

GraphEdit 자체는 DirectShow에서 무엇을하는지 확인할 수있는 훌륭한 도구입니다.아마도 시스템의 필터 (및 상호 작용)에 대한 더 많은 정보를 얻을 수 있습니다.

1

다른 점을 잊어 버렸습니다.

Windows Media Foundation은 WMV/WMA를 사용하기위한 툴킷입니다. DirectShow가 지원하는 모든 것을 제공하는 것은 아닙니다. Windows Media 용 SDK 만 있습니다. DirectShow 응용 프로그램에서 WM * 파일/스트림을 사용할 수 있도록 DirectShow에 대한 WMV/WMA 바인딩이 있습니다.