mf/samplegrabber: Implement IMFRateSupport.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
12821cbb75
commit
07139b0be2
|
@ -18,6 +18,8 @@
|
|||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "mfidl.h"
|
||||
#include "mf_private.h"
|
||||
|
||||
|
@ -61,6 +63,8 @@ struct sample_grabber
|
|||
IMFMediaSink IMFMediaSink_iface;
|
||||
IMFClockStateSink IMFClockStateSink_iface;
|
||||
IMFMediaEventGenerator IMFMediaEventGenerator_iface;
|
||||
IMFGetService IMFGetService_iface;
|
||||
IMFRateSupport IMFRateSupport_iface;
|
||||
IMFStreamSink IMFStreamSink_iface;
|
||||
IMFMediaTypeHandler IMFMediaTypeHandler_iface;
|
||||
IMFAsyncCallback timer_callback;
|
||||
|
@ -117,6 +121,16 @@ static struct sample_grabber *impl_from_IMFMediaEventGenerator(IMFMediaEventGene
|
|||
return CONTAINING_RECORD(iface, struct sample_grabber, IMFMediaEventGenerator_iface);
|
||||
}
|
||||
|
||||
static struct sample_grabber *impl_from_IMFGetService(IMFGetService *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct sample_grabber, IMFGetService_iface);
|
||||
}
|
||||
|
||||
static struct sample_grabber *impl_from_IMFRateSupport(IMFRateSupport *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct sample_grabber, IMFRateSupport_iface);
|
||||
}
|
||||
|
||||
static struct sample_grabber *impl_from_IMFStreamSink(IMFStreamSink *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct sample_grabber, IMFStreamSink_iface);
|
||||
|
@ -773,6 +787,14 @@ static HRESULT WINAPI sample_grabber_sink_QueryInterface(IMFMediaSink *iface, RE
|
|||
{
|
||||
*obj = &grabber->IMFMediaEventGenerator_iface;
|
||||
}
|
||||
else if (IsEqualIID(riid, &IID_IMFGetService))
|
||||
{
|
||||
*obj = &grabber->IMFGetService_iface;
|
||||
}
|
||||
else if (IsEqualIID(riid, &IID_IMFRateSupport))
|
||||
{
|
||||
*obj = &grabber->IMFRateSupport_iface;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Unsupported %s.\n", debugstr_guid(riid));
|
||||
|
@ -1249,6 +1271,109 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl =
|
|||
sample_grabber_clock_sink_OnClockSetRate,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI sample_grabber_getservice_QueryInterface(IMFGetService *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFGetService(iface);
|
||||
return IMFMediaSink_QueryInterface(&grabber->IMFMediaSink_iface, riid, obj);
|
||||
}
|
||||
|
||||
static ULONG WINAPI sample_grabber_getservice_AddRef(IMFGetService *iface)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFGetService(iface);
|
||||
return IMFMediaSink_AddRef(&grabber->IMFMediaSink_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI sample_grabber_getservice_Release(IMFGetService *iface)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFGetService(iface);
|
||||
return IMFMediaSink_Release(&grabber->IMFMediaSink_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_grabber_getservice_GetService(IMFGetService *iface, REFGUID service,
|
||||
REFIID riid, void **obj)
|
||||
{
|
||||
TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
|
||||
|
||||
if (IsEqualGUID(service, &MF_RATE_CONTROL_SERVICE))
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IMFRateSupport))
|
||||
return IMFGetService_QueryInterface(iface, riid, obj);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
FIXME("Unsupported service %s, riid %s.\n", debugstr_guid(service), debugstr_guid(riid));
|
||||
|
||||
return MF_E_UNSUPPORTED_SERVICE;
|
||||
}
|
||||
|
||||
static const IMFGetServiceVtbl sample_grabber_getservice_vtbl =
|
||||
{
|
||||
sample_grabber_getservice_QueryInterface,
|
||||
sample_grabber_getservice_AddRef,
|
||||
sample_grabber_getservice_Release,
|
||||
sample_grabber_getservice_GetService,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI sample_grabber_rate_support_QueryInterface(IMFRateSupport *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFRateSupport(iface);
|
||||
return IMFMediaSink_QueryInterface(&grabber->IMFMediaSink_iface, riid, obj);
|
||||
}
|
||||
|
||||
static ULONG WINAPI sample_grabber_rate_support_AddRef(IMFRateSupport *iface)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFRateSupport(iface);
|
||||
return IMFMediaSink_AddRef(&grabber->IMFMediaSink_iface);
|
||||
}
|
||||
|
||||
static ULONG WINAPI sample_grabber_rate_support_Release(IMFRateSupport *iface)
|
||||
{
|
||||
struct sample_grabber *grabber = impl_from_IMFRateSupport(iface);
|
||||
return IMFMediaSink_Release(&grabber->IMFMediaSink_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_grabber_rate_support_GetSlowestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction,
|
||||
BOOL thin, float *rate)
|
||||
{
|
||||
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate);
|
||||
|
||||
*rate = 0.0f;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_grabber_rate_support_GetFastestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction,
|
||||
BOOL thin, float *rate)
|
||||
{
|
||||
TRACE("%p, %d, %d, %p.\n", iface, direction, thin, rate);
|
||||
|
||||
*rate = direction == MFRATE_REVERSE ? -FLT_MAX : FLT_MAX;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI sample_grabber_rate_support_IsRateSupported(IMFRateSupport *iface, BOOL thin, float rate,
|
||||
float *ret_rate)
|
||||
{
|
||||
TRACE("%p, %d, %f, %p.\n", iface, thin, rate, ret_rate);
|
||||
|
||||
if (ret_rate)
|
||||
*ret_rate = rate;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IMFRateSupportVtbl sample_grabber_rate_support_vtbl =
|
||||
{
|
||||
sample_grabber_rate_support_QueryInterface,
|
||||
sample_grabber_rate_support_AddRef,
|
||||
sample_grabber_rate_support_Release,
|
||||
sample_grabber_rate_support_GetSlowestRate,
|
||||
sample_grabber_rate_support_GetFastestRate,
|
||||
sample_grabber_rate_support_IsRateSupported,
|
||||
};
|
||||
|
||||
static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj)
|
||||
{
|
||||
struct sample_grabber_activate_context *context = user_context;
|
||||
|
@ -1272,6 +1397,8 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use
|
|||
object->IMFMediaSink_iface.lpVtbl = &sample_grabber_sink_vtbl;
|
||||
object->IMFClockStateSink_iface.lpVtbl = &sample_grabber_clock_sink_vtbl;
|
||||
object->IMFMediaEventGenerator_iface.lpVtbl = &sample_grabber_sink_events_vtbl;
|
||||
object->IMFGetService_iface.lpVtbl = &sample_grabber_getservice_vtbl;
|
||||
object->IMFRateSupport_iface.lpVtbl = &sample_grabber_rate_support_vtbl;
|
||||
object->IMFStreamSink_iface.lpVtbl = &sample_grabber_stream_vtbl;
|
||||
object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl;
|
||||
object->timer_callback.lpVtbl = &sample_grabber_stream_timer_callback_vtbl;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
|
@ -71,6 +72,21 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
|
|||
IUnknown_Release(unk);
|
||||
}
|
||||
|
||||
#define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
|
||||
static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
|
||||
{
|
||||
IUnknown *iface = iface_ptr;
|
||||
HRESULT hr, expected_hr;
|
||||
IUnknown *unk;
|
||||
|
||||
expected_hr = supported ? S_OK : E_NOINTERFACE;
|
||||
|
||||
hr = MFGetService(iface, service, iid, (void **)&unk);
|
||||
ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
|
||||
if (SUCCEEDED(hr))
|
||||
IUnknown_Release(unk);
|
||||
}
|
||||
|
||||
static HWND create_window(void)
|
||||
{
|
||||
RECT r = {0, 0, 640, 480};
|
||||
|
@ -2097,6 +2113,7 @@ static void test_sample_grabber(void)
|
|||
IMFPresentationTimeSource *time_source;
|
||||
IMFPresentationClock *clock, *clock2;
|
||||
IMFStreamSink *stream, *stream2;
|
||||
IMFRateSupport *rate_support;
|
||||
IMFMediaEventGenerator *eg;
|
||||
IMFMediaSink *sink, *sink2;
|
||||
DWORD flags, count, id;
|
||||
|
@ -2104,6 +2121,7 @@ static void test_sample_grabber(void)
|
|||
IMFMediaEvent *event;
|
||||
ULONG refcount;
|
||||
IUnknown *unk;
|
||||
float rate;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
|
||||
|
@ -2136,6 +2154,53 @@ static void test_sample_grabber(void)
|
|||
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
|
||||
ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
|
||||
|
||||
check_interface(sink, &IID_IMFClockStateSink, TRUE);
|
||||
check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
|
||||
check_interface(sink, &IID_IMFGetService, TRUE);
|
||||
check_interface(sink, &IID_IMFRateSupport, TRUE);
|
||||
check_service_interface(sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
|
||||
|
||||
if (SUCCEEDED(MFGetService((IUnknown *)sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support)))
|
||||
{
|
||||
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
|
||||
|
||||
hr = IMFRateSupport_IsRateSupported(rate_support, TRUE, 1.0f, &rate);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
|
||||
|
||||
IMFRateSupport_Release(rate_support);
|
||||
}
|
||||
|
||||
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
|
||||
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
|
||||
ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags);
|
||||
|
@ -2148,6 +2213,7 @@ static void test_sample_grabber(void)
|
|||
ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
|
||||
|
||||
check_interface(stream, &IID_IMFMediaEventGenerator, TRUE);
|
||||
check_interface(stream, &IID_IMFMediaTypeHandler, TRUE);
|
||||
|
||||
hr = IMFStreamSink_GetIdentifier(stream, &id);
|
||||
ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr);
|
||||
|
|
Loading…
Reference in New Issue