Signed-off-by: Anton Baskanov baskanov@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;