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);