DirectShow DirectShow 의 사용법 비디오 캡춰 캡춰에 관한 고도의 주제 커널 모드 필터의 생성   [목차열람] [주소복사] [슬롯비우기]
커널 모드 필터의 생성
 
Microsoft DirectX 9.0

커널 모드 필터의 생성

일부의 커널 모드 필터는 CoCreateInstance 를 사용해 생성 할 수 없기 때문에, CLSID 가 없다. 이러한 필터에는,티/싱크 투 싱크 컨버터,CC 디코더 필터, 및 WST CODEC 필터가 있다. 이러한 필터의 1 개를 생성 하려면 ,System Device Enumerator 개체를 사용해, 필터의 이름으로 검색한다.

  1. System Device Enumerator 를 생성 한다.
  2. 대상 필터에 대한 필터 카테고리의 CLSID 를 사용해 ICreateDevEnum::CreateClassEnumerator 메서드를 호출한다. 이 메서드는 필터 카테고리의 열거자를 생성 한다. ("열거자" 란, 정의가 끝난 COM 인터페이스를 사용해 다른 개체의 리스트를 돌려주는 개체이다. ) 열거자는 IMoniker 포인터를 돌려준다. 이 포인터는 그 카테고리의 필터를 나타낸다.
  3. 모니카 마다,IMoniker::BindToStorage 를 호출해,IPropertyBag 인터페이스를 얻어온다.
  4. IPropertyBag::Read 를 호출해, 필터명을 얻어온다.
  5. 이름이 일치했을 경우,IMoniker::BindToObject 를 호출해, 필터를 생성 한다.

다음 코드는, 위의 순서를 실행하는 함수를 나타내고 있다.

HRESULT CreateKernelFilter(
    const GUID &guidCategory,  // 필터 카테고리.
    LPCOLESTR szName,          // 필터의 이름.
    IBaseFilter **ppFilter     // 필터의 포인터를 얻어온다.
)
{
    HRESULT hr;
    ICreateDevEnum *pDevEnum = NULL;
    IEnumMoniker *pEnum = NULL;
    if (! szName || ! ppFilter) 
    {
        return E_POINTER;
    }

    // 시스템 장치 열거자를 생성 한다.
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
        IID_ICreateDevEnum, (void**) &pDevEnum);
    if (FAILED(hr))
    {
        return hr;
    }

    // 지정된 카테고리의 클래스 열거자를 생성 한다.
    hr = pDevEnum->CreateClassEnumerator(guidCategory, &pEnum, 0);
    pDevEnum->Release();
    if (hr != S_OK) // S_FALSE 는, 카테고리가 하늘인 것을 의미한다.
    {
        return E_FAIL;
    }

    // 이 카테고리내의 장치를 열거한다.
    bool bFound = false;
    IMoniker *pMoniker;
    while (! bFound && (S_OK == pEnum->Next(1, &pMoniker, 0)))
    {
        IPropertyBag *pBag = NULL;
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag);
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue; // 다음은 올바르게 움직일 가능성이 있다.
        }
        // 프렌들리명을 조사한다.
        VARIANT var;
        VariantInit(&var);
        hr = pBag->Read(L"FriendlyName", &var, NULL);
        if (SUCCEEDED(hr) && (lstrcmpiW(var.bstrVal, szName) == 0))
        {
            // 이 필터는 올바르다.
            hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter,
                (void**) ppFilter);
            bFound = true;
        }
        VariantClear(&var);
        pBag->Release();
        pMoniker->Release();
    }
    pEnum->Release();
    return (bFound ?  hr : E_FAIL);
}

다음 샘플 코드는, 이 함수를 사용해 CC 디코더 필터를 생성 해, 필터 그래프에 추가한다.

IBaseFilter *pCC = NULL;
hr = CreateKernelFilter(AM_KSCATEGORY_VBICODEC, 
    OLESTR("CC Decoder"), &pCC);
if (SUCCEEDED(hr))
{
    hr = pGraph->AddFilter(pCC, L"CC Decoder");
    pCC->Release();
}

참조

↑TOP