[PATCH 3/5] amstream: Reject incompatible media types in AMDirectDrawStream::ReceiveConnection.
Zebediah Figura
z.figura12 at gmail.com
Sat Aug 29 15:37:16 CDT 2020
On 8/29/20 8:51 AM, Anton Baskanov wrote:
> Signed-off-by: Anton Baskanov <baskanov at gmail.com>
> ---
> dlls/amstream/ddrawstream.c | 41 +++++++++++-
> dlls/amstream/tests/amstream.c | 110 +++++++++++++++++++++++++++++++++
> 2 files changed, 150 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c
> index a713b80be45..dcb36d0028f 100644
> --- a/dlls/amstream/ddrawstream.c
> +++ b/dlls/amstream/ddrawstream.c
> @@ -53,6 +53,44 @@ struct ddraw_stream
> static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,
> const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
>
> +static BOOL is_media_type_compatible(const AM_MEDIA_TYPE *media_type, const DDSURFACEDESC *format)
> +{
> + const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)media_type->pbFormat;
> +
> + if ((format->dwFlags & DDSD_WIDTH) && video_info->bmiHeader.biWidth != format->dwWidth)
> + return FALSE;
> +
> + if ((format->dwFlags & DDSD_HEIGHT) && abs(video_info->bmiHeader.biHeight) != format->dwHeight)
> + return FALSE;
> +
> + if (format->dwFlags & DDSD_PIXELFORMAT)
> + {
> + const GUID *subtype = &GUID_NULL;
> + switch (format->ddpfPixelFormat.u1.dwRGBBitCount)
> + {
> + case 8:
> + subtype = &MEDIASUBTYPE_RGB8;
> + break;
> + case 16:
> + if (format->ddpfPixelFormat.u3.dwGBitMask == 0x7e0)
> + subtype = &MEDIASUBTYPE_RGB565;
> + else
> + subtype = &MEDIASUBTYPE_RGB555;
> + break;
> + case 24:
> + subtype = &MEDIASUBTYPE_RGB24;
> + break;
> + case 32:
> + subtype = &MEDIASUBTYPE_RGB32;
> + break;
> + }
> + if (!IsEqualGUID(&media_type->subtype, subtype))
> + return FALSE;
> + }
I wonder if there's a nice way to combine the pixel format translation
with the validity check from 2/5, maybe along the lines of a helper
function that checks both.
> +
> + return TRUE;
> +}
> +
> static inline struct ddraw_stream *impl_from_IAMMediaStream(IAMMediaStream *iface)
> {
> return CONTAINING_RECORD(iface, struct ddraw_stream, IAMMediaStream_iface);
> @@ -750,7 +788,8 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons
> && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32)
> && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555)
> && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
> - || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
> + || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
> + || !is_media_type_compatible(mt, &stream->format))
> {
> LeaveCriticalSection(&stream->cs);
> return VFW_E_TYPE_NOT_ACCEPTED;
> diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
> index 2ce72d4f1c1..fe1cca4036c 100644
> --- a/dlls/amstream/tests/amstream.c
> +++ b/dlls/amstream/tests/amstream.c
> @@ -3440,7 +3440,9 @@ static void test_ddrawstream_receive_connection(void)
> IDirectDrawMediaStream *ddraw_stream;
> IAMMultiMediaStream *mmstream;
> struct testfilter source;
> + DDSURFACEDESC format;
> IMediaStream *stream;
> + VIDEOINFO video_info;
> AM_MEDIA_TYPE mt;
> HRESULT hr;
> ULONG ref;
> @@ -3507,6 +3509,114 @@ static void test_ddrawstream_receive_connection(void)
> }
> }
>
> + format = rgb8_format;
> + format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
> + format.dwWidth = 333;
> + format.dwHeight = 444;
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + video_info = rgb555_video_info;
> + video_info.bmiHeader.biWidth = 333;
> + video_info.bmiHeader.biHeight = 444;
> + mt = rgb555_mt;
> + mt.pbFormat = (BYTE *)&video_info;
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + video_info = rgb32_video_info;
> + video_info.bmiHeader.biWidth = 333;
> + video_info.bmiHeader.biHeight = -444;
> + mt = rgb32_mt;
> + mt.pbFormat = (BYTE *)&video_info;
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + video_info = rgb32_video_info;
> + video_info.bmiHeader.biWidth = 332;
> + video_info.bmiHeader.biHeight = 444;
> + mt = rgb32_mt;
> + mt.pbFormat = (BYTE *)&video_info;
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + video_info = rgb32_video_info;
> + video_info.bmiHeader.biWidth = 333;
> + video_info.bmiHeader.biHeight = 443;
> + mt = rgb32_mt;
> + mt.pbFormat = (BYTE *)&video_info;
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
> + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + format = rgb8_format;
> + format.dwFlags = 0;
> + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> + hr = IPin_Disconnect(pin);
> + ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> ref = IAMMultiMediaStream_Release(mmstream);
> ok(!ref, "Got outstanding refcount %d.\n", ref);
> IPin_Release(pin);
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200829/45ebb24c/attachment.sig>
More information about the wine-devel
mailing list