Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 46 ++++++++++- dlls/amstream/tests/amstream.c | 135 +++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..0a291f37214 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); + + EnterCriticalSection(&stream->cs);
- return MS_E_NOSTREAM; + 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,6 +667,7 @@ 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; struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir;
@@ -673,6 +704,9 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
+ stream->format.dwWidth = video_info->bmiHeader.biWidth; + stream->format.dwHeight = abs(video_info->bmiHeader.biHeight); + LeaveCriticalSection(&stream->cs);
return S_OK; @@ -981,6 +1015,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..934639258d6 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,26 @@ static const AM_MEDIA_TYPE audio_mt = .pbFormat = (BYTE *)&audio_format, };
+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 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 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 +4494,120 @@ static void test_ddrawstream_initialize(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void check_ddrawstream_get_format(IDirectDrawMediaStream *ddraw_stream) +{ + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + IDirectDrawPalette *palette; + DWORD flags; + HRESULT hr; + + memset(¤t_format, 0xcc, sizeof(current_format)); + current_format.dwSize = sizeof(current_format); + palette = (IDirectDrawPalette *)0xdeadbeef; + memset(&desired_format, 0xcc, sizeof(desired_format)); + desired_format.dwSize = sizeof(desired_format); + flags = 0xdeadbeef; + hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS), "Got flags %#x.\n", current_format.dwFlags); + ok(current_format.dwWidth == 333, "Got width %u.\n", current_format.dwWidth); + ok(current_format.dwHeight == 444, "Got height %u.\n", current_format.dwHeight); + ok(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY), + "Got caps %#x.\n", current_format.ddsCaps.dwCaps); + ok(palette == NULL, "Got palette %p.\n", palette); + ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), "Got flags %#x.\n", desired_format.dwFlags); + ok(desired_format.dwWidth == 333, "Got width %u.\n", desired_format.dwWidth); + ok(desired_format.dwHeight == 444, "Got height %u.\n", desired_format.dwHeight); + ok(flags == 0, "Got flags %#x.\n", flags); +} + +static void test_ddrawstream_get_format(void) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + IDirectDrawMediaStream *ddraw_stream; + DDSURFACEDESC current_format; + DDSURFACEDESC desired_format; + IDirectDrawPalette *palette; + struct testfilter source; + IGraphBuilder *graph; + IMediaStream *stream; + VIDEOINFO video_info; + AM_MEDIA_TYPE mt; + DWORD flags; + HRESULT hr; + ULONG ref; + IPin *pin; + + 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); + + 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; + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_ddrawstream_get_format(ddraw_stream); + + hr = IGraphBuilder_Disconnect(graph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + video_info = rgb32_video_info; + video_info.bmiHeader.biHeight = 444; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_ddrawstream_get_format(ddraw_stream); + + hr = IGraphBuilder_Disconnect(graph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface); + 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); + + 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); + ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface); + 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 +6070,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 | 69 ++++++- dlls/amstream/tests/amstream.c | 347 +++++++++++++++++++++++++++++++++ 2 files changed, 413 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0a291f37214..a713b80be45 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -401,11 +401,74 @@ 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 (!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_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) + stream->format.dwWidth = format->dwWidth; + if (format->dwFlags & DDSD_HEIGHT) + 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 934639258d6..2ce72d4f1c1 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,47 @@ 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), @@ -61,6 +102,46 @@ static const VIDEOINFO rgb32_video_info = .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 */ @@ -71,6 +152,63 @@ static const AM_MEDIA_TYPE rgb32_mt = .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}";
@@ -4608,6 +4746,214 @@ static void test_ddrawstream_get_format(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void check_ddrawstream_set_format(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(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_QueryPinInfo(pin, &pin_info); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + testfilter_init(&source); + + hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source"); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL); + ok(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(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(hr == S_OK, "Got hr %#x.\n", hr); + if (format->dwFlags & DDSD_PIXELFORMAT) + { + ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT), + "Got flags %#x.\n", current_format.dwFlags); + ok(memcmp(¤t_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0, + "Pixel format didn't match.\n"); + } + else + { + ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS), + "Got flags %#x.\n", current_format.dwFlags); + } + ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), + "Got flags %#x.\n", desired_format.dwFlags); + ok(flags == 0, "Got flags %#x.\n", flags); + + hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph_Disconnect(filter_info.pGraph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + } + + hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface); + ok(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, + }; + static const DDSURFACEDESC yuv32_format = + { + .dwSize = sizeof(DDSURFACEDESC), + .dwFlags = DDSD_PIXELFORMAT, + .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT), + .ddpfPixelFormat.dwFlags = DDPF_YUV, + .ddpfPixelFormat.dwYUVBitCount = 32, + .ddpfPixelFormat.dwYBitMask = 0xff0000, + .ddpfPixelFormat.dwUBitMask = 0x00ff00, + .ddpfPixelFormat.dwVBitMask = 0x0000ff, + }; + + 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); + + format = rgb32_format; + format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA | DDPF_FOURCC + | 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 = 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); + check_ddrawstream_set_format(ddraw_stream, &yuv32_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 = 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(); @@ -6071,6 +6417,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();
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 69 ++++++- dlls/amstream/tests/amstream.c | 347 +++++++++++++++++++++++++++++++++ 2 files changed, 413 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0a291f37214..a713b80be45 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -401,11 +401,74 @@ 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 (!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_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)
stream->format.dwWidth = format->dwWidth;
- if (format->dwFlags & DDSD_HEIGHT)
stream->format.dwHeight = format->dwHeight;
Adding a brief test for omitted width/height seems like a good idea.
I also notice that this function would ignore modified caps; is that right? That could use a test or two as well.
- 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 934639258d6..2ce72d4f1c1 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,47 @@ 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), @@ -61,6 +102,46 @@ static const VIDEOINFO rgb32_video_info = .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 */ @@ -71,6 +152,63 @@ static const AM_MEDIA_TYPE rgb32_mt = .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}";
@@ -4608,6 +4746,214 @@ static void test_ddrawstream_get_format(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void check_ddrawstream_set_format(IDirectDrawMediaStream *stream,
const DDSURFACEDESC *format, const AM_MEDIA_TYPE *mt, HRESULT expected_hr)
It would probably be a good idea to add a __LINE__ parameter to this, though as far as I'm concerned it's not strictly necessary.
+{
- struct testfilter source;
- FILTER_INFO filter_info;
- PIN_INFO pin_info;
- HRESULT hr;
- IPin *pin;
- hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_QueryPinInfo(pin, &pin_info);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- testfilter_init(&source);
- hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL);
- ok(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(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(hr == S_OK, "Got hr %#x.\n", hr);
if (format->dwFlags & DDSD_PIXELFORMAT)
{
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
"Got flags %#x.\n", current_format.dwFlags);
ok(memcmp(¤t_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
"Pixel format didn't match.\n");
}
else
{
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS),
"Got flags %#x.\n", current_format.dwFlags);
}
ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
"Got flags %#x.\n", desired_format.dwFlags);
ok(flags == 0, "Got flags %#x.\n", flags);
hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- }
- hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
- ok(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,
- };
- static const DDSURFACEDESC yuv32_format =
- {
.dwSize = sizeof(DDSURFACEDESC),
.dwFlags = DDSD_PIXELFORMAT,
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
.ddpfPixelFormat.dwFlags = DDPF_YUV,
.ddpfPixelFormat.dwYUVBitCount = 32,
.ddpfPixelFormat.dwYBitMask = 0xff0000,
.ddpfPixelFormat.dwUBitMask = 0x00ff00,
.ddpfPixelFormat.dwVBitMask = 0x0000ff,
- };
This isn't exactly an interesting YUV test, though. (I'm not even sure if I've seen such a YUV format.) You probably want to test with things like YUY2, UYVY, AYUV.
[I'm not immediately sure how planar formats interact with the "mask" parameters, or if DirectDraw even supports planar formats, but if so, I'd also test at least NV12 and YV12.]
While we're here, I'd be kind of curious to see if ARGB32 is recognized.
- 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);
- format = rgb32_format;
- format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA | DDPF_FOURCC
| 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 = 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);
- check_ddrawstream_set_format(ddraw_stream, &yuv32_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 = 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(); @@ -6071,6 +6417,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();
On Sunday, 30 August 2020 03:30:51 +07 you wrote:
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 69 ++++++- dlls/amstream/tests/amstream.c | 347 +++++++++++++++++++++++++++++++++ 2 files changed, 413 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0a291f37214..a713b80be45 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -401,11 +401,74 @@ 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 (!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_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)
stream->format.dwWidth = format->dwWidth;
- if (format->dwFlags & DDSD_HEIGHT)
stream->format.dwHeight = format->dwHeight;
Adding a brief test for omitted width/height seems like a good idea.
I also notice that this function would ignore modified caps; is that right? That could use a test or two as well.
- 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 934639258d6..2ce72d4f1c1 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,47 @@ 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),
@@ -61,6 +102,46 @@ static const VIDEOINFO rgb32_video_info =
.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 */
@@ -71,6 +152,63 @@ static const AM_MEDIA_TYPE rgb32_mt =
.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}";> @@ -4608,6 +4746,214 @@ static void test_ddrawstream_get_format(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
+static void check_ddrawstream_set_format(IDirectDrawMediaStream *stream,
const DDSURFACEDESC *format, const AM_MEDIA_TYPE *mt, HRESULT
expected_hr)
It would probably be a good idea to add a __LINE__ parameter to this, though as far as I'm concerned it's not strictly necessary.
+{
- struct testfilter source;
- FILTER_INFO filter_info;
- PIN_INFO pin_info;
- HRESULT hr;
- IPin *pin;
- hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void
**)&pin); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_QueryPinInfo(pin, &pin_info);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- testfilter_init(&source);
- hr = IFilterGraph_AddFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface, L"source"); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL);
- ok(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(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(hr == S_OK, "Got hr %#x.\n", hr);
if (format->dwFlags & DDSD_PIXELFORMAT)
{
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT |
DDSD_CAPS | DDSD_PIXELFORMAT), + "Got flags %#x.\n", current_format.dwFlags);
ok(memcmp(¤t_format.ddpfPixelFormat,
&format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0, + "Pixel format didn't match.\n");
}
else
{
ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT |
DDSD_CAPS), + "Got flags %#x.\n", current_format.dwFlags);
}
ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
"Got flags %#x.\n", desired_format.dwFlags);
ok(flags == 0, "Got flags %#x.\n", flags);
hr = IFilterGraph_Disconnect(filter_info.pGraph,
&source.source.pin.IPin_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- }
- hr = IFilterGraph_RemoveFilter(filter_info.pGraph,
&source.filter.IBaseFilter_iface); + ok(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,
- };
- static const DDSURFACEDESC yuv32_format =
- {
.dwSize = sizeof(DDSURFACEDESC),
.dwFlags = DDSD_PIXELFORMAT,
.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
.ddpfPixelFormat.dwFlags = DDPF_YUV,
.ddpfPixelFormat.dwYUVBitCount = 32,
.ddpfPixelFormat.dwYBitMask = 0xff0000,
.ddpfPixelFormat.dwUBitMask = 0x00ff00,
.ddpfPixelFormat.dwVBitMask = 0x0000ff,
- };
This isn't exactly an interesting YUV test, though. (I'm not even sure if I've seen such a YUV format.) You probably want to test with things like YUY2, UYVY, AYUV.
[I'm not immediately sure how planar formats interact with the "mask" parameters, or if DirectDraw even supports planar formats, but if so, I'd also test at least NV12 and YV12.]
Added tests with YUY2 and YV12 formats. Seems strange though that while the stream allows these formats to be set, the pin rejects connections with such media types.
While we're here, I'd be kind of curious to see if ARGB32 is recognized.
- 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); +
- format = rgb32_format;
- format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA |
DDPF_FOURCC + | 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 = 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); + check_ddrawstream_set_format(ddraw_stream, &yuv32_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 = 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();
@@ -6071,6 +6417,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();
One more comment I missed: this ignores the "palette" parameter, which is fine for now but deserves a FIXME.
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 41 +++++++++++- dlls/amstream/tests/amstream.c | 110 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index a713b80be45..dcb36d0028f 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -53,6 +53,44 @@ struct ddraw_stream static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface, const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
+static BOOL is_media_type_compatible(const AM_MEDIA_TYPE *media_type, const DDSURFACEDESC *format) +{ + const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)media_type->pbFormat; + + if ((format->dwFlags & DDSD_WIDTH) && video_info->bmiHeader.biWidth != format->dwWidth) + return FALSE; + + if ((format->dwFlags & DDSD_HEIGHT) && abs(video_info->bmiHeader.biHeight) != format->dwHeight) + return FALSE; + + if (format->dwFlags & DDSD_PIXELFORMAT) + { + const GUID *subtype = &GUID_NULL; + switch (format->ddpfPixelFormat.u1.dwRGBBitCount) + { + case 8: + subtype = &MEDIASUBTYPE_RGB8; + break; + case 16: + if (format->ddpfPixelFormat.u3.dwGBitMask == 0x7e0) + subtype = &MEDIASUBTYPE_RGB565; + else + subtype = &MEDIASUBTYPE_RGB555; + break; + case 24: + subtype = &MEDIASUBTYPE_RGB24; + break; + case 32: + subtype = &MEDIASUBTYPE_RGB32; + break; + } + if (!IsEqualGUID(&media_type->subtype, subtype)) + return FALSE; + } + + return TRUE; +} + static inline struct ddraw_stream *impl_from_IAMMediaStream(IAMMediaStream *iface) { return CONTAINING_RECORD(iface, struct ddraw_stream, IAMMediaStream_iface); @@ -750,7 +788,8 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565)) - || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)) + || !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo) + || !is_media_type_compatible(mt, &stream->format)) { LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED; diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 2ce72d4f1c1..fe1cca4036c 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -3440,7 +3440,9 @@ static void test_ddrawstream_receive_connection(void) IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream; struct testfilter source; + DDSURFACEDESC format; IMediaStream *stream; + VIDEOINFO video_info; AM_MEDIA_TYPE mt; HRESULT hr; ULONG ref; @@ -3507,6 +3509,114 @@ static void test_ddrawstream_receive_connection(void) } }
+ format = rgb8_format; + format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + format.dwWidth = 333; + format.dwHeight = 444; + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + video_info = rgb555_video_info; + video_info.bmiHeader.biWidth = 333; + video_info.bmiHeader.biHeight = 444; + mt = rgb555_mt; + mt.pbFormat = (BYTE *)&video_info; + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + video_info = rgb32_video_info; + video_info.bmiHeader.biWidth = 333; + video_info.bmiHeader.biHeight = -444; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + video_info = rgb32_video_info; + video_info.bmiHeader.biWidth = 332; + video_info.bmiHeader.biHeight = 444; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + video_info = rgb32_video_info; + video_info.bmiHeader.biWidth = 333; + video_info.bmiHeader.biHeight = 443; + mt = rgb32_mt; + mt.pbFormat = (BYTE *)&video_info; + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + format = rgb8_format; + format.dwFlags = 0; + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_Disconnect(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = IAMMultiMediaStream_Release(mmstream); ok(!ref, "Got outstanding refcount %d.\n", ref); IPin_Release(pin);
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 41 +++++++++++- dlls/amstream/tests/amstream.c | 110 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index a713b80be45..dcb36d0028f 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -53,6 +53,44 @@ struct ddraw_stream static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface, const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
+static BOOL is_media_type_compatible(const AM_MEDIA_TYPE *media_type, const DDSURFACEDESC *format) +{
- const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)media_type->pbFormat;
- if ((format->dwFlags & DDSD_WIDTH) && video_info->bmiHeader.biWidth != format->dwWidth)
return FALSE;
- if ((format->dwFlags & DDSD_HEIGHT) && abs(video_info->bmiHeader.biHeight) != format->dwHeight)
return FALSE;
- if (format->dwFlags & DDSD_PIXELFORMAT)
- {
const GUID *subtype = &GUID_NULL;
switch (format->ddpfPixelFormat.u1.dwRGBBitCount)
{
case 8:
subtype = &MEDIASUBTYPE_RGB8;
break;
case 16:
if (format->ddpfPixelFormat.u3.dwGBitMask == 0x7e0)
subtype = &MEDIASUBTYPE_RGB565;
else
subtype = &MEDIASUBTYPE_RGB555;
break;
case 24:
subtype = &MEDIASUBTYPE_RGB24;
break;
case 32:
subtype = &MEDIASUBTYPE_RGB32;
break;
}
if (!IsEqualGUID(&media_type->subtype, subtype))
return FALSE;
- }
I wonder if there's a nice way to combine the pixel format translation with the validity check from 2/5, maybe along the lines of a helper function that checks both.
- return TRUE;
+}
static inline struct ddraw_stream *impl_from_IAMMediaStream(IAMMediaStream *iface) { return CONTAINING_RECORD(iface, struct ddraw_stream, IAMMediaStream_iface); @@ -750,7 +788,8 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
|| !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
|| !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
{ LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED;|| !is_media_type_compatible(mt, &stream->format))
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 2ce72d4f1c1..fe1cca4036c 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -3440,7 +3440,9 @@ static void test_ddrawstream_receive_connection(void) IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream; struct testfilter source;
- DDSURFACEDESC format; IMediaStream *stream;
- VIDEOINFO video_info; AM_MEDIA_TYPE mt; HRESULT hr; ULONG ref;
@@ -3507,6 +3509,114 @@ static void test_ddrawstream_receive_connection(void) } }
- format = rgb8_format;
- format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
- format.dwWidth = 333;
- format.dwHeight = 444;
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb555_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb555_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = -444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 332;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = 443;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- format = rgb8_format;
- format.dwFlags = 0;
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- ref = IAMMultiMediaStream_Release(mmstream); ok(!ref, "Got outstanding refcount %d.\n", ref); IPin_Release(pin);
On Sunday, 30 August 2020 03:37:16 +07 you wrote:
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 41 +++++++++++- dlls/amstream/tests/amstream.c | 110 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index a713b80be45..dcb36d0028f 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -53,6 +53,44 @@ struct ddraw_stream
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,> const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
+static BOOL is_media_type_compatible(const AM_MEDIA_TYPE *media_type, const DDSURFACEDESC *format) +{
- const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER
*)media_type->pbFormat; +
- if ((format->dwFlags & DDSD_WIDTH) && video_info->bmiHeader.biWidth
!= format->dwWidth) + return FALSE;
- if ((format->dwFlags & DDSD_HEIGHT) &&
abs(video_info->bmiHeader.biHeight) != format->dwHeight) + return FALSE;
- if (format->dwFlags & DDSD_PIXELFORMAT)
- {
const GUID *subtype = &GUID_NULL;
switch (format->ddpfPixelFormat.u1.dwRGBBitCount)
{
case 8:
subtype = &MEDIASUBTYPE_RGB8;
break;
case 16:
if (format->ddpfPixelFormat.u3.dwGBitMask == 0x7e0)
subtype = &MEDIASUBTYPE_RGB565;
else
subtype = &MEDIASUBTYPE_RGB555;
break;
case 24:
subtype = &MEDIASUBTYPE_RGB24;
break;
case 32:
subtype = &MEDIASUBTYPE_RGB32;
break;
}
if (!IsEqualGUID(&media_type->subtype, subtype))
return FALSE;
- }
I wonder if there's a nice way to combine the pixel format translation with the validity check from 2/5, maybe along the lines of a helper function that checks both.
I've rearranged things so that the media type is now translated to pixel format in ReceiveConnection and the compatibility check is done between two pixel formats.
- return TRUE;
+}
static inline struct ddraw_stream *impl_from_IAMMediaStream(IAMMediaStream *iface) {
return CONTAINING_RECORD(iface, struct ddraw_stream, IAMMediaStream_iface);
@@ -750,7 +788,8 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons> && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB32) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB555) && !IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB565))
|| !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
|| !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
|| !is_media_type_compatible(mt, &stream->format))
{
LeaveCriticalSection(&stream->cs); return VFW_E_TYPE_NOT_ACCEPTED;
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 2ce72d4f1c1..fe1cca4036c 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -3440,7 +3440,9 @@ static void test_ddrawstream_receive_connection(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream; struct testfilter source;
DDSURFACEDESC format;
IMediaStream *stream;
VIDEOINFO video_info;
AM_MEDIA_TYPE mt; HRESULT hr; ULONG ref;
@@ -3507,6 +3509,114 @@ static void test_ddrawstream_receive_connection(void)> }
}
- format = rgb8_format;
- format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
- format.dwWidth = 333;
- format.dwHeight = 444;
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb555_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb555_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = -444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 332;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biWidth = 333;
- video_info.bmiHeader.biHeight = 443;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
- ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format,
NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb555_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb8_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format,
NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb565_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb555_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format,
NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb24_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb565_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format,
NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb32_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb24_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format,
NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb8_mt); + ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb32_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_Disconnect(pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- format = rgb8_format;
- format.dwFlags = 0;
- hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface,
&rgb565_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_Disconnect(pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = IAMMultiMediaStream_Release(mmstream); ok(!ref, "Got outstanding refcount %d.\n", ref); IPin_Release(pin);
On 9/5/20 1:05 PM, Anton Baskanov wrote:
On Sunday, 30 August 2020 03:37:16 +07 you wrote:
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 41 +++++++++++- dlls/amstream/tests/amstream.c | 110 +++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index a713b80be45..dcb36d0028f 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -53,6 +53,44 @@ struct ddraw_stream
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,> const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
+static BOOL is_media_type_compatible(const AM_MEDIA_TYPE *media_type, const DDSURFACEDESC *format) +{
- const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER
*)media_type->pbFormat; +
- if ((format->dwFlags & DDSD_WIDTH) && video_info->bmiHeader.biWidth
!= format->dwWidth) + return FALSE;
- if ((format->dwFlags & DDSD_HEIGHT) &&
abs(video_info->bmiHeader.biHeight) != format->dwHeight) + return FALSE;
- if (format->dwFlags & DDSD_PIXELFORMAT)
- {
const GUID *subtype = &GUID_NULL;
switch (format->ddpfPixelFormat.u1.dwRGBBitCount)
{
case 8:
subtype = &MEDIASUBTYPE_RGB8;
break;
case 16:
if (format->ddpfPixelFormat.u3.dwGBitMask == 0x7e0)
subtype = &MEDIASUBTYPE_RGB565;
else
subtype = &MEDIASUBTYPE_RGB555;
break;
case 24:
subtype = &MEDIASUBTYPE_RGB24;
break;
case 32:
subtype = &MEDIASUBTYPE_RGB32;
break;
}
if (!IsEqualGUID(&media_type->subtype, subtype))
return FALSE;
- }
I wonder if there's a nice way to combine the pixel format translation with the validity check from 2/5, maybe along the lines of a helper function that checks both.
I've rearranged things so that the media type is now translated to pixel format in ReceiveConnection and the compatibility check is done between two pixel formats.
Yech, on rereading my review was more than a little confused. v2 seems like an improvement regardless, though :-)
(What I kind of want to do is translate ddraw pixel formats back into amstream subtypes and compare those directly, but given that there's no other reason to do that translation, it's probably best the way you have it...)
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/ddrawstream.c | 37 +++++++++++ dlls/amstream/tests/amstream.c | 116 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index dcb36d0028f..5dc29bed033 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; @@ -304,6 +305,8 @@ static HRESULT WINAPI ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface
TRACE("stream %p, filtergraph %p.\n", stream, filtergraph);
+ stream->graph = filtergraph; + return S_OK; }
@@ -442,6 +445,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);
@@ -496,6 +503,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) stream->format.dwWidth = format->dwWidth; @@ -504,6 +512,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr if (format->dwFlags & DDSD_PIXELFORMAT) stream->format.ddpfPixelFormat = format->ddpfPixelFormat;
+ if (stream->peer && !is_media_type_compatible(&stream->mt, &stream->format)) + { + 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 fe1cca4036c..7c02bd223d4 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1005,6 +1005,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; @@ -1065,6 +1066,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); @@ -1079,6 +1090,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) { @@ -1098,10 +1128,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) @@ -4985,10 +5016,15 @@ static void test_ddrawstream_set_format(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream; + 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();
@@ -5062,6 +5098,84 @@ 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)); + + 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)); + + 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)
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 37 +++++++++++ dlls/amstream/tests/amstream.c | 116 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index dcb36d0028f..5dc29bed033 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;
@@ -304,6 +305,8 @@ static HRESULT WINAPI ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface
TRACE("stream %p, filtergraph %p.\n", stream, filtergraph);
- stream->graph = filtergraph;
- return S_OK;
}
@@ -442,6 +445,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);
@@ -496,6 +503,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) stream->format.dwWidth = format->dwWidth;
@@ -504,6 +512,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr if (format->dwFlags & DDSD_PIXELFORMAT) stream->format.ddpfPixelFormat = format->ddpfPixelFormat;
- if (stream->peer && !is_media_type_compatible(&stream->mt, &stream->format))
- {
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;
}
Falling back to the old connection type is an interesting behaviour, which, if correct, could explain the difference between the "current" and "desired" formats in GetFormat. That said, I'm probably just blind, but I don't see tests for this behaviour in this patch.
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 fe1cca4036c..7c02bd223d4 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1005,6 +1005,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;
@@ -1065,6 +1066,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); @@ -1079,6 +1090,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) { @@ -1098,10 +1128,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) @@ -4985,10 +5016,15 @@ static void test_ddrawstream_set_format(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream;
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();
@@ -5062,6 +5098,84 @@ 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));
- 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));
- 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)
On Sunday, 30 August 2020 03:52:02 +07 you wrote:
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 37 +++++++++++ dlls/amstream/tests/amstream.c | 116 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index dcb36d0028f..5dc29bed033 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;
@@ -304,6 +305,8 @@ static HRESULT WINAPI ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface> TRACE("stream %p, filtergraph %p.\n", stream, filtergraph);
stream->graph = filtergraph;
return S_OK;
}
@@ -442,6 +445,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);
@@ -496,6 +503,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)
stream->format.dwWidth = format->dwWidth;
@@ -504,6 +512,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr> if (format->dwFlags & DDSD_PIXELFORMAT)
stream->format.ddpfPixelFormat = format->ddpfPixelFormat;
- if (stream->peer && !is_media_type_compatible(&stream->mt,
&stream->format)) + {
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;
}
Falling back to the old connection type is an interesting behaviour, which, if correct, could explain the difference between the "current" and "desired" formats in GetFormat. That said, I'm probably just blind, but I don't see tests for this behaviour in this patch.
There is a test that tries to change the stream format with no media types advertised by the test source. I've added checks for current and desired formats to it and the formats seem to always be the same.
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 fe1cca4036c..7c02bd223d4 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1005,6 +1005,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;
@@ -1065,6 +1066,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);
@@ -1079,6 +1090,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)
{
@@ -1098,10 +1128,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)
@@ -4985,10 +5016,15 @@ static void test_ddrawstream_set_format(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream;
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();
@@ -5062,6 +5098,84 @@ 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)); +
- 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)); +
- 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)
On 9/5/20 1:05 PM, Anton Baskanov wrote:
On Sunday, 30 August 2020 03:52:02 +07 you wrote:
On 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 37 +++++++++++ dlls/amstream/tests/amstream.c | 116 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index dcb36d0028f..5dc29bed033 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;
@@ -304,6 +305,8 @@ static HRESULT WINAPI ddraw_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface> TRACE("stream %p, filtergraph %p.\n", stream, filtergraph);
stream->graph = filtergraph;
return S_OK;
}
@@ -442,6 +445,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);
@@ -496,6 +503,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)
stream->format.dwWidth = format->dwWidth;
@@ -504,6 +512,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStr> if (format->dwFlags & DDSD_PIXELFORMAT)
stream->format.ddpfPixelFormat = format->ddpfPixelFormat;
- if (stream->peer && !is_media_type_compatible(&stream->mt,
&stream->format)) + {
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;
}
Falling back to the old connection type is an interesting behaviour, which, if correct, could explain the difference between the "current" and "desired" formats in GetFormat. That said, I'm probably just blind, but I don't see tests for this behaviour in this patch.
There is a test that tries to change the stream format with no media types advertised by the test source. I've added checks for current and desired formats to it and the formats seem to always be the same.
Thanks, I knew I was just blind ;-)
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 fe1cca4036c..7c02bd223d4 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -1005,6 +1005,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;
@@ -1065,6 +1066,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);
@@ -1079,6 +1090,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)
{
@@ -1098,10 +1128,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)
@@ -4985,10 +5016,15 @@ static void test_ddrawstream_set_format(void)
IDirectDrawMediaStream *ddraw_stream; IAMMultiMediaStream *mmstream;
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();
@@ -5062,6 +5098,84 @@ 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)); +
- 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)); +
- 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 | 142 +++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 13 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 5dc29bed033..da5cd18df99 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -1364,19 +1364,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 7c02bd223d4..173ab9cac62 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -6424,6 +6424,81 @@ static void test_audiostreamsample_get_audio_data(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void get_ddrawstream_create_sample_desc(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(hr == S_OK, "Got hr %#x.\n", hr); + 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); + + testfilter_init(&source); + + hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + if (format1) + { + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format1, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + } + if (format2) + { + hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format2, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + } + if (mt) + { + hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + 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); + } + + hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!surface, "Expected non-NULL sufrace.\n"); + + desc->dwSize = sizeof(*desc); + hr = IDirectDrawSurface_GetSurfaceDesc(surface, desc); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ref = IDirectDrawStreamSample_Release(sample); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IDirectDrawSurface_Release(surface); + ok(!ref, "Got outstanding refcount %d.\n", ref); + 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 test_ddrawstream_create_sample(void) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -6431,6 +6506,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; @@ -6532,6 +6609,71 @@ 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 |= DDSD_WIDTH | 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); + 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(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); + + format1 = rgb32_format; + format1.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS; + format1.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000; + 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 | 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_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 8/29/20 8:51 AM, Anton Baskanov wrote:
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/amstream/ddrawstream.c | 46 ++++++++++- dlls/amstream/tests/amstream.c | 135 +++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 0d3f2d0d4b8..0a291f37214 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);
- EnterCriticalSection(&stream->cs);
- return MS_E_NOSTREAM;
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;
Could you please add a quick test to show these parameters are optional?
- LeaveCriticalSection(&stream->cs);
- return S_OK;
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface, @@ -637,6 +667,7 @@ 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; struct ddraw_stream *stream = impl_from_IPin(iface); PIN_DIRECTION dir;
@@ -673,6 +704,9 @@ static HRESULT WINAPI ddraw_sink_ReceiveConnection(IPin *iface, IPin *peer, cons CopyMediaType(&stream->mt, mt); IPin_AddRef(stream->peer = peer);
stream->format.dwWidth = video_info->bmiHeader.biWidth;
stream->format.dwHeight = abs(video_info->bmiHeader.biHeight);
LeaveCriticalSection(&stream->cs);
return S_OK;
@@ -981,6 +1015,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..934639258d6 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -51,6 +51,26 @@ static const AM_MEDIA_TYPE audio_mt = .pbFormat = (BYTE *)&audio_format, };
+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 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 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 +4494,120 @@ static void test_ddrawstream_initialize(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void check_ddrawstream_get_format(IDirectDrawMediaStream *ddraw_stream) +{
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- IDirectDrawPalette *palette;
- DWORD flags;
- HRESULT hr;
- memset(¤t_format, 0xcc, sizeof(current_format));
- current_format.dwSize = sizeof(current_format);
- palette = (IDirectDrawPalette *)0xdeadbeef;
- memset(&desired_format, 0xcc, sizeof(desired_format));
- desired_format.dwSize = sizeof(desired_format);
- flags = 0xdeadbeef;
- hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, ¤t_format, &palette, &desired_format, &flags);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS), "Got flags %#x.\n", current_format.dwFlags);
- ok(current_format.dwWidth == 333, "Got width %u.\n", current_format.dwWidth);
- ok(current_format.dwHeight == 444, "Got height %u.\n", current_format.dwHeight);
- ok(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
"Got caps %#x.\n", current_format.ddsCaps.dwCaps);
- ok(palette == NULL, "Got palette %p.\n", palette);
- ok(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT), "Got flags %#x.\n", desired_format.dwFlags);
- ok(desired_format.dwWidth == 333, "Got width %u.\n", desired_format.dwWidth);
- ok(desired_format.dwHeight == 444, "Got height %u.\n", desired_format.dwHeight);
- ok(flags == 0, "Got flags %#x.\n", flags);
+}
What worries me slightly about this is that native also seems to set the pixel format (and perhaps other members?) to reasonable values, despite not setting DDSD_PIXELFORMAT. I vaguely recall trying to fix a game that used this function an age and a half ago; I can't remember if it actually depended on those fields being initialized or if it's something I just discovered while testing. Either way it may not be a bad idea to at least check the other fields in the test (and even to check how different DirectShow pixel formats are translated).
+static void test_ddrawstream_get_format(void) +{
- IAMMultiMediaStream *mmstream = create_ammultimediastream();
- IDirectDrawMediaStream *ddraw_stream;
- DDSURFACEDESC current_format;
- DDSURFACEDESC desired_format;
- IDirectDrawPalette *palette;
- struct testfilter source;
- IGraphBuilder *graph;
- IMediaStream *stream;
- VIDEOINFO video_info;
- AM_MEDIA_TYPE mt;
- DWORD flags;
- HRESULT hr;
- ULONG ref;
- IPin *pin;
- 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);
- 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;
- hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- check_ddrawstream_get_format(ddraw_stream);
- hr = IGraphBuilder_Disconnect(graph, pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- video_info = rgb32_video_info;
- video_info.bmiHeader.biHeight = 444;
- mt = rgb32_mt;
- mt.pbFormat = (BYTE *)&video_info;
- hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- check_ddrawstream_get_format(ddraw_stream);
- hr = IGraphBuilder_Disconnect(graph, pin);
- ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
- 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);
- 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);
- ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
- 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 +6070,7 @@ START_TEST(amstream) test_ddrawstream_getsetdirectdraw(); test_ddrawstream_receive_connection(); test_ddrawstream_create_sample();
test_ddrawstream_get_format();
test_ddrawstreamsample_get_media_stream();