Zebediah Figura : devenum: Return filter data for DMO monikers.
Alexandre Julliard
julliard at winehq.org
Fri May 15 16:55:07 CDT 2020
Module: wine
Branch: master
Commit: 2f2ac792427348b9172a8d269780002a484ab16e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2f2ac792427348b9172a8d269780002a484ab16e
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Fri May 15 16:09:19 2020 -0500
devenum: Return filter data for DMO monikers.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/devenum/createdevenum.c | 48 ++++++++++++----------
dlls/devenum/devenum_private.h | 1 +
dlls/devenum/mediacatenum.c | 93 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 22 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index a3b9447144..c72bb683f9 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -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;
- SAFEARRAYBOUND sabound;
- VARIANT var = {};
+ BYTE *data = NULL;
ULONG size;
HRESULT hr;
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);
- if (FAILED(hr)) goto cleanup;
+ IAMFilterData_Release(fildata);
+ if (FAILED(hr))
+ return hr;
- 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;
+ V_VT(var) = VT_ARRAY | VT_UI1;
+ if (!(V_ARRAY(var) = SafeArrayCreateVector(VT_UI1, 1, size)))
+ {
+ VariantClear(var);
+ CoTaskMemFree(data);
+ return E_OUTOFMEMORY;
+ }
- memcpy(array, data, size);
- hr = SafeArrayUnaccessData(V_ARRAY(&var));
- if (FAILED(hr)) goto cleanup;
+ memcpy(V_ARRAY(var)->pvData, data, size);
+ CoTaskMemFree(data);
+ return S_OK;
+}
- hr = IPropertyBag_Write(prop_bag, L"FilterData", &var);
- if (FAILED(hr)) goto cleanup;
+static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
+{
+ VARIANT var;
-cleanup:
- VariantClear(&var);
- CoTaskMemFree(data);
- IAMFilterData_Release(fildata);
+ if (SUCCEEDED(create_filter_data(&var, rgf)))
+ {
+ IPropertyBag_Write(prop_bag, L"FilterData", &var);
+ VariantClear(&var);
+ }
}
static void register_legacy_filters(void)
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index bd018a42a0..15c41afd57 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -54,6 +54,7 @@ struct moniker
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 *codec_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
struct moniker *filter_moniker_create(const GUID *class, const WCHAR *name) DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c
index 85634ead1a..16b729ab1f 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -28,6 +28,35 @@
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
{
IEnumMoniker IEnumMoniker_iface;
@@ -106,6 +135,70 @@ static HRESULT WINAPI property_bag_Read(IPropertyBag *iface,
}
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);
}
More information about the wine-cvs
mailing list