Microsoft DirectX 8.1 (C++) |
Several types of software components can perform video or audio compression, such as:
In DirectShow, VCM codecs are wrapped by the AVI Compressor Filter, and ACM codecs are wrapped by the ACM Wrapper Filter. DMOs are wrapped by the DMO Wrapper Filter. The system device enumerator provides a consistent way to enumerate and create any of these compressor types, without worrying about the underlying model.
For details about the system device enumerator, see Using the System Device Enumerator. Briefly, all DirectShow filters are classified by category, and each category is identified by a GUID. For video compressors, the category GUID is CLSID_VideoCompressorCategory. For audio compressors, it is CLSID_AudioCompressorCategory. To enumerate a particular category, the system device enumerator creates an enumerator object that supports the IEnumMoniker interface. The application uses this interface to retrieve device monikers, where each device moniker represents an instance of a DirectShow filter. You can use the moniker to create the filter, or to get the device's friendly name without creating the filter.
To enumerate the video or audio compressors available on the user's system, do the following:
To get the friendly name from a moniker, do the following:
Typically, an application would display a list of compressors, so that the user could choose one. For example, the following code populates a list box with the names of the available video compressors. (Error checking is omitted for clarity.)
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);
hr = pSysDevEnum->CreateClassEnumerator(
CLSID_VideoCompressorCategory, &pEnum, 0);
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();
}
To create a filter instance from the moniker, call the IMoniker::BindToObject method. The method returns an IBaseFilter pointer.
IBaseFilter *pFilter = NULL;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)&pFilter);
if (SUCCEEDED(hr))
{
// Use the filter.
// Remember to release the IBaseFilter interface.
}
For VCM codecs, each moniker represents one particular codec, even though all of the codecs are wrapped by the same AVI Compression filter. Calling BindToObject creates an instance of this filter, initialized for that codec. For this reason, you cannot call CoCreateInstance directly on the AVI Compression filter. You must go through the system device enumerator.