[PATCH 0/2] MR1050: winegstreamer: Register AAC / WMV decoder MFT stubs.
From: Rémi Bernon <rbernon(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 --- MAINTAINERS | 1 + dlls/mf/tests/transform.c | 9 + dlls/winegstreamer/Makefile.in | 1 + dlls/winegstreamer/aac_decoder.c | 276 +++++++++++++++++++ dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 24 ++ dlls/winegstreamer/winegstreamer_classes.idl | 6 + 7 files changed, 318 insertions(+) create mode 100644 dlls/winegstreamer/aac_decoder.c diff --git a/MAINTAINERS b/MAINTAINERS index 4f0cd37ad5d..73c2a486a91 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -207,6 +207,7 @@ M: Rémi Bernon <rbernon(a)codeweavers.com> P: Nikolay Sivov <nsivov(a)codeweavers.com> P: Zebediah Figura <z.figura12(a)gmail.com> F: dlls/mf/tests/transform.c +F: dlls/winegstreamer/aac_decoder.c F: dlls/winegstreamer/color_convert.c F: dlls/winegstreamer/h264_decoder.c F: dlls/winegstreamer/resampler.c diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index e66baa6e7c9..5ee181e5b0f 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -327,6 +327,7 @@ static void check_mft_get_attributes(IMFTransform *transform, const struct attri ULONG ref; hr = IMFTransform_GetAttributes(transform, &attributes); + todo_wine_if(expect_transform_attributes && hr == E_NOTIMPL) ok(hr == (expect_transform_attributes ? S_OK : E_NOTIMPL), "GetAttributes returned %#lx\n", hr); if (hr == S_OK) { @@ -1940,10 +1941,13 @@ static void test_aac_decoder(void) check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_transform_attributes, FALSE); + todo_wine check_mft_get_input_stream_info(transform, S_OK, &input_info); + todo_wine check_mft_get_output_stream_info(transform, S_OK, &output_info); hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); + todo_wine ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); i = -1; @@ -1957,10 +1961,14 @@ static void test_aac_decoder(void) ok(ret <= 1, "Release returned %lu\n", ret); winetest_pop_context(); } + todo_wine ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + todo_wine ok(i == ARRAY_SIZE(expect_available_inputs) || broken(i == 2) /* w7 */ || broken(i == 4) /* w8 */, "%lu input media types\n", i); + if (hr == E_NOTIMPL) + goto skip_tests; /* setting output media type first doesn't work */ check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); @@ -2053,6 +2061,7 @@ static void test_aac_decoder(void) ret = IMFSample_Release(input_sample); ok(ret == 0, "Release returned %lu\n", ret); +skip_tests: ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret); diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 2245500f0c3..abb11591996 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -7,6 +7,7 @@ UNIX_CFLAGS = $(GSTREAMER_CFLAGS) UNIX_LIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) C_SRCS = \ + aac_decoder.c \ color_convert.c \ h264_decoder.c \ main.c \ diff --git a/dlls/winegstreamer/aac_decoder.c b/dlls/winegstreamer/aac_decoder.c new file mode 100644 index 00000000000..5573166b2db --- /dev/null +++ b/dlls/winegstreamer/aac_decoder.c @@ -0,0 +1,276 @@ +/* AAC Decoder Transform + * + * Copyright 2022 Rémi Bernon for CodeWeavers + * + * 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 "gst_private.h" + +#include "mfapi.h" +#include "mferror.h" +#include "mfobjects.h" +#include "mftransform.h" +#include "wmcodecdsp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +struct aac_decoder +{ + IMFTransform IMFTransform_iface; + LONG refcount; +}; + +static struct aac_decoder *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct aac_decoder, IMFTransform_iface); +} + +static HRESULT WINAPI transform_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{ + struct aac_decoder *decoder = impl_from_IMFTransform(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IMFTransform)) + *out = &decoder->IMFTransform_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI transform_AddRef(IMFTransform *iface) +{ + struct aac_decoder *decoder = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&decoder->refcount); + TRACE("iface %p increasing refcount to %lu.\n", decoder, refcount); + return refcount; +} + +static ULONG WINAPI transform_Release(IMFTransform *iface) +{ + struct aac_decoder *decoder = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&decoder->refcount); + + TRACE("iface %p decreasing refcount to %lu.\n", decoder, refcount); + + if (!refcount) + free(decoder); + + return refcount; +} + +static HRESULT WINAPI transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + TRACE("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p.\n", + iface, input_minimum, input_maximum, output_minimum, output_maximum); + *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; + return S_OK; +} + +static HRESULT WINAPI transform_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + TRACE("iface %p, inputs %p, outputs %p.\n", iface, inputs, outputs); + *inputs = *outputs = 1; + return S_OK; +} + +static HRESULT WINAPI transform_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + TRACE("iface %p, input_size %lu, inputs %p, output_size %lu, outputs %p.\n", iface, + input_size, inputs, output_size, outputs); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + TRACE("iface %p, attributes %p.\n", iface, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + TRACE("iface %p, id %#lx, attributes %p.\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + TRACE("iface %p, id %#lx, attributes %p.\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + TRACE("iface %p, id %#lx.\n", iface, id); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + TRACE("iface %p, streams %lu, ids %p.\n", iface, streams, ids); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + FIXME("iface %p, id %#lx, flags %p stub!\n", iface, id, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + FIXME("iface %p, flags %p stub!\n", iface, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + TRACE("iface %p, lower %I64d, upper %I64d.\n", iface, lower, upper); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + FIXME("iface %p, id %#lx, event %p stub!\n", iface, id, event); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param); + return S_OK; +} + +static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + FIXME("iface %p, id %#lx, sample %p, flags %#lx stub!\n", iface, id, sample, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status); + return E_NOTIMPL; +} + +static const IMFTransformVtbl transform_vtbl = +{ + transform_QueryInterface, + transform_AddRef, + transform_Release, + transform_GetStreamLimits, + transform_GetStreamCount, + transform_GetStreamIDs, + transform_GetInputStreamInfo, + transform_GetOutputStreamInfo, + transform_GetAttributes, + transform_GetInputStreamAttributes, + transform_GetOutputStreamAttributes, + transform_DeleteInputStream, + transform_AddInputStreams, + transform_GetInputAvailableType, + transform_GetOutputAvailableType, + transform_SetInputType, + transform_SetOutputType, + transform_GetInputCurrentType, + transform_GetOutputCurrentType, + transform_GetInputStatus, + transform_GetOutputStatus, + transform_SetOutputBounds, + transform_ProcessEvent, + transform_ProcessMessage, + transform_ProcessInput, + transform_ProcessOutput, +}; + +HRESULT aac_decoder_create(REFIID riid, void **ret) +{ + struct aac_decoder *decoder; + + TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret); + + if (!(decoder = calloc(1, sizeof(*decoder)))) + return E_OUTOFMEMORY; + + decoder->IMFTransform_iface.lpVtbl = &transform_vtbl; + decoder->refcount = 1; + + *ret = &decoder->IMFTransform_iface; + TRACE("Created decoder %p\n", *ret); + return S_OK; +} diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index fed5766d3a4..4d2df415e23 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -140,6 +140,7 @@ HRESULT wg_transform_read_quartz(struct wg_transform *transform, struct wg_sampl HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); +HRESULT aac_decoder_create(REFIID riid, void **ret); HRESULT h264_decoder_create(REFIID riid, void **ret); HRESULT video_processor_create(REFIID riid, void **ret); diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 7e83d570f06..997521768a6 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -36,6 +36,7 @@ DEFINE_GUID(DMOVideoFormat_RGB24,D3DFMT_R8G8B8,0x524f,0x11ce,0x9f,0x53,0x00,0x20 DEFINE_GUID(DMOVideoFormat_RGB565,D3DFMT_R5G6B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(DMOVideoFormat_RGB555,D3DFMT_X1R5G5B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); +DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1); struct class_factory { @@ -124,6 +125,7 @@ class_objects[] = { { &CLSID_VideoProcessorMFT, &video_processor_create }, { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, + { &CLSID_MSAACDecMFT, &aac_decoder_create }, { &CLSID_MSH264DecoderMFT, &h264_decoder_create }, }; @@ -161,6 +163,18 @@ HRESULT mfplat_DllRegisterServer(void) {MFMediaType_Audio, MFAudioFormat_Float}, }; + MFT_REGISTER_TYPE_INFO aac_decoder_input_types[] = + { + {MFMediaType_Audio, MFAudioFormat_AAC}, + {MFMediaType_Audio, MFAudioFormat_RAW_AAC}, + {MFMediaType_Audio, MFAudioFormat_ADTS}, + }; + MFT_REGISTER_TYPE_INFO aac_decoder_output_types[] = + { + {MFMediaType_Audio, MFAudioFormat_Float}, + {MFMediaType_Audio, MFAudioFormat_PCM}, + }; + MFT_REGISTER_TYPE_INFO wma_decoder_input_types[] = { {MFMediaType_Audio, MEDIASUBTYPE_MSAUDIO1}, @@ -294,6 +308,16 @@ HRESULT mfplat_DllRegisterServer(void) } mfts[] = { + { + CLSID_MSAACDecMFT, + MFT_CATEGORY_AUDIO_DECODER, + L"Microsoft AAC Audio Decoder MFT", + MFT_ENUM_FLAG_SYNCMFT, + ARRAY_SIZE(aac_decoder_input_types), + aac_decoder_input_types, + ARRAY_SIZE(aac_decoder_output_types), + aac_decoder_output_types, + }, { CLSID_WMADecMediaObject, MFT_CATEGORY_AUDIO_DECODER, diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl index c95f4135835..0bb88d9cd08 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl @@ -75,6 +75,12 @@ coclass GStreamerByteStreamHandler {} ] coclass CWMADecMediaObject {}; +[ + threading(both), + uuid(32d186a7-218f-4c75-8876-dd77273a8999) +] +coclass CMSAACDecMFT {} + [ threading(both), uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1050
From: Rémi Bernon <rbernon(a)codeweavers.com> --- MAINTAINERS | 1 + dlls/mf/tests/transform.c | 3 + dlls/winegstreamer/Makefile.in | 3 +- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/main.c | 34 ++ dlls/winegstreamer/mfplat.c | 38 ++ dlls/winegstreamer/winegstreamer_classes.idl | 6 + dlls/winegstreamer/wmv_decoder.c | 608 +++++++++++++++++++ 8 files changed, 693 insertions(+), 1 deletion(-) create mode 100644 dlls/winegstreamer/wmv_decoder.c diff --git a/MAINTAINERS b/MAINTAINERS index 73c2a486a91..f7669c09b97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -215,6 +215,7 @@ F: dlls/winegstreamer/video_processor.c F: dlls/winegstreamer/wg_sample.c F: dlls/winegstreamer/wg_transform.c F: dlls/winegstreamer/wma_decoder.c +F: dlls/winegstreamer/wmv_decoder.c Microsoft C Runtime M: Piotr Caban <piotr(a)codeweavers.com> diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 5ee181e5b0f..d2bd2b9a065 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -344,6 +344,7 @@ static void check_mft_get_attributes(IMFTransform *transform, const struct attri } hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes); + todo_wine_if(expect_output_attributes && hr == E_NOTIMPL) ok(hr == (expect_output_attributes ? S_OK : E_NOTIMPL) || broken(hr == MF_E_UNSUPPORTED_REPRESENTATION) /* Win7 */, "GetOutputStreamAttributes returned %#lx\n", hr); @@ -4401,7 +4402,9 @@ static void test_wmv_decoder(void) check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_attributes, TRUE); + todo_wine check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL); + todo_wine check_mft_get_output_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, &empty_output_info); hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index abb11591996..3daa929b36d 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -24,7 +24,8 @@ C_SRCS = \ wg_transform.c \ wm_asyncreader.c \ wm_reader.c \ - wma_decoder.c + wma_decoder.c \ + wmv_decoder.c IDL_SRCS = \ winegstreamer_classes.idl diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 4d2df415e23..2ec07dbf5b0 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -112,6 +112,7 @@ HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out); HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out); HRESULT wave_parser_create(IUnknown *outer, IUnknown **out); HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out); +HRESULT wmv_decoder_create(IUnknown *outer, IUnknown **out); HRESULT resampler_create(IUnknown *outer, IUnknown **out); HRESULT color_convert_create(IUnknown *outer, IUnknown **out); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 40507a4b929..2efa3bd26ac 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -34,6 +34,7 @@ static unixlib_handle_t unix_handle; WINE_DEFAULT_DEBUG_CHANNEL(quartz); DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +DEFINE_GUID(MEDIASUBTYPE_VC1S,MAKEFOURCC('V','C','1','S'),0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); bool array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { @@ -452,6 +453,7 @@ static struct class_factory mpeg_audio_codec_cf = {{&class_factory_vtbl}, mpeg_a static struct class_factory mpeg_splitter_cf = {{&class_factory_vtbl}, mpeg_splitter_create}; static struct class_factory wave_parser_cf = {{&class_factory_vtbl}, wave_parser_create}; static struct class_factory wma_decoder_cf = {{&class_factory_vtbl}, wma_decoder_create}; +static struct class_factory wmv_decoder_cf = {{&class_factory_vtbl}, wmv_decoder_create}; static struct class_factory resampler_cf = {{&class_factory_vtbl}, resampler_create}; static struct class_factory color_convert_cf = {{&class_factory_vtbl}, color_convert_create}; @@ -480,6 +482,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) factory = &wave_parser_cf; else if (IsEqualGUID(clsid, &CLSID_WMADecMediaObject)) factory = &wma_decoder_cf; + else if (IsEqualGUID(clsid, &CLSID_WMVDecoderMFT)) + factory = &wmv_decoder_cf; else if (IsEqualGUID(clsid, &CLSID_CResamplerMediaObject)) factory = &resampler_cf; else if (IsEqualGUID(clsid, &CLSID_CColorConvertDMO)) @@ -695,6 +699,31 @@ HRESULT WINAPI DllRegisterServer(void) {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_WMAUDIO3}, {.type = MEDIATYPE_Audio, .subtype = MEDIASUBTYPE_WMAUDIO_LOSSLESS}, }; + DMO_PARTIAL_MEDIATYPE wmv_decoder_output[11] = + { + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YV12}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YUY2}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_UYVY}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YVYU}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV11}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_NV12}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB32}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB24}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB565}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB555}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_RGB8}, + }; + DMO_PARTIAL_MEDIATYPE wmv_decoder_input[8] = + { + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV1}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV2}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMV3}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMVA}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WVC1}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WMVP}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_WVP2}, + {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_VC1S}, + }; DMO_PARTIAL_MEDIATYPE color_convert_input[20] = { {.type = MEDIATYPE_Video, .subtype = MEDIASUBTYPE_YV12}, @@ -764,6 +793,9 @@ HRESULT WINAPI DllRegisterServer(void) if (FAILED(hr = DMORegister(L"WMAudio Decoder DMO", &CLSID_WMADecMediaObject, &DMOCATEGORY_AUDIO_DECODER, 0, ARRAY_SIZE(wma_decoder_input), wma_decoder_input, ARRAY_SIZE(wma_decoder_output), wma_decoder_output))) return hr; + if (FAILED(hr = DMORegister(L"WMVideo Decoder DMO", &CLSID_WMVDecoderMFT, &DMOCATEGORY_VIDEO_DECODER, + 0, ARRAY_SIZE(wmv_decoder_input), wmv_decoder_input, ARRAY_SIZE(wmv_decoder_output), wmv_decoder_output))) + return hr; if (FAILED(hr = DMORegister(L"Resampler DMO", &CLSID_CResamplerMediaObject, &DMOCATEGORY_AUDIO_EFFECT, 0, ARRAY_SIZE(audio_convert_types), audio_convert_types, ARRAY_SIZE(audio_convert_types), audio_convert_types))) return hr; @@ -802,6 +834,8 @@ HRESULT WINAPI DllUnregisterServer(void) return hr; if (FAILED(hr = DMOUnregister(&CLSID_WMADecMediaObject, &DMOCATEGORY_AUDIO_DECODER))) return hr; + if (FAILED(hr = DMOUnregister(&CLSID_WMVDecoderMFT, &DMOCATEGORY_VIDEO_DECODER))) + return hr; return S_OK; } diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 997521768a6..9e6a43a3414 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -37,6 +37,7 @@ DEFINE_GUID(DMOVideoFormat_RGB565,D3DFMT_R5G6B5,0x524f,0x11ce,0x9f,0x53,0x00,0x2 DEFINE_GUID(DMOVideoFormat_RGB555,D3DFMT_X1R5G5B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S,MAKEFOURCC('V','C','1','S')); struct class_factory { @@ -252,6 +253,33 @@ HRESULT mfplat_DllRegisterServer(void) {MFMediaType_Video, MFVideoFormat_YVYU}, }; + MFT_REGISTER_TYPE_INFO wmv_decoder_input_types[] = + { + {MFMediaType_Video, MFVideoFormat_WMV1}, + {MFMediaType_Video, MFVideoFormat_WMV2}, + {MFMediaType_Video, MFVideoFormat_WMV3}, + {MFMediaType_Video, MEDIASUBTYPE_WMVP}, + {MFMediaType_Video, MEDIASUBTYPE_WVP2}, + {MFMediaType_Video, MEDIASUBTYPE_WMVR}, + {MFMediaType_Video, MEDIASUBTYPE_WMVA}, + {MFMediaType_Video, MFVideoFormat_WVC1}, + {MFMediaType_Video, MFVideoFormat_VC1S}, + }; + MFT_REGISTER_TYPE_INFO wmv_decoder_output_types[] = + { + {MFMediaType_Video, MFVideoFormat_YV12}, + {MFMediaType_Video, MFVideoFormat_YUY2}, + {MFMediaType_Video, MFVideoFormat_UYVY}, + {MFMediaType_Video, MFVideoFormat_YVYU}, + {MFMediaType_Video, MFVideoFormat_NV11}, + {MFMediaType_Video, MFVideoFormat_NV12}, + {MFMediaType_Video, DMOVideoFormat_RGB32}, + {MFMediaType_Video, DMOVideoFormat_RGB24}, + {MFMediaType_Video, DMOVideoFormat_RGB565}, + {MFMediaType_Video, DMOVideoFormat_RGB555}, + {MFMediaType_Video, DMOVideoFormat_RGB8}, + }; + MFT_REGISTER_TYPE_INFO color_convert_input_types[] = { {MFMediaType_Video, MFVideoFormat_YV12}, @@ -338,6 +366,16 @@ HRESULT mfplat_DllRegisterServer(void) ARRAY_SIZE(h264_decoder_output_types), h264_decoder_output_types, }, + { + CLSID_WMVDecoderMFT, + MFT_CATEGORY_VIDEO_DECODER, + L"WMVideo Decoder MFT", + MFT_ENUM_FLAG_SYNCMFT, + ARRAY_SIZE(wmv_decoder_input_types), + wmv_decoder_input_types, + ARRAY_SIZE(wmv_decoder_output_types), + wmv_decoder_output_types, + }, { CLSID_VideoProcessorMFT, MFT_CATEGORY_VIDEO_PROCESSOR, diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl index 0bb88d9cd08..ae258f1c2ec 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl @@ -81,6 +81,12 @@ coclass CWMADecMediaObject {}; ] coclass CMSAACDecMFT {} +[ + threading(both), + uuid(82d353df-90bd-4382-8bc2-3f6192b76e34) +] +coclass CWMVDecMediaObject {} + [ threading(both), uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c new file mode 100644 index 00000000000..6ee21e5b5c1 --- /dev/null +++ b/dlls/winegstreamer/wmv_decoder.c @@ -0,0 +1,608 @@ +/* Copyright 2022 Rémi Bernon for CodeWeavers + * + * 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 "gst_private.h" + +#include "mfapi.h" +#include "mferror.h" +#include "mfobjects.h" +#include "mftransform.h" +#include "wmcodecdsp.h" +#include "initguid.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +struct wmv_decoder +{ + IUnknown IUnknown_inner; + IMFTransform IMFTransform_iface; + IMediaObject IMediaObject_iface; + IPropertyBag IPropertyBag_iface; + IPropertyStore IPropertyStore_iface; + IUnknown *outer; + LONG refcount; +}; + +static inline struct wmv_decoder *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct wmv_decoder, IUnknown_inner); +} + +static HRESULT WINAPI unknown_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + struct wmv_decoder *impl = impl_from_IUnknown(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown)) + *out = &impl->IUnknown_inner; + else if (IsEqualGUID(iid, &IID_IMFTransform)) + *out = &impl->IMFTransform_iface; + else if (IsEqualGUID(iid, &IID_IMediaObject)) + *out = &impl->IMediaObject_iface; + else if (IsEqualIID(iid, &IID_IPropertyBag)) + *out = &impl->IPropertyBag_iface; + else if (IsEqualIID(iid, &IID_IPropertyStore)) + *out = &impl->IPropertyStore_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI unknown_AddRef(IUnknown *iface) +{ + struct wmv_decoder *impl = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&impl->refcount); + + TRACE("iface %p increasing refcount to %lu.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI unknown_Release(IUnknown *iface) +{ + struct wmv_decoder *impl = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&impl->refcount); + + TRACE("iface %p decreasing refcount to %lu.\n", iface, refcount); + + if (!refcount) + free(impl); + + return refcount; +} + +static const IUnknownVtbl unknown_vtbl = +{ + unknown_QueryInterface, + unknown_AddRef, + unknown_Release, +}; + +static struct wmv_decoder *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct wmv_decoder, IMFTransform_iface); +} + +static HRESULT WINAPI transform_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{ + return IUnknown_QueryInterface(impl_from_IMFTransform(iface)->outer, iid, out); +} + +static ULONG WINAPI transform_AddRef(IMFTransform *iface) +{ + return IUnknown_AddRef(impl_from_IMFTransform(iface)->outer); +} + +static ULONG WINAPI transform_Release(IMFTransform *iface) +{ + return IUnknown_Release(impl_from_IMFTransform(iface)->outer); +} + +static HRESULT WINAPI transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + TRACE("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p.\n", + iface, input_minimum, input_maximum, output_minimum, output_maximum); + *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; + return S_OK; +} + +static HRESULT WINAPI transform_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + TRACE("iface %p, inputs %p, outputs %p.\n", iface, inputs, outputs); + *inputs = *outputs = 1; + return S_OK; +} + +static HRESULT WINAPI transform_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + TRACE("iface %p, input_size %lu, inputs %p, output_size %lu, outputs %p.\n", iface, + input_size, inputs, output_size, outputs); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + FIXME("iface %p, attributes %p stub!\n", iface, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + TRACE("iface %p, id %#lx, attributes %p.\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + FIXME("iface %p, id %#lx, attributes %p stub!\n", iface, id, attributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + TRACE("iface %p, id %#lx.\n", iface, id); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + TRACE("iface %p, streams %lu, ids %p.\n", iface, streams, ids); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, index %lu, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, index %lu, type %p stub!\n", iface, id, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + FIXME("iface %p, id %#lx, flags %p stub!\n", iface, id, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + FIXME("iface %p, flags %p stub!\n", iface, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + TRACE("iface %p, lower %I64d, upper %I64d.\n", iface, lower, upper); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + FIXME("iface %p, id %#lx, event %p stub!\n", iface, id, event); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("iface %p, message %#x, param %#Ix stub!\n", iface, message, param); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + FIXME("iface %p, id %#lx, sample %p, flags %#lx stub!\n", iface, id, sample, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status); + return E_NOTIMPL; +} + +static const IMFTransformVtbl transform_vtbl = +{ + transform_QueryInterface, + transform_AddRef, + transform_Release, + transform_GetStreamLimits, + transform_GetStreamCount, + transform_GetStreamIDs, + transform_GetInputStreamInfo, + transform_GetOutputStreamInfo, + transform_GetAttributes, + transform_GetInputStreamAttributes, + transform_GetOutputStreamAttributes, + transform_DeleteInputStream, + transform_AddInputStreams, + transform_GetInputAvailableType, + transform_GetOutputAvailableType, + transform_SetInputType, + transform_SetOutputType, + transform_GetInputCurrentType, + transform_GetOutputCurrentType, + transform_GetInputStatus, + transform_GetOutputStatus, + transform_SetOutputBounds, + transform_ProcessEvent, + transform_ProcessMessage, + transform_ProcessInput, + transform_ProcessOutput, +}; + +static inline struct wmv_decoder *impl_from_IMediaObject(IMediaObject *iface) +{ + return CONTAINING_RECORD(iface, struct wmv_decoder, IMediaObject_iface); +} + +static HRESULT WINAPI media_object_QueryInterface(IMediaObject *iface, REFIID iid, void **obj) +{ + return IUnknown_QueryInterface(impl_from_IMediaObject(iface)->outer, iid, obj); +} + +static ULONG WINAPI media_object_AddRef(IMediaObject *iface) +{ + return IUnknown_AddRef(impl_from_IMediaObject(iface)->outer); +} + +static ULONG WINAPI media_object_Release(IMediaObject *iface) +{ + return IUnknown_Release(impl_from_IMediaObject(iface)->outer); +} + +static HRESULT WINAPI media_object_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output) +{ + FIXME("iface %p, input %p, output %p stub!\n", iface, input, output); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + FIXME("iface %p, index %lu, flags %p stub!\n", iface, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{ + FIXME("iface %p, index %lu, flags %p stub!\n", iface, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, + DMO_MEDIA_TYPE *type) +{ + FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface, index, type_index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, + DMO_MEDIA_TYPE *type) +{ + FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface, index, type_index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index, + const DMO_MEDIA_TYPE *type, DWORD flags) +{ + FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface, index, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD index, + const DMO_MEDIA_TYPE *type, DWORD flags) +{ + FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface, index, type, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{ + FIXME("iface %p, index %lu, type %p stub!\n", iface, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{ + FIXME("iface %p, index %lu, type %p stub!\n", iface, index, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, + DWORD *lookahead, DWORD *alignment) +{ + FIXME("iface %p, index %lu, size %p, lookahead %p, alignment %p stub!\n", iface, index, size, + lookahead, alignment); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) +{ + FIXME("iface %p, index %lu, size %p, alignment %p stub!\n", iface, index, size, alignment); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) +{ + FIXME("iface %p, index %lu, latency %p stub!\n", iface, index, latency); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency) +{ + FIXME("iface %p, index %lu, latency %s stub!\n", iface, index, wine_dbgstr_longlong(latency)); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_Flush(IMediaObject *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_Discontinuity(IMediaObject *iface, DWORD index) +{ + FIXME("iface %p, index %lu stub!\n", iface, index); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_AllocateStreamingResources(IMediaObject *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_FreeStreamingResources(IMediaObject *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags) +{ + FIXME("iface %p, index %lu, flags %p stub!\n", iface, index, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_ProcessInput(IMediaObject *iface, DWORD index, + IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength) +{ + FIXME("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s stub!\n", iface, + index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(timelength)); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_ProcessOutput(IMediaObject *iface, DWORD flags, DWORD count, + DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status) +{ + FIXME("iface %p, flags %#lx, count %lu, buffers %p, status %p stub!\n", iface, flags, count, buffers, status); + return E_NOTIMPL; +} + +static HRESULT WINAPI media_object_Lock(IMediaObject *iface, LONG lock) +{ + FIXME("iface %p, lock %ld stub!\n", iface, lock); + return E_NOTIMPL; +} + +static const IMediaObjectVtbl media_object_vtbl = +{ + media_object_QueryInterface, + media_object_AddRef, + media_object_Release, + media_object_GetStreamCount, + media_object_GetInputStreamInfo, + media_object_GetOutputStreamInfo, + media_object_GetInputType, + media_object_GetOutputType, + media_object_SetInputType, + media_object_SetOutputType, + media_object_GetInputCurrentType, + media_object_GetOutputCurrentType, + media_object_GetInputSizeInfo, + media_object_GetOutputSizeInfo, + media_object_GetInputMaxLatency, + media_object_SetInputMaxLatency, + media_object_Flush, + media_object_Discontinuity, + media_object_AllocateStreamingResources, + media_object_FreeStreamingResources, + media_object_GetInputStatus, + media_object_ProcessInput, + media_object_ProcessOutput, + media_object_Lock, +}; + +static inline struct wmv_decoder *impl_from_IPropertyBag(IPropertyBag *iface) +{ + return CONTAINING_RECORD(iface, struct wmv_decoder, IPropertyBag_iface); +} + +static HRESULT WINAPI property_bag_QueryInterface(IPropertyBag *iface, REFIID iid, void **out) +{ + return IUnknown_QueryInterface(impl_from_IPropertyBag(iface)->outer, iid, out); +} + +static ULONG WINAPI property_bag_AddRef(IPropertyBag *iface) +{ + return IUnknown_AddRef(impl_from_IPropertyBag(iface)->outer); +} + +static ULONG WINAPI property_bag_Release(IPropertyBag *iface) +{ + return IUnknown_Release(impl_from_IPropertyBag(iface)->outer); +} + +static HRESULT WINAPI property_bag_Read(IPropertyBag *iface, const WCHAR *prop_name, VARIANT *value, + IErrorLog *error_log) +{ + FIXME("iface %p, prop_name %s, value %p, error_log %p stub!\n", iface, debugstr_w(prop_name), value, error_log); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_bag_Write(IPropertyBag *iface, const WCHAR *prop_name, VARIANT *value) +{ + FIXME("iface %p, prop_name %s, value %p stub!\n", iface, debugstr_w(prop_name), value); + return S_OK; +} + +static const IPropertyBagVtbl property_bag_vtbl = +{ + property_bag_QueryInterface, + property_bag_AddRef, + property_bag_Release, + property_bag_Read, + property_bag_Write, +}; + +static inline struct wmv_decoder *impl_from_IPropertyStore(IPropertyStore *iface) +{ + return CONTAINING_RECORD(iface, struct wmv_decoder, IPropertyStore_iface); +} + +static HRESULT WINAPI property_store_QueryInterface(IPropertyStore *iface, REFIID iid, void **out) +{ + return IUnknown_QueryInterface(impl_from_IPropertyStore(iface)->outer, iid, out); +} + +static ULONG WINAPI property_store_AddRef(IPropertyStore *iface) +{ + return IUnknown_AddRef(impl_from_IPropertyStore(iface)->outer); +} + +static ULONG WINAPI property_store_Release(IPropertyStore *iface) +{ + return IUnknown_Release(impl_from_IPropertyStore(iface)->outer); +} + +static HRESULT WINAPI property_store_GetCount(IPropertyStore *iface, DWORD *count) +{ + FIXME("iface %p, count %p stub!\n", iface, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_store_GetAt(IPropertyStore *iface, DWORD index, PROPERTYKEY *key) +{ + FIXME("iface %p, index %lu, key %p stub!\n", iface, index, key); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_store_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *value) +{ + FIXME("iface %p, key %p, value %p stub!\n", iface, key, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_store_SetValue(IPropertyStore *iface, REFPROPERTYKEY key, REFPROPVARIANT value) +{ + FIXME("iface %p, key %p, value %p stub!\n", iface, key, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI property_store_Commit(IPropertyStore *iface) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static const IPropertyStoreVtbl property_store_vtbl = +{ + property_store_QueryInterface, + property_store_AddRef, + property_store_Release, + property_store_GetCount, + property_store_GetAt, + property_store_GetValue, + property_store_SetValue, + property_store_Commit, +}; + +HRESULT wmv_decoder_create(IUnknown *outer, IUnknown **out) +{ + struct wmv_decoder *impl; + + TRACE("outer %p, out %p.\n", outer, out); + + if (!(impl = calloc(1, sizeof(*impl)))) + return E_OUTOFMEMORY; + + impl->IUnknown_inner.lpVtbl = &unknown_vtbl; + impl->IMFTransform_iface.lpVtbl = &transform_vtbl; + impl->IMediaObject_iface.lpVtbl = &media_object_vtbl; + impl->IPropertyBag_iface.lpVtbl = &property_bag_vtbl; + impl->IPropertyStore_iface.lpVtbl = &property_store_vtbl; + impl->refcount = 1; + impl->outer = outer ? outer : &impl->IUnknown_inner; + + *out = &impl->IUnknown_inner; + TRACE("Created %p\n", *out); + return S_OK; +} -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1050
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124944 Your paranoid android. === build (build log) === error: patch failed: dlls/winegstreamer/mfplat.c:37 error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:81 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/winegstreamer/mfplat.c:37 error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:81 Task: Patch failed to apply === debian11 (build log) === error: patch failed: dlls/winegstreamer/mfplat.c:37 error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:81 Task: Patch failed to apply
This merge request was approved by Zebediah Figura. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1050
participants (3)
-
Marvin -
Rémi Bernon -
Zebediah Figura (@zfigura)