devenum: Register AVI capture devices as codec devices.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9ebbcb4f47
commit
ec16a92b1d
|
@ -53,7 +53,7 @@ static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a',
|
||||||
static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
|
static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
|
||||||
|
|
||||||
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
|
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface);
|
||||||
static HRESULT register_codecs(void);
|
static void register_codecs(void);
|
||||||
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
|
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
@ -773,6 +773,57 @@ static void register_vfw_codecs(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void register_avicap_devices(void)
|
||||||
|
{
|
||||||
|
static const WCHAR vfwindexW[] = {'V','F','W','I','n','d','e','x',0};
|
||||||
|
WCHAR friendlyname[] = {'v','i','d','e','o','0',0};
|
||||||
|
IPropertyBag *prop_bag = NULL;
|
||||||
|
WCHAR name[32], version[32];
|
||||||
|
REGFILTERPINS2 rgpins;
|
||||||
|
REGPINTYPES rgtypes;
|
||||||
|
REGFILTER2 rgf;
|
||||||
|
VARIANT var;
|
||||||
|
HRESULT hr;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
hr = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
if (!capGetDriverDescriptionW(i, name, sizeof(name), version, sizeof(version)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
friendlyname[5] = '0' + i;
|
||||||
|
|
||||||
|
hr = register_codec(&CLSID_VideoInputDeviceCategory, name,
|
||||||
|
&CLSID_VfwCapture, friendlyname, &prop_bag);
|
||||||
|
if (FAILED(hr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rgf.dwVersion = 2;
|
||||||
|
rgf.dwMerit = MERIT_DO_NOT_USE;
|
||||||
|
rgf.u.s2.cPins2 = 1;
|
||||||
|
rgf.u.s2.rgPins2 = &rgpins;
|
||||||
|
rgpins.dwFlags = 0;
|
||||||
|
rgpins.nMediaTypes = 1;
|
||||||
|
rgpins.lpMediaType = &rgtypes;
|
||||||
|
rgtypes.clsMajorType = &MEDIATYPE_Video;
|
||||||
|
rgtypes.clsMinorType = &MEDIASUBTYPE_None;
|
||||||
|
|
||||||
|
write_filter_data(prop_bag, &rgf);
|
||||||
|
|
||||||
|
/* write VFWIndex */
|
||||||
|
V_VT(&var) = VT_I4;
|
||||||
|
V_I4(&var) = i;
|
||||||
|
IPropertyBag_Write(prop_bag, vfwindexW, &var);
|
||||||
|
|
||||||
|
VariantClear(&var);
|
||||||
|
IPropertyBag_Release(prop_bag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* DEVENUM_ICreateDevEnum_CreateClassEnumerator
|
* DEVENUM_ICreateDevEnum_CreateClassEnumerator
|
||||||
*/
|
*/
|
||||||
|
@ -799,6 +850,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
|
||||||
register_wavein_devices();
|
register_wavein_devices();
|
||||||
register_midiout_devices();
|
register_midiout_devices();
|
||||||
register_vfw_codecs();
|
register_vfw_codecs();
|
||||||
|
register_avicap_devices();
|
||||||
|
|
||||||
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
|
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
|
||||||
}
|
}
|
||||||
|
@ -851,14 +903,9 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT register_codecs(void)
|
static void register_codecs(void)
|
||||||
{
|
{
|
||||||
HRESULT res;
|
|
||||||
WCHAR class[CHARS_IN_GUID];
|
WCHAR class[CHARS_IN_GUID];
|
||||||
DWORD iDefaultDevice = -1;
|
|
||||||
IFilterMapper2 * pMapper = NULL;
|
|
||||||
REGFILTER2 rf2;
|
|
||||||
REGFILTERPINS2 rfp2;
|
|
||||||
HKEY basekey;
|
HKEY basekey;
|
||||||
|
|
||||||
/* Since devices can change between session, for example because you just plugged in a webcam
|
/* Since devices can change between session, for example because you just plugged in a webcam
|
||||||
|
@ -878,82 +925,4 @@ static HRESULT register_codecs(void)
|
||||||
StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID);
|
StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID);
|
||||||
RegDeleteTreeW(basekey, class);
|
RegDeleteTreeW(basekey, class);
|
||||||
RegCloseKey(basekey);
|
RegCloseKey(basekey);
|
||||||
|
|
||||||
rf2.dwVersion = 2;
|
|
||||||
rf2.dwMerit = MERIT_PREFERRED;
|
|
||||||
rf2.u.s2.cPins2 = 1;
|
|
||||||
rf2.u.s2.rgPins2 = &rfp2;
|
|
||||||
rfp2.cInstances = 1;
|
|
||||||
rfp2.nMediums = 0;
|
|
||||||
rfp2.lpMedium = NULL;
|
|
||||||
rfp2.clsPinCategory = &IID_NULL;
|
|
||||||
|
|
||||||
res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
|
|
||||||
&IID_IFilterMapper2, (void **) &pMapper);
|
|
||||||
/*
|
|
||||||
* Fill in info for devices
|
|
||||||
*/
|
|
||||||
if (SUCCEEDED(res))
|
|
||||||
{
|
|
||||||
UINT i;
|
|
||||||
REGPINTYPES * pTypes;
|
|
||||||
IPropertyBag * pPropBag = NULL;
|
|
||||||
|
|
||||||
res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
|
|
||||||
if (SUCCEEDED(res))
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10];
|
|
||||||
|
|
||||||
if (capGetDriverDescriptionW (i, szDeviceName, ARRAY_SIZE(szDeviceName),
|
|
||||||
szDeviceVersion, ARRAY_SIZE(szDeviceVersion)))
|
|
||||||
{
|
|
||||||
IMoniker * pMoniker = NULL;
|
|
||||||
WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 };
|
|
||||||
snprintfW(szDevicePath, ARRAY_SIZE(szDevicePath), dprintf, i);
|
|
||||||
/* The above code prevents 1 device with a different ID overwriting another */
|
|
||||||
|
|
||||||
rfp2.nMediaTypes = 1;
|
|
||||||
pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
|
|
||||||
if (!pTypes) {
|
|
||||||
IFilterMapper2_Release(pMapper);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTypes[0].clsMajorType = &MEDIATYPE_Video;
|
|
||||||
pTypes[0].clsMinorType = &MEDIASUBTYPE_None;
|
|
||||||
|
|
||||||
rfp2.lpMediaType = pTypes;
|
|
||||||
|
|
||||||
res = IFilterMapper2_RegisterFilter(pMapper,
|
|
||||||
&CLSID_VfwCapture,
|
|
||||||
szDeviceName,
|
|
||||||
&pMoniker,
|
|
||||||
&CLSID_VideoInputDeviceCategory,
|
|
||||||
szDevicePath,
|
|
||||||
&rf2);
|
|
||||||
|
|
||||||
if (pMoniker) {
|
|
||||||
OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 };
|
|
||||||
VARIANT var;
|
|
||||||
V_VT(&var) = VT_I4;
|
|
||||||
V_I4(&var) = i;
|
|
||||||
res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);
|
|
||||||
if (SUCCEEDED(res)) {
|
|
||||||
res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var);
|
|
||||||
IPropertyBag_Release(pPropBag);
|
|
||||||
}
|
|
||||||
IMoniker_Release(pMoniker);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == iDefaultDevice) FIXME("Default device\n");
|
|
||||||
CoTaskMemFree(pTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pMapper)
|
|
||||||
IFilterMapper2_Release(pMapper);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue