[PATCH v2 3/5] amstream: Reject incompatible media types in AMDirectDrawStream::ReceiveConnection.
Anton Baskanov
baskanov at gmail.com
Sat Sep 5 13:04:27 CDT 2020
Signed-off-by: Anton Baskanov <baskanov at gmail.com>
---
dlls/amstream/ddrawstream.c | 27 ++++++
dlls/amstream/tests/amstream.c | 152 +++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c
index 6f60dec94e1..6e11f4fbf18 100644
--- a/dlls/amstream/ddrawstream.c
+++ b/dlls/amstream/ddrawstream.c
@@ -53,6 +53,27 @@ struct ddraw_stream
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,
const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
+static BOOL is_format_compatible(struct ddraw_stream *stream,
+ DWORD width, DWORD height, const DDPIXELFORMAT *connection_pf)
+{
+ if (stream->format.dwFlags & DDSD_HEIGHT)
+ {
+ if (stream->format.dwWidth != width || stream->format.dwHeight != height)
+ return FALSE;
+ }
+ if (stream->format.dwFlags & DDSD_PIXELFORMAT)
+ {
+ const DDPIXELFORMAT *stream_pf = &stream->format.ddpfPixelFormat;
+ if (stream_pf->dwFlags & DDPF_FOURCC)
+ return FALSE;
+ if (stream_pf->u1.dwRGBBitCount != connection_pf->u1.dwRGBBitCount)
+ return FALSE;
+ if (stream_pf->u1.dwRGBBitCount == 16 && stream_pf->u3.dwGBitMask != connection_pf->u3.dwGBitMask)
+ return FALSE;
+ }
+ return TRUE;
+}
+
static inline struct ddraw_stream *impl_from_IAMMediaStream(IAMMediaStream *iface)
{
return CONTAINING_RECORD(iface, struct ddraw_stream, IAMMediaStream_iface);
@@ -808,6 +829,12 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons
return VFW_E_TYPE_NOT_ACCEPTED;
}
+ if (!is_format_compatible(stream, width, height, &pixel_format))
+ {
+ LeaveCriticalSection(&stream->cs);
+ return VFW_E_TYPE_NOT_ACCEPTED;
+ }
+
IPin_QueryDirection(peer, &dir);
if (dir != PINDIR_OUTPUT)
{
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
index b11c0112f8f..556db987ead 100644
--- a/dlls/amstream/tests/amstream.c
+++ b/dlls/amstream/tests/amstream.c
@@ -3473,13 +3473,34 @@ 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;
IPin *pin;
int i;
+ static const VIDEOINFO yuy2_video_info =
+ {
+ .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
+ .bmiHeader.biWidth = 333,
+ .bmiHeader.biHeight = -444,
+ .bmiHeader.biPlanes = 1,
+ .bmiHeader.biBitCount = 16,
+ .bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'),
+ };
+
+ const AM_MEDIA_TYPE yuy2_mt =
+ {
+ .majortype = MEDIATYPE_Video,
+ .subtype = MEDIASUBTYPE_YUY2,
+ .formattype = FORMAT_VideoInfo,
+ .cbFormat = sizeof(VIDEOINFOHEADER),
+ .pbFormat = (BYTE *)&yuy2_video_info,
+ };
+
const AM_MEDIA_TYPE video_mt =
{
.majortype = MEDIATYPE_Video,
@@ -3540,6 +3561,137 @@ static void test_ddrawstream_receive_connection(void)
}
}
+ format = rgb8_format;
+ format.dwFlags = DDSD_WIDTH;
+ format.dwWidth = 222;
+ format.dwHeight = 555;
+ 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, &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 = 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);
+
+ 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);
+
+ 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);
+
+ hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &yuy2_format, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &yuy2_mt);
+ ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
+
+ format = yuy2_format;
+ format.ddpfPixelFormat.dwRBitMask = 0xf800;
+ format.ddpfPixelFormat.dwGBitMask = 0x07e0;
+ format.ddpfPixelFormat.dwBBitMask = 0x001f;
+ 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 == VFW_E_TYPE_NOT_ACCEPTED, "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);
--
2.17.1
More information about the wine-devel
mailing list