winegstreamer: Reject incompatible output 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
a7a90de929
commit
64b96eec7d
|
@ -819,7 +819,7 @@ static void test_media_types(void)
|
|||
|
||||
init_pcm_mt(&mt, &format, 1, 32000, 16);
|
||||
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);
|
||||
|
||||
|
@ -951,42 +951,42 @@ static void test_connect_pin(void)
|
|||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 16);
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 16);
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 16);
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 2, 32000, 16);
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 16000, 16);
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 24);
|
||||
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, &pcm16ex_mt);
|
||||
todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
|
||||
ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 16);
|
||||
req_format.nBlockAlign = 333;
|
||||
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);
|
||||
|
||||
init_pcm_mt(&req_mt, &req_format, 1, 32000, 16);
|
||||
req_format.nAvgBytesPerSec = 333;
|
||||
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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -145,9 +154,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)
|
||||
|
|
Loading…
Reference in New Issue