[PATCH 7/7] winegstreamer: Add a skeleton MPEG audio decoder filter.

Anton Baskanov baskanov at gmail.com
Mon Apr 25 02:32:13 CDT 2022


Signed-off-by: Anton Baskanov <baskanov at gmail.com>
---
 dlls/quartz/tests/mpegaudio.c                |   6 +-
 dlls/winegstreamer/Makefile.in               |   1 +
 dlls/winegstreamer/gst_private.h             |   1 +
 dlls/winegstreamer/main.c                    |   3 +
 dlls/winegstreamer/quartz_transform.c        | 120 +++++++++++++++++++
 dlls/winegstreamer/winegstreamer_classes.idl |   7 ++
 6 files changed, 135 insertions(+), 3 deletions(-)
 create mode 100644 dlls/winegstreamer/quartz_transform.c

diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c
index d948c2648f2..44e1a9ad2e6 100644
--- a/dlls/quartz/tests/mpegaudio.c
+++ b/dlls/quartz/tests/mpegaudio.c
@@ -28,7 +28,7 @@ static IBaseFilter *create_mpeg_audio_codec(void)
     IBaseFilter *filter = NULL;
     HRESULT hr = CoCreateInstance(&CLSID_CMpegAudioCodec, NULL, CLSCTX_INPROC_SERVER,
             &IID_IBaseFilter, (void **)&filter);
-    todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
     return filter;
 }
 
@@ -156,12 +156,12 @@ static void test_aggregation(void)
     filter = (IBaseFilter *)0xdeadbeef;
     hr = CoCreateInstance(&CLSID_CMpegAudioCodec, &test_outer, CLSCTX_INPROC_SERVER,
             &IID_IBaseFilter, (void **)&filter);
-    todo_wine ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
+    ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
     ok(!filter, "Got interface %p.\n", filter);
 
     hr = CoCreateInstance(&CLSID_CMpegAudioCodec, &test_outer, CLSCTX_INPROC_SERVER,
             &IID_IUnknown, (void **)&unk);
-    todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
     if (FAILED(hr))
     {
         skip("Failed to create MPEG audio decoder instance, skipping tests.\n");
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index 3524cffb399..05b7ffc3c2f 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
 	main.c \
 	media_source.c \
 	mfplat.c \
+	quartz_transform.c \
 	quartz_parser.c \
 	wg_format.c \
 	wg_parser.c \
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index f5da807a2ab..2a4b16079c1 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -103,6 +103,7 @@ unsigned int wg_format_get_max_size(const struct wg_format *format);
 
 HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out);
 HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out);
+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);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index d88a462d81e..a408704cf47 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -431,6 +431,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
 
 static struct class_factory avi_splitter_cf = {{&class_factory_vtbl}, avi_splitter_create};
 static struct class_factory decodebin_parser_cf = {{&class_factory_vtbl}, decodebin_parser_create};
+static struct class_factory mpeg_audio_codec_cf = {{&class_factory_vtbl}, mpeg_audio_codec_create};
 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};
@@ -452,6 +453,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
         factory = &avi_splitter_cf;
     else if (IsEqualGUID(clsid, &CLSID_decodebin_parser))
         factory = &decodebin_parser_cf;
+    else if (IsEqualGUID(clsid, &CLSID_CMpegAudioCodec))
+        factory = &mpeg_audio_codec_cf;
     else if (IsEqualGUID(clsid, &CLSID_MPEG1Splitter))
         factory = &mpeg_splitter_cf;
     else if (IsEqualGUID(clsid, &CLSID_WAVEParser))
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
new file mode 100644
index 00000000000..9665c56d848
--- /dev/null
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -0,0 +1,120 @@
+/*
+ * DirectShow transform filters
+ *
+ * Copyright 2022 Anton Baskanov
+ *
+ * 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"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+struct transform
+{
+    struct strmbase_filter filter;
+
+    struct strmbase_sink sink;
+    struct strmbase_source source;
+};
+
+static inline struct transform *impl_from_strmbase_filter(struct strmbase_filter *iface)
+{
+    return CONTAINING_RECORD(iface, struct transform, filter);
+}
+
+static struct strmbase_pin *transform_get_pin(struct strmbase_filter *iface, unsigned int index)
+{
+    struct transform *filter = impl_from_strmbase_filter(iface);
+    if (index == 0)
+        return &filter->sink.pin;
+    if (index == 1)
+        return &filter->source.pin;
+    return NULL;
+}
+
+static void transform_destroy(struct strmbase_filter *iface)
+{
+    struct transform *filter = impl_from_strmbase_filter(iface);
+
+    strmbase_source_cleanup(&filter->source);
+    strmbase_sink_cleanup(&filter->sink);
+    strmbase_filter_cleanup(&filter->filter);
+
+    free(filter);
+}
+
+static const struct strmbase_filter_ops filter_ops =
+{
+    .filter_get_pin = transform_get_pin,
+    .filter_destroy = transform_destroy,
+};
+
+static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID iid, void **out)
+{
+    struct transform *filter = impl_from_strmbase_filter(pin->filter);
+
+    if (IsEqualGUID(iid, &IID_IMemInputPin))
+        *out = &filter->sink.IMemInputPin_iface;
+    else
+        return E_NOINTERFACE;
+
+    IUnknown_AddRef((IUnknown *)*out);
+    return S_OK;
+}
+
+static const struct strmbase_sink_ops sink_ops =
+{
+    .base.pin_query_interface = transform_sink_query_interface,
+};
+
+static const struct strmbase_source_ops source_ops =
+{
+    .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
+    .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
+};
+
+static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, struct transform **out)
+{
+    struct transform *object;
+
+    object = calloc(1, sizeof(*object));
+    if (!object)
+        return E_OUTOFMEMORY;
+
+    strmbase_filter_init(&object->filter, outer, clsid, &filter_ops);
+    strmbase_sink_init(&object->sink, &object->filter, L"In", &sink_ops, NULL);
+    strmbase_source_init(&object->source, &object->filter, L"Out", &source_ops);
+
+    *out = object;
+    return S_OK;
+}
+
+HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out)
+{
+    struct transform *object;
+    HRESULT hr;
+
+    hr = transform_create(outer, &CLSID_CMpegAudioCodec, &object);
+    if (FAILED(hr))
+        return hr;
+
+    wcscpy(object->sink.pin.name, L"XForm In");
+    wcscpy(object->source.pin.name, L"XForm Out");
+
+    TRACE("Created MPEG audio decoder %p.\n", object);
+    *out = &object->filter.IUnknown_inner;
+    return hr;
+}
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
index 347ee906a52..037f0573b34 100644
--- a/dlls/winegstreamer/winegstreamer_classes.idl
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
@@ -28,6 +28,13 @@
 ]
 coclass AviSplitter {}
 
+[
+    helpstring("MPEG Audio Decoder"),
+    threading(both),
+    uuid(4a2286e0-7bef-11ce-9bd9-0000e202599c)
+]
+coclass CMpegAudioCodec {}
+
 [
     helpstring("MPEG-I Stream Splitter"),
     threading(both),
-- 
2.34.1




More information about the wine-devel mailing list