Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 70 +++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 0b64e18..4f84deb 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -70,6 +70,40 @@ static void MD_cleanup(MediaDetImpl *This) This->cur_stream = 0; }
+/* From quartz, 2008/04/07 */ +static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) +{ + IPropertyBag *pPropBagCat = NULL; + HRESULT hr; + + VariantInit(var); + V_VT(var) = VT_BSTR; + + hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, + (LPVOID *) &pPropBagCat); + + if (SUCCEEDED(hr)) + hr = IPropertyBag_Read(pPropBagCat, L"CLSID", var, NULL); + + if (SUCCEEDED(hr)) + { + hr = CLSIDFromString(V_BSTR(var), clsid); + VariantClear(var); + V_VT(var) = VT_BSTR; + } + + if (SUCCEEDED(hr)) + hr = IPropertyBag_Read(pPropBagCat, L"FriendlyName", var, NULL); + + if (SUCCEEDED(hr)) + TRACE("Moniker = %s - %s\n", debugstr_guid(clsid), debugstr_w(V_BSTR(var))); + + if (pPropBagCat) + IPropertyBag_Release(pPropBagCat); + + return hr; +} + /* MediaDet inner IUnknown */ static HRESULT WINAPI MediaDet_inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { @@ -372,40 +406,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 +458,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;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 220 +++++++++++++++++++++--------------------- 1 file changed, 110 insertions(+), 110 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 4f84deb..52090b8 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -104,6 +104,115 @@ static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) return hr; }
+static HRESULT get_splitter(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; +} + /* MediaDet inner IUnknown */ static HRESULT WINAPI MediaDet_inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { @@ -406,115 +515,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); @@ -543,7 +543,7 @@ static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal)
This->graph = gb; This->source = bf; - hr = GetSplitter(This); + hr = get_splitter(This); if (FAILED(hr)) return hr;
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 46 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 52090b8..56ecc2f 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -305,11 +305,51 @@ 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 *filter) { MediaDetImpl *This = impl_from_IMediaDet(iface); - FIXME("(%p)->(%p): not implemented!\n", This, newVal); - return E_NOTIMPL; + IGraphBuilder *gb; + IBaseFilter *bf; + HRESULT hr; + + TRACE("detector %p, filter %p.\n", This, filter); + + if (!filter) + return E_POINTER; + + hr = IUnknown_QueryInterface(filter, &IID_IBaseFilter, (void **) &bf); + if (FAILED(hr)) + return hr; + + if (This->graph) + MD_cleanup(This); + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IGraphBuilder, (void **) &gb); + if (FAILED(hr)) + { + IBaseFilter_Release(bf); + return hr; + } + + if (FAILED(hr = IGraphBuilder_AddFilter(gb, bf, L"Source"))) + { + IGraphBuilder_Release(gb); + IBaseFilter_Release(bf); + return hr; + } + + This->graph = gb; + This->source = bf; + hr = get_splitter(This); + if (FAILED(hr)) + { + /* No splitter found, use the source directly */ + This->splitter = This->source; + IBaseFilter_AddRef(This->splitter); + } + + return IMediaDet_put_CurrentStream(&This->IMediaDet_iface, 0); }
static HRESULT WINAPI MediaDet_get_OutputStreams(IMediaDet* iface, LONG *pVal)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70174
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 Task: Patch failed to apply
Testbot hiccup? Did it not update to latest git? They all apply cleanly here.
On 21/04/2020 15:26, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70174
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 Task: Patch failed to apply
On Tue, 21 Apr 2020, Gabriel Ivăncescu wrote:
Testbot hiccup? Did it not update to latest git? They all apply cleanly here.
The Wine Mono naming change triggered an error in the script that fetches the addons, causing the Wine update to fail [1].
https://testbot.winehq.org/JobDetails.pl?Key=70144
I manually applied a fix to the debiant VM and sent a patch which was committed so all should be fine now.
[1] It's either that and have some patches fail to apply, or having every test get stuck trying to download the addon. Besides we want to know when these things go wrong.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/tests/mediadet.c | 192 +++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index ea10f57..067adf1 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" @@ -71,6 +72,108 @@ static const IUnknownVtbl outer_vtbl =
static IUnknown test_outer = {&outer_vtbl};
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; +}; + +static inline struct testfilter *impl_from_BaseFilter(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_BaseFilter(iface); + + return index ? NULL : &filter->source.pin; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); + free(filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy +}; + +static inline struct testfilter *impl_from_Pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, source.pin); +} + +static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +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_decide_allocator(struct strmbase_source *iface, + IMemInputPin *peer, IMemAllocator **allocator) +{ + return S_OK; +} + +static const struct strmbase_source_ops testsource_ops = +{ + .base.pin_query_accept = testsource_query_accept, + .base.pin_get_media_type = testsource_get_media_type, + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideAllocator = testsource_decide_allocator +}; + +static struct testfilter *create_testfilter(void) +{ + static const GUID clsid = {0xabacab}; + struct testfilter *filter = malloc(sizeof(*filter)); + + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + + return filter; +} + +static void release_testfilter(struct testfilter *filter) +{ + IBaseFilter_Release(&filter->filter.IBaseFilter_iface); +} + static void test_aggregation(void) { IMediaDet *detector, *detector2; @@ -188,12 +291,14 @@ static BOOL init_tests(void) static void test_mediadet(void) { HRESULT hr; + struct testfilter *testfilter; + IBaseFilter *filter, *filter2; FILTER_INFO filter_info; AM_MEDIA_TYPE mt, *pmt; IEnumMediaTypes *type; IMediaDet *pM = NULL; BSTR filename = NULL; - IBaseFilter *filter; + IFilterGraph *graph; IEnumPins *enumpins; LONG nstrms = 0; IUnknown *unk; @@ -270,6 +375,48 @@ static void test_mediadet(void) ok(hr == S_FALSE, "Got hr %#x.\n", hr); ok(!unk, "Got filter %p.\n", unk);
+ hr = IMediaDet_put_Filter(pM, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + + ok(!wcscmp(testfilter->filter.name, L"Source"), "Got name %s.\n", wine_dbgstr_w(testfilter->filter.name)); + IFilterGraph_AddRef(graph = testfilter->filter.graph); + release_testfilter(testfilter); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + + ok(graph != testfilter->filter.graph, "Expected a different filter graph.\n"); + release_testfilter(testfilter); + IFilterGraph_Release(graph); + + strm = -1; + hr = IMediaDet_get_CurrentStream(pM, &strm); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(strm == 0, "strm is %i\n", strm); + filename = SysAllocString(test_avi_filename); hr = IMediaDet_put_Filename(pM, filename); ok(hr == S_OK, "IMediaDet_put_Filename failed: %08x\n", hr); @@ -474,9 +621,52 @@ static void test_mediadet(void) hr = IBaseFilter_QueryFilterInfo(filter, &filter_info); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!wcscmp(filter_info.achName, L"Source"), "Got name %s.\n", debugstr_w(filter_info.achName)); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter2); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter != filter2, "Expected a different filter.\n"); + ok(filter2 == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter2); + + ok(!wcscmp(testfilter->filter.name, L"Source"), "Got name %s.\n", wine_dbgstr_w(testfilter->filter.name)); + ok(filter_info.pGraph != testfilter->filter.graph, "Expected a different filter graph.\n"); IFilterGraph_Release(filter_info.pGraph); + release_testfilter(testfilter); + + filename = NULL; + hr = IMediaDet_get_Filename(pM, &filename); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + SysFreeString(filename); + + hr = IMediaDet_get_OutputStreams(pM, &nstrms); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(nstrms == 1, "nstrms is %i\n", nstrms); + + /* Now use the filter obtained from put_Filename for put_Filter. */ + hr = IMediaDet_put_Filter(pM, (IUnknown*)filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); IBaseFilter_Release(filter);
+ filename = NULL; + hr = IMediaDet_get_Filename(pM, &filename); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + SysFreeString(filename); + + /* It still looks for a downstream source and splits it into video+audio in this case. */ + hr = IMediaDet_get_OutputStreams(pM, &nstrms); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(nstrms == 2, "nstrms is %i\n", nstrms); + hr = IMediaDet_Release(pM); ok(hr == 0, "IMediaDet_Release returned: %x\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70175
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 Task: Patch failed to apply
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 30 ++++++++++++++---------------- dlls/qedit/tests/mediadet.c | 4 ++-- 2 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 56ecc2f..b134a03 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,8 @@ 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; } @@ -522,9 +525,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);
@@ -534,21 +534,10 @@ 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;
@@ -560,6 +549,7 @@ static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) MediaDetImpl *This = impl_from_IMediaDet(iface); IGraphBuilder *gb; IBaseFilter *bf; + WCHAR *filename; HRESULT hr;
TRACE("(%p)->(%s)\n", This, debugstr_w(newVal)); @@ -575,14 +565,22 @@ static HRESULT WINAPI MediaDet_put_Filename(IMediaDet* iface, BSTR newVal) if (FAILED(hr)) return hr;
+ if (!(filename = wcsdup(newVal))) + { + IGraphBuilder_Release(gb); + return E_OUTOFMEMORY; + } + if (FAILED(hr = IGraphBuilder_AddSourceFilter(gb, newVal, L"Source", &bf))) { + free(filename); IGraphBuilder_Release(gb); return hr; }
This->graph = gb; This->source = bf; + This->filename = filename; hr = get_splitter(This); if (FAILED(hr)) return hr; diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index 067adf1..f9aa3b3 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -643,7 +643,7 @@ static void test_mediadet(void)
filename = NULL; hr = IMediaDet_get_Filename(pM, &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)); SysFreeString(filename);
@@ -659,7 +659,7 @@ static void test_mediadet(void) filename = NULL; hr = IMediaDet_get_Filename(pM, &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)); SysFreeString(filename);
/* It still looks for a downstream source and splits it into video+audio in this case. */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70176
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index b134a03..d1e8b71 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -73,6 +73,28 @@ static void MD_cleanup(MediaDetImpl *This) This->cur_stream = 0; }
+static HRESULT get_pin_media_type(IPin *pin, AM_MEDIA_TYPE *out) +{ + IEnumMediaTypes *types; + AM_MEDIA_TYPE *pmt; + HRESULT hr; + + hr = IPin_EnumMediaTypes(pin, &types); + if (SUCCEEDED(hr)) + { + hr = IEnumMediaTypes_Next(types, 1, &pmt, NULL) == S_OK ? S_OK : E_NOINTERFACE; + IEnumMediaTypes_Release(types); + } + + if (SUCCEEDED(hr)) + { + *out = *pmt; + CoTaskMemFree(pmt); + } + + return hr; +} + /* From quartz, 2008/04/07 */ static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) { @@ -612,9 +634,6 @@ static HRESULT WINAPI MediaDet_get_StreamMediaType(IMediaDet* iface, AM_MEDIA_TYPE *pVal) { MediaDetImpl *This = impl_from_IMediaDet(iface); - IEnumMediaTypes *types; - AM_MEDIA_TYPE *pmt; - HRESULT hr;
TRACE("(%p)\n", This);
@@ -624,22 +643,7 @@ static HRESULT WINAPI MediaDet_get_StreamMediaType(IMediaDet* iface, if (!This->cur_pin) return E_INVALIDARG;
- hr = IPin_EnumMediaTypes(This->cur_pin, &types); - if (SUCCEEDED(hr)) - { - hr = (IEnumMediaTypes_Next(types, 1, &pmt, NULL) == S_OK - ? S_OK - : E_NOINTERFACE); - IEnumMediaTypes_Release(types); - } - - if (SUCCEEDED(hr)) - { - *pVal = *pmt; - CoTaskMemFree(pmt); - } - - return hr; + return get_pin_media_type(This->cur_pin, pVal); }
static HRESULT WINAPI MediaDet_GetSampleGrabber(IMediaDet* iface,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70177
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
The IFileSourceFilter is not queried for filters placed via put_Filter, so obtain the media type from the first pin to use for finding a matching splitter.
dlls/qedit/mediadet.c | 45 +++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index d1e8b71..0a9210c 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -150,22 +150,43 @@ static HRESULT get_splitter(MediaDetImpl *This) if (FAILED(hr)) return hr;
- hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter, - (void **) &file); - if (FAILED(hr)) + if (This->filename) { - IFilterMapper2_Release(map); - 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)) + hr = IFileSourceFilter_GetCurFile(file, &name, &mt); + IFileSourceFilter_Release(file); + CoTaskMemFree(name); + if (FAILED(hr)) + { + IFilterMapper2_Release(map); + return hr; + } + } + else { - IFilterMapper2_Release(map); - return hr; + mt.majortype = GUID_NULL; + mt.subtype = GUID_NULL; + mt.pbFormat = NULL; + + hr = IBaseFilter_EnumPins(This->source, &pins); + if (SUCCEEDED(hr)) + { + if (IEnumPins_Next(pins, 1, &source_pin, NULL) == S_OK) + { + get_pin_media_type(source_pin, &mt); + IPin_Release(source_pin); + } + IEnumPins_Release(pins); + } } + type[0] = mt.majortype; type[1] = mt.subtype; CoTaskMemFree(mt.pbFormat);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70178
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The IFileSourceFilter is not queried for filters placed via put_Filter, so obtain the media type from the first pin to use for finding a matching splitter.
The async reader (at least) exposes the same (first) media type from the source as through IFileSourceFilter::GetCurFile(), so it seems to me we could simplify by using this path for all filters.
dlls/qedit/mediadet.c | 45 +++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index d1e8b71..0a9210c 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -150,22 +150,43 @@ static HRESULT get_splitter(MediaDetImpl *This) if (FAILED(hr)) return hr;
- hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter,
(void **) &file);
- if (FAILED(hr))
- if (This->filename) {
IFilterMapper2_Release(map);
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))
hr = IFileSourceFilter_GetCurFile(file, &name, &mt);
IFileSourceFilter_Release(file);
CoTaskMemFree(name);
if (FAILED(hr))
{
IFilterMapper2_Release(map);
return hr;
}
- }
- else {
IFilterMapper2_Release(map);
return hr;
mt.majortype = GUID_NULL;
mt.subtype = GUID_NULL;
mt.pbFormat = NULL;
hr = IBaseFilter_EnumPins(This->source, &pins);
if (SUCCEEDED(hr))
{
if (IEnumPins_Next(pins, 1, &source_pin, NULL) == S_OK)
{
get_pin_media_type(source_pin, &mt);
IPin_Release(source_pin);
}
IEnumPins_Release(pins);
}}
- type[0] = mt.majortype; type[1] = mt.subtype; CoTaskMemFree(mt.pbFormat);
On 23/04/2020 22:51, Zebediah Figura wrote:
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The IFileSourceFilter is not queried for filters placed via put_Filter, so obtain the media type from the first pin to use for finding a matching splitter.
The async reader (at least) exposes the same (first) media type from the source as through IFileSourceFilter::GetCurFile(), so it seems to me we could simplify by using this path for all filters.
But Windows doesn't query it, though, that's why I wrote that comment. It's not obvious now, because I've converted it to strmbase, but I had a test for that before. This might break custom installed filters who don't expose it (not Wine's own).
On 4/24/20 6:24 AM, Gabriel Ivăncescu wrote:
On 23/04/2020 22:51, Zebediah Figura wrote:
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The IFileSourceFilter is not queried for filters placed via put_Filter, so obtain the media type from the first pin to use for finding a matching splitter.
The async reader (at least) exposes the same (first) media type from the source as through IFileSourceFilter::GetCurFile(), so it seems to me we could simplify by using this path for all filters.
But Windows doesn't query it, though, that's why I wrote that comment. It's not obvious now, because I've converted it to strmbase, but I had a test for that before. This might break custom installed filters who don't expose it (not Wine's own).
Sorry, that was poorly worded. I mean that we could query the media type from the pin always, and get rid of the path using IFileSourceFilter::GetCurFile().
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/mediadet.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 0a9210c..e0002cc 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -219,7 +219,11 @@ static HRESULT get_splitter(MediaDetImpl *This) VariantClear(&var); This->splitter = splitter; if (FAILED(hr)) - goto retry; + { + IBaseFilter_Release(splitter); + This->splitter = NULL; + continue; + }
hr = IBaseFilter_EnumPins(This->source, &pins); if (FAILED(hr)) @@ -248,6 +252,7 @@ static HRESULT get_splitter(MediaDetImpl *This) break;
retry: + IGraphBuilder_RemoveFilter(This->graph, splitter); IBaseFilter_Release(splitter); This->splitter = NULL; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70179
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 Task: Patch failed to apply
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Comparing directly to 4.2 works, I guess it was just a display issue since it can't be represented exactly in base 2.
dlls/qedit/mediadet.c | 32 ++++++- dlls/qedit/tests/mediadet.c | 180 +++++++++++++++++++++++++++++++++++- 2 files changed, 208 insertions(+), 4 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index e0002cc..1ab26f5 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -563,11 +563,37 @@ static HRESULT WINAPI MediaDet_get_StreamTypeB(IMediaDet *iface, BSTR *bstr) return hr; }
-static HRESULT WINAPI MediaDet_get_StreamLength(IMediaDet* iface, double *pVal) +static HRESULT WINAPI MediaDet_get_StreamLength(IMediaDet* iface, double *length) { MediaDetImpl *This = impl_from_IMediaDet(iface); - FIXME("(%p): stub!\n", This); - return VFW_E_INVALIDMEDIATYPE; + IMediaSeeking *seeking; + HRESULT hr; + + TRACE("detector %p, output length %p.\n", This, length); + + if (!length) + return E_POINTER; + + if (!This->cur_pin) + return E_INVALIDARG; + + hr = IPin_QueryInterface(This->cur_pin, &IID_IMediaSeeking, (void **) &seeking); + if (SUCCEEDED(hr)) + { + LONGLONG duration; + + hr = IMediaSeeking_GetDuration(seeking, &duration); + if (SUCCEEDED(hr)) + { + hr = IMediaSeeking_ConvertTimeFormat(seeking, &duration, &TIME_FORMAT_MEDIA_TIME, duration, NULL); + if (SUCCEEDED(hr)) + *length = (REFTIME)duration / 10000000; + } + IMediaSeeking_Release(seeking); + return hr; + } + + return hr; }
static HRESULT WINAPI MediaDet_get_Filename(IMediaDet* iface, BSTR *pVal) diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index f9aa3b3..14edc64 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -76,6 +76,7 @@ struct testfilter { struct strmbase_filter filter; struct strmbase_source source; + IMediaSeeking IMediaSeeking_iface; };
static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface) @@ -144,6 +145,19 @@ static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned in return S_OK; }
+static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) +{ + struct testfilter *filter = impl_from_Pin(iface); + + if (IsEqualGUID(iid, &IID_IMediaSeeking)) + *out = &filter->IMediaSeeking_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown*)*out); + return S_OK; +} + static HRESULT WINAPI testsource_decide_allocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator) { @@ -154,10 +168,163 @@ static const struct strmbase_source_ops testsource_ops = { .base.pin_query_accept = testsource_query_accept, .base.pin_get_media_type = testsource_get_media_type, + .base.pin_query_interface = testsource_query_interface, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideAllocator = testsource_decide_allocator };
+static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface); +} + +static HRESULT WINAPI testseek_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IPin_QueryInterface(&filter->source.pin.IPin_iface, iid, out); +} + +static ULONG WINAPI testseek_AddRef(IMediaSeeking *iface) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IPin_AddRef(&filter->source.pin.IPin_iface); +} + +static ULONG WINAPI testseek_Release(IMediaSeeking *iface) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IPin_Release(&filter->source.pin.IPin_iface); +} + +static HRESULT WINAPI testseek_GetCapabilities(IMediaSeeking *iface, DWORD *caps) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *caps) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *format) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format) +{ + if (winetest_debug > 1) trace("IMediaSeeking_GetTimeFormat()\n"); + + *format = TIME_FORMAT_MEDIA_TIME; + return S_OK; +} + +static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + if (winetest_debug > 1) trace("IMediaSeeking_IsUsingTimeFormat(%s)\n", wine_dbgstr_guid(format)); + + return IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE; +} + +static HRESULT WINAPI testseek_SetTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetDuration(IMediaSeeking *iface, LONGLONG *duration) +{ + if (winetest_debug > 1) trace("IMediaSeeking_GetDuration()\n"); + + *duration = 42000000; + return S_OK; +} + +static HRESULT WINAPI testseek_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, + const GUID *target_format, LONGLONG source, const GUID *source_format) +{ + if (winetest_debug > 1) + trace("IMediaSeeking_ConvertTimeFormat(%s: %s -> %s)\n", wine_dbgstr_longlong(source), + wine_dbgstr_guid(source_format), wine_dbgstr_guid(target_format)); + + if (source_format && !IsEqualGUID(source_format, &TIME_FORMAT_MEDIA_TIME)) + return E_INVALIDARG; + if (target_format && !IsEqualGUID(target_format, &TIME_FORMAT_MEDIA_TIME)) + return E_INVALIDARG; + + *target = source; + return S_OK; +} + +static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current, + DWORD current_flags, LONGLONG *stop, DWORD stop_flags) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_SetRate(IMediaSeeking *iface, double rate) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetRate(IMediaSeeking *iface, double *rate) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll) +{ + return E_NOTIMPL; +} + +static const IMediaSeekingVtbl testseek_vtbl = +{ + testseek_QueryInterface, + testseek_AddRef, + testseek_Release, + testseek_GetCapabilities, + testseek_CheckCapabilities, + testseek_IsFormatSupported, + testseek_QueryPreferredFormat, + testseek_GetTimeFormat, + testseek_IsUsingTimeFormat, + testseek_SetTimeFormat, + testseek_GetDuration, + testseek_GetStopPosition, + testseek_GetCurrentPosition, + testseek_ConvertTimeFormat, + testseek_SetPositions, + testseek_GetPositions, + testseek_GetAvailable, + testseek_SetRate, + testseek_GetRate, + testseek_GetPreroll +}; + static struct testfilter *create_testfilter(void) { static const GUID clsid = {0xabacab}; @@ -165,6 +332,7 @@ static struct testfilter *create_testfilter(void)
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + filter->IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
return filter; } @@ -298,6 +466,7 @@ static void test_mediadet(void) IEnumMediaTypes *type; IMediaDet *pM = NULL; BSTR filename = NULL; + double fps, duration; IFilterGraph *graph; IEnumPins *enumpins; LONG nstrms = 0; @@ -306,7 +475,6 @@ static void test_mediadet(void) LONG strm; GUID guid; BSTR bstr; - double fps; int flags; int i;
@@ -367,6 +535,12 @@ static void test_mediadet(void) hr = IMediaDet_get_StreamTypeB(pM, NULL); ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_StreamLength(pM, &duration); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_StreamLength(pM, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + hr = IMediaDet_get_Filter(pM, NULL); ok(hr == E_POINTER, "Got hr %#x.\n", hr);
@@ -651,6 +825,10 @@ static void test_mediadet(void) ok(hr == S_OK, "Got hr %#x.\n", hr); ok(nstrms == 1, "nstrms is %i\n", nstrms);
+ hr = IMediaDet_get_StreamLength(pM, &duration); + ok(hr == S_OK, "IMediaDet_get_StreamLength failed: %08x\n", hr); + ok(duration == 4.2, "Got duration %.16e\n", duration); + /* Now use the filter obtained from put_Filename for put_Filter. */ hr = IMediaDet_put_Filter(pM, (IUnknown*)filter); ok(hr == S_OK, "Got hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70180
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 error: patch failed: dlls/qedit/mediadet.c:563 error: patch failed: dlls/qedit/tests/mediadet.c:76 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/qedit/mediadet.c:305 error: patch failed: dlls/qedit/tests/mediadet.c:188 error: patch failed: dlls/qedit/mediadet.c:575 error: patch failed: dlls/qedit/tests/mediadet.c:643 error: patch failed: dlls/qedit/mediadet.c:563 error: patch failed: dlls/qedit/tests/mediadet.c:76 Task: Patch failed to apply
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
hr = IMediaSeeking_ConvertTimeFormat(seeking, &duration, &TIME_FORMAT_MEDIA_TIME, duration, NULL);
According to my testing, Windows doesn't do this.
On 23/04/2020 22:48, Zebediah Figura wrote:
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
hr = IMediaSeeking_ConvertTimeFormat(seeking, &duration, &, duration, NULL);
According to my testing, Windows doesn't do this.
Yeah, I assumed it's a bug, since it doesn't call any of the time functions either, it just assumes it's TIME_FORMAT_MEDIA_TIME or something?
Should I drop this and just assume so, too? Do you think it's worth? (perhaps I can just ignore the return value instead?)
On 4/24/20 6:25 AM, Gabriel Ivăncescu wrote:
On 23/04/2020 22:48, Zebediah Figura wrote:
On 4/21/20 7:19 AM, Gabriel Ivăncescu wrote:
hr = IMediaSeeking_ConvertTimeFormat(seeking, &duration, &, duration, NULL);
According to my testing, Windows doesn't do this.
Yeah, I assumed it's a bug, since it doesn't call any of the time functions either, it just assumes it's TIME_FORMAT_MEDIA_TIME or something?
Should I drop this and just assume so, too? Do you think it's worth? (perhaps I can just ignore the return value instead?)
It could be called a bug, yes; it seems the DirectShow documentation doesn't specify that the default time format should be reference time. But it results in less code for us to replicate that bug.
According ot my tests the return value of GetDuration() is checked, so no reason to get rid of that.