압축 필터 선택
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine 및 오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]
여러 유형의 소프트웨어 구성 요소는 다음과 같은 비디오 또는 오디오 압축을 수행할 수 있습니다.
- 네이티브 DirectShow 필터
- VCM(비디오 압축 관리자) 코덱
- ACM(오디오 압축 관리자) 코덱
- DDO(DirectX 미디어 개체)
DirectShow에서 VCM 코덱은 AVI 압축기 필터에 의해 래핑되고 ACM 코덱은 ACM 래퍼 필터에 의해 래핑됩니다. DMO는 DMO 래퍼 필터에 의해 래핑됩니다. 시스템 디바이스 열거자는 기본 모델에 대한 걱정 없이 이러한 압축기 유형을 열거하고 만드는 일관된 방법을 제공합니다.
시스템 디바이스 열거자에 대한 자세한 내용은 시스템 디바이스 열거자 사용을 참조하세요. 간단히 말해서 모든 DirectShow 필터는 범주별로 분류되며 각 범주는 GUID로 식별됩니다. 비디오 압축기의 경우 범주 GUID가 CLSID_VideoCompressorCategory. 오디오 압축기의 경우 CLSID_AudioCompressorCategory. 특정 범주를 열거하기 위해 시스템 디바이스 열거자는 IEnumMoniker 인터페이스를 지원하는 열거자 개체를 만듭니다. 애플리케이션은 이 인터페이스를 사용하여 디바이스 모니커를 검색합니다. 여기서 각 디바이스 모니커는 DirectShow 필터의 instance 나타냅니다. 모니커를 사용하여 필터를 만들거나 필터를 만들지 않고 디바이스의 이름을 가져올 수 있습니다.
사용자 시스템에서 사용할 수 있는 비디오 또는 오디오 압축기를 열거하려면 다음을 수행합니다.
- CoCreateInstance를 호출하여 클래스 ID가 CLSID_SystemDeviceEnum 시스템 디바이스 열거자를 만듭니다.
- 필터 범주 GUID를 사용하여 ICreateDevEnum::CreateClassEnumerator 를 호출합니다. 메서드는 IEnumMoniker 인터페이스 포인터를 반환합니다.
- IEnumMoniker::Next 메서드를 사용하여 디바이스 모니커를 열거합니다. 이 메서드는 모 니커를 나타내는 IMoniker 인터페이스를 반환합니다.
모니커에서 친숙한 이름을 얻으려면 다음을 수행합니다.
- IMoniker::BindToStorage 메서드를 호출합니다. 이 메서드는 IPropertyBag 인터페이스 포인터를 반환합니다.
- IPropertyBag::Read 메서드를 사용하여 FriendlyName 속성을 읽습니다.
일반적으로 애플리케이션은 사용자가 압축기 목록을 선택할 수 있도록 압축기 목록을 표시합니다. 예를 들어 다음 코드는 사용 가능한 비디오 압축기의 이름으로 목록 상자를 채웁니다.
void OnInitDialog(HWND hDlg)
{
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pSysDevEnum);
if (FAILED(hr))
{
// Handle the error.
}
hr = pSysDevEnum->CreateClassEnumerator(
CLSID_VideoCompressorCategory, &pEnum, 0);
if (hr == S_OK) // S_FALSE means nothing in this category.
{
while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
VARIANT var;
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if (SUCCEEDED(hr))
{
LRESULT iSel = AddString(GetDlgItem(hDlg,
IDC_CODEC_LIST), var.bstrVal);
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
}
SendDlgItemMessage(hDlg, IDC_CODEC_LIST,
LB_SETCURSEL, 0, 0);
pSysDevEnum->Release();
pEnum->Release();
}
모니커에서 필터 instance 만들려면 IMoniker::BindToObject 메서드를 호출합니다. 메서드는 IBaseFilter 포인터를 반환합니다.
IBaseFilter *pFilter = NULL;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)&pFilter);
if (SUCCEEDED(hr))
{
// Use the filter.
// Remember to release the IBaseFilter interface.
}
VCM 코덱의 경우 모든 코덱이 동일한 AVI 압축 필터로 래핑되더라도 각 모니커는 하나의 특정 코덱을 나타냅니다. BindToObject를 호출하면 이 필터의 instance 만들어 해당 코덱에 대해 초기화됩니다. 따라서 AVI 압축 필터에서 직접 CoCreateInstance 를 호출할 수 없습니다. 시스템 디바이스 열거자를 통과해야 합니다.
관련 항목