From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/quartz/Makefile.in | 1 + dlls/quartz/colorconv.c | 83 +++++++++++++++++++++++++++++++++++ dlls/quartz/main.c | 44 +++++++++++++++++++ dlls/quartz/quartz_private.h | 1 + dlls/quartz/quartz_strmif.idl | 7 +++ dlls/quartz/tests/colorconv.c | 32 +------------- 6 files changed, 137 insertions(+), 31 deletions(-) create mode 100644 dlls/quartz/colorconv.c diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index a61bbc2b5fa..1e38b24ef73 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -9,6 +9,7 @@ VER_OLESELFREGISTER = 1 SOURCES = \ acmwrapper.c \ avidec.c \ + colorconv.c \ control_tlb.idl \ decoder.c \ dsoundrender.c \ diff --git a/dlls/quartz/colorconv.c b/dlls/quartz/colorconv.c new file mode 100644 index 00000000000..934462a345d --- /dev/null +++ b/dlls/quartz/colorconv.c @@ -0,0 +1,83 @@ +/* + * Color converter + * + * Copyright 2026 Brendan McGrath + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "quartz_private.h" + +#include "vfw.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +struct color_converter +{ + struct strmbase_filter filter; +}; + +static struct color_converter *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct color_converter, filter); +} + +static struct strmbase_pin *color_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + return NULL; +} + +static void color_destroy(struct strmbase_filter *iface) +{ + struct color_converter *filter = impl_from_strmbase_filter(iface); + + strmbase_filter_cleanup(&filter->filter); + free(filter); +} + +static HRESULT color_init_stream(struct strmbase_filter *iface) +{ + return S_OK; +} + +static HRESULT color_cleanup_stream(struct strmbase_filter *iface) +{ + return S_OK; +} + +static const struct strmbase_filter_ops filter_ops = +{ + .filter_get_pin = color_get_pin, + .filter_destroy = color_destroy, + .filter_init_stream = color_init_stream, + .filter_cleanup_stream = color_cleanup_stream, +}; + +HRESULT color_create(IUnknown *outer, IUnknown **out) +{ + struct color_converter *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + strmbase_filter_init(&object->filter, outer, &CLSID_Colour, &filter_ops); + + TRACE("Created Color Converter %p.\n", object); + *out = &object->filter.IUnknown_inner; + + return S_OK; +} diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index d8da7bde5fa..d38ace1eb20 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -93,6 +93,7 @@ static const struct object_creation_info object_creation[] = { &CLSID_AudioRender, dsound_render_create }, { &CLSID_AVIDec, avi_dec_create }, { &CLSID_AviSplitter, avi_splitter_create }, + { &CLSID_Colour, color_create }, { &CLSID_CMpegAudioCodec, mpeg_audio_codec_create }, { &CLSID_CMpegVideoCodec, mpeg_video_codec_create }, { &CLSID_DSoundRender, dsound_render_create }, @@ -353,6 +354,44 @@ HRESULT WINAPI DllRegisterServer(void) .rgPins2 = acm_wrapper_pins, }; + static const REGPINTYPES color_inputs[] = + { + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB8}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB555}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB565}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB24}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB32}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_ARGB32}, + }; + static const REGPINTYPES color_outputs[] = + { + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB8}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB555}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB565}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB24}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_RGB32}, + {&MEDIATYPE_Video, &MEDIASUBTYPE_ARGB32}, + }; + static const REGFILTERPINS2 color_pins[] = + { + { + .nMediaTypes = ARRAY_SIZE(color_inputs), + .lpMediaType = color_inputs, + }, + { + .nMediaTypes = ARRAY_SIZE(color_outputs), + .lpMediaType = color_outputs, + .dwFlags = REG_PINFLAG_B_OUTPUT, + }, + }; + static const REGFILTER2 color_reg = + { + .dwVersion = 2, + .dwMerit = MERIT_UNLIKELY + 1, + .cPins2 = ARRAY_SIZE(color_pins), + .rgPins2 = color_pins, + }; + static const REGPINTYPES mpeg_splitter_inputs[] = { {&MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio}, @@ -542,6 +581,9 @@ HRESULT WINAPI DllRegisterServer(void) if (FAILED(hr = IFilterMapper2_RegisterFilter(mapper, &CLSID_ACMWrapper, L"ACM Wrapper", NULL, &CLSID_LegacyAmFilterCategory, NULL, &acm_wrapper_reg))) goto done; + if (FAILED(hr = IFilterMapper2_RegisterFilter(mapper, &CLSID_Colour, L"Color Space Converter", NULL, + &CLSID_LegacyAmFilterCategory, NULL, &color_reg))) + goto done; if (FAILED(hr = IFilterMapper2_RegisterFilter(mapper, &CLSID_AviSplitter, L"AVI Splitter", NULL, NULL, NULL, &avi_splitter_reg))) goto done; @@ -589,6 +631,8 @@ HRESULT WINAPI DllUnregisterServer(void) goto done; if (FAILED(hr = IFilterMapper2_UnregisterFilter(mapper, &CLSID_LegacyAmFilterCategory, NULL, &CLSID_ACMWrapper))) goto done; + if (FAILED(hr = IFilterMapper2_UnregisterFilter(mapper, &CLSID_LegacyAmFilterCategory, NULL, &CLSID_Colour))) + goto done; if (FAILED(hr = IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_AviSplitter))) goto done; if (FAILED(hr = IFilterMapper2_UnregisterFilter(mapper, NULL, NULL, &CLSID_MPEG1Splitter))) diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index e683dc51cdc..7c8e296d43c 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -54,6 +54,7 @@ HRESULT acm_wrapper_create(IUnknown *outer, IUnknown **out); HRESULT async_reader_create(IUnknown *outer, IUnknown **out); HRESULT avi_dec_create(IUnknown *outer, IUnknown **out); HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out); +HRESULT color_create(IUnknown *outer, IUnknown **out); HRESULT dsound_render_create(IUnknown *outer, IUnknown **out); HRESULT filter_graph_create(IUnknown *outer, IUnknown **out); HRESULT filter_graph_no_thread_create(IUnknown *outer, IUnknown **out); diff --git a/dlls/quartz/quartz_strmif.idl b/dlls/quartz/quartz_strmif.idl index ad63352ff07..e9469e1be80 100644 --- a/dlls/quartz/quartz_strmif.idl +++ b/dlls/quartz/quartz_strmif.idl @@ -91,6 +91,13 @@ coclass AsyncReader { interface IBaseFilter; } ] coclass AVIDec { interface IBaseFilter; } +[ + helpstring("Color Space Converter"), + threading(both), + uuid(1643e180-90f5-11ce-97d5-00aa0055595a) +] +coclass Colour { interface IBaseFilter; } + [ helpstring("DirectSound Audio Renderer"), threading(both), diff --git a/dlls/quartz/tests/colorconv.c b/dlls/quartz/tests/colorconv.c index cb8a2ee4fac..f1ceba3f61c 100644 --- a/dlls/quartz/tests/colorconv.c +++ b/dlls/quartz/tests/colorconv.c @@ -806,12 +806,7 @@ static void test_registration(void) int i, j; hr = create_color_conv_property_bag(&property_bag); - - if (hr != S_OK) - { - skip("Skipping registration tests.\n"); - return; - } + ok(hr == S_OK, "Got hr %#lx.\n", hr); VariantInit(&var); hr = IPropertyBag_Read(property_bag, L"FilterData", &var, NULL); @@ -885,12 +880,8 @@ static void test_interfaces(void) IPin *pin; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; - check_interface(filter, &IID_IBaseFilter, TRUE); check_interface(filter, &IID_IMediaFilter, TRUE); check_interface(filter, &IID_IPersist, TRUE); @@ -1052,10 +1043,7 @@ static void test_enum_pins(void) HRESULT hr; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; refcount = get_refcount(filter); ok(refcount == 1, "Got refcount %ld.\n", refcount); @@ -1181,10 +1169,7 @@ static void test_find_pin(void) HRESULT hr; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = IBaseFilter_EnumPins(filter, &enum_pins); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -1227,10 +1212,7 @@ static void test_pin_info(void) IPin *pin; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = IBaseFilter_FindPin(filter, L"In", &pin); todo_wine @@ -1316,10 +1298,7 @@ static void test_media_types(void) int i; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = create_filter_graph(&graph); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -1486,10 +1465,7 @@ static void test_enum_media_types(void) IPin *pin; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = IBaseFilter_FindPin(filter, L"In", &pin); todo_wine @@ -1570,10 +1546,7 @@ static void test_unconnected_filter_state(void) ULONG ref; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = IBaseFilter_GetState(filter, 0, &state); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -2311,10 +2284,7 @@ static void test_connect_pin(void) HRESULT hr; hr = create_color_conv(&filter); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) - return; hr = create_filter_graph(&graph); ok(hr == S_OK, "Got hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11679