Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 98 ++++++++++- dlls/amstream/tests/amstream.c | 306 +++++++++++++++++++++++++++++++++ 2 files changed, 396 insertions(+), 8 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..eb8e35b5ac4 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -47,6 +47,7 @@ struct ddraw_stream IPin *peer; IMemAllocator *allocator; AM_MEDIA_TYPE mt; + DDSURFACEDESC format; };
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface, @@ -363,11 +364,40 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStr DDSURFACEDESC *current_format, IDirectDrawPalette **palette, DDSURFACEDESC *desired_format, DWORD *flags) { - FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette, desired_format, - flags); + struct ddraw_stream *stream = impl_from_IDirectDrawMediaStream(iface); + + TRACE("stream %p, current_format %p, palette %p, desired_format %p, flags %p.\n", stream, current_format, palette, + desired_format, flags);
- return MS_E_NOSTREAM; + EnterCriticalSection(&stream->cs); + + if (!stream->peer) + { + LeaveCriticalSection(&stream->cs); + return MS_E_NOSTREAM; + }
+ if (current_format) + { + *current_format = stream->format; + current_format->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; + } + + if (palette) + *palette = NULL; + + if (desired_format) + { + *desired_format = stream->format; + desired_format->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + } + + if (flags) + *flags = 0; + + LeaveCriticalSection(&stream->cs); + + return S_OK; }
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface, @@ -637,8 +667,12 @@ static HRESULT WINAPI ddraw_sink_Connect(IPin *iface, IPin *peer, const AM_MEDIA
static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) { + const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)mt->pbFormat; + DDPIXELFORMAT pixel_format = {sizeof(DDPIXELFORMAT)}; struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir; + DWORD width; + DWORD height;
TRACE("stream %p, peer %p, mt %p.\n", stream, peer, mt);
@@ -651,17 +685,54 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons }
if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video) - || (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8) - && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24) - && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32) - && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555) - && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)) { LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED; }
+ width = video_info->bmiHeader.biWidth; + height = abs(video_info->bmiHeader.biHeight); + pixel_format.dwFlags = DDPF_RGB; + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8)) + { + pixel_format.dwFlags |= DDPF_PALETTEINDEXED8; + pixel_format.u1.dwRGBBitCount = 8; + } + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555)) + { + pixel_format.u1.dwRGBBitCount = 16; + pixel_format.u2.dwRBitMask = 0x7c00; + pixel_format.u3.dwGBitMask = 0x03e0; + pixel_format.u4.dwBBitMask = 0x001f; + } + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) + { + pixel_format.u1.dwRGBBitCount = 16; + pixel_format.u2.dwRBitMask = 0xf800; + pixel_format.u3.dwGBitMask = 0x07e0; + pixel_format.u4.dwBBitMask = 0x001f; + } + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24)) + { + pixel_format.u1.dwRGBBitCount = 24; + pixel_format.u2.dwRBitMask = 0xff0000; + pixel_format.u3.dwGBitMask = 0x00ff00; + pixel_format.u4.dwBBitMask = 0x0000ff; + } + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32)) + { + pixel_format.u1.dwRGBBitCount = 32; + pixel_format.u2.dwRBitMask = 0xff0000; + pixel_format.u3.dwGBitMask = 0x00ff00; + pixel_format.u4.dwBBitMask = 0x0000ff; + } + else + { + LeaveCriticalSection(&stream->cs); + return VFW_E_TYPE_NOT_ACCEPTED; + } + IPin_QueryDirection(peer, &dir); if (dir != PINDIR_OUTPUT) { @@ -673,6 +744,11 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
+ stream->format.dwWidth = width; + stream->format.dwHeight = height; + if (!(stream->format.dwFlags & DDSD_PIXELFORMAT)) + stream->format.ddpfPixelFormat = pixel_format; + LeaveCriticalSection(&stream->cs);
return S_OK; @@ -981,6 +1057,12 @@ HRESULT ddraw_stream_create(IUnknown *outer, void **out) object->IPin_iface.lpVtbl = &ddraw_sink_vtbl; object->ref = 1;
+ object->format.dwSize = sizeof(DDSURFACEDESC); + object->format.dwFlags = DDSD_CAPS; + object->format.dwWidth = 100; + object->format.dwHeight = 100; + object->format.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; + InitializeCriticalSection(&object->cs);
TRACE("Created ddraw stream %p.\n", object); diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index f4c033a1807..2a69ff60fc3 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,164 @@ static const AM_MEDIA_TYPE audio_mt = .pbFormat = (BYTE *)&audio_format, };
+static const VIDEOINFO rgb8_video_info = +{ + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 333, + .bmiHeader.biHeight = -444, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 8, + .bmiHeader.biCompression = BI_RGB, +}; + +static const VIDEOINFO rgb555_video_info = +{ + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 333, + .bmiHeader.biHeight = -444, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 16, + .bmiHeader.biCompression = BI_RGB, +}; + +static const VIDEOINFO rgb565_video_info = +{ + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 333, + .bmiHeader.biHeight = -444, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 16, + .bmiHeader.biCompression = BI_BITFIELDS, + .dwBitMasks = {0xff0000, 0x00ff00, 0x0000ff}, +}; + +static const VIDEOINFO rgb24_video_info = +{ + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 333, + .bmiHeader.biHeight = -444, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 24, + .bmiHeader.biCompression = BI_RGB, +}; + +static const VIDEOINFO rgb32_video_info = +{ + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 333, + .bmiHeader.biHeight = -444, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 32, + .bmiHeader.biCompression = BI_RGB, +}; + +static const AM_MEDIA_TYPE rgb8_mt = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO), + .pbFormat = (BYTE *)&rgb8_video_info, +}; + +static const AM_MEDIA_TYPE rgb555_mt = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO), + .pbFormat = (BYTE *)&rgb555_video_info, +}; + +static const AM_MEDIA_TYPE rgb565_mt = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO), + .pbFormat = (BYTE *)&rgb565_video_info, +}; + +static const AM_MEDIA_TYPE rgb24_mt = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO), + .pbFormat = (BYTE *)&rgb24_video_info, +}; + +static const AM_MEDIA_TYPE rgb32_mt = +{ + /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO), + .pbFormat = (BYTE *)&rgb32_video_info, +}; + +static const DDSURFACEDESC rgb8_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8, + .ddpfPixelFormat.dwRGBBitCount = 8, +}; + +static const DDSURFACEDESC rgb555_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB, + .ddpfPixelFormat.dwRGBBitCount = 16, + .ddpfPixelFormat.dwRBitMask = 0x7c00, + .ddpfPixelFormat.dwGBitMask = 0x03e0, + .ddpfPixelFormat.dwBBitMask = 0x001f, +}; + +static const DDSURFACEDESC rgb565_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB, + .ddpfPixelFormat.dwRGBBitCount = 16, + .ddpfPixelFormat.dwRBitMask = 0xf800, + .ddpfPixelFormat.dwGBitMask = 0x07e0, + .ddpfPixelFormat.dwBBitMask = 0x001f, +}; + +static const DDSURFACEDESC rgb24_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB, + .ddpfPixelFormat.dwRGBBitCount = 24, + .ddpfPixelFormat.dwRBitMask = 0xff0000, + .ddpfPixelFormat.dwGBitMask = 0x00ff00, + .ddpfPixelFormat.dwBBitMask = 0x0000ff, +}; + +static const DDSURFACEDESC rgb32_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB, + .ddpfPixelFormat.dwRGBBitCount = 32, + .ddpfPixelFormat.dwRBitMask = 0xff0000, + .ddpfPixelFormat.dwGBitMask = 0x00ff00, + .ddpfPixelFormat.dwBBitMask = 0x0000ff, +}; + static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
@@ -4474,6 +4632,153 @@ static void test_ddrawstream_initialize(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+#define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c) +static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream, + const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format) +{ + const DDPIXELFORMAT *expected_pf = &expected_format->ddpfPixelFormat; + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + struct testfilter source; + FILTER_INFO filter_info; + PIN_INFO pin_info; + DWORD flags; + HRESULT hr; + IPin *pin; + + hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_QueryPinInfo(pin, &pin_info); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&source); + + hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source"); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + memset(¤t_format, 0xcc, sizeof(current_format)); + current_format.dwSize = sizeof(current_format); + memset(&desired_format, 0xcc, sizeof(desired_format)); + desired_format.dwSize = sizeof(desired_format); + flags = 0xdeadbeef; + hr = IDirectDrawMediaStream_GetFormat(stream, ¤t_format, NULL, &desired_format, &flags); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS), + "Got current format flags %#x.\n", current_format.dwFlags); + ok_(__FILE__, line)(current_format.dwWidth == 333, "Got current format width %u.\n", current_format.dwWidth); + ok_(__FILE__, line)(current_format.dwHeight == 444, "Got current format height %u.\n", current_format.dwHeight); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got current format size %u.\n", current_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got current format flags %#x.\n", current_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got current format rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got current format r bit mask %#x.\n", current_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got current format g bit mask %#x.\n", current_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got current format b bit mask %#x.\n", current_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got current format caps %#x.\n", current_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), + "Got desired format flags %#x.\n", desired_format.dwFlags); + ok_(__FILE__, line)(desired_format.dwWidth == 333, "Got desired format width %u.\n", desired_format.dwWidth); + ok_(__FILE__, line)(desired_format.dwHeight == 444, "Got desired format height %u.\n", desired_format.dwHeight); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got desired format size %u.\n", desired_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got desired format flags %#x.\n", desired_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got desired format rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got desired format r bit mask %#x.\n", desired_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got desired format g bit mask %#x.\n", desired_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got desired format b bit mask %#x.\n", desired_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got desired format caps %#x.\n", desired_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags); + + hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph_Disconnect(filter_info.pGraph, pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + IFilterGraph_Release(filter_info.pGraph); + IBaseFilter_Release(pin_info.pFilter); + IPin_Release(pin); +} + +static void test_ddrawstream_get_format(void) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + IDirectDrawMediaStream *ddraw_stream; + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + IDirectDrawPalette *palette; + IMediaStream *stream; + VIDEOINFO video_info; + AM_MEDIA_TYPE mt; + DWORD flags; + HRESULT hr; + ULONG ref; + + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + current_format.dwSize = sizeof(current_format); + desired_format.dwSize = sizeof(desired_format); + hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr); + + video_info = rgb32_video_info; + video_info.rcSource.right = 222; + video_info.rcSource.bottom = 333; + video_info.rcTarget.right = 444; + video_info.rcTarget.bottom = 666; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format); + + video_info = rgb32_video_info; + video_info.bmiHeader.biHeight = 444; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format); + + check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format); + check_ddrawstream_get_format(ddraw_stream, &rgb555_mt, &rgb555_format); + check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format); + check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format); + check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format); + + current_format.dwSize = sizeof(current_format); + desired_format.dwSize = sizeof(desired_format); + hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + IDirectDrawMediaStream_Release(ddraw_stream); + ref = IMediaStream_Release(stream); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -5936,6 +6241,7 @@ START_TEST(amstream) test_ddrawstream_getsetdirectdraw(); test_ddrawstream_receive_connection(); test_ddrawstream_create_sample(); + test_ddrawstream_get_format();
test_ddrawstreamsample_get_media_stream();
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 81 ++++++++++- dlls/amstream/tests/amstream.c | 258 +++++++++++++++++++++++++++++++++ 2 files changed, 336 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index eb8e35b5ac4..6f60dec94e1 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -401,11 +401,86 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStr }
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface, - const DDSURFACEDESC *pDDSurfaceDesc, IDirectDrawPalette *pDirectDrawPalette) + const DDSURFACEDESC *format, IDirectDrawPalette *palette) { - FIXME("(%p)->(%p,%p) stub!\n", iface, pDDSurfaceDesc, pDirectDrawPalette); + struct ddraw_stream *stream = impl_from_IDirectDrawMediaStream(iface);
- return E_NOTIMPL; + TRACE("stream %p, format %p, palette %p.\n", stream, format, palette); + + if (palette) + FIXME("Setting palette is not yet supported.\n"); + + if (!format) + return E_POINTER; + + if (format->dwSize != sizeof(DDSURFACEDESC)) + return E_INVALIDARG; + + if (format->dwFlags & DDSD_PIXELFORMAT) + { + if (format->ddpfPixelFormat.dwSize != sizeof(DDPIXELFORMAT)) + return DDERR_INVALIDSURFACETYPE; + + if (format->ddpfPixelFormat.dwFlags & DDPF_FOURCC) + { + if (!format->ddpfPixelFormat.u1.dwRGBBitCount) + return E_INVALIDARG; + } + else + { + if (format->ddpfPixelFormat.dwFlags & (DDPF_YUV | DDPF_PALETTEINDEXED1 | + DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXEDTO8)) + return DDERR_INVALIDSURFACETYPE; + + if (!(format->ddpfPixelFormat.dwFlags & DDPF_RGB)) + return DDERR_INVALIDSURFACETYPE; + + switch (format->ddpfPixelFormat.u1.dwRGBBitCount) + { + case 8: + if (!(format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)) + return DDERR_INVALIDSURFACETYPE; + break; + case 16: + if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) + return DDERR_INVALIDSURFACETYPE; + if ((format->ddpfPixelFormat.u2.dwRBitMask != 0x7c00 || + format->ddpfPixelFormat.u3.dwGBitMask != 0x03e0 || + format->ddpfPixelFormat.u4.dwBBitMask != 0x001f) && + (format->ddpfPixelFormat.u2.dwRBitMask != 0xf800 || + format->ddpfPixelFormat.u3.dwGBitMask != 0x07e0 || + format->ddpfPixelFormat.u4.dwBBitMask != 0x001f)) + return DDERR_INVALIDSURFACETYPE; + break; + case 24: + case 32: + if (format->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) + return DDERR_INVALIDSURFACETYPE; + if (format->ddpfPixelFormat.u2.dwRBitMask != 0xff0000 || + format->ddpfPixelFormat.u3.dwGBitMask != 0x00ff00 || + format->ddpfPixelFormat.u4.dwBBitMask != 0x0000ff) + return DDERR_INVALIDSURFACETYPE; + break; + default: + return DDERR_INVALIDSURFACETYPE; + } + } + } + + EnterCriticalSection(&stream->cs); + + stream->format.dwFlags = DDSD_CAPS | (format->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT)); + if (format->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) + { + stream->format.dwWidth = format->dwWidth; + stream->format.dwHeight = format->dwHeight; + } + if (format->dwFlags & DDSD_PIXELFORMAT) + stream->format.ddpfPixelFormat = format->ddpfPixelFormat; + + LeaveCriticalSection(&stream->cs); + + return S_OK; }
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream *iface, diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 2a69ff60fc3..b11c0112f8f 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -209,6 +209,39 @@ static const DDSURFACEDESC rgb32_format = .ddpfPixelFormat.dwBBitMask = 0x0000ff, };
+static const DDSURFACEDESC argb32_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS, + .ddpfPixelFormat.dwRGBBitCount = 32, + .ddpfPixelFormat.dwRBitMask = 0xff0000, + .ddpfPixelFormat.dwGBitMask = 0x00ff00, + .ddpfPixelFormat.dwBBitMask = 0x0000ff, + .ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000, +}; + +static const DDSURFACEDESC yuy2_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_FOURCC, + .ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'U', 'Y', '2'), + .ddpfPixelFormat.dwYUVBitCount = 16, +}; + +static const DDSURFACEDESC yv12_format = +{ + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_FOURCC, + .ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'V', '1', '2'), + .ddpfPixelFormat.dwYUVBitCount = 12, +}; + static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
@@ -4779,6 +4812,230 @@ static void test_ddrawstream_get_format(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+#define check_ddrawstream_set_format(a,b,c,d) check_ddrawstream_set_format_(__LINE__,a,b,c,d) +static void check_ddrawstream_set_format_(int line, IDirectDrawMediaStream *stream, + const DDSURFACEDESC *format, const AM_MEDIA_TYPE *mt, HRESULT expected_hr) +{ + struct testfilter source; + FILTER_INFO filter_info; + PIN_INFO pin_info; + HRESULT hr; + IPin *pin; + + hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_QueryPinInfo(pin, &pin_info); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&source); + + hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source"); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x.\n", hr); + + if (mt) + { + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + DWORD flags; + + hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + memset(¤t_format, 0xcc, sizeof(current_format)); + memset(&desired_format, 0xcc, sizeof(desired_format)); + flags = 0xdeadbeef; + current_format.dwSize = sizeof(current_format); + desired_format.dwSize = sizeof(desired_format); + hr = IDirectDrawMediaStream_GetFormat(stream, ¤t_format, NULL, &desired_format, &flags); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + if (format->dwFlags & DDSD_PIXELFORMAT) + { + ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT), + "Got flags %#x.\n", current_format.dwFlags); + ok_(__FILE__, line)(memcmp(¤t_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0, + "Pixel format didn't match.\n"); + ok_(__FILE__, line)(memcmp(&desired_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0, + "Pixel format didn't match.\n"); + } + else + { + ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS), + "Got flags %#x.\n", current_format.dwFlags); + } + ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), + "Got flags %#x.\n", desired_format.dwFlags); + ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got caps %#x.\n", current_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got caps %#x.\n", desired_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags); + + hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph_Disconnect(filter_info.pGraph, pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + } + + hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + IFilterGraph_Release(filter_info.pGraph); + IBaseFilter_Release(pin_info.pFilter); + IPin_Release(pin); +} + +static void test_ddrawstream_set_format(void) +{ + static const DDSURFACEDESC rgb1_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED1, + .ddpfPixelFormat.dwRGBBitCount = 1, + }; + static const DDSURFACEDESC rgb2_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED2, + .ddpfPixelFormat.dwRGBBitCount = 2, + }; + static const DDSURFACEDESC rgb4_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4, + .ddpfPixelFormat.dwRGBBitCount = 4, + }; + static const DDSURFACEDESC rgb4to8_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXEDTO8, + .ddpfPixelFormat.dwRGBBitCount = 4, + }; + static const DDSURFACEDESC rgb332_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_RGB, + .ddpfPixelFormat.dwRGBBitCount = 8, + .ddpfPixelFormat.dwRBitMask = 0xe0, + .ddpfPixelFormat.dwGBitMask = 0x1c, + .ddpfPixelFormat.dwBBitMask = 0x03, + }; + + IDirectDrawMediaStream *ddraw_stream; + IAMMultiMediaStream *mmstream; + DDSURFACEDESC format; + IMediaStream *stream; + HRESULT hr; + ULONG ref; + + mmstream = create_ammultimediastream(); + + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_ddrawstream_set_format(ddraw_stream, &rgb8_format, &rgb8_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &rgb555_format, &rgb555_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &rgb565_format, &rgb565_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &rgb24_format, &rgb24_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &rgb32_format, &rgb32_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &argb32_format, &rgb32_mt, S_OK); + check_ddrawstream_set_format(ddraw_stream, &yuy2_format, NULL, S_OK); + check_ddrawstream_set_format(ddraw_stream, &yv12_format, NULL, S_OK); + + format = rgb32_format; + format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA + | DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_ZBUFFER | DDPF_ZPIXELS | DDPF_STENCILBUFFER + | DDPF_ALPHAPREMULT | DDPF_LUMINANCE | DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV; + check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK); + + format = yuy2_format; + format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA + | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXEDTO8 | DDPF_PALETTEINDEXED8 + | DDPF_RGB | DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_YUV | DDPF_ZBUFFER + | DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_ZPIXELS + | DDPF_STENCILBUFFER | DDPF_ALPHAPREMULT | DDPF_LUMINANCE + | DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, S_OK); + + format = rgb32_format; + format.dwFlags |= DDSD_CAPS; + format.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK); + + format = rgb8_format; + format.dwFlags = 0; + check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK); + + check_ddrawstream_set_format(ddraw_stream, &rgb1_format, NULL, DDERR_INVALIDSURFACETYPE); + check_ddrawstream_set_format(ddraw_stream, &rgb2_format, NULL, DDERR_INVALIDSURFACETYPE); + check_ddrawstream_set_format(ddraw_stream, &rgb4_format, NULL, DDERR_INVALIDSURFACETYPE); + check_ddrawstream_set_format(ddraw_stream, &rgb4to8_format, NULL, DDERR_INVALIDSURFACETYPE); + check_ddrawstream_set_format(ddraw_stream, &rgb332_format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb8_format; + format.ddpfPixelFormat.dwFlags &= ~DDPF_RGB; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb8_format; + format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb32_format; + format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb32_format; + format.ddpfPixelFormat.dwFlags |= DDPF_YUV; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb565_format; + format.ddpfPixelFormat.dwRBitMask = 0x001f; + format.ddpfPixelFormat.dwGBitMask = 0x07e0; + format.ddpfPixelFormat.dwBBitMask = 0xf800; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = rgb32_format; + format.ddpfPixelFormat.dwRBitMask = 0x00ff00; + format.ddpfPixelFormat.dwGBitMask = 0x0000ff; + format.ddpfPixelFormat.dwBBitMask = 0xff0000; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + format = yuy2_format; + format.ddpfPixelFormat.dwYUVBitCount = 0; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG); + + format = rgb32_format; + format.dwSize = sizeof(DDSURFACEDESC) + 1; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG); + + format = rgb32_format; + format.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT) + 1; + check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + IDirectDrawMediaStream_Release(ddraw_stream); + ref = IMediaStream_Release(stream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + +} + static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -6242,6 +6499,7 @@ START_TEST(amstream) test_ddrawstream_receive_connection(); test_ddrawstream_create_sample(); test_ddrawstream_get_format(); + test_ddrawstream_set_format();
test_ddrawstreamsample_get_media_stream();
Signed-off-by: Anton Baskanov baskanov@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);
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 38 ++++++++++ dlls/amstream/tests/amstream.c | 130 ++++++++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 6e11f4fbf18..bfe2efa43e7 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -43,6 +43,7 @@ struct ddraw_stream IDirectDraw *ddraw; CRITICAL_SECTION cs; IMediaStreamFilter *filter; + IFilterGraph *graph;
IPin *peer; IMemAllocator *allocator; @@ -287,6 +288,8 @@ static HRESULT WINAPI ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface
TRACE("stream %p, filtergraph %p.\n", stream, filtergraph);
+ stream->graph = filtergraph; + return S_OK; }
@@ -425,6 +428,10 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr const DDSURFACEDESC *format, IDirectDrawPalette *palette) { struct ddraw_stream *stream = impl_from_IDirectDrawMediaStream(iface); + AM_MEDIA_TYPE old_media_type; + DDSURFACEDESC old_format; + IPin *old_peer; + HRESULT hr;
TRACE("stream %p, format %p, palette %p.\n", stream, format, palette);
@@ -490,6 +497,7 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr
EnterCriticalSection(&stream->cs);
+ old_format = stream->format; stream->format.dwFlags = DDSD_CAPS | (format->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT)); if (format->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) { @@ -499,6 +507,36 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr if (format->dwFlags & DDSD_PIXELFORMAT) stream->format.ddpfPixelFormat = format->ddpfPixelFormat;
+ if (stream->peer && + !is_format_compatible(stream, old_format.dwWidth, old_format.dwHeight, &old_format.ddpfPixelFormat)) + { + hr = CopyMediaType(&old_media_type, &stream->mt); + if (FAILED(hr)) + { + stream->format = old_format; + LeaveCriticalSection(&stream->cs); + return hr; + } + old_peer = stream->peer; + IPin_AddRef(old_peer); + + IFilterGraph_Disconnect(stream->graph, stream->peer); + IFilterGraph_Disconnect(stream->graph, &stream->IPin_iface); + hr = IFilterGraph_ConnectDirect(stream->graph, old_peer, &stream->IPin_iface, NULL); + if (FAILED(hr)) + { + stream->format = old_format; + IFilterGraph_ConnectDirect(stream->graph, old_peer, &stream->IPin_iface, &old_media_type); + IPin_Release(old_peer); + FreeMediaType(&old_media_type); + LeaveCriticalSection(&stream->cs); + return DDERR_INVALIDSURFACETYPE; + } + + IPin_Release(old_peer); + FreeMediaType(&old_media_type); + } + LeaveCriticalSection(&stream->cs);
return S_OK; diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 556db987ead..b20404fc4a7 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1038,6 +1038,7 @@ struct testfilter IMediaSeeking IMediaSeeking_iface; LONGLONG current_position; LONGLONG stop_position; + const AM_MEDIA_TYPE *preferred_mt; HRESULT get_duration_hr; HRESULT get_stop_position_hr; HRESULT set_positions_hr; @@ -1098,6 +1099,16 @@ static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface) return CONTAINING_RECORD(iface, struct testfilter, source.pin); }
+static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) +{ + struct testfilter *filter = impl_from_base_pin(iface); + + if (index < 1 && filter->preferred_mt) + return CopyMediaType(mt, filter->preferred_mt); + + return VFW_S_NO_MORE_ITEMS; +} + static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) { struct testfilter *filter = impl_from_base_pin(iface); @@ -1112,6 +1123,25 @@ static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid return S_OK; }
+static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *pin, IMemAllocator **alloc) +{ + ALLOCATOR_PROPERTIES props = {0}; + HRESULT hr; + + /* AMDirectDrawStream tries to use it's custom allocator and + * when it is able to do so it's behavior changes slightly + * (e.g. it uses dynamic format change instead of reconnecting in SetFormat). + * We don't yet implement the custom allocator so force the standard one for now. */ + hr = BaseOutputPinImpl_InitAllocator(iface, alloc); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IMemInputPin_GetAllocatorRequirements(pin, &props); + hr = iface->pFuncsTable->pfnDecideBufferSize(iface, *alloc, &props); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + return IMemInputPin_NotifyAllocator(pin, *alloc, FALSE); +} + static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface, IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested) { @@ -1131,10 +1161,11 @@ static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
static const struct strmbase_source_ops testsource_ops = { + .base.pin_get_media_type = testsource_get_media_type, .base.pin_query_interface = testsource_query_interface, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideBufferSize = testsource_DecideBufferSize, - .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, + .pfnDecideAllocator = testsource_DecideAllocator, };
static void testfilter_init(struct testfilter *filter) @@ -5089,10 +5120,17 @@ static void test_ddrawstream_set_format(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream; + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + struct testfilter source; + IGraphBuilder *graph; DDSURFACEDESC format; IMediaStream *stream; + VIDEOINFO video_info; + AM_MEDIA_TYPE mt; HRESULT hr; ULONG ref; + IPin *pin;
mmstream = create_ammultimediastream();
@@ -5186,6 +5224,96 @@ static void test_ddrawstream_set_format(void) ref = IMediaStream_Release(stream); ok(!ref, "Got outstanding refcount %d.\n", ref);
+ mmstream = create_ammultimediastream(); + + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!graph, "Expected non-NULL graph.\n"); + + testfilter_init(&source); + + hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source"); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb8_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + source.preferred_mt = NULL; + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL); + ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8), + "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype)); + hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, NULL, &desired_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(current_format.ddpfPixelFormat.dwRGBBitCount == 8, + "Got rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount); + ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 8, + "Got rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount); + + format = rgb555_format; + format.dwFlags = 0; + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8), + "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype)); + + source.preferred_mt = &rgb555_mt; + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL); + 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); + ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555), + "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype)); + hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, NULL, &desired_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(current_format.ddpfPixelFormat.dwRGBBitCount == 16, + "Got rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount); + ok(desired_format.ddpfPixelFormat.dwRGBBitCount == 16, + "Got rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount); + + video_info = rgb555_video_info; + video_info.bmiHeader.biWidth = 222; + video_info.bmiHeader.biHeight = -555; + mt = rgb555_mt; + mt.pbFormat = (BYTE *)&video_info; + source.preferred_mt = &mt; + + format = rgb555_format; + format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; + format.dwWidth = 222; + format.dwHeight = 555; + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555), + "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype)); + ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 222, + "Got width %d.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth); + ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -555, + "Got height %d.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight); + + hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IGraphBuilder_Disconnect(graph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IGraphBuilder_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + IPin_Release(pin); + IDirectDrawMediaStream_Release(ddraw_stream); + ref = IMediaStream_Release(stream); + ok(!ref, "Got outstanding refcount %d.\n", ref); }
static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid)
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 24 +++-- dlls/amstream/tests/amstream.c | 174 +++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 13 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index bfe2efa43e7..701e6d35c7c 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -1407,19 +1407,17 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw return hr; }
- desc.dwSize = sizeof(desc); - desc.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; - desc.dwHeight = 100; - desc.dwWidth = 100; - desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); - desc.ddpfPixelFormat.dwFlags = DDPF_RGB; - desc.ddpfPixelFormat.u1.dwRGBBitCount = 32; - desc.ddpfPixelFormat.u2.dwRBitMask = 0xff0000; - desc.ddpfPixelFormat.u3.dwGBitMask = 0x00ff00; - desc.ddpfPixelFormat.u4.dwBBitMask = 0x0000ff; - desc.ddpfPixelFormat.u5.dwRGBAlphaBitMask = 0; - desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN; - desc.lpSurface = NULL; + desc = object->parent->format; + if (!(desc.dwFlags & DDSD_PIXELFORMAT)) + { + desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); + desc.ddpfPixelFormat.dwFlags = DDPF_RGB; + desc.ddpfPixelFormat.u1.dwRGBBitCount = 32; + desc.ddpfPixelFormat.u2.dwRBitMask = 0xff0000; + desc.ddpfPixelFormat.u3.dwGBitMask = 0x00ff00; + desc.ddpfPixelFormat.u4.dwBBitMask = 0x0000ff; + } + desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
hr = IDirectDraw_CreateSurface(ddraw, &desc, &object->surface, NULL); IDirectDraw_Release(ddraw); diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index b20404fc4a7..fb49dda2d6f 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -6562,6 +6562,83 @@ static void test_audiostreamsample_get_audio_data(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+#define get_ddrawstream_create_sample_desc(a,b,c,d) get_ddrawstream_create_sample_desc_(__LINE__,a,b,c,d) +static void get_ddrawstream_create_sample_desc_(int line, const DDSURFACEDESC *format1, + const DDSURFACEDESC *format2, const AM_MEDIA_TYPE *mt, DDSURFACEDESC *desc) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + IDirectDrawMediaStream *ddraw_stream; + IDirectDrawStreamSample *sample; + IDirectDrawSurface *surface; + struct testfilter source; + IGraphBuilder *graph; + IMediaStream *stream; + HRESULT hr; + ULONG ref; + IPin *pin; + + hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&source); + + hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + if (format1) + { + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format1, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + } + if (format2) + { + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format2, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + } + if (mt) + { + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, mt); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + hr = IGraphBuilder_Disconnect(graph, pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + } + + hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + ok_(__FILE__, line)(!!surface, "Expected non-NULL sufrace.\n"); + + desc->dwSize = sizeof(*desc); + hr = IDirectDrawSurface_GetSurfaceDesc(surface, desc); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr); + + ref = IDirectDrawStreamSample_Release(sample); + ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref); + ref = IDirectDrawSurface_Release(surface); + ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref); + ref = IAMMultiMediaStream_Release(mmstream); + ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref); + ref = IGraphBuilder_Release(graph); + ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref); + IPin_Release(pin); + IDirectDrawMediaStream_Release(ddraw_stream); + ref = IMediaStream_Release(stream); + ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref); +} + static void test_ddrawstream_create_sample(void) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -6569,6 +6646,8 @@ static void test_ddrawstream_create_sample(void) DDSURFACEDESC desc = { sizeof(desc) }; IDirectDrawMediaStream *ddraw_stream; IDirectDrawStreamSample *sample; + DDSURFACEDESC format1; + DDSURFACEDESC format2; IMediaStream *stream; IDirectDraw *ddraw; HRESULT hr; @@ -6670,6 +6749,101 @@ static void test_ddrawstream_create_sample(void) ok(!ref, "Got outstanding refcount %d.\n", ref); ref = IDirectDraw_Release(ddraw); ok(!ref, "Got outstanding refcount %d.\n", ref); + + format1 = rgb8_format; + format1.dwFlags = 0; + format1.dwWidth = 333; + format1.dwHeight = 444; + get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc); + ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + + format1 = rgb8_format; + format1.dwFlags |= DDSD_WIDTH; + format1.dwWidth = 333; + format1.dwHeight = 444; + format2 = rgb8_format; + format2.dwFlags = 0; + get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc); + ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight); + + format1 = rgb8_format; + format1.dwFlags |= DDSD_HEIGHT; + format1.dwWidth = 333; + format1.dwHeight = 444; + format2 = rgb8_format; + format2.dwFlags = 0; + get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc); + ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight); + + get_ddrawstream_create_sample_desc(NULL, NULL, &rgb8_mt, &desc); + ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + + get_ddrawstream_create_sample_desc(&rgb565_format, NULL, NULL, &desc); + ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 16, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xf800, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x07e0, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x001f, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + + get_ddrawstream_create_sample_desc(&argb32_format, NULL, NULL, &desc); + ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS), "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + ok(desc.ddpfPixelFormat.dwRGBAlphaBitMask == 0xff000000, + "Got alpha bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + + format1 = rgb32_format; + format1.dwFlags |= DDSD_CAPS; + format1.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc); + ok(desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "Expected set DDSCAPS_OFFSCREENPLAIN.\n"); + ok(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY, "Expected set DDSCAPS_SYSTEMMEMORY.\n"); + ok(!(desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY), "Expected unset DDSCAPS_VIDEOMEMORY.\n"); + ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + + format1 = rgb32_format; + format1.dwFlags |= DDSD_CKSRCBLT; + format1.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff; + format1.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff; + get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc); + ok(!(desc.dwFlags & DDSD_CKSRCBLT), "Expected unset DDSD_CKSRCBLT.\n"); + ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth); + ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight); + ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags); + ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.dwRGBBitCount); + ok(desc.ddpfPixelFormat.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.dwRBitMask); + ok(desc.ddpfPixelFormat.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.dwGBitMask); + ok(desc.ddpfPixelFormat.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.dwBBitMask); + ok(desc.ddckCKSrcBlt.dwColorSpaceLowValue == 0, "Got color key low value %#x.\n", + desc.ddckCKSrcBlt.dwColorSpaceLowValue); + ok(desc.ddckCKSrcBlt.dwColorSpaceHighValue == 0, "Got color key high value %#x.\n", + desc.ddckCKSrcBlt.dwColorSpaceHighValue); }
static void test_ddrawstreamsample_get_media_stream(void)
On 9/5/20 1:04 PM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 98 ++++++++++- dlls/amstream/tests/amstream.c | 306 +++++++++++++++++++++++++++++++++ 2 files changed, 396 insertions(+), 8 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..eb8e35b5ac4 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -47,6 +47,7 @@ struct ddraw_stream IPin *peer; IMemAllocator *allocator; AM_MEDIA_TYPE mt;
- DDSURFACEDESC format;
};
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface, @@ -363,11 +364,40 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStr DDSURFACEDESC *current_format, IDirectDrawPalette **palette, DDSURFACEDESC *desired_format, DWORD *flags) {
- FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette, desired_format,
flags);
- struct ddraw_stream *stream = impl_from_IDirectDrawMediaStream(iface);
- TRACE("stream %p, current_format %p, palette %p, desired_format %p, flags %p.\n", stream, current_format, palette,
desired_format, flags);
- return MS_E_NOSTREAM;
EnterCriticalSection(&stream->cs);
if (!stream->peer)
{
LeaveCriticalSection(&stream->cs);
return MS_E_NOSTREAM;
}
if (current_format)
{
*current_format = stream->format;
current_format->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
}
if (palette)
*palette = NULL;
if (desired_format)
{
*desired_format = stream->format;
desired_format->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
}
if (flags)
*flags = 0;
LeaveCriticalSection(&stream->cs);
return S_OK;
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface, @@ -637,8 +667,12 @@ static HRESULT WINAPI ddraw_sink_Connect(IPin *iface, IPin *peer, const AM_MEDIA
static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) {
const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)mt->pbFormat;
DDPIXELFORMAT pixel_format = {sizeof(DDPIXELFORMAT)}; struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir;
DWORD width;
DWORD height;
TRACE("stream %p, peer %p, mt %p.\n", stream, peer, mt);
@@ -651,17 +685,54 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons }
if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)
|| (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555)
{ LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED; }&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
- width = video_info->bmiHeader.biWidth;
- height = abs(video_info->bmiHeader.biHeight);
- pixel_format.dwFlags = DDPF_RGB;
- if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8))
- {
pixel_format.dwFlags |= DDPF_PALETTEINDEXED8;
pixel_format.u1.dwRGBBitCount = 8;
- }
- else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555))
- {
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0x7c00;
pixel_format.u3.dwGBitMask = 0x03e0;
pixel_format.u4.dwBBitMask = 0x001f;
- }
- else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
- {
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0xf800;
pixel_format.u3.dwGBitMask = 0x07e0;
pixel_format.u4.dwBBitMask = 0x001f;
- }
- else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24))
- {
pixel_format.u1.dwRGBBitCount = 24;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
- }
- else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32))
- {
pixel_format.u1.dwRGBBitCount = 32;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
- }
- else
- {
LeaveCriticalSection(&stream->cs);
return VFW_E_TYPE_NOT_ACCEPTED;
- }
- IPin_QueryDirection(peer, &dir); if (dir != PINDIR_OUTPUT) {
@@ -673,6 +744,11 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
stream->format.dwWidth = width;
stream->format.dwHeight = height;
if (!(stream->format.dwFlags & DDSD_PIXELFORMAT))
stream->format.ddpfPixelFormat = pixel_format;
LeaveCriticalSection(&stream->cs);
return S_OK;
@@ -981,6 +1057,12 @@ HRESULT ddraw_stream_create(IUnknown *outer, void **out) object->IPin_iface.lpVtbl = &ddraw_sink_vtbl; object->ref = 1;
object->format.dwSize = sizeof(DDSURFACEDESC);
object->format.dwFlags = DDSD_CAPS;
object->format.dwWidth = 100;
object->format.dwHeight = 100;
object->format.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
InitializeCriticalSection(&object->cs);
TRACE("Created ddraw stream %p.\n", object);
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index f4c033a1807..2a69ff60fc3 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,164 @@ static const AM_MEDIA_TYPE audio_mt = .pbFormat = (BYTE *)&audio_format, };
+static const VIDEOINFO rgb8_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 8,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb555_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb565_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_BITFIELDS,
- .dwBitMasks = {0xff0000, 0x00ff00, 0x0000ff},
I think this is a mistake for {0xf800, 0x07e0, 0x001f}, right?
+};
+static const VIDEOINFO rgb24_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 24,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb32_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 32,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const AM_MEDIA_TYPE rgb8_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
- .subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
- .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
- .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb8_video_info,
+};
+static const AM_MEDIA_TYPE rgb555_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
- .subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
- .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
- .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb555_video_info,
+};
+static const AM_MEDIA_TYPE rgb565_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
- .subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
- .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
- .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb565_video_info,
+};
+static const AM_MEDIA_TYPE rgb24_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
- .subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
- .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
- .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb24_video_info,
+};
+static const AM_MEDIA_TYPE rgb32_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
- .subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
- .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
- .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb32_video_info,
+};
+static const DDSURFACEDESC rgb8_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8,
- .ddpfPixelFormat.dwRGBBitCount = 8,
+};
+static const DDSURFACEDESC rgb555_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0x7c00,
- .ddpfPixelFormat.dwGBitMask = 0x03e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb565_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0xf800,
- .ddpfPixelFormat.dwGBitMask = 0x07e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb24_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 24,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
+static const DDSURFACEDESC rgb32_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 32,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
@@ -4474,6 +4632,153 @@ static void test_ddrawstream_initialize(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+#define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c) +static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream,
const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format)
+{
- const DDPIXELFORMAT *expected_pf = &expected_format->ddpfPixelFormat;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- struct testfilter source;
- FILTER_INFO filter_info;
- PIN_INFO pin_info;
- DWORD flags;
- HRESULT hr;
- IPin *pin;
- hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_QueryPinInfo(pin, &pin_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- testfilter_init(&source);
- hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL, NULL);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- memset(¤t_format, 0xcc, sizeof(current_format));
- current_format.dwSize = sizeof(current_format);
- memset(&desired_format, 0xcc, sizeof(desired_format));
- desired_format.dwSize = sizeof(desired_format);
- flags = 0xdeadbeef;
- hr = IDirectDrawMediaStream_GetFormat(stream, ¤t_format, NULL, &desired_format, &flags);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS),
"Got current format flags %#x.\n", current_format.dwFlags);
- ok_(__FILE__, line)(current_format.dwWidth == 333, "Got current format width %u.\n", current_format.dwWidth);
- ok_(__FILE__, line)(current_format.dwHeight == 444, "Got current format height %u.\n", current_format.dwHeight);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT),
"Got current format size %u.\n", current_format.ddpfPixelFormat.dwSize);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags,
"Got current format flags %#x.\n", current_format.ddpfPixelFormat.dwFlags);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount,
"Got current format rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask,
"Got current format r bit mask %#x.\n", current_format.ddpfPixelFormat.dwRBitMask);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask,
"Got current format g bit mask %#x.\n", current_format.ddpfPixelFormat.dwGBitMask);
- ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask,
"Got current format b bit mask %#x.\n", current_format.ddpfPixelFormat.dwBBitMask);
- ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
"Got current format caps %#x.\n", current_format.ddsCaps.dwCaps);
- ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
"Got desired format flags %#x.\n", desired_format.dwFlags);
- ok_(__FILE__, line)(desired_format.dwWidth == 333, "Got desired format width %u.\n", desired_format.dwWidth);
- ok_(__FILE__, line)(desired_format.dwHeight == 444, "Got desired format height %u.\n", desired_format.dwHeight);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT),
"Got desired format size %u.\n", desired_format.ddpfPixelFormat.dwSize);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags,
"Got desired format flags %#x.\n", desired_format.ddpfPixelFormat.dwFlags);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount,
"Got desired format rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask,
"Got desired format r bit mask %#x.\n", desired_format.ddpfPixelFormat.dwRBitMask);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask,
"Got desired format g bit mask %#x.\n", desired_format.ddpfPixelFormat.dwGBitMask);
- ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask,
"Got desired format b bit mask %#x.\n", desired_format.ddpfPixelFormat.dwBBitMask);
- ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
"Got desired format caps %#x.\n", desired_format.ddsCaps.dwCaps);
- ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags);
I'd be fine with signing off on the patch as-is (with that rgb565 error fixed, probably), but as just a suggestion, you might try building the expected DDSURFACEDESC as a local variable and then just performing a memcmp(). That helps test all members at once, simplifies the code, and makes it (I think) quite a lot more readable. Of course, the downside is that you don't know what doesn't match if the test fails, but I'm inclined to call it worthwhile.
- hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- IFilterGraph_Release(filter_info.pGraph);
- IBaseFilter_Release(pin_info.pFilter);
- IPin_Release(pin);
+}
+static void test_ddrawstream_get_format(void) +{
- IAMMultiMediaStream *mmstream = create_ammultimediastream();
- IDirectDrawMediaStream *ddraw_stream;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- IDirectDrawPalette *palette;
- IMediaStream *stream;
- VIDEOINFO video_info;
- AM_MEDIA_TYPE mt;
- DWORD flags;
- HRESULT hr;
- ULONG ref;
- hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags);
- ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.rcSource.right = 222;
- video_info.rcSource.bottom = 333;
- video_info.rcTarget.right = 444;
- video_info.rcTarget.bottom = 666;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb555_mt, &rgb555_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format);
Again, fine with the patch as is, but as an alternative you might use non-static-const local variables; it could make the translation a bit clearer. I could go either way with this, so your call ;-)
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags);
- ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- ref = IAMMultiMediaStream_Release(mmstream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
- IDirectDrawMediaStream_Release(ddraw_stream);
- ref = IMediaStream_Release(stream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -5936,6 +6241,7 @@ START_TEST(amstream) test_ddrawstream_getsetdirectdraw(); test_ddrawstream_receive_connection(); test_ddrawstream_create_sample();
test_ddrawstream_get_format();
test_ddrawstreamsample_get_media_stream();
On Tuesday, 8 September 2020 23:37:31 +07 you wrote:
On 9/5/20 1:04 PM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 98 ++++++++++- dlls/amstream/tests/amstream.c | 306 +++++++++++++++++++++++++++++++++ 2 files changed, 396 insertions(+), 8 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..eb8e35b5ac4 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -47,6 +47,7 @@ struct ddraw_stream
IPin *peer; IMemAllocator *allocator; AM_MEDIA_TYPE mt;
- DDSURFACEDESC format;
};
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,> @@ -363,11 +364,40 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStr> DDSURFACEDESC *current_format, IDirectDrawPalette **palette, DDSURFACEDESC *desired_format, DWORD *flags)
{
- FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette,
desired_format, - flags);
- struct ddraw_stream *stream =
impl_from_IDirectDrawMediaStream(iface);
- TRACE("stream %p, current_format %p, palette %p, desired_format %p,
flags %p.\n", stream, current_format, palette, + desired_format, flags);
- return MS_E_NOSTREAM;
EnterCriticalSection(&stream->cs);
if (!stream->peer)
{
LeaveCriticalSection(&stream->cs);
return MS_E_NOSTREAM;
}
if (current_format)
{
*current_format = stream->format;
current_format->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
}
if (palette)
*palette = NULL;
if (desired_format)
{
*desired_format = stream->format;
desired_format->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
}
if (flags)
*flags = 0;
LeaveCriticalSection(&stream->cs);
return S_OK;
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface,> @@ -637,8 +667,12 @@ static HRESULT WINAPI ddraw_sink_Connect(IPin *iface, IPin *peer, const AM_MEDIA> static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) {
- const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER
*)mt->pbFormat; + DDPIXELFORMAT pixel_format = {sizeof(DDPIXELFORMAT)};
struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir;
DWORD width;
DWORD height;
TRACE("stream %p, peer %p, mt %p.\n", stream, peer, mt);
@@ -651,17 +685,54 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons> }
if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)
|| (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
{
LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED;
}
width = video_info->bmiHeader.biWidth;
height = abs(video_info->bmiHeader.biHeight);
pixel_format.dwFlags = DDPF_RGB;
if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8))
{
pixel_format.dwFlags |= DDPF_PALETTEINDEXED8;
pixel_format.u1.dwRGBBitCount = 8;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555))
{
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0x7c00;
pixel_format.u3.dwGBitMask = 0x03e0;
pixel_format.u4.dwBBitMask = 0x001f;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
{
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0xf800;
pixel_format.u3.dwGBitMask = 0x07e0;
pixel_format.u4.dwBBitMask = 0x001f;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24))
{
pixel_format.u1.dwRGBBitCount = 24;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32))
{
pixel_format.u1.dwRGBBitCount = 32;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
}
else
{
LeaveCriticalSection(&stream->cs);
return VFW_E_TYPE_NOT_ACCEPTED;
}
IPin_QueryDirection(peer, &dir); if (dir != PINDIR_OUTPUT) {
@@ -673,6 +744,11 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons> CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
stream->format.dwWidth = width;
stream->format.dwHeight = height;
if (!(stream->format.dwFlags & DDSD_PIXELFORMAT))
stream->format.ddpfPixelFormat = pixel_format;
LeaveCriticalSection(&stream->cs);
return S_OK;
@@ -981,6 +1057,12 @@ HRESULT ddraw_stream_create(IUnknown *outer, void **out)> object->IPin_iface.lpVtbl = &ddraw_sink_vtbl; object->ref = 1;
- object->format.dwSize = sizeof(DDSURFACEDESC);
- object->format.dwFlags = DDSD_CAPS;
- object->format.dwWidth = 100;
- object->format.dwHeight = 100;
- object->format.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY |
DDSCAPS_OFFSCREENPLAIN; +
InitializeCriticalSection(&object->cs); TRACE("Created ddraw stream %p.\n", object);
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index f4c033a1807..2a69ff60fc3 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,164 @@ static const AM_MEDIA_TYPE audio_mt =
.pbFormat = (BYTE *)&audio_format,
};
+static const VIDEOINFO rgb8_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 8,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb555_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb565_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_BITFIELDS,
- .dwBitMasks = {0xff0000, 0x00ff00, 0x0000ff},
I think this is a mistake for {0xf800, 0x07e0, 0x001f}, right?
+};
+static const VIDEOINFO rgb24_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 24,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb32_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 32,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const AM_MEDIA_TYPE rgb8_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb8_video_info,
+};
+static const AM_MEDIA_TYPE rgb555_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb555_video_info,
+};
+static const AM_MEDIA_TYPE rgb565_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb565_video_info,
+};
+static const AM_MEDIA_TYPE rgb24_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb24_video_info,
+};
+static const AM_MEDIA_TYPE rgb32_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb32_video_info,
+};
+static const DDSURFACEDESC rgb8_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8,
- .ddpfPixelFormat.dwRGBBitCount = 8,
+};
+static const DDSURFACEDESC rgb555_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0x7c00,
- .ddpfPixelFormat.dwGBitMask = 0x03e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb565_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0xf800,
- .ddpfPixelFormat.dwGBitMask = 0x07e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb24_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 24,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
+static const DDSURFACEDESC rgb32_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 32,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";> @@ -4474,6 +4632,153 @@ static void test_ddrawstream_initialize(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
+#define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c) +static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream, + const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format) +{
- const DDPIXELFORMAT *expected_pf = &expected_format->ddpfPixelFormat;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- struct testfilter source;
- FILTER_INFO filter_info;
- PIN_INFO pin_info;
- DWORD flags;
- HRESULT hr;
- IPin *pin;
- hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void
**)&pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_QueryPinInfo(pin, &pin_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- testfilter_init(&source);
- hr = IFilterGraph_AddFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface, L"source"); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_ConnectDirect(filter_info.pGraph,
&source.source.pin.IPin_iface, pin, mt); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL,
NULL);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- memset(¤t_format, 0xcc, sizeof(current_format));
- current_format.dwSize = sizeof(current_format);
- memset(&desired_format, 0xcc, sizeof(desired_format));
- desired_format.dwSize = sizeof(desired_format);
- flags = 0xdeadbeef;
- hr = IDirectDrawMediaStream_GetFormat(stream, ¤t_format, NULL,
&desired_format, &flags); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH |
DDSD_HEIGHT | DDSD_CAPS), + "Got current format flags %#x.\n", current_format.dwFlags); + ok_(__FILE__, line)(current_format.dwWidth == 333, "Got current format width %u.\n", current_format.dwWidth); + ok_(__FILE__, line)(current_format.dwHeight == 444, "Got current format height %u.\n", current_format.dwHeight); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got current format size %u.\n", current_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got current format flags %#x.\n", current_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got current format rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got current format r bit mask %#x.\n", current_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got current format g bit mask %#x.\n", current_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got current format b bit mask %#x.\n", current_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got current format caps %#x.\n", current_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), + "Got desired format flags %#x.\n", desired_format.dwFlags); + ok_(__FILE__, line)(desired_format.dwWidth == 333, "Got desired format width %u.\n", desired_format.dwWidth); + ok_(__FILE__, line)(desired_format.dwHeight == 444, "Got desired format height %u.\n", desired_format.dwHeight); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got desired format size %u.\n", desired_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got desired format flags %#x.\n", desired_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got desired format rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got desired format r bit mask %#x.\n", desired_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got desired format g bit mask %#x.\n", desired_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got desired format b bit mask %#x.\n", desired_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got desired format caps %#x.\n", desired_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags);
I'd be fine with signing off on the patch as-is (with that rgb565 error fixed, probably), but as just a suggestion, you might try building the expected DDSURFACEDESC as a local variable and then just performing a memcmp(). That helps test all members at once, simplifies the code, and makes it (I think) quite a lot more readable. Of course, the downside is that you don't know what doesn't match if the test fails, but I'm inclined to call it worthwhile.
Changed to memcmp. I also had to change the way the format is returned in ::GetFormat: the native implementation only assigns flags, width, height, pixel format, and caps, leaving other fields unchanged.
- hr = IFilterGraph_Disconnect(filter_info.pGraph,
&source.source.pin.IPin_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_RemoveFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- IFilterGraph_Release(filter_info.pGraph);
- IBaseFilter_Release(pin_info.pFilter);
- IPin_Release(pin);
+}
+static void test_ddrawstream_get_format(void) +{
- IAMMultiMediaStream *mmstream = create_ammultimediastream();
- IDirectDrawMediaStream *ddraw_stream;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- IDirectDrawPalette *palette;
- IMediaStream *stream;
- VIDEOINFO video_info;
- AM_MEDIA_TYPE mt;
- DWORD flags;
- HRESULT hr;
- ULONG ref;
- hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL,
&MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream,
(void **)&ddraw_stream); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format,
&palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.rcSource.right = 222;
- video_info.rcSource.bottom = 333;
- video_info.rcTarget.right = 444;
- video_info.rcTarget.bottom = 666;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb555_mt,
&rgb555_format); + check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format); + check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format); + check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format);
Again, fine with the patch as is, but as an alternative you might use non-static-const local variables; it could make the translation a bit clearer. I could go either way with this, so your call ;-)
Sorry, I don't quite understand your suggestion. Could you please provide more details? I've sent v3 without this improvement for now. I'll make another version with this improvement if you think it's worthwhile.
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format,
&palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- ref = IAMMultiMediaStream_Release(mmstream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
- IDirectDrawMediaStream_Release(ddraw_stream);
- ref = IMediaStream_Release(stream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid) {
IAMMultiMediaStream *mmstream = create_ammultimediastream();
@@ -5936,6 +6241,7 @@ START_TEST(amstream)
test_ddrawstream_getsetdirectdraw(); test_ddrawstream_receive_connection(); test_ddrawstream_create_sample();
test_ddrawstream_get_format();
test_ddrawstreamsample_get_media_stream();
On 9/9/20 2:58 PM, Anton Baskanov wrote:
On Tuesday, 8 September 2020 23:37:31 +07 you wrote:
On 9/5/20 1:04 PM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 98 ++++++++++- dlls/amstream/tests/amstream.c | 306 +++++++++++++++++++++++++++++++++ 2 files changed, 396 insertions(+), 8 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..eb8e35b5ac4 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -47,6 +47,7 @@ struct ddraw_stream
IPin *peer; IMemAllocator *allocator; AM_MEDIA_TYPE mt;
- DDSURFACEDESC format;
};
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,> @@ -363,11 +364,40 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStr> DDSURFACEDESC *current_format, IDirectDrawPalette **palette, DDSURFACEDESC *desired_format, DWORD *flags)
{
- FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette,
desired_format, - flags);
- struct ddraw_stream *stream =
impl_from_IDirectDrawMediaStream(iface);
- TRACE("stream %p, current_format %p, palette %p, desired_format %p,
flags %p.\n", stream, current_format, palette, + desired_format, flags);
- return MS_E_NOSTREAM;
EnterCriticalSection(&stream->cs);
if (!stream->peer)
{
LeaveCriticalSection(&stream->cs);
return MS_E_NOSTREAM;
}
if (current_format)
{
*current_format = stream->format;
current_format->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
}
if (palette)
*palette = NULL;
if (desired_format)
{
*desired_format = stream->format;
desired_format->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
}
if (flags)
*flags = 0;
LeaveCriticalSection(&stream->cs);
return S_OK;
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface,> @@ -637,8 +667,12 @@ static HRESULT WINAPI ddraw_sink_Connect(IPin *iface, IPin *peer, const AM_MEDIA> static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) {
- const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER
*)mt->pbFormat; + DDPIXELFORMAT pixel_format = {sizeof(DDPIXELFORMAT)};
struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir;
DWORD width;
DWORD height;
TRACE("stream %p, peer %p, mt %p.\n", stream, peer, mt);
@@ -651,17 +685,54 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons> }
if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)
|| (!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555)
&& !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
{
LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED;
}
width = video_info->bmiHeader.biWidth;
height = abs(video_info->bmiHeader.biHeight);
pixel_format.dwFlags = DDPF_RGB;
if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8))
{
pixel_format.dwFlags |= DDPF_PALETTEINDEXED8;
pixel_format.u1.dwRGBBitCount = 8;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555))
{
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0x7c00;
pixel_format.u3.dwGBitMask = 0x03e0;
pixel_format.u4.dwBBitMask = 0x001f;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
{
pixel_format.u1.dwRGBBitCount = 16;
pixel_format.u2.dwRBitMask = 0xf800;
pixel_format.u3.dwGBitMask = 0x07e0;
pixel_format.u4.dwBBitMask = 0x001f;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB24))
{
pixel_format.u1.dwRGBBitCount = 24;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
}
else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32))
{
pixel_format.u1.dwRGBBitCount = 32;
pixel_format.u2.dwRBitMask = 0xff0000;
pixel_format.u3.dwGBitMask = 0x00ff00;
pixel_format.u4.dwBBitMask = 0x0000ff;
}
else
{
LeaveCriticalSection(&stream->cs);
return VFW_E_TYPE_NOT_ACCEPTED;
}
IPin_QueryDirection(peer, &dir); if (dir != PINDIR_OUTPUT) {
@@ -673,6 +744,11 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons> CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
stream->format.dwWidth = width;
stream->format.dwHeight = height;
if (!(stream->format.dwFlags & DDSD_PIXELFORMAT))
stream->format.ddpfPixelFormat = pixel_format;
LeaveCriticalSection(&stream->cs);
return S_OK;
@@ -981,6 +1057,12 @@ HRESULT ddraw_stream_create(IUnknown *outer, void **out)> object->IPin_iface.lpVtbl = &ddraw_sink_vtbl; object->ref = 1;
- object->format.dwSize = sizeof(DDSURFACEDESC);
- object->format.dwFlags = DDSD_CAPS;
- object->format.dwWidth = 100;
- object->format.dwHeight = 100;
- object->format.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY |
DDSCAPS_OFFSCREENPLAIN; +
InitializeCriticalSection(&object->cs); TRACE("Created ddraw stream %p.\n", object);
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index f4c033a1807..2a69ff60fc3 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,164 @@ static const AM_MEDIA_TYPE audio_mt =
.pbFormat = (BYTE *)&audio_format,
};
+static const VIDEOINFO rgb8_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 8,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb555_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb565_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 16,
- .bmiHeader.biCompression = BI_BITFIELDS,
- .dwBitMasks = {0xff0000, 0x00ff00, 0x0000ff},
I think this is a mistake for {0xf800, 0x07e0, 0x001f}, right?
+};
+static const VIDEOINFO rgb24_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 24,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const VIDEOINFO rgb32_video_info = +{
- .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
- .bmiHeader.biWidth = 333,
- .bmiHeader.biHeight = -444,
- .bmiHeader.biPlanes = 1,
- .bmiHeader.biBitCount = 32,
- .bmiHeader.biCompression = BI_RGB,
+};
+static const AM_MEDIA_TYPE rgb8_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb8_video_info,
+};
+static const AM_MEDIA_TYPE rgb555_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb555_video_info,
+};
+static const AM_MEDIA_TYPE rgb565_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb565_video_info,
+};
+static const AM_MEDIA_TYPE rgb24_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb24_video_info,
+};
+static const AM_MEDIA_TYPE rgb32_mt = +{
- /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
- .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFO),
- .pbFormat = (BYTE *)&rgb32_video_info,
+};
+static const DDSURFACEDESC rgb8_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8,
- .ddpfPixelFormat.dwRGBBitCount = 8,
+};
+static const DDSURFACEDESC rgb555_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0x7c00,
- .ddpfPixelFormat.dwGBitMask = 0x03e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb565_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 16,
- .ddpfPixelFormat.dwRBitMask = 0xf800,
- .ddpfPixelFormat.dwGBitMask = 0x07e0,
- .ddpfPixelFormat.dwBBitMask = 0x001f,
+};
+static const DDSURFACEDESC rgb24_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 24,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
+static const DDSURFACEDESC rgb32_format = +{
- .dwSize = sizeof(DDSURFACEDESC),
- .dwFlags = DDSD_PIXELFORMAT,
- .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
- .ddpfPixelFormat.dwFlags = DDPF_RGB,
- .ddpfPixelFormat.dwRGBBitCount = 32,
- .ddpfPixelFormat.dwRBitMask = 0xff0000,
- .ddpfPixelFormat.dwGBitMask = 0x00ff00,
- .ddpfPixelFormat.dwBBitMask = 0x0000ff,
+};
static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";> @@ -4474,6 +4632,153 @@ static void test_ddrawstream_initialize(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
+#define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c) +static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream, + const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format) +{
- const DDPIXELFORMAT *expected_pf = &expected_format->ddpfPixelFormat;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- struct testfilter source;
- FILTER_INFO filter_info;
- PIN_INFO pin_info;
- DWORD flags;
- HRESULT hr;
- IPin *pin;
- hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void
**)&pin); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_QueryPinInfo(pin, &pin_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- testfilter_init(&source);
- hr = IFilterGraph_AddFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface, L"source"); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_ConnectDirect(filter_info.pGraph,
&source.source.pin.IPin_iface, pin, mt); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL,
NULL);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- memset(¤t_format, 0xcc, sizeof(current_format));
- current_format.dwSize = sizeof(current_format);
- memset(&desired_format, 0xcc, sizeof(desired_format));
- desired_format.dwSize = sizeof(desired_format);
- flags = 0xdeadbeef;
- hr = IDirectDrawMediaStream_GetFormat(stream, ¤t_format, NULL,
&desired_format, &flags); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH |
DDSD_HEIGHT | DDSD_CAPS), + "Got current format flags %#x.\n", current_format.dwFlags); + ok_(__FILE__, line)(current_format.dwWidth == 333, "Got current format width %u.\n", current_format.dwWidth); + ok_(__FILE__, line)(current_format.dwHeight == 444, "Got current format height %u.\n", current_format.dwHeight); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got current format size %u.\n", current_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got current format flags %#x.\n", current_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got current format rgb bit count %u.\n", current_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got current format r bit mask %#x.\n", current_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got current format g bit mask %#x.\n", current_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(current_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got current format b bit mask %#x.\n", current_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got current format caps %#x.\n", current_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), + "Got desired format flags %#x.\n", desired_format.dwFlags); + ok_(__FILE__, line)(desired_format.dwWidth == 333, "Got desired format width %u.\n", desired_format.dwWidth); + ok_(__FILE__, line)(desired_format.dwHeight == 444, "Got desired format height %u.\n", desired_format.dwHeight); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwSize == sizeof(DDPIXELFORMAT), + "Got desired format size %u.\n", desired_format.ddpfPixelFormat.dwSize); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwFlags == expected_pf->dwFlags, + "Got desired format flags %#x.\n", desired_format.ddpfPixelFormat.dwFlags); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRGBBitCount == expected_pf->dwRGBBitCount, + "Got desired format rgb bit count %u.\n", desired_format.ddpfPixelFormat.dwRGBBitCount); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwRBitMask == expected_pf->dwRBitMask, + "Got desired format r bit mask %#x.\n", desired_format.ddpfPixelFormat.dwRBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwGBitMask == expected_pf->dwGBitMask, + "Got desired format g bit mask %#x.\n", desired_format.ddpfPixelFormat.dwGBitMask); + ok_(__FILE__, line)(desired_format.ddpfPixelFormat.dwBBitMask == expected_pf->dwBBitMask, + "Got desired format b bit mask %#x.\n", desired_format.ddpfPixelFormat.dwBBitMask); + ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got desired format caps %#x.\n", desired_format.ddsCaps.dwCaps); + ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags);
I'd be fine with signing off on the patch as-is (with that rgb565 error fixed, probably), but as just a suggestion, you might try building the expected DDSURFACEDESC as a local variable and then just performing a memcmp(). That helps test all members at once, simplifies the code, and makes it (I think) quite a lot more readable. Of course, the downside is that you don't know what doesn't match if the test fails, but I'm inclined to call it worthwhile.
Changed to memcmp. I also had to change the way the format is returned in ::GetFormat: the native implementation only assigns flags, width, height, pixel format, and caps, leaving other fields unchanged.
Looks good, thanks.
(I do feel like this is one of those cases where it actually is a good idea to zealously match native behaviour, knowing that the application may or may not draw conclusions from struct members but also might do something like modify the struct and then pass it straight to ddraw, which by nature is pretty strict about its parameters.)
- hr = IFilterGraph_Disconnect(filter_info.pGraph,
&source.source.pin.IPin_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
- ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IFilterGraph_RemoveFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface); + ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
- IFilterGraph_Release(filter_info.pGraph);
- IBaseFilter_Release(pin_info.pFilter);
- IPin_Release(pin);
+}
+static void test_ddrawstream_get_format(void) +{
- IAMMultiMediaStream *mmstream = create_ammultimediastream();
- IDirectDrawMediaStream *ddraw_stream;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- IDirectDrawPalette *palette;
- IMediaStream *stream;
- VIDEOINFO video_info;
- AM_MEDIA_TYPE mt;
- DWORD flags;
- HRESULT hr;
- ULONG ref;
- hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL,
&MSPID_PrimaryVideo, 0, &stream); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream,
(void **)&ddraw_stream); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format,
&palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.rcSource.right = 222;
- video_info.rcSource.bottom = 333;
- video_info.rcTarget.right = 444;
- video_info.rcTarget.bottom = 666;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format);
- check_ddrawstream_get_format(ddraw_stream, &rgb555_mt,
&rgb555_format); + check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format); + check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format); + check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format);
Again, fine with the patch as is, but as an alternative you might use non-static-const local variables; it could make the translation a bit clearer. I could go either way with this, so your call ;-)
Sorry, I don't quite understand your suggestion. Could you please provide more details? I've sent v3 without this improvement for now. I'll make another version with this improvement if you think it's worthwhile.
Sorry, to clarify, something like:
DDSURFACEDESC desc = { .dwSize = sizeof(DDSURFACEDESC), .dwFlags = DDSD_PIXELFORMAT, .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), }; VIDEOINFO vi = { .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), .bmiHeader.biWidth = 333, .bmiHeader.biHeight = -444, .bmiHeader.biPlanes = 1, }; AM_MEDIA_TYPE mt = { .majortype = MEDIATYPE_Video, .formattype = FORMAT_VideoInfo, .cbFormat = sizeof(vi), .pbFormat = (BYTE *)&vi; };
desc.ddpfPixelFormat.dwFlags = DDPF_RGB; desc.ddpfPixelFormat.dwRGBBitCount = 16; desc.ddpfPixelFormat.dwRBitMask = 0xf800; desc.ddpfPixelFormat.dwGBitMask = 0x07e0; desc.ddpfPixelFormat.dwBBitMask = 0x001f; mt.subtype = MEDIASUBTPYE_RGB565; vi.biBitCount = 16; vi.biCompression = BI_BITFIELDS; check_ddrawstream_get_format(ddraw_stream, &mt, &desc);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; desc.ddpfPixelFormat.dwRGBBitCount = 8; mt.subtype = MEDIASUBTPYE_RGB8; vi.biBitCount = 8; vi.biCompression = BI_RGB; check_ddrawstream_get_format(ddraw_stream, &mt, &desc);
Which, granted, is still a lot of code; it saves a bit of duplication at the expense of adding some more. It puts the two sides of the mapping right next to each other, but it's also not unreadable as it is. Anyway, it's more than a little quibbling ;-)
- current_format.dwSize = sizeof(current_format);
- desired_format.dwSize = sizeof(desired_format);
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format,
&palette, &desired_format, &flags); + ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
- ref = IAMMultiMediaStream_Release(mmstream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
- IDirectDrawMediaStream_Release(ddraw_stream);
- ref = IMediaStream_Release(stream);
- ok(!ref, "Got outstanding refcount %d.\n", ref);
+}
static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid) {
IAMMultiMediaStream *mmstream = create_ammultimediastream();
@@ -5936,6 +6241,7 @@ START_TEST(amstream)
test_ddrawstream_getsetdirectdraw(); test_ddrawstream_receive_connection(); test_ddrawstream_create_sample();
test_ddrawstream_get_format();
test_ddrawstreamsample_get_media_stream();