devenum: Return filter data for DMO monikers.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d83167f75c
commit
2f2ac79242
|
@ -351,40 +351,44 @@ static void free_regfilter2(REGFILTER2 *rgf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
|
HRESULT create_filter_data(VARIANT *var, REGFILTER2 *rgf)
|
||||||
{
|
{
|
||||||
BYTE *data = NULL, *array;
|
|
||||||
IAMFilterData *fildata;
|
IAMFilterData *fildata;
|
||||||
SAFEARRAYBOUND sabound;
|
BYTE *data = NULL;
|
||||||
VARIANT var = {};
|
|
||||||
ULONG size;
|
ULONG size;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData, (void **)&fildata);
|
hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData, (void **)&fildata);
|
||||||
if (FAILED(hr)) goto cleanup;
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
hr = IAMFilterData_CreateFilterData(fildata, rgf, &data, &size);
|
hr = IAMFilterData_CreateFilterData(fildata, rgf, &data, &size);
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
V_VT(&var) = VT_ARRAY | VT_UI1;
|
|
||||||
sabound.lLbound = 0;
|
|
||||||
sabound.cElements = size;
|
|
||||||
if (!(V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &sabound)))
|
|
||||||
goto cleanup;
|
|
||||||
hr = SafeArrayAccessData(V_ARRAY(&var), (void *)&array);
|
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
memcpy(array, data, size);
|
|
||||||
hr = SafeArrayUnaccessData(V_ARRAY(&var));
|
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
hr = IPropertyBag_Write(prop_bag, L"FilterData", &var);
|
|
||||||
if (FAILED(hr)) goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VariantClear(&var);
|
|
||||||
CoTaskMemFree(data);
|
|
||||||
IAMFilterData_Release(fildata);
|
IAMFilterData_Release(fildata);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
V_VT(var) = VT_ARRAY | VT_UI1;
|
||||||
|
if (!(V_ARRAY(var) = SafeArrayCreateVector(VT_UI1, 1, size)))
|
||||||
|
{
|
||||||
|
VariantClear(var);
|
||||||
|
CoTaskMemFree(data);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(V_ARRAY(var)->pvData, data, size);
|
||||||
|
CoTaskMemFree(data);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
|
||||||
|
{
|
||||||
|
VARIANT var;
|
||||||
|
|
||||||
|
if (SUCCEEDED(create_filter_data(&var, rgf)))
|
||||||
|
{
|
||||||
|
IPropertyBag_Write(prop_bag, L"FilterData", &var);
|
||||||
|
VariantClear(&var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_legacy_filters(void)
|
static void register_legacy_filters(void)
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct moniker
|
||||||
IPropertyBag IPropertyBag_iface;
|
IPropertyBag IPropertyBag_iface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HRESULT create_filter_data(VARIANT *var, REGFILTER2 *rgf) DECLSPEC_HIDDEN;
|
||||||
struct moniker *dmo_moniker_create(const GUID class, const GUID clsid) DECLSPEC_HIDDEN;
|
struct moniker *dmo_moniker_create(const GUID class, const GUID clsid) DECLSPEC_HIDDEN;
|
||||||
struct moniker *codec_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
|
struct moniker *codec_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
|
||||||
struct moniker *filter_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
|
struct moniker *filter_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -28,6 +28,35 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
|
||||||
|
|
||||||
|
BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
|
||||||
|
{
|
||||||
|
unsigned int max_capacity, new_capacity;
|
||||||
|
void *new_elements;
|
||||||
|
|
||||||
|
if (count <= *capacity)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
max_capacity = ~0u / size;
|
||||||
|
if (count > max_capacity)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
new_capacity = max(8, *capacity);
|
||||||
|
while (new_capacity < count && new_capacity <= max_capacity / 2)
|
||||||
|
new_capacity *= 2;
|
||||||
|
if (new_capacity < count)
|
||||||
|
new_capacity = count;
|
||||||
|
|
||||||
|
if (!(new_elements = realloc(*elements, new_capacity * size)))
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate memory.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*elements = new_elements;
|
||||||
|
*capacity = new_capacity;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IEnumMoniker IEnumMoniker_iface;
|
IEnumMoniker IEnumMoniker_iface;
|
||||||
|
@ -106,6 +135,70 @@ static HRESULT WINAPI property_bag_Read(IPropertyBag *iface,
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
else if (!wcscmp(name, L"FilterData"))
|
||||||
|
{
|
||||||
|
REGFILTERPINS2 reg_pins[2] = {{0}};
|
||||||
|
REGFILTER2 reg_filter =
|
||||||
|
{
|
||||||
|
.dwVersion = 2,
|
||||||
|
.dwMerit = MERIT_NORMAL + 0x800,
|
||||||
|
.cPins2 = 2,
|
||||||
|
.rgPins2 = reg_pins,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int count = 1, input_count, output_count, i;
|
||||||
|
DMO_PARTIAL_MEDIATYPE *types = NULL;
|
||||||
|
REGPINTYPES *reg_types;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!(types = malloc(2 * count * sizeof(*types))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
while ((hr = DMOGetTypes(&moniker->clsid, count, &input_count, types,
|
||||||
|
count, &output_count, types + count)) == S_FALSE)
|
||||||
|
{
|
||||||
|
count *= 2;
|
||||||
|
if (!(types = realloc(types, count * sizeof(*types))))
|
||||||
|
{
|
||||||
|
free(types);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hr != S_OK)
|
||||||
|
{
|
||||||
|
free(types);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(reg_types = malloc(2 * count * sizeof(*reg_types))))
|
||||||
|
{
|
||||||
|
free(types);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < input_count; ++i)
|
||||||
|
{
|
||||||
|
reg_types[i].clsMajorType = &types[i].type;
|
||||||
|
reg_types[i].clsMinorType = &types[i].subtype;
|
||||||
|
}
|
||||||
|
for (i = 0; i < output_count; ++i)
|
||||||
|
{
|
||||||
|
reg_types[count + i].clsMajorType = &types[count + i].type;
|
||||||
|
reg_types[count + i].clsMinorType = &types[count + i].subtype;
|
||||||
|
}
|
||||||
|
reg_pins[0].cInstances = 1;
|
||||||
|
reg_pins[0].nMediaTypes = input_count;
|
||||||
|
reg_pins[0].lpMediaType = reg_types;
|
||||||
|
reg_pins[1].dwFlags = REG_PINFLAG_B_OUTPUT;
|
||||||
|
reg_pins[1].cInstances = 1;
|
||||||
|
reg_pins[1].nMediaTypes = output_count;
|
||||||
|
reg_pins[1].lpMediaType = reg_types + count;
|
||||||
|
|
||||||
|
hr = create_filter_data(var, ®_filter);
|
||||||
|
free(reg_types);
|
||||||
|
free(types);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue