From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v5: Clean up the function while we're at it.
This supersedes https://source.winehq.org/patches/data/183887.
dlls/qedit/mediadet.c | 65 ++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 35 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 0b64e189830..059465d3d7f 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -70,6 +70,35 @@ static void MD_cleanup(MediaDetImpl *This) This->cur_stream = 0; }
+static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) +{ + IPropertyBag *prop_bag; + HRESULT hr; + + if (FAILED(hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag))) + { + ERR("Failed to get property bag, hr %#x.\n", hr); + return hr; + } + + VariantInit(var); + V_VT(var) = VT_BSTR; + if (FAILED(hr = IPropertyBag_Read(prop_bag, L"CLSID", var, NULL))) + { + ERR("Failed to get CLSID, hr %#x.\n", hr); + IPropertyBag_Release(prop_bag); + return hr; + } + CLSIDFromString(V_BSTR(var), clsid); + VariantClear(var); + + if (FAILED(hr = IPropertyBag_Read(prop_bag, L"FriendlyName", var, NULL))) + ERR("Failed to get name, hr %#x.\n", hr); + + IPropertyBag_Release(prop_bag); + return hr; +} + /* MediaDet inner IUnknown */ static HRESULT WINAPI MediaDet_inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { @@ -372,40 +401,6 @@ static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) return S_OK; }
-/* From quartz, 2008/04/07 */ -static HRESULT GetFilterInfo(IMoniker *pMoniker, GUID *pclsid, VARIANT *pvar) -{ - IPropertyBag *pPropBagCat = NULL; - HRESULT hr; - - VariantInit(pvar); - V_VT(pvar) = VT_BSTR; - - hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, - (LPVOID *) &pPropBagCat); - - if (SUCCEEDED(hr)) - hr = IPropertyBag_Read(pPropBagCat, L"CLSID", pvar, NULL); - - if (SUCCEEDED(hr)) - { - hr = CLSIDFromString(V_BSTR(pvar), pclsid); - VariantClear(pvar); - V_VT(pvar) = VT_BSTR; - } - - if (SUCCEEDED(hr)) - hr = IPropertyBag_Read(pPropBagCat, L"FriendlyName", pvar, NULL); - - if (SUCCEEDED(hr)) - TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_BSTR(pvar))); - - if (pPropBagCat) - IPropertyBag_Release(pPropBagCat); - - return hr; -} - static HRESULT GetSplitter(MediaDetImpl *This) { IFileSourceFilter *file; @@ -458,7 +453,7 @@ static HRESULT GetSplitter(MediaDetImpl *This) hr = E_NOINTERFACE; while (IEnumMoniker_Next(filters, 1, &mon, NULL) == S_OK) { - hr = GetFilterInfo(mon, &clsid, &var); + hr = get_filter_info(mon, &clsid, &var); IMoniker_Release(mon); if (FAILED(hr)) continue;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v5: Clean up the function while we're at it.
This supersedes https://source.winehq.org/patches/data/183888.
dlls/qedit/mediadet.c | 229 ++++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 110 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 059465d3d7f..49d9bc36c0d 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -99,6 +99,124 @@ static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) return hr; }
+static HRESULT find_splitter(MediaDetImpl *detector) +{ + IPin *source_pin, *splitter_pin; + IFileSourceFilter *file_source; + IEnumMoniker *enum_moniker; + IFilterMapper2 *mapper; + IBaseFilter *splitter; + IEnumPins *enum_pins; + LPOLESTR filename; + AM_MEDIA_TYPE mt; + IMoniker *mon; + GUID type[2]; + VARIANT var; + HRESULT hr; + GUID clsid; + + if (FAILED(hr = IBaseFilter_QueryInterface(detector->source, + &IID_IFileSourceFilter, (void **)&file_source))) + { + ERR("Failed to get file source interface.\n"); + return hr; + } + + hr = IFileSourceFilter_GetCurFile(file_source, &filename, &mt); + IFileSourceFilter_Release(file_source); + CoTaskMemFree(filename); + if (FAILED(hr)) + { + ERR("Failed to get current file, hr %#x.\n", hr); + return hr; + } + type[0] = mt.majortype; + type[1] = mt.subtype; + FreeMediaType(&mt); + + if (FAILED(hr = IBaseFilter_EnumPins(detector->source, &enum_pins))) + { + ERR("Failed to enumerate source pins, hr %#x.\n", hr); + return hr; + } + hr = IEnumPins_Next(enum_pins, 1, &source_pin, NULL); + IEnumPins_Release(enum_pins); + if (FAILED(hr)) + { + ERR("Failed to get source pin, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, + CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (void **)&mapper))) + { + IPin_Release(source_pin); + return hr; + } + + hr = IFilterMapper2_EnumMatchingFilters(mapper, &enum_moniker, 0, TRUE, + MERIT_UNLIKELY, FALSE, 1, type, NULL, NULL, FALSE, TRUE, 0, NULL, NULL, NULL); + IFilterMapper2_Release(mapper); + if (FAILED(hr)) + { + IPin_Release(source_pin); + return hr; + } + + hr = E_NOINTERFACE; + while (IEnumMoniker_Next(enum_moniker, 1, &mon, NULL) == S_OK) + { + hr = get_filter_info(mon, &clsid, &var); + IMoniker_Release(mon); + if (FAILED(hr)) + continue; + + hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&splitter); + if (FAILED(hr)) + { + VariantClear(&var); + continue; + } + + hr = IGraphBuilder_AddFilter(detector->graph, splitter, V_BSTR(&var)); + VariantClear(&var); + if (FAILED(hr)) + { + IBaseFilter_Release(splitter); + continue; + } + + hr = IBaseFilter_EnumPins(splitter, &enum_pins); + if (FAILED(hr)) + { + IBaseFilter_Release(splitter); + continue; + } + hr = IEnumPins_Next(enum_pins, 1, &splitter_pin, NULL); + IEnumPins_Release(enum_pins); + if (FAILED(hr)) + { + IBaseFilter_Release(splitter); + continue; + } + + hr = IPin_Connect(source_pin, splitter_pin, NULL); + IPin_Release(splitter_pin); + if (SUCCEEDED(hr)) + { + detector->splitter = splitter; + break; + } + + IBaseFilter_Release(splitter); + } + + IEnumMoniker_Release(enum_moniker); + IPin_Release(source_pin); + return hr; +} + /* MediaDet inner IUnknown */ static HRESULT WINAPI MediaDet_inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { @@ -401,115 +519,6 @@ static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) return S_OK; }
-static HRESULT GetSplitter(MediaDetImpl *This) -{ - IFileSourceFilter *file; - LPOLESTR name; - AM_MEDIA_TYPE mt; - GUID type[2]; - IFilterMapper2 *map; - IEnumMoniker *filters; - IMoniker *mon; - VARIANT var; - GUID clsid; - IBaseFilter *splitter; - IEnumPins *pins; - IPin *source_pin, *splitter_pin; - HRESULT hr; - - hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, - &IID_IFilterMapper2, (void **) &map); - if (FAILED(hr)) - return hr; - - hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, - (void **) &file); - if (FAILED(hr)) - { - IFilterMapper2_Release(map); - return hr; - } - - hr = IFileSourceFilter_GetCurFile(file, &name, &mt); - IFileSourceFilter_Release(file); - CoTaskMemFree(name); - if (FAILED(hr)) - { - IFilterMapper2_Release(map); - return hr; - } - type[0] = mt.majortype; - type[1] = mt.subtype; - CoTaskMemFree(mt.pbFormat); - - hr = IFilterMapper2_EnumMatchingFilters(map, &filters, 0, TRUE, - MERIT_UNLIKELY, FALSE, 1, type, - NULL, NULL, FALSE, TRUE, - 0, NULL, NULL, NULL); - IFilterMapper2_Release(map); - if (FAILED(hr)) - return hr; - - hr = E_NOINTERFACE; - while (IEnumMoniker_Next(filters, 1, &mon, NULL) == S_OK) - { - hr = get_filter_info(mon, &clsid, &var); - IMoniker_Release(mon); - if (FAILED(hr)) - continue; - - hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, - &IID_IBaseFilter, (void **) &splitter); - if (FAILED(hr)) - { - VariantClear(&var); - continue; - } - - hr = IGraphBuilder_AddFilter(This->graph, splitter, V_BSTR(&var)); - VariantClear(&var); - This->splitter = splitter; - if (FAILED(hr)) - goto retry; - - hr = IBaseFilter_EnumPins(This->source, &pins); - if (FAILED(hr)) - goto retry; - IEnumPins_Next(pins, 1, &source_pin, NULL); - IEnumPins_Release(pins); - - hr = IBaseFilter_EnumPins(splitter, &pins); - if (FAILED(hr)) - { - IPin_Release(source_pin); - goto retry; - } - if (IEnumPins_Next(pins, 1, &splitter_pin, NULL) != S_OK) - { - IEnumPins_Release(pins); - IPin_Release(source_pin); - goto retry; - } - IEnumPins_Release(pins); - - hr = IPin_Connect(source_pin, splitter_pin, NULL); - IPin_Release(source_pin); - IPin_Release(splitter_pin); - if (SUCCEEDED(hr)) - break; - -retry: - IBaseFilter_Release(splitter); - This->splitter = NULL; - } - - IEnumMoniker_Release(filters); - if (FAILED(hr)) - return hr; - - return S_OK; -} - static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) { MediaDetImpl *This = impl_from_IMediaDet(iface); @@ -538,7 +547,7 @@ static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal)
This->graph = gb; This->source = bf; - hr = GetSplitter(This); + hr = find_splitter(This); if (FAILED(hr)) return hr;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v5: Use clearer variable names; remove a superfluous comment.
This supersedes https://source.winehq.org/patches/data/183891.
dlls/qedit/mediadet.c | 47 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 49d9bc36c0d..22df05647eb 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -309,11 +309,50 @@ static HRESULT WINAPI MediaDet_get_Filter(IMediaDet *iface, IUnknown **filter) return S_OK; }
-static HRESULT WINAPI MediaDet_put_Filter(IMediaDet* iface, IUnknown *newVal) +static HRESULT WINAPI MediaDet_put_Filter(IMediaDet *iface, IUnknown *unk) { - MediaDetImpl *This = impl_from_IMediaDet(iface); - FIXME("(%p)->(%p): not implemented!\n", This, newVal); - return E_NOTIMPL; + MediaDetImpl *detector = impl_from_IMediaDet(iface); + IGraphBuilder *graph; + IBaseFilter *filter; + HRESULT hr; + + TRACE("detector %p, unk %p.\n", detector, unk); + + if (!unk) + return E_POINTER; + + if (FAILED(hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter))) + { + WARN("Object does not expose IBaseFilter.\n"); + return hr; + } + + if (detector->graph) + MD_cleanup(detector); + + if (FAILED(hr = CoCreateInstance(&CLSID_FilterGraph, NULL, + CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void **)&graph))) + { + IBaseFilter_Release(filter); + return hr; + } + + if (FAILED(hr = IGraphBuilder_AddFilter(graph, filter, L"Source"))) + { + IGraphBuilder_Release(graph); + IBaseFilter_Release(filter); + return hr; + } + + detector->graph = graph; + detector->source = filter; + if (FAILED(find_splitter(detector))) + { + detector->splitter = detector->source; + IBaseFilter_AddRef(detector->splitter); + } + + return IMediaDet_put_CurrentStream(&detector->IMediaDet_iface, 0); }
static HRESULT WINAPI MediaDet_get_OutputStreams(IMediaDet* iface, LONG *pVal)
Based on a patch by Gabriel Ivăncescu.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- I quite prefer having these tests in a separate function.
This supersedes https://source.winehq.org/patches/data/183897.
dlls/qedit/tests/mediadet.c | 212 +++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 3 deletions(-)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index ea10f5783e0..6decda85576 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -24,6 +24,7 @@ #include "ole2.h" #include "vfwmsgs.h" #include "uuids.h" +#include "wine/strmbase.h" #include "wine/test.h" #include "qedit.h" #include "control.h" @@ -130,6 +131,89 @@ static void test_aggregation(void) ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); }
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; +}; + +static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, filter); +} + +static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + + return index ? NULL : &filter->source.pin; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy, +}; + +static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) +{ + static const VIDEOINFOHEADER source_format = + { + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 640, + .bmiHeader.biHeight = 480, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 24, + .bmiHeader.biCompression = BI_RGB, + .bmiHeader.biSizeImage = 640 * 480 * 3 + }; + + if (index) + return S_FALSE; + + mt->majortype = MEDIATYPE_Video; + mt->subtype = MEDIASUBTYPE_RGB24; + mt->bFixedSizeSamples = TRUE; + mt->bTemporalCompression = FALSE; + mt->lSampleSize = source_format.bmiHeader.biSizeImage; + mt->formattype = FORMAT_VideoInfo; + mt->pUnk = NULL; + mt->cbFormat = sizeof(source_format); + mt->pbFormat = CoTaskMemAlloc(mt->cbFormat); + memcpy(mt->pbFormat, &source_format, mt->cbFormat); + return S_OK; +} + +static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, + IMemInputPin *peer, IMemAllocator **allocator) +{ + return S_OK; +} + +static const struct strmbase_source_ops testsource_ops = +{ + .base.pin_get_media_type = testsource_get_media_type, + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideAllocator = testsource_DecideAllocator, +}; + +static void testfilter_init(struct testfilter *filter) +{ + static const GUID clsid = {0xabacab}; + + memset(filter, 0, sizeof(*filter)); + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); +} + static WCHAR test_avi_filename[MAX_PATH]; static WCHAR test_sound_avi_filename[MAX_PATH];
@@ -369,8 +453,6 @@ static void test_mediadet(void) hr = IMediaDet_Release(pM); ok(hr == 0, "IMediaDet_Release returned: %x\n", hr);
- DeleteFileW(test_avi_filename); - /* test_sound.avi has one video stream and one audio stream. */ hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaDet, (LPVOID*)&pM); @@ -479,8 +561,125 @@ static void test_mediadet(void)
hr = IMediaDet_Release(pM); ok(hr == 0, "IMediaDet_Release returned: %x\n", hr); +} + +static void test_put_filter(void) +{ + struct testfilter testfilter, testfilter2; + IFilterGraph *graph; + IBaseFilter *filter; + IMediaDet *detector; + LONG index, count; + AM_MEDIA_TYPE mt; + IUnknown *unk; + BSTR filename; + HRESULT hr; + ULONG ref; + + hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, + &IID_IMediaDet, (void **)&detector); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_put_Filter(detector, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(detector, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + testfilter_init(&testfilter); + hr = IMediaDet_put_Filter(detector, &testfilter.filter.IUnknown_inner); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- DeleteFileW(test_sound_avi_filename); + hr = IMediaDet_get_Filter(detector, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL interface.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter.filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + IUnknown_Release(unk); + + ok(!wcscmp(testfilter.filter.name, L"Source"), "Got name %s.\n", + debugstr_w(testfilter.filter.name)); + graph = testfilter.filter.graph; + IFilterGraph_AddRef(graph); + + testfilter_init(&testfilter2); + hr = IMediaDet_put_Filter(detector, &testfilter2.filter.IUnknown_inner); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(detector, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL interface.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter2.filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + IUnknown_Release(unk); + + ok(testfilter2.filter.graph != graph, "Expected a different graph.\n"); + + ref = IFilterGraph_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(&testfilter.filter.IBaseFilter_iface); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + count = 0xdeadbeef; + hr = IMediaDet_get_OutputStreams(detector, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 1, "Got %d streams.\n", count); + + index = 0xdeadbeef; + hr = IMediaDet_get_CurrentStream(detector, &index); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(index == 0, "Got stream %d.\n", index); + + filename = (BSTR)0xdeadbeef; + hr = IMediaDet_get_Filename(detector, &filename); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + + ref = IMediaDet_Release(detector); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(&testfilter2.filter.IBaseFilter_iface); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, + &IID_IMediaDet, (void **)&detector); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + filename = SysAllocString(test_sound_avi_filename); + hr = IMediaDet_put_Filename(detector, filename); + ok(hr == S_OK, "Got hr %#x.\n", hr); + SysFreeString(filename); + + hr = IMediaDet_get_StreamMediaType(detector, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + FreeMediaType(&mt); + + hr = IMediaDet_get_Filter(detector, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaDet_put_Filter(detector, unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IUnknown_Release(unk); + + filename = (BSTR)0xdeadbeef; + hr = IMediaDet_get_Filename(detector, &filename); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + + count = 0xdeadbeef; + hr = IMediaDet_get_OutputStreams(detector, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 2, "Got %d streams.\n", count); + + index = 0xdeadbeef; + hr = IMediaDet_get_CurrentStream(detector, &index); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(index == 0, "Got stream %d.\n", index); + + ref = IMediaDet_Release(detector); + ok(!ref, "Got outstanding refcount %d.\n", ref); }
static HRESULT WINAPI ms_QueryInterface(IMediaSample *iface, REFIID riid, @@ -737,6 +936,7 @@ START_TEST(mediadet) { IMediaDet *detector; HRESULT hr; + BOOL ret;
if (!init_tests()) { @@ -757,8 +957,14 @@ START_TEST(mediadet)
test_aggregation(); test_mediadet(); + test_put_filter(); test_samplegrabber(); test_COM_sg_enumpins();
+ ret = DeleteFileW(test_avi_filename); + todo_wine ok(ret, "Failed to delete file, error %u.\n", GetLastError()); + ret = DeleteFileW(test_sound_avi_filename); + todo_wine ok(ret, "Failed to delete file, error %u.\n", GetLastError()); + CoUninitialize(); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v5: Move some code around bit to simplify error handling, and rename the unspecific "newVal" to "filename".
This supersedes https://source.winehq.org/patches/data/183889.
dlls/qedit/mediadet.c | 35 ++++++++++++++++------------------- dlls/qedit/tests/mediadet.c | 4 ++-- 2 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 22df05647eb..d63825c6290 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -41,6 +41,7 @@ typedef struct MediaDetImpl { IGraphBuilder *graph; IBaseFilter *source; IBaseFilter *splitter; + WCHAR *filename; LONG num_streams; LONG cur_stream; IPin *cur_pin; @@ -66,6 +67,9 @@ static void MD_cleanup(MediaDetImpl *This) This->splitter = NULL; if (This->graph) IGraphBuilder_Release(This->graph); This->graph = NULL; + if (This->filename) + free(This->filename); + This->filename = NULL; This->num_streams = -1; This->cur_stream = 0; } @@ -525,9 +529,6 @@ static HRESULT WINAPI MediaDet_get_StreamLength(IMediaDet* iface, double *pVal) static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) { MediaDetImpl *This = impl_from_IMediaDet(iface); - IFileSourceFilter *file; - LPOLESTR name; - HRESULT hr;
TRACE("(%p)\n", This);
@@ -537,35 +538,24 @@ static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) *pVal = NULL; /* MSDN says it should return E_FAIL if no file is open, but tests show otherwise. */ - if (!This->source) + if (!This->filename) return S_OK;
- hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, - (void **) &file); - if (FAILED(hr)) - return hr; - - hr = IFileSourceFilter_GetCurFile(file, &name, NULL); - IFileSourceFilter_Release(file); - if (FAILED(hr)) - return hr; - - *pVal = SysAllocString(name); - CoTaskMemFree(name); + *pVal = SysAllocString(This->filename); if (!*pVal) return E_OUTOFMEMORY;
return S_OK; }
-static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) +static HRESULT WINAPI MediaDet_put_Filename(IMediaDet *iface, BSTR filename) { MediaDetImpl *This = impl_from_IMediaDet(iface); IGraphBuilder *gb; IBaseFilter *bf; HRESULT hr;
- TRACE("(%p)->(%s)\n", This, debugstr_w(newVal)); + TRACE("detector %p, filename %s.\n", This, debugstr_w(filename));
if (This->graph) { @@ -578,12 +568,19 @@ static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) if (FAILED(hr)) return hr;
- if (FAILED(hr = IGraphBuilder_AddSourceFilter(gb, newVal, L"Source", &bf))) + if (FAILED(hr = IGraphBuilder_AddSourceFilter(gb, filename, L"Source", &bf))) { IGraphBuilder_Release(gb); return hr; }
+ if (!(This->filename = wcsdup(filename))) + { + IBaseFilter_Release(bf); + IGraphBuilder_Release(gb); + return E_OUTOFMEMORY; + } + This->graph = gb; This->source = bf; hr = find_splitter(This); diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index 6decda85576..32861476dd0 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -636,7 +636,7 @@ static void test_put_filter(void)
filename = (BSTR)0xdeadbeef; hr = IMediaDet_get_Filename(detector, &filename); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!filename, "Got filename %s.\n", debugstr_w(filename));
ref = IMediaDet_Release(detector); @@ -666,7 +666,7 @@ static void test_put_filter(void) filename = (BSTR)0xdeadbeef; hr = IMediaDet_get_Filename(detector, &filename); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + ok(!filename, "Got filename %s.\n", debugstr_w(filename));
count = 0xdeadbeef; hr = IMediaDet_get_OutputStreams(detector, &count);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v5: Rebased onto cleanup of find_splitter().
This supersedes https://source.winehq.org/patches/data/183892.
dlls/qedit/mediadet.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index d63825c6290..eb7a51928b9 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -193,17 +193,12 @@ static HRESULT find_splitter(MediaDetImpl *detector)
hr = IBaseFilter_EnumPins(splitter, &enum_pins); if (FAILED(hr)) - { - IBaseFilter_Release(splitter); - continue; - } + goto next; + hr = IEnumPins_Next(enum_pins, 1, &splitter_pin, NULL); IEnumPins_Release(enum_pins); if (FAILED(hr)) - { - IBaseFilter_Release(splitter); - continue; - } + goto next;
hr = IPin_Connect(source_pin, splitter_pin, NULL); IPin_Release(splitter_pin); @@ -213,6 +208,8 @@ static HRESULT find_splitter(MediaDetImpl *detector) break; }
+next: + IGraphBuilder_RemoveFilter(detector->graph, splitter); IBaseFilter_Release(splitter); }