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

mf/samplegrabber: Implement IMFRateSupport.

parent 12821cbb
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#define COBJMACROS #define COBJMACROS
#include <float.h>
#include "mfidl.h" #include "mfidl.h"
#include "mf_private.h" #include "mf_private.h"
...@@ -61,6 +63,8 @@ struct sample_grabber ...@@ -61,6 +63,8 @@ struct sample_grabber
IMFMediaSink IMFMediaSink_iface; IMFMediaSink IMFMediaSink_iface;
IMFClockStateSink IMFClockStateSink_iface; IMFClockStateSink IMFClockStateSink_iface;
IMFMediaEventGenerator IMFMediaEventGenerator_iface; IMFMediaEventGenerator IMFMediaEventGenerator_iface;
IMFGetService IMFGetService_iface;
IMFRateSupport IMFRateSupport_iface;
IMFStreamSink IMFStreamSink_iface; IMFStreamSink IMFStreamSink_iface;
IMFMediaTypeHandler IMFMediaTypeHandler_iface; IMFMediaTypeHandler IMFMediaTypeHandler_iface;
IMFAsyncCallback timer_callback; IMFAsyncCallback timer_callback;
...@@ -117,6 +121,16 @@ static struct sample_grabber *impl_from_IMFMediaEventGenerator(IMFMediaEventGene ...@@ -117,6 +121,16 @@ static struct sample_grabber *impl_from_IMFMediaEventGenerator(IMFMediaEventGene
return CONTAINING_RECORD(iface, struct sample_grabber, IMFMediaEventGenerator_iface); 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) static struct sample_grabber *impl_from_IMFStreamSink(IMFStreamSink *iface)
{ {
return CONTAINING_RECORD(iface, struct sample_grabber, 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 ...@@ -773,6 +787,14 @@ static HRESULT WINAPI sample_grabber_sink_QueryInterface(IMFMediaSink *iface, RE
{ {
*obj = &grabber->IMFMediaEventGenerator_iface; *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 else
{ {
WARN("Unsupported %s.\n", debugstr_guid(riid)); WARN("Unsupported %s.\n", debugstr_guid(riid));
...@@ -1249,6 +1271,109 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl = ...@@ -1249,6 +1271,109 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl =
sample_grabber_clock_sink_OnClockSetRate, 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) static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj)
{ {
struct sample_grabber_activate_context *context = user_context; struct sample_grabber_activate_context *context = user_context;
...@@ -1272,6 +1397,8 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use ...@@ -1272,6 +1397,8 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use
object->IMFMediaSink_iface.lpVtbl = &sample_grabber_sink_vtbl; object->IMFMediaSink_iface.lpVtbl = &sample_grabber_sink_vtbl;
object->IMFClockStateSink_iface.lpVtbl = &sample_grabber_clock_sink_vtbl; object->IMFClockStateSink_iface.lpVtbl = &sample_grabber_clock_sink_vtbl;
object->IMFMediaEventGenerator_iface.lpVtbl = &sample_grabber_sink_events_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->IMFStreamSink_iface.lpVtbl = &sample_grabber_stream_vtbl;
object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl; object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl;
object->timer_callback.lpVtbl = &sample_grabber_stream_timer_callback_vtbl; object->timer_callback.lpVtbl = &sample_grabber_stream_timer_callback_vtbl;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <float.h>
#define COBJMACROS #define COBJMACROS
...@@ -71,6 +72,21 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO ...@@ -71,6 +72,21 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
IUnknown_Release(unk); 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) static HWND create_window(void)
{ {
RECT r = {0, 0, 640, 480}; RECT r = {0, 0, 640, 480};
...@@ -2097,6 +2113,7 @@ static void test_sample_grabber(void) ...@@ -2097,6 +2113,7 @@ static void test_sample_grabber(void)
IMFPresentationTimeSource *time_source; IMFPresentationTimeSource *time_source;
IMFPresentationClock *clock, *clock2; IMFPresentationClock *clock, *clock2;
IMFStreamSink *stream, *stream2; IMFStreamSink *stream, *stream2;
IMFRateSupport *rate_support;
IMFMediaEventGenerator *eg; IMFMediaEventGenerator *eg;
IMFMediaSink *sink, *sink2; IMFMediaSink *sink, *sink2;
DWORD flags, count, id; DWORD flags, count, id;
...@@ -2104,6 +2121,7 @@ static void test_sample_grabber(void) ...@@ -2104,6 +2121,7 @@ static void test_sample_grabber(void)
IMFMediaEvent *event; IMFMediaEvent *event;
ULONG refcount; ULONG refcount;
IUnknown *unk; IUnknown *unk;
float rate;
HRESULT hr; HRESULT hr;
GUID guid; GUID guid;
...@@ -2136,6 +2154,53 @@ static void test_sample_grabber(void) ...@@ -2136,6 +2154,53 @@ static void test_sample_grabber(void)
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr); 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); hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags); ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags);
...@@ -2148,6 +2213,7 @@ static void test_sample_grabber(void) ...@@ -2148,6 +2213,7 @@ static void test_sample_grabber(void)
ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
check_interface(stream, &IID_IMFMediaEventGenerator, TRUE); check_interface(stream, &IID_IMFMediaEventGenerator, TRUE);
check_interface(stream, &IID_IMFMediaTypeHandler, TRUE);
hr = IMFStreamSink_GetIdentifier(stream, &id); hr = IMFStreamSink_GetIdentifier(stream, &id);
ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr); 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