Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 33 +++++++++++++++-- dlls/mf/tests/mf.c | 92 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index eae8338df7a..1d7c792fb1a 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -2715,6 +2715,17 @@ static ULONG WINAPI video_renderer_rate_support_Release(IMFRateSupport *iface) return IMFMediaSink_Release(&renderer->IMFMediaSink_iface); }
+static BOOL video_renderer_is_main_stream_configured(const struct video_renderer *renderer) +{ + IMFMediaType *media_type; + HRESULT hr; + + if (SUCCEEDED(hr = IMFTransform_GetInputCurrentType(renderer->mixer, 0, &media_type))) + IMFMediaType_Release(media_type); + + return SUCCEEDED(hr); +} + static HRESULT WINAPI video_renderer_rate_support_GetSlowestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction, BOOL thin, float *rate) { @@ -2741,11 +2752,27 @@ static HRESULT WINAPI video_renderer_rate_support_GetFastestRate(IMFRateSupport }
static HRESULT WINAPI video_renderer_rate_support_IsRateSupported(IMFRateSupport *iface, BOOL thin, float rate, - float *nearest_supported_rate) + float *nearest_rate) { - FIXME("%p, %d, %f, %p.\n", iface, thin, rate, nearest_supported_rate); + struct video_renderer *renderer = impl_from_IMFRateSupport(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %d, %f, %p.\n", iface, thin, rate, nearest_rate); + + EnterCriticalSection(&renderer->cs); + if (renderer->flags & EVR_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else + { + if (!thin && !video_renderer_is_main_stream_configured(renderer)) + hr = MF_E_INVALIDREQUEST; + + if (nearest_rate) + *nearest_rate = rate; + } + LeaveCriticalSection(&renderer->cs); + + return hr; }
static const IMFRateSupportVtbl video_renderer_rate_support_vtbl = diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 6bde7568202..58c7cbbadd4 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4258,6 +4258,10 @@ if (SUCCEEDED(hr))
static void test_evr(void) { + static const float supported_rates[] = + { + 0.0f, 1.0f, -20.0f, 20.0f, 1000.0f, -1000.0f, + }; IMFVideoSampleAllocatorCallback *allocator_callback; IMFStreamSink *stream_sink, *stream_sink2; IMFVideoDisplayControl *display_control; @@ -4275,8 +4279,9 @@ static void test_evr(void) IMFRateSupport *rs; LONG sample_count; IMFSample *sample; - IUnknown *unk; + unsigned int i; UINT64 window3; + IUnknown *unk; float rate; HRESULT hr; GUID guid; @@ -4607,6 +4612,88 @@ todo_wine { hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, &rate); ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(supported_rates); ++i) + { + rate = supported_rates[i] + 1.0f; + hr = IMFRateSupport_IsRateSupported(rs, TRUE, supported_rates[i], &rate); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == supported_rates[i], "Unexpected rate %f.\n", rate); + + rate = supported_rates[i] + 1.0f; + hr = IMFRateSupport_IsRateSupported(rs, FALSE, supported_rates[i], &rate); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + ok(rate == supported_rates[i], "Unexpected rate %f.\n", rate); + + hr = IMFRateSupport_IsRateSupported(rs, TRUE, supported_rates[i], NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFRateSupport_IsRateSupported(rs, FALSE, supported_rates[i], NULL); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + } + + /* Configuring stream type make rate support work. */ + hr = IMFMediaSink_GetStreamSinkById(sink, 0, &stream_sink); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &type_handler); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)64 << 32 | 64); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type); + ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr); + + rate = 1.0f; + hr = IMFRateSupport_GetSlowestRate(rs, MFRATE_FORWARD, TRUE, &rate); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == 0.0f, "Unexpected rate %f.\n", rate); + + rate = 1.0f; + hr = IMFRateSupport_GetSlowestRate(rs, MFRATE_REVERSE, TRUE, &rate); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == 0.0f, "Unexpected rate %f.\n", rate); + + rate = 0.0f; + hr = IMFRateSupport_GetFastestRate(rs, MFRATE_FORWARD, TRUE, &rate); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate); +} + rate = 0.0f; + hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, &rate); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate); +} + for (i = 0; i < ARRAY_SIZE(supported_rates); ++i) + { + rate = supported_rates[i] + 1.0f; + hr = IMFRateSupport_IsRateSupported(rs, TRUE, supported_rates[i], &rate); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == supported_rates[i], "Unexpected rate %f.\n", rate); + + rate = supported_rates[i] + 1.0f; + hr = IMFRateSupport_IsRateSupported(rs, FALSE, supported_rates[i], &rate); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(rate == supported_rates[i], "Unexpected rate %f.\n", rate); + + hr = IMFRateSupport_IsRateSupported(rs, TRUE, supported_rates[i], NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFRateSupport_IsRateSupported(rs, FALSE, supported_rates[i], NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + } + + IMFMediaTypeHandler_Release(type_handler); + IMFMediaType_Release(media_type); + IMFStreamSink_Release(stream_sink); + hr = IMFMediaSink_Shutdown(sink); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -4622,6 +4709,9 @@ todo_wine { hr = IMFRateSupport_GetFastestRate(rs, MFRATE_FORWARD, FALSE, &rate); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+ hr = IMFRateSupport_IsRateSupported(rs, TRUE, 1.0f, &rate); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + IMFPresentationClock_Release(clock);
IMFActivate_Release(activate);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/evr.c | 33 ++++++++++++++++++++++++++++----- dlls/mf/tests/mf.c | 21 +++++++++++++++++---- 2 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c index 1d7c792fb1a..b035b8b601b 100644 --- a/dlls/mf/evr.c +++ b/dlls/mf/evr.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <float.h> + #define COBJMACROS
#include "mf_private.h" @@ -2730,25 +2732,46 @@ static HRESULT WINAPI video_renderer_rate_support_GetSlowestRate(IMFRateSupport BOOL thin, float *rate) { struct video_renderer *renderer = impl_from_IMFRateSupport(iface); + HRESULT hr = S_OK;
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate);
+ EnterCriticalSection(&renderer->cs); if (renderer->flags & EVR_SHUT_DOWN) - return MF_E_SHUTDOWN; - - *rate = 0.0f; + hr = MF_E_SHUTDOWN; + else if (!rate) + hr = E_POINTER; + else + { + *rate = 0.0f; + } + LeaveCriticalSection(&renderer->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI video_renderer_rate_support_GetFastestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction, BOOL thin, float *rate) { struct video_renderer *renderer = impl_from_IMFRateSupport(iface); + HRESULT hr = S_OK;
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate);
- return renderer->flags & EVR_SHUT_DOWN ? MF_E_SHUTDOWN : MF_E_INVALIDREQUEST; + EnterCriticalSection(&renderer->cs); + if (renderer->flags & EVR_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else if (!rate) + hr = E_POINTER; + else if (video_renderer_is_main_stream_configured(renderer)) + { + *rate = direction == MFRATE_FORWARD ? FLT_MAX : -FLT_MAX; + } + else + hr = MF_E_INVALIDREQUEST; + LeaveCriticalSection(&renderer->cs); + + return hr; }
static HRESULT WINAPI video_renderer_rate_support_IsRateSupported(IMFRateSupport *iface, BOOL thin, float rate, diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 58c7cbbadd4..b3f50665e79 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4612,6 +4612,9 @@ todo_wine { hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, &rate); ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
+ hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(supported_rates); ++i) { rate = supported_rates[i] + 1.0f; @@ -4661,16 +4664,20 @@ todo_wine {
rate = 0.0f; hr = IMFRateSupport_GetFastestRate(rs, MFRATE_FORWARD, TRUE, &rate); -todo_wine { ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate); -} + rate = 0.0f; hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, &rate); -todo_wine { ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate); -} + + hr = IMFRateSupport_GetFastestRate(rs, MFRATE_REVERSE, TRUE, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMFRateSupport_GetSlowestRate(rs, MFRATE_REVERSE, TRUE, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(supported_rates); ++i) { rate = supported_rates[i] + 1.0f; @@ -4709,6 +4716,12 @@ todo_wine { hr = IMFRateSupport_GetFastestRate(rs, MFRATE_FORWARD, FALSE, &rate); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+ hr = IMFRateSupport_GetSlowestRate(rs, MFRATE_FORWARD, FALSE, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFRateSupport_GetFastestRate(rs, MFRATE_FORWARD, FALSE, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + hr = IMFRateSupport_IsRateSupported(rs, TRUE, 1.0f, &rate); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/winegstreamer/media_source.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 9a77cf72c07..bccbf888a4a 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -105,6 +105,7 @@ struct media_source SOURCE_RUNNING, SOURCE_SHUTDOWN, } state; + float rate;
HANDLE read_thread; bool read_thread_shutdown; @@ -1110,6 +1111,7 @@ static ULONG WINAPI media_source_rate_control_Release(IMFRateControl *iface) static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, BOOL thin, float rate) { struct media_source *source = impl_from_IMFRateControl(iface); + HRESULT hr;
FIXME("%p, %d, %f.\n", iface, thin, rate);
@@ -1119,20 +1121,24 @@ static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, B if (thin) return MF_E_THINNING_UNSUPPORTED;
- if (rate != 1.0f) - return MF_E_UNSUPPORTED_RATE; + if (FAILED(hr = IMFRateSupport_IsRateSupported(&source->IMFRateSupport_iface, thin, rate, NULL))) + return hr; + + source->rate = rate;
return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceRateChanged, &GUID_NULL, S_OK, NULL); }
static HRESULT WINAPI media_source_rate_control_GetRate(IMFRateControl *iface, BOOL *thin, float *rate) { + struct media_source *source = impl_from_IMFRateControl(iface); + TRACE("%p, %p, %p.\n", iface, thin, rate);
if (thin) *thin = FALSE;
- *rate = 1.0f; + *rate = source->rate;
return S_OK; } @@ -1427,6 +1433,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ object->ref = 1; object->byte_stream = bytestream; IMFByteStream_AddRef(bytestream); + object->rate = 1.0f;
if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto fail;