DirectShow DirectShow 의 사용법 비디오 캡춰 캡춰에 관한 고도의 주제 커널 모드 필터의 생성 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
일부의 커널 모드 필터는 CoCreateInstance 를 사용해 생성 할 수 없기 때문에, CLSID 가 없다. 이러한 필터에는,티/싱크 투 싱크 컨버터,CC 디코더 필터, 및 WST CODEC 필터가 있다. 이러한 필터의 1 개를 생성 하려면 ,System Device Enumerator 개체를 사용해, 필터의 이름으로 검색한다.
다음 코드는, 위의 순서를 실행하는 함수를 나타내고 있다.
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();
}
참조