[PATCH 3/5] winegstreamer: Reject incompatible input media types in MPEG audio decoder.

Anton Baskanov baskanov at gmail.com
Wed Apr 27 01:42:20 CDT 2022


Signed-off-by: Anton Baskanov <baskanov at gmail.com>
---
 dlls/quartz/tests/mpegaudio.c         | 10 ++---
 dlls/winegstreamer/quartz_transform.c | 55 ++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c
index cbf8ef393d2..84297884a6d 100644
--- a/dlls/quartz/tests/mpegaudio.c
+++ b/dlls/quartz/tests/mpegaudio.c
@@ -759,25 +759,25 @@ static void test_media_types(void)
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(pin, &mp3_mt0);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(pin, &mp3_mt1);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     mt = mp2_mt;
     mt.majortype = GUID_NULL;
     hr = IPin_QueryAccept(pin, &mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     mt = mp2_mt;
     mt.subtype = MEDIASUBTYPE_PCM;
     hr = IPin_QueryAccept(pin, &mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     mt = mp2_mt;
     mt.formattype = GUID_NULL;
     hr = IPin_QueryAccept(pin, &mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     IPin_Release(pin);
 
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
index 9665c56d848..698d08a0d2a 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -28,6 +28,13 @@ struct transform
 
     struct strmbase_sink sink;
     struct strmbase_source source;
+
+    const struct transform_ops *ops;
+};
+
+struct transform_ops
+{
+    HRESULT (*sink_query_accept)(struct transform *filter, const AM_MEDIA_TYPE *mt);
 };
 
 static inline struct transform *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -62,6 +69,13 @@ static const struct strmbase_filter_ops filter_ops =
     .filter_destroy = transform_destroy,
 };
 
+static HRESULT transform_sink_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt)
+{
+    struct transform *filter = impl_from_strmbase_filter(pin->filter);
+
+    return filter->ops->sink_query_accept(filter, mt);
+}
+
 static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID iid, void **out)
 {
     struct transform *filter = impl_from_strmbase_filter(pin->filter);
@@ -77,6 +91,7 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i
 
 static const struct strmbase_sink_ops sink_ops =
 {
+    .base.pin_query_accept = transform_sink_query_accept,
     .base.pin_query_interface = transform_sink_query_interface,
 };
 
@@ -86,7 +101,7 @@ static const struct strmbase_source_ops source_ops =
     .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
 };
 
-static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, struct transform **out)
+static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, const struct transform_ops *ops, struct transform **out)
 {
     struct transform *object;
 
@@ -98,16 +113,52 @@ static HRESULT transform_create(IUnknown *outer, const CLSID *clsid, struct tran
     strmbase_sink_init(&object->sink, &object->filter, L"In", &sink_ops, NULL);
     strmbase_source_init(&object->source, &object->filter, L"Out", &source_ops);
 
+    object->ops = ops;
+
     *out = object;
     return S_OK;
 }
 
+static HRESULT mpeg_audio_codec_sink_query_accept(struct transform *filter, const AM_MEDIA_TYPE *mt)
+{
+    const MPEG1WAVEFORMAT *format;
+
+    if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio))
+        return S_FALSE;
+
+    if (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1Packet)
+            && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1Payload)
+            && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload)
+            && !IsEqualGUID(&mt->subtype, &GUID_NULL))
+        return S_FALSE;
+
+    if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)
+            || mt->cbFormat < sizeof(MPEG1WAVEFORMAT))
+        return S_FALSE;
+
+    format = (const MPEG1WAVEFORMAT *)mt->pbFormat;
+
+    if (format->wfx.wFormatTag != WAVE_FORMAT_MPEG
+            || sizeof(WAVEFORMATEX) + format->wfx.cbSize < sizeof(MPEG1WAVEFORMAT))
+        return S_FALSE;
+
+    if ((format->fwHeadLayer & (ACM_MPEG_LAYER1 | ACM_MPEG_LAYER2)) != format->fwHeadLayer)
+        return S_FALSE;
+
+    return S_OK;
+}
+
+static const struct transform_ops mpeg_audio_codec_transform_ops =
+{
+    mpeg_audio_codec_sink_query_accept,
+};
+
 HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out)
 {
     struct transform *object;
     HRESULT hr;
 
-    hr = transform_create(outer, &CLSID_CMpegAudioCodec, &object);
+    hr = transform_create(outer, &CLSID_CMpegAudioCodec, &mpeg_audio_codec_transform_ops, &object);
     if (FAILED(hr))
         return hr;
 
-- 
2.34.1




More information about the wine-devel mailing list