Commit 07139b0b authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

mf/samplegrabber: Implement IMFRateSupport.

parent 12821cbb
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment