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 --- v6: Simplify error handling a bit.
This supersedes https://source.winehq.org/patches/data/184349.
dlls/qedit/mediadet.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 392320560b8..3c00a85b9ed 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -103,6 +103,24 @@ static HRESULT get_filter_info(IMoniker *moniker, GUID *clsid, VARIANT *var) return hr; }
+static HRESULT get_pin_media_type(IPin *pin, AM_MEDIA_TYPE *out) +{ + IEnumMediaTypes *enummt; + AM_MEDIA_TYPE *pmt; + HRESULT hr; + + if (FAILED(hr = IPin_EnumMediaTypes(pin, &enummt))) + return hr; + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + IEnumMediaTypes_Release(enummt); + if (hr != S_OK) + return E_NOINTERFACE; + + *out = *pmt; + CoTaskMemFree(pmt); + return S_OK; +} + static HRESULT find_splitter(MediaDetImpl *detector) { IPin *source_pin, *splitter_pin; @@ -611,9 +629,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);
@@ -623,22 +638,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,
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 --- v6: No changes.
This supersedes https://source.winehq.org/patches/data/184350.
dlls/qedit/mediadet.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 3c00a85b9ed..5a192689858 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -124,12 +124,10 @@ static HRESULT get_pin_media_type(IPin *pin, AM_MEDIA_TYPE *out) 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]; @@ -137,25 +135,6 @@ static HRESULT find_splitter(MediaDetImpl *detector) 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); @@ -169,6 +148,17 @@ static HRESULT find_splitter(MediaDetImpl *detector) return hr; }
+ if (FAILED(hr = get_pin_media_type(source_pin, &mt))) + { + ERR("Failed to get media type, hr %#x.\n", hr); + IPin_Release(source_pin); + return hr; + } + + type[0] = mt.majortype; + type[1] = mt.subtype; + FreeMediaType(&mt); + if (FAILED(hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (void **)&mapper))) {
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=70690
Your paranoid android.
=== debiant (32 bit report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x004167a7).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x004167a7).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit WoW report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x004167a7).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (64 bit WoW report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x004167a7).
Report validation errors: qedit:mediadet crashed (c0000005)
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 --- v6: Style tweaks (avoid This, remove a redundant "return hr").
This supersedes https://source.winehq.org/patches/data/184351.
dlls/qedit/mediadet.c | 32 ++++++- dlls/qedit/tests/mediadet.c | 185 ++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 4 deletions(-)
diff --git a/dlls/qedit/mediadet.c b/dlls/qedit/mediadet.c index 5a192689858..d32679b6bb8 100644 --- a/dlls/qedit/mediadet.c +++ b/dlls/qedit/mediadet.c @@ -524,11 +524,35 @@ 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; + MediaDetImpl *detector = impl_from_IMediaDet(iface); + IMediaSeeking *seeking; + HRESULT hr; + + TRACE("detector %p, length %p.\n", detector, length); + + if (!length) + return E_POINTER; + + if (!detector->cur_pin) + return E_INVALIDARG; + + if (SUCCEEDED(hr = IPin_QueryInterface(detector->cur_pin, + &IID_IMediaSeeking, (void **)&seeking))) + { + LONGLONG duration; + + if (SUCCEEDED(hr = IMediaSeeking_GetDuration(seeking, &duration))) + { + /* Windows assumes the time format is TIME_FORMAT_MEDIA_TIME + and does not check it nor convert it, as tests show. */ + *length = (REFTIME)duration / 10000000; + } + IMediaSeeking_Release(seeking); + } + + 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 32861476dd0..9bf6c43a2af 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -135,6 +135,7 @@ struct testfilter { struct strmbase_filter filter; struct strmbase_source source; + IMediaSeeking IMediaSeeking_iface; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -163,6 +164,11 @@ static const struct strmbase_filter_ops testfilter_ops = .filter_destroy = testfilter_destroy, };
+static inline struct testfilter *impl_from_strmbase_pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, source.pin); +} + static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) { static const VIDEOINFOHEADER source_format = @@ -192,6 +198,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_strmbase_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_DecideAllocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator) { @@ -201,10 +220,164 @@ static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, static const struct strmbase_source_ops testsource_ops = { .base.pin_get_media_type = testsource_get_media_type, + .base.pin_query_interface = testsource_query_interface, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideAllocator = testsource_DecideAllocator, };
+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) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *caps) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_SetTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + 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) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, + const GUID *target_format, LONGLONG source, const GUID *source_format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current, + DWORD current_flags, LONGLONG *stop, DWORD stop_flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_SetRate(IMediaSeeking *iface, double rate) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetRate(IMediaSeeking *iface, double *rate) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testseek_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll) +{ + ok(0, "Unexpected call.\n"); + 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 void testfilter_init(struct testfilter *filter) { static const GUID clsid = {0xabacab}; @@ -212,6 +385,7 @@ static void testfilter_init(struct testfilter *filter) memset(filter, 0, sizeof(*filter)); 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; }
static WCHAR test_avi_filename[MAX_PATH]; @@ -571,6 +745,7 @@ static void test_put_filter(void) IMediaDet *detector; LONG index, count; AM_MEDIA_TYPE mt; + double duration; IUnknown *unk; BSTR filename; HRESULT hr; @@ -586,6 +761,12 @@ static void test_put_filter(void) hr = IMediaDet_get_Filter(detector, NULL); ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+ hr = IMediaDet_get_StreamLength(detector, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_StreamLength(detector, &duration); + ok(hr == E_INVALIDARG, "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); @@ -639,6 +820,10 @@ static void test_put_filter(void) ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!filename, "Got filename %s.\n", debugstr_w(filename));
+ hr = IMediaDet_get_StreamLength(detector, &duration); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(duration == 4.2, "Got duration %.16e.\n", duration); + ref = IMediaDet_Release(detector); ok(!ref, "Got outstanding refcount %d.\n", ref); ref = IBaseFilter_Release(&testfilter2.filter.IBaseFilter_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=70691
Your paranoid android.
=== debiant (32 bit report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit French report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (32 bit WoW report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)
=== debiant (64 bit WoW report) ===
qedit: Unhandled exception: page fault on read access to 0x00000024 in 32-bit code (0x00416e07).
Report validation errors: qedit:mediadet crashed (c0000005)