winegstreamer: Reject incompatible input media types in MPEG audio decoder.
Signed-off-by: Anton Baskanov <baskanov@gmail.com> Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3aaa953bd6
commit
2298f04a1d
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,49 @@ 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
|
||||
|| format->fwHeadLayer == ACM_MPEG_LAYER3)
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue