From 24e90e4350c61ad6f967b1510928e27708ab061e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov <nsivov@codeweavers.com> Date: Mon, 29 Aug 2022 22:56:15 +0300 Subject: [PATCH] evr/filter: Implement pin's connect/disconnect. Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/evr/evr.c | 86 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/dlls/evr/evr.c b/dlls/evr/evr.c index 2f0eeb6a22d..d45bd361aff 100644 --- a/dlls/evr/evr.c +++ b/dlls/evr/evr.c @@ -224,6 +224,64 @@ static void evr_release_services(struct evr *filter) } } +static HRESULT evr_test_input_type(struct evr *filter, const AM_MEDIA_TYPE *mt, IMFMediaType **ret) +{ + IMFMediaType *media_type; + HRESULT hr = S_OK; + + if (!filter->presenter) + hr = evr_initialize(filter, NULL, NULL); + + if (SUCCEEDED(hr)) + hr = evr_init_services(filter); + + if (SUCCEEDED(hr)) + hr = MFCreateMediaType(&media_type); + + if (SUCCEEDED(hr)) + { + if (SUCCEEDED(hr = MFInitMediaTypeFromAMMediaType(media_type, mt))) + { + /* TODO: some pin -> mixer input mapping is necessary to test the substreams. */ + if (SUCCEEDED(hr = IMFTransform_SetInputType(filter->mixer, 0, media_type, MFT_SET_TYPE_TEST_ONLY))) + { + if (ret) + IMFMediaType_AddRef((*ret = media_type)); + } + } + + IMFMediaType_Release(media_type); + } + + return hr; +} + +static HRESULT evr_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt) +{ + struct evr *filter = impl_from_strmbase_renderer(iface); + IMFMediaType *media_type; + HRESULT hr; + + if (SUCCEEDED(hr = evr_test_input_type(filter, mt, &media_type))) + { + if (SUCCEEDED(hr = IMFTransform_SetInputType(filter->mixer, 0, media_type, 0))) + hr = IMFVideoPresenter_ProcessMessage(filter->presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0); + + IMFMediaType_Release(media_type); + } + + return hr; +} + +static void evr_disconnect(struct strmbase_renderer *iface) +{ + struct evr *filter = impl_from_strmbase_renderer(iface); + + if (filter->mixer) + IMFTransform_SetInputType(filter->mixer, 0, NULL, 0); + evr_release_services(filter); +} + static void evr_destroy(struct strmbase_renderer *iface) { struct evr *filter = impl_from_strmbase_renderer(iface); @@ -242,32 +300,12 @@ static HRESULT evr_render(struct strmbase_renderer *iface, IMediaSample *sample) static HRESULT evr_query_accept(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt) { struct evr *filter = impl_from_strmbase_renderer(iface); - IMFMediaType *media_type; - HRESULT hr = S_OK; + HRESULT hr; EnterCriticalSection(&filter->renderer.filter.filter_cs); - if (!filter->presenter) - hr = evr_initialize(filter, NULL, NULL); - - if (SUCCEEDED(hr)) - hr = evr_init_services(filter); - - if (SUCCEEDED(hr)) - hr = MFCreateMediaType(&media_type); - - if (SUCCEEDED(hr)) - { - if (SUCCEEDED(hr = MFInitMediaTypeFromAMMediaType(media_type, mt))) - { - /* TODO: some pin -> mixer input mapping is necessary to test the substreams. */ - hr = IMFTransform_SetInputType(filter->mixer, 0, media_type, MFT_SET_TYPE_TEST_ONLY); - } - - IMFMediaType_Release(media_type); - - evr_release_services(filter); - } + hr = evr_test_input_type(filter, mt, NULL); + evr_release_services(filter); LeaveCriticalSection(&filter->renderer.filter.filter_cs); @@ -279,6 +317,8 @@ static const struct strmbase_renderer_ops renderer_ops = .renderer_query_accept = evr_query_accept, .renderer_render = evr_render, .renderer_query_interface = evr_query_interface, + .renderer_connect = evr_connect, + .renderer_disconnect = evr_disconnect, .renderer_destroy = evr_destroy, };