From: Derek Lesho Subject: [PATCH] mf/samplegrabber: Evaluate type compatibility by comparison to the initial type. Message-Id: <20201123203437.16143-1-dlesho@codeweavers.com> Date: Mon, 23 Nov 2020 15:34:37 -0500 Signed-off-by: Derek Lesho --- dlls/mf/samplegrabber.c | 9 ++++--- dlls/mf/tests/mf.c | 56 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index 566ee2f2930..aa583e38dc0 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -67,7 +67,7 @@ struct sample_grabber LONG refcount; IMFSampleGrabberSinkCallback *callback; IMFSampleGrabberSinkCallback2 *callback2; - IMFMediaType *media_type; + IMFMediaType *media_type, *base_type; BOOL is_shut_down; IMFMediaEventQueue *event_queue; IMFMediaEventQueue *stream_event_queue; @@ -558,7 +558,7 @@ static ULONG WINAPI sample_grabber_stream_type_handler_Release(IMFMediaTypeHandl static HRESULT sample_grabber_stream_is_media_type_supported(struct sample_grabber *grabber, IMFMediaType *in_type) { - const DWORD supported_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES; + const DWORD supported_flags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA; DWORD flags; if (grabber->is_shut_down) @@ -567,7 +567,7 @@ static HRESULT sample_grabber_stream_is_media_type_supported(struct sample_grabb if (!in_type) return E_POINTER; - if (IMFMediaType_IsEqual(grabber->media_type, in_type, &flags) == S_OK) + if (IMFMediaType_IsEqual(grabber->base_type, in_type, &flags) == S_OK) return S_OK; return (flags & supported_flags) == supported_flags ? S_OK : MF_E_INVALIDMEDIATYPE; @@ -819,6 +819,7 @@ static ULONG WINAPI sample_grabber_sink_Release(IMFMediaSink *iface) if (grabber->callback2) IMFSampleGrabberSinkCallback2_Release(grabber->callback2); IMFMediaType_Release(grabber->media_type); + IMFMediaType_Release(grabber->base_type); if (grabber->event_queue) IMFMediaEventQueue_Release(grabber->event_queue); if (grabber->clock) @@ -1284,6 +1285,8 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use } object->media_type = context->media_type; IMFMediaType_AddRef(object->media_type); + MFCreateMediaType(&object->base_type); + IMFMediaType_CopyAllItems(context->media_type, (IMFAttributes *)object->base_type); IMFAttributes_GetUINT32(attributes, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, &object->ignore_clock); IMFAttributes_GetUINT64(attributes, &MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET, &object->sample_time_offset); list_init(&object->items); diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 43dc9a49ee7..dd3605c1075 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2421,6 +2421,62 @@ static void test_sample_grabber(void) refcount = IMFActivate_Release(activate); ok(!refcount, "Unexpected refcount %u.\n", refcount); + /* IsMediaTypeSupported checks are done against the creation type, and check format data */ + 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 = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate); + ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr); + + hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); + ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream); + ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr); + + hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler); + 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 = 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 = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2); + ok(hr == MF_E_INVALIDMEDIATYPE, "Failed to set media type, hr %#x.\n", hr); + + hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2); + ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr); + + IMFMediaType_Release(media_type2); + IMFMediaType_Release(media_type); + + IMFMediaTypeHandler_Release(handler); + IMFMediaSink_Release(sink); + IMFStreamSink_Release(stream); + + refcount = IMFActivate_Release(activate); + ok(!refcount, "Unexpected refcount %u.\n", refcount); + /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */ hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); -- 2.29.2