Module: wine Branch: master Commit: d8bbbfd589c3a766165d54e8389420f80b75c0af URL: https://source.winehq.org/git/wine.git/?a=commit;h=d8bbbfd589c3a766165d54e83...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Nov 8 11:41:45 2021 +0300
mf/session: Implement IsRateSupported().
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mf/session.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index e3d77864494..c4dc6419b87 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -3537,6 +3537,80 @@ static HRESULT session_get_presentation_rate(struct media_session *session, MFRA return hr; }
+static HRESULT session_is_presentation_rate_supported(struct media_session *session, BOOL thin, float rate, + float *nearest_rate) +{ + IMFRateSupport *rate_support; + struct media_source *source; + struct media_sink *sink; + float value = 0.0f, tmp; + unsigned int flags; + HRESULT hr = S_OK; + + if (!nearest_rate) nearest_rate = &tmp; + + if (rate == 0.0f) + { + *nearest_rate = 1.0f; + return S_OK; + } + + EnterCriticalSection(&session->cs); + + if (session->presentation.topo_status != MF_TOPOSTATUS_INVALID) + { + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + if (FAILED(hr = MFGetService((IUnknown *)source->source, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, + (void **)&rate_support))) + { + value = 1.0f; + break; + } + + value = rate; + if (FAILED(hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, &value))) + WARN("Source does not support rate %f, hr %#x.\n", rate, hr); + IMFRateSupport_Release(rate_support); + + /* Only "first" source is considered. */ + break; + } + + if (SUCCEEDED(hr)) + { + /* For sinks only check if rate is supported, ignoring nearest values. */ + LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) + { + flags = 0; + if (FAILED(hr = IMFMediaSink_GetCharacteristics(sink->sink, &flags))) + break; + + if (flags & MEDIASINK_RATELESS) + continue; + + if (FAILED(MFGetService((IUnknown *)sink->sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, + (void **)&rate_support))) + continue; + + hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, NULL); + IMFRateSupport_Release(rate_support); + if (FAILED(hr)) + { + WARN("Sink %p does not support rate %f, hr %#x.\n", sink->sink, rate, hr); + break; + } + } + } + } + + LeaveCriticalSection(&session->cs); + + *nearest_rate = value; + + return hr; +} + static HRESULT WINAPI session_rate_support_GetSlowestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction, BOOL thin, float *rate) { @@ -3560,9 +3634,11 @@ static HRESULT WINAPI session_rate_support_GetFastestRate(IMFRateSupport *iface, static HRESULT WINAPI session_rate_support_IsRateSupported(IMFRateSupport *iface, BOOL thin, float rate, float *nearest_supported_rate) { - FIXME("%p, %d, %f, %p.\n", iface, thin, rate, nearest_supported_rate); + struct media_session *session = impl_session_from_IMFRateSupport(iface);
- return E_NOTIMPL; + TRACE("%p, %d, %f, %p.\n", iface, thin, rate, nearest_supported_rate); + + return session_is_presentation_rate_supported(session, thin, rate, nearest_supported_rate); }
static const IMFRateSupportVtbl session_rate_support_vtbl =