mf: Implement type handler methods for sample grabber stream.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Nikolay Sivov 2019-05-27 17:07:37 +03:00 committed by Alexandre Julliard
parent bc7e98a1a9
commit 3139727a97
2 changed files with 172 additions and 26 deletions

View File

@ -28,12 +28,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat); WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
struct sample_grabber;
struct sample_grabber_stream struct sample_grabber_stream
{ {
IMFStreamSink IMFStreamSink_iface; IMFStreamSink IMFStreamSink_iface;
IMFMediaTypeHandler IMFMediaTypeHandler_iface; IMFMediaTypeHandler IMFMediaTypeHandler_iface;
LONG refcount; LONG refcount;
IMFMediaSink *sink; struct sample_grabber *sink;
IMFMediaEventQueue *event_queue; IMFMediaEventQueue *event_queue;
}; };
@ -136,7 +138,7 @@ static ULONG WINAPI sample_grabber_stream_Release(IMFStreamSink *iface)
if (!refcount) if (!refcount)
{ {
IMFMediaSink_Release(stream->sink); IMFMediaSink_Release(&stream->sink->IMFMediaSink_iface);
if (stream->event_queue) if (stream->event_queue)
{ {
IMFMediaEventQueue_Shutdown(stream->event_queue); IMFMediaEventQueue_Shutdown(stream->event_queue);
@ -193,7 +195,7 @@ static HRESULT WINAPI sample_grabber_stream_GetMediaSink(IMFStreamSink *iface, I
TRACE("%p, %p.\n", iface, sink); TRACE("%p, %p.\n", iface, sink);
*sink = stream->sink; *sink = &stream->sink->IMFMediaSink_iface;
IMFMediaSink_AddRef(*sink); IMFMediaSink_AddRef(*sink);
return S_OK; return S_OK;
@ -281,47 +283,81 @@ static ULONG WINAPI sample_grabber_stream_type_handler_Release(IMFMediaTypeHandl
static HRESULT WINAPI sample_grabber_stream_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, static HRESULT WINAPI sample_grabber_stream_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface,
IMFMediaType *in_type, IMFMediaType **out_type) IMFMediaType *in_type, IMFMediaType **out_type)
{ {
FIXME("%p, %p, %p.\n", iface, in_type, out_type); struct sample_grabber_stream *stream = impl_from_IMFMediaTypeHandler(iface);
const DWORD supported_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES;
DWORD flags;
return E_NOTIMPL; TRACE("%p, %p, %p.\n", iface, in_type, out_type);
if (!in_type)
return E_POINTER;
if (IMFMediaType_IsEqual(stream->sink->media_type, in_type, &flags) == S_OK)
return S_OK;
return (flags & supported_flags) == supported_flags ? S_OK : MF_E_INVALIDMEDIATYPE;
} }
static HRESULT WINAPI sample_grabber_stream_type_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count) static HRESULT WINAPI sample_grabber_stream_type_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count)
{ {
FIXME("%p, %p.\n", iface, count); TRACE("%p, %p.\n", iface, count);
return E_NOTIMPL; if (!count)
return E_POINTER;
*count = 0;
return S_OK;
} }
static HRESULT WINAPI sample_grabber_stream_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index, static HRESULT WINAPI sample_grabber_stream_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index,
IMFMediaType **type) IMFMediaType **media_type)
{ {
FIXME("%p, %u, %p.\n", iface, index, type); TRACE("%p, %u, %p.\n", iface, index, media_type);
return E_NOTIMPL; if (!media_type)
return E_POINTER;
return MF_E_NO_MORE_TYPES;
} }
static HRESULT WINAPI sample_grabber_stream_type_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, static HRESULT WINAPI sample_grabber_stream_type_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface,
IMFMediaType *type) IMFMediaType *media_type)
{ {
FIXME("%p, %p.\n", iface, type); struct sample_grabber_stream *stream = impl_from_IMFMediaTypeHandler(iface);
return E_NOTIMPL; TRACE("%p, %p.\n", iface, media_type);
if (!media_type)
return E_POINTER;
IMFMediaType_Release(stream->sink->media_type);
stream->sink->media_type = media_type;
IMFMediaType_AddRef(stream->sink->media_type);
return S_OK;
} }
static HRESULT WINAPI sample_grabber_stream_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, static HRESULT WINAPI sample_grabber_stream_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface,
IMFMediaType **type) IMFMediaType **type)
{ {
FIXME("%p, %p.\n", iface, type); struct sample_grabber_stream *stream = impl_from_IMFMediaTypeHandler(iface);
return E_NOTIMPL; TRACE("%p, %p.\n", iface, type);
*type = stream->sink->media_type;
IMFMediaType_AddRef(*type);
return S_OK;
} }
static HRESULT WINAPI sample_grabber_stream_type_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type) static HRESULT WINAPI sample_grabber_stream_type_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type)
{ {
FIXME("%p, %p.\n", iface, type); struct sample_grabber_stream *stream = impl_from_IMFMediaTypeHandler(iface);
return E_NOTIMPL; TRACE("%p, %p.\n", iface, type);
return IMFMediaType_GetMajorType(stream->sink->media_type, type);
} }
static const IMFMediaTypeHandlerVtbl sample_grabber_stream_type_handler_vtbl = static const IMFMediaTypeHandlerVtbl sample_grabber_stream_type_handler_vtbl =
@ -682,7 +718,7 @@ static const IMFClockStateSinkVtbl sample_grabber_clock_sink_vtbl =
sample_grabber_clock_sink_OnClockSetRate, sample_grabber_clock_sink_OnClockSetRate,
}; };
static HRESULT sample_grabber_create_stream(IMFMediaSink *sink, IMFStreamSink **stream) static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, IMFStreamSink **stream)
{ {
struct sample_grabber_stream *object; struct sample_grabber_stream *object;
HRESULT hr; HRESULT hr;
@ -695,7 +731,7 @@ static HRESULT sample_grabber_create_stream(IMFMediaSink *sink, IMFStreamSink **
object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl; object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl;
object->refcount = 1; object->refcount = 1;
object->sink = sink; object->sink = sink;
IMFMediaSink_AddRef(object->sink); IMFMediaSink_AddRef(&object->sink->IMFMediaSink_iface);
if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
goto failed; goto failed;
@ -715,9 +751,14 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use
struct sample_grabber_activate_context *context = user_context; struct sample_grabber_activate_context *context = user_context;
struct sample_grabber *object; struct sample_grabber *object;
HRESULT hr; HRESULT hr;
GUID guid;
TRACE("%p, %p, %p.\n", attributes, user_context, obj); TRACE("%p, %p, %p.\n", attributes, user_context, obj);
/* At least major type is required. */
if (FAILED(IMFMediaType_GetMajorType(context->media_type, &guid)))
return MF_E_INVALIDMEDIATYPE;
object = heap_alloc_zero(sizeof(*object)); object = heap_alloc_zero(sizeof(*object));
if (!object) if (!object)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -732,7 +773,7 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use
IMFMediaType_AddRef(object->media_type); IMFMediaType_AddRef(object->media_type);
InitializeCriticalSection(&object->cs); InitializeCriticalSection(&object->cs);
if (FAILED(hr = sample_grabber_create_stream(&object->IMFMediaSink_iface, &object->stream))) if (FAILED(hr = sample_grabber_create_stream(object, &object->stream)))
goto failed; goto failed;
if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))

View File

@ -1638,17 +1638,23 @@ static IMFSampleGrabberSinkCallback grabber_callback = { &grabber_callback_vtbl
static void test_sample_grabber(void) static void test_sample_grabber(void)
{ {
IMFMediaType *media_type, *media_type2, *media_type3;
IMFMediaTypeHandler *handler, *handler2; IMFMediaTypeHandler *handler, *handler2;
IMFPresentationTimeSource *time_source;
IMFStreamSink *stream, *stream2; IMFStreamSink *stream, *stream2;
IMFClockStateSink *clocksink; IMFClockStateSink *clocksink;
IMFPresentationClock *clock;
IMFMediaEventGenerator *eg; IMFMediaEventGenerator *eg;
IMFMediaSink *sink, *sink2; IMFMediaSink *sink, *sink2;
IMFMediaType *media_type;
DWORD flags, count, id; DWORD flags, count, id;
IMFActivate *activate; IMFActivate *activate;
ULONG refcount; ULONG refcount;
IUnknown *unk; IUnknown *unk;
HRESULT hr; HRESULT hr;
GUID guid;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
hr = MFCreateMediaType(&media_type); hr = MFCreateMediaType(&media_type);
ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
@ -1725,15 +1731,32 @@ static void test_sample_grabber(void)
hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler); hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count); hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
todo_wine {
ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
ok(count == 0, "Unexpected count %u.\n", count); ok(count == 0, "Unexpected count %u.\n", count);
}
ok(handler == handler2, "Unexpected handler.\n"); ok(handler == handler2, "Unexpected handler.\n");
IMFMediaTypeHandler_Release(handler); IMFMediaTypeHandler_Release(handler);
IMFMediaTypeHandler_Release(handler2); IMFMediaTypeHandler_Release(handler2);
/* Set clock. */
hr = MFCreatePresentationClock(&clock);
ok(hr == S_OK, "Failed to create clock object, hr %#x.\n", hr);
hr = IMFMediaSink_SetPresentationClock(sink, clock);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
hr = MFCreateSystemTimeSource(&time_source);
ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
hr = IMFPresentationClock_SetTimeSource(clock, time_source);
ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
IMFPresentationTimeSource_Release(time_source);
hr = IMFMediaSink_SetPresentationClock(sink, clock);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
IMFPresentationClock_Release(clock);
hr = IMFActivate_ShutdownObject(activate); hr = IMFActivate_ShutdownObject(activate);
todo_wine todo_wine
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
@ -1768,20 +1791,102 @@ todo_wine
hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler); hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
/* On Win8+ this initialization happens automatically. */
hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count); hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
todo_wine {
ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr); ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
ok(count == 0, "Unexpected count %u.\n", count); ok(count == 0, "Unexpected count %u.\n", count);
}
hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
ok(media_type2 == media_type, "Unexpected media type.\n");
IMFMediaType_Release(media_type2);
hr = MFCreateMediaType(&media_type2);
ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
IMFMediaType_Release(media_type);
hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
ok(media_type2 == media_type, "Unexpected media type.\n");
IMFMediaType_Release(media_type);
hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = MFCreateMediaType(&media_type);
ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
media_type3 = (void *)0xdeadbeef;
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 1024);
ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
media_type3 = (void *)0xdeadbeef;
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
IMFMediaTypeHandler_Release(handler); IMFMediaTypeHandler_Release(handler);
IMFMediaType_Release(media_type2);
IMFMediaType_Release(media_type);
IMFMediaSink_Release(sink); IMFMediaSink_Release(sink);
IMFStreamSink_Release(stream); IMFStreamSink_Release(stream);
refcount = IMFActivate_Release(activate); refcount = IMFActivate_Release(activate);
ok(!refcount, "Unexpected refcount %u.\n", refcount); ok(!refcount, "Unexpected refcount %u.\n", refcount);
IMFMediaType_Release(media_type); hr = MFShutdown();
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
} }
START_TEST(mf) START_TEST(mf)