[PATCH 5/5] winegstreamer: Reject incompatible output types in MPEG audio decoder.

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


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

diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c
index defd65eaa62..70809d2d218 100644
--- a/dlls/quartz/tests/mpegaudio.c
+++ b/dlls/quartz/tests/mpegaudio.c
@@ -908,7 +908,7 @@ static void test_media_types(void)
     IBaseFilter_FindPin(filter, L"Out", &pin);
 
     hr = IPin_QueryAccept(pin, &pcm16_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     IPin_Release(pin);
 
@@ -1038,43 +1038,43 @@ static void test_connect_pin(void)
     req_mt = pcm16_mt;
     req_mt.majortype = GUID_NULL;
     hr = IPin_QueryAccept(source, &req_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     req_mt = pcm16_mt;
     req_mt.subtype = GUID_NULL;
     hr = IPin_QueryAccept(source, &req_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     req_mt = pcm16_mt;
     req_mt.formattype = GUID_NULL;
     hr = IPin_QueryAccept(source, &req_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(source, &pcm16_stereo_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(source, &pcm16_16khz_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(source, &pcm24_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IPin_QueryAccept(source, &pcm16ex_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     req_format = pcm16_format;
     req_format.nBlockAlign = 333;
     req_mt = pcm16_mt;
     req_mt.pbFormat = (BYTE *)&req_format;
     hr = IPin_QueryAccept(source, &req_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     req_format = pcm16_format;
     req_format.nAvgBytesPerSec = 333;
     req_mt = pcm16_mt;
     req_mt.pbFormat = (BYTE *)&req_format;
     hr = IPin_QueryAccept(source, &req_mt);
-    todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
 
     hr = IMediaControl_Pause(control);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
index 698d08a0d2a..a8f6806346e 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -35,6 +35,7 @@ struct transform
 struct transform_ops
 {
     HRESULT (*sink_query_accept)(struct transform *filter, const AM_MEDIA_TYPE *mt);
+    HRESULT (*source_query_accept)(struct transform *filter, const AM_MEDIA_TYPE *mt);
 };
 
 static inline struct transform *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -95,8 +96,16 @@ static const struct strmbase_sink_ops sink_ops =
     .base.pin_query_interface = transform_sink_query_interface,
 };
 
+static HRESULT transform_source_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt)
+{
+    struct transform *filter = impl_from_strmbase_filter(pin->filter);
+
+    return filter->ops->source_query_accept(filter, mt);
+}
+
 static const struct strmbase_source_ops source_ops =
 {
+    .base.pin_query_accept = transform_source_query_accept,
     .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
     .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
 };
@@ -148,9 +157,45 @@ static HRESULT mpeg_audio_codec_sink_query_accept(struct transform *filter, cons
     return S_OK;
 }
 
+static HRESULT mpeg_audio_codec_source_query_accept(struct transform *filter, const AM_MEDIA_TYPE *mt)
+{
+    const MPEG1WAVEFORMAT *input_format;
+    const WAVEFORMATEX *output_format;
+    DWORD expected_avg_bytes_per_sec;
+    WORD expected_block_align;
+
+    if (!filter->sink.pin.peer)
+        return S_FALSE;
+
+    if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)
+            || !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_PCM)
+            || !IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)
+            || mt->cbFormat < sizeof(WAVEFORMATEX))
+        return S_FALSE;
+
+    input_format = (const MPEG1WAVEFORMAT *)filter->sink.pin.mt.pbFormat;
+    output_format = (const WAVEFORMATEX *)mt->pbFormat;
+
+    if (output_format->wFormatTag != WAVE_FORMAT_PCM
+            || input_format->wfx.nSamplesPerSec != output_format->nSamplesPerSec
+            || input_format->wfx.nChannels != output_format->nChannels
+            || (output_format->wBitsPerSample != 8 && output_format->wBitsPerSample != 16))
+        return S_FALSE;
+
+    expected_block_align = output_format->nChannels * output_format->wBitsPerSample / 8;
+    expected_avg_bytes_per_sec = expected_block_align * output_format->nSamplesPerSec;
+
+    if (output_format->nBlockAlign != expected_block_align
+            || output_format->nAvgBytesPerSec != expected_avg_bytes_per_sec)
+        return S_FALSE;
+
+    return S_OK;
+}
+
 static const struct transform_ops mpeg_audio_codec_transform_ops =
 {
     mpeg_audio_codec_sink_query_accept,
+    mpeg_audio_codec_source_query_accept,
 };
 
 HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out)
-- 
2.34.1




More information about the wine-devel mailing list