[PATCH 0/6] MR9718: amstream, quartz, ir50_32: Plumb the sample rect.
Earth 2150 uses this. This fixes a regression from 2f180106471a41fa3d95f21919b87b94d8e13e63. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/amstream/tests/amstream.c | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index b94ecb34844..a650a5ca6c2 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -8688,6 +8688,7 @@ static void test_ddrawstream_mem_allocator(void) ULONG ref; IPin *pin; LONG size; + RECT rect; DDSURFACEDESC surface_desc = { @@ -9203,6 +9204,60 @@ static void test_ddrawstream_mem_allocator(void) ref = IDirectDrawStreamSample_Release(ddraw_sample1); ok(!ref, "Got refcount %ld.\n", ref); + /* Test providing an existing surface and rect. */ + + source.query_accept_width = 100; + source.query_accept_height = 220; + source.query_accept_subtype = MEDIASUBTYPE_RGB555; + + hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(hr == S_OK, "got hr %#lx\n", hr); + SetRect(&rect, 10, 20, 110, 240); + hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &ddraw_sample1); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IDirectDrawStreamSample_Update(ddraw_sample1, SSUPDATE_ASYNC, NULL, NULL, 0); + ok(hr == MS_S_PENDING, "Got hr %#lx.\n", hr); + IDirectDrawSurface_Release(surface); + IDirectDraw_Release(ddraw); + + hr = IMemAllocator_Commit(mem_allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IMemAllocator_GetBuffer(mem_allocator, &media_sample1, NULL, NULL, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + SetRect(&expect_video_info.rcSource, 0, 0, 100, 220); + SetRect(&expect_video_info.rcTarget, 10, 20, 110, 240); + expect_video_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + expect_video_info.bmiHeader.biWidth = 336, + expect_video_info.bmiHeader.biHeight = -444, + expect_video_info.bmiHeader.biSizeImage = 336 * 444 * 2, + expect_video_info.bmiHeader.biPlanes = 1, + expect_video_info.bmiHeader.biBitCount = 16, + + hr = IMediaSample_GetMediaType(media_sample1, &sample_mt); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(IsEqualGUID(&sample_mt->majortype, &MEDIATYPE_Video), + "Got major type %s.\n", debugstr_guid(&sample_mt->majortype)); + ok(IsEqualGUID(&sample_mt->subtype, &MEDIASUBTYPE_RGB555), + "Got subtype %s.\n", debugstr_guid(&sample_mt->subtype)); + ok(sample_mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", sample_mt->bFixedSizeSamples); + ok(!sample_mt->bTemporalCompression, "Got temporal compression %d.\n", sample_mt->bTemporalCompression); + ok(sample_mt->lSampleSize == 336 * 444 * 2, + "Expected sample size %u, got %lu.\n", 336 * 444 * 2, sample_mt->lSampleSize); + ok(IsEqualGUID(&sample_mt->formattype, &FORMAT_VideoInfo), + "Got format type %s.\n", debugstr_guid(&sample_mt->formattype)); + ok(!sample_mt->pUnk, "Got pUnk %p.\n", sample_mt->pUnk); + ok(sample_mt->cbFormat == sizeof(VIDEOINFO), "Got format size %lu.\n", sample_mt->cbFormat); + todo_wine ok(!memcmp(sample_mt->pbFormat, &expect_video_info, sizeof(VIDEOINFO)), "Format blocks didn't match.\n"); + + ref = IMediaSample_Release(media_sample1); + ok(!ref, "Got refcount %ld.\n", ref); + ref = IDirectDrawStreamSample_Release(ddraw_sample1); + ok(!ref, "Got refcount %ld.\n", ref); + IMemAllocator_Release(mem_allocator); hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59097 --- dlls/amstream/ddrawstream.c | 17 ++++++++++++++++- dlls/amstream/tests/amstream.c | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index 40e7fab1e79..29e17f54542 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -1537,8 +1537,10 @@ static HRESULT WINAPI ddraw_mem_allocator_GetBuffer(IMemAllocator *iface, } sample->surface_desc.dwSize = sizeof(DDSURFACEDESC); + /* Don't pass the sample rect here; the upstream filter is expected to + * deal with it. */ if ((FAILED(hr = IDirectDrawSurface_Lock(sample->surface, - &sample->rect, &sample->surface_desc, DDLOCK_WAIT, NULL)))) + NULL, &sample->surface_desc, DDLOCK_WAIT, NULL)))) { LeaveCriticalSection(&stream->cs); return hr; @@ -2282,12 +2284,23 @@ static HRESULT WINAPI media_sample_SetActualDataLength(IMediaSample *iface, LONG static HRESULT WINAPI media_sample_GetMediaType(IMediaSample *iface, AM_MEDIA_TYPE **ret_mt) { struct ddraw_sample *sample = impl_from_IMediaSample(iface); + VIDEOINFOHEADER *video_info; TRACE("sample %p, ret_mt %p.\n", sample, ret_mt); + /* Note that this usually matches the media type we pass to QueryAccept(), + * but not if there's a sub-rect. + * That's amstream just breaking the DirectShow rules. + * The type we pass to QueryAccept() just uses the size of the sub-rect for + * everything. The type we return from GetMediaType() uses the size of the + * surface for everything except rcSource/rcTarget. */ if (!(*ret_mt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) return E_OUTOFMEMORY; set_mt_from_desc(*ret_mt, &sample->surface_desc, sample->surface_desc.lPitch); + video_info = (VIDEOINFOHEADER *)(*ret_mt)->pbFormat; + SetRect(&video_info->rcSource, 0, 0, sample->rect.right - sample->rect.left, + sample->rect.bottom - sample->rect.top); + video_info->rcTarget = sample->rect; return S_OK; } @@ -2458,6 +2471,8 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw IDirectDrawStreamSample_Release(&object->IDirectDrawStreamSample_iface); return hr; } + + SetRect(&object->rect, 0, 0, desc.dwWidth, desc.dwHeight); } *ddraw_stream_sample = &object->IDirectDrawStreamSample_iface; diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index a650a5ca6c2..55a46f60027 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -9251,7 +9251,7 @@ static void test_ddrawstream_mem_allocator(void) "Got format type %s.\n", debugstr_guid(&sample_mt->formattype)); ok(!sample_mt->pUnk, "Got pUnk %p.\n", sample_mt->pUnk); ok(sample_mt->cbFormat == sizeof(VIDEOINFO), "Got format size %lu.\n", sample_mt->cbFormat); - todo_wine ok(!memcmp(sample_mt->pbFormat, &expect_video_info, sizeof(VIDEOINFO)), "Format blocks didn't match.\n"); + ok(!memcmp(sample_mt->pbFormat, &expect_video_info, sizeof(VIDEOINFO)), "Format blocks didn't match.\n"); ref = IMediaSample_Release(media_sample1); ok(!ref, "Got refcount %ld.\n", ref); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/quartz/tests/avidec.c | 143 +++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/dlls/quartz/tests/avidec.c b/dlls/quartz/tests/avidec.c index 4a0f731fc66..74f02e63dd7 100644 --- a/dlls/quartz/tests/avidec.c +++ b/dlls/quartz/tests/avidec.c @@ -174,6 +174,113 @@ static LRESULT CALLBACK vfw_driver_proc(DWORD_PTR id, HDRVR driver, UINT msg, return sizeof(ICINFO); } + case ICM_DECOMPRESSEX_QUERY: + { + const ICDECOMPRESSEX *params = (ICDECOMPRESSEX *)lparam1; + + ok(lparam2 == sizeof(ICDECOMPRESSEX), "Got size %#Ix.\n", lparam2); + + ok(!params->dwFlags, "Got flags %#lx.\n", params->dwFlags); + ok(!params->lpSrc, "Got src pointer %p.\n", params->lpSrc); + ok(!params->lpDst, "Got dst pointer %p.\n", params->lpDst); + + if (params->lpbiSrc->biCompression != test_handler || params->lpbiSrc->biBitCount != 16) + return ICERR_BADFORMAT; + + if (params->lpbiDst && params->lpbiDst->biCompression != mmioFOURCC('N','V','1','2')) + return ICERR_BADFORMAT; + + ok(params->xDst == 10, "Got dst x %d.\n", params->xDst); + ok(params->yDst == 20, "Got dst y %d.\n", params->yDst); + ok(params->dxDst == 30, "Got dst width %d.\n", params->dxDst); + ok(params->dyDst == 40, "Got dst height %d.\n", params->dyDst); + ok(params->xSrc == 4, "Got src x %d.\n", params->xSrc); + ok(params->ySrc == 6, "Got src y %d.\n", params->ySrc); + ok(params->dxSrc == 12, "Got src width %d.\n", params->dxSrc); + ok(params->dySrc == 10, "Got src height %d.\n", params->dySrc); + + return ICERR_OK; + } + + case ICM_DECOMPRESSEX_BEGIN: + { + const ICDECOMPRESSEX *params = (ICDECOMPRESSEX *)lparam1; + + ok(lparam2 == sizeof(ICDECOMPRESSEX), "Got size %#Ix.\n", lparam2); + + ok(!params->dwFlags, "Got flags %#lx.\n", params->dwFlags); + ok(!params->lpSrc, "Got src pointer %p.\n", params->lpSrc); + ok(!params->lpDst, "Got dst pointer %p.\n", params->lpDst); + + todo_wine_if (params->lpbiSrc->biSizeImage != sink_bitmap_info.biSizeImage) + ok(!memcmp(params->lpbiSrc, &sink_bitmap_info, sizeof(BITMAPINFOHEADER)), + "Input types didn't match.\n"); + ok(!memcmp(params->lpbiDst, &source_bitmap_info, sizeof(BITMAPINFOHEADER)), + "Output types didn't match.\n"); + + ok(params->xDst == 10, "Got dst x %d.\n", params->xDst); + ok(params->yDst == 20, "Got dst y %d.\n", params->yDst); + ok(params->dxDst == 30, "Got dst width %d.\n", params->dxDst); + ok(params->dyDst == 40, "Got dst height %d.\n", params->dyDst); + ok(params->xSrc == 4, "Got src x %d.\n", params->xSrc); + ok(params->ySrc == 6, "Got src y %d.\n", params->ySrc); + ok(params->dxSrc == 12, "Got src width %d.\n", params->dxSrc); + ok(params->dySrc == 10, "Got src height %d.\n", params->dySrc); + + ok(!in_begin, "Got multiple ICM_DECOMPRESS_BEGIN messages.\n"); + in_begin = 1; + return ICERR_OK; + } + + case ICM_DECOMPRESSEX_END: + ok(!lparam1, "Got param1 %#Ix.\n", lparam1); + ok(!lparam2, "Got param2 %#Ix.\n", lparam2); + ok(in_begin, "Got unmatched ICM_DECOMPRESS_END message.\n"); + in_begin = 0; + return ICERR_OK; + + case ICM_DECOMPRESSEX: + { + BITMAPINFOHEADER expect_sink_format = sink_bitmap_info; + ICDECOMPRESSEX *params = (ICDECOMPRESSEX *)lparam1; + BYTE *output = params->lpDst, expect[200]; + unsigned int i; + + ok(in_begin, "Got ICM_DECOMPRESSEX without ICM_DECOMPRESSEX_BEGIN.\n"); + + ok(lparam2 == sizeof(ICDECOMPRESSEX), "Got size %#Ix.\n", lparam2); + + if (testmode == 5 || testmode == 6) + ok(params->dwFlags == ICDECOMPRESS_NOTKEYFRAME, "Got flags %#lx.\n", params->dwFlags); + else if (testmode == 3) + ok(params->dwFlags == ICDECOMPRESS_PREROLL, "Got flags %#lx.\n", params->dwFlags); + else + ok(params->dwFlags == 0, "Got flags %#lx.\n", params->dwFlags); + + expect_sink_format.biSizeImage = 200; + ok(!memcmp(params->lpbiSrc, &expect_sink_format, sizeof(BITMAPINFOHEADER)), + "Input types didn't match.\n"); + ok(!memcmp(params->lpbiDst, &source_bitmap_info, sizeof(BITMAPINFOHEADER)), + "Output types didn't match.\n"); + + for (i = 0; i < 200; ++i) + expect[i] = i; + ok(!memcmp(params->lpSrc, expect, 200), "Data didn't match.\n"); + for (i = 0; i < source_bitmap_info.biSizeImage; ++i) + output[i] = 111 - i; + + ok(params->xDst == 10, "Got dst x %d.\n", params->xDst); + ok(params->yDst == 20, "Got dst y %d.\n", params->yDst); + ok(params->dxDst == 30, "Got dst width %d.\n", params->dxDst); + ok(params->dyDst == 40, "Got dst height %d.\n", params->dyDst); + ok(params->xSrc == 4, "Got src x %d.\n", params->xSrc); + ok(params->ySrc == 6, "Got src y %d.\n", params->ySrc); + ok(params->dxSrc == 12, "Got src width %d.\n", params->dxSrc); + ok(params->dySrc == 10, "Got src height %d.\n", params->dySrc); + + return ICERR_OK; + } + default: ok(0, "Got unexpected message %#x.\n", msg); return ICERR_UNSUPPORTED; @@ -1659,6 +1766,8 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input, ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr); IMediaSample_Release(sample); + hr = IMemAllocator_Decommit(allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); IMemAllocator_Release(allocator); } @@ -1735,6 +1844,9 @@ static void test_streaming_events(IMediaControl *control, IPin *sink, hr = IMediaControl_Stop(control); ok(hr == S_OK, "Got hr %#lx.\n", hr); IMediaSample_Release(sample); + + hr = IMemAllocator_Decommit(allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); IMemAllocator_Release(allocator); } @@ -1761,6 +1873,7 @@ static void test_connect_pin(void) IBaseFilter *filter = create_avi_dec(); AM_MEDIA_TYPE mt, source_mt, *pmt; IPin *sink, *source, *peer; + VIDEOINFOHEADER *format; IEnumMediaTypes *enummt; IMediaControl *control; IMemInputPin *meminput; @@ -2043,6 +2156,36 @@ static void test_connect_pin(void) ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n"); + IFilterGraph2_Disconnect(graph, source); + IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface); + + testsink.mt = NULL; + + /* Test a format with nontrivial rects. This uses ICM_DECOMPRESSEX_*. */ + + req_mt.lSampleSize = source_mt.lSampleSize; + format = (VIDEOINFOHEADER *)req_mt.pbFormat; + SetRect(&format->rcSource, 4, 6, 16, 16); + SetRect(&format->rcTarget, 10, 20, 40, 60); + + hr = IPin_QueryAccept(source, &req_mt); + todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + + format->bmiHeader.biCompression = mmioFOURCC('N','V','1','2'); + source_bitmap_info = format->bmiHeader; + + hr = IPin_QueryAccept(source, &req_mt); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr == S_OK) + { + ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n"); + + test_sample_processing(control, meminput, &testsink); + } + hr = IFilterGraph2_Disconnect(graph, sink); ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IFilterGraph2_Disconnect(graph, sink); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59097 --- dlls/quartz/avidec.c | 146 +++++++++++++++++++++++++++++++++---- dlls/quartz/tests/avidec.c | 13 ++-- 2 files changed, 136 insertions(+), 23 deletions(-) diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c index 9f1a7db1586..521e0ededf6 100644 --- a/dlls/quartz/avidec.c +++ b/dlls/quartz/avidec.c @@ -127,6 +127,106 @@ static int AVIDec_DropSample(struct avi_decompressor *This, REFERENCE_TIME tStar return 0; } +static bool is_nontrivial_rect(const BITMAPINFOHEADER *header, const RECT *rect) +{ + return rect->left || rect->top || (rect->right && rect->right != header->biWidth) + || (rect->bottom && rect->bottom != header->biHeight); +} + +static bool needs_decompressex(const AM_MEDIA_TYPE *mt) +{ + const BITMAPINFOHEADER *header; + const RECT *src, *dst; + + if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2)) + { + const VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat; + + header = &format->bmiHeader; + src = &format->rcSource; + dst = &format->rcTarget; + } + else + { + const VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat; + + header = &format->bmiHeader; + src = &format->rcSource; + dst = &format->rcTarget; + } + + return is_nontrivial_rect(header, src) || is_nontrivial_rect(header, dst); +} + +static void fill_decompressex(struct avi_decompressor *filter, + ICDECOMPRESSEX *params, const AM_MEDIA_TYPE *mt) +{ + BITMAPINFOHEADER *header; + const RECT *src, *dst; + + if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2)) + { + VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat; + + header = &format->bmiHeader; + src = &format->rcSource; + dst = &format->rcTarget; + } + else + { + VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat; + + header = &format->bmiHeader; + src = &format->rcSource; + dst = &format->rcTarget; + } + + memset(params, 0, sizeof(ICDECOMPRESSEX)); + params->lpbiSrc = filter->input_format; + params->lpbiDst = header; + params->xDst = dst->left; + params->yDst = dst->top; + params->dxDst = dst->right - dst->left; + params->dyDst = dst->bottom - dst->top; + params->xSrc = src->left; + params->ySrc = src->top; + params->dxSrc = src->right - src->left; + params->dySrc = src->bottom - src->top; +} + +static LRESULT begin_decompress(struct avi_decompressor *filter) +{ + LRESULT res; + + if (needs_decompressex(&filter->source.pin.mt)) + { + ICDECOMPRESSEX params; + + fill_decompressex(filter, ¶ms, &filter->source.pin.mt); + res = ICSendMessage(filter->hvid, ICM_DECOMPRESSEX_BEGIN, (DWORD_PTR)¶ms, sizeof(params)); + } + else + { + res = ICDecompressBegin(filter->hvid, filter->input_format, filter->output_format); + } + if (res) + ERR("ICDecompressEnd() failed, error %Id.\n", res); + return res; +} + +static LRESULT end_decompress(struct avi_decompressor *filter) +{ + LRESULT res; + + if (needs_decompressex(&filter->source.pin.mt)) + res = ICDecompressExEnd(filter->hvid); + else + res = ICDecompressEnd(filter->hvid); + if (res) + ERR("ICDecompressEnd() failed, error %Id.\n", res); + return res; +} + static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface, IMediaSample *pSample) { struct avi_decompressor *This = impl_from_strmbase_filter(iface->pin.filter); @@ -183,10 +283,9 @@ static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface, } else { - if ((res = ICDecompressEnd(This->hvid))) + if ((res = end_decompress(This))) { DeleteMediaType(mt); - ERR("ICDecompressEnd() failed, error %Id.\n", res); IMediaSample_Release(pOutSample); return E_FAIL; } @@ -201,9 +300,8 @@ static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface, DeleteMediaType(mt); - if ((res = ICDecompressBegin(This->hvid, This->input_format, This->output_format))) + if ((res = begin_decompress(This))) { - ERR("ICDecompressBegin() failed, error %Id.\n", res); IMediaSample_Release(pOutSample); return E_FAIL; } @@ -238,7 +336,20 @@ static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface, flags |= ICDECOMPRESS_HURRYUP; LeaveCriticalSection(&This->late_cs); - res = ICDecompress(This->hvid, flags, This->input_format, pbSrcStream, This->output_format, pbDstStream); + if (needs_decompressex(&This->source.pin.mt)) + { + ICDECOMPRESSEX params; + + fill_decompressex(This, ¶ms, &This->source.pin.mt); + params.lpSrc = pbSrcStream; + params.lpDst = pbDstStream; + params.dwFlags = flags; + res = ICSendMessage(This->hvid, ICM_DECOMPRESSEX, (DWORD_PTR)¶ms, sizeof(params)); + } + else + { + res = ICDecompress(This->hvid, flags, This->input_format, pbSrcStream, This->output_format, pbDstStream); + } if (res != ICERR_OK) ERR("Failed to decompress, error %Id.\n", res); @@ -362,8 +473,19 @@ static HRESULT avi_decompressor_source_query_accept(struct strmbase_pin *iface, sink_format = (VIDEOINFOHEADER *)filter->sink.pin.mt.pbFormat; format = (VIDEOINFOHEADER *)mt->pbFormat; - if (ICDecompressQuery(filter->hvid, &sink_format->bmiHeader, &format->bmiHeader)) - return S_FALSE; + if (needs_decompressex(mt)) + { + ICDECOMPRESSEX params; + + fill_decompressex(filter, ¶ms, mt); + if (ICSendMessage(filter->hvid, ICM_DECOMPRESSEX_QUERY, (DWORD_PTR)¶ms, sizeof(params))) + return S_FALSE; + } + else + { + if (ICDecompressQuery(filter->hvid, &sink_format->bmiHeader, &format->bmiHeader)) + return S_FALSE; + } return S_OK; } @@ -629,11 +751,8 @@ static HRESULT avi_decompressor_init_stream(struct strmbase_filter *iface) filter->late = -1; LeaveCriticalSection(&filter->late_cs); - if ((res = ICDecompressBegin(filter->hvid, filter->input_format, filter->output_format))) - { - ERR("ICDecompressBegin() failed, error %Id.\n", res); + if ((res = begin_decompress(filter))) return E_FAIL; - } if (FAILED(hr = IMemAllocator_Commit(filter->source.pAllocator))) ERR("Failed to commit allocator, hr %#lx.\n", hr); @@ -654,13 +773,10 @@ static HRESULT avi_decompressor_cleanup_stream(struct strmbase_filter *iface) if (filter->hvid) { EnterCriticalSection(&filter->filter.stream_cs); - res = ICDecompressEnd(filter->hvid); + res = end_decompress(filter); LeaveCriticalSection(&filter->filter.stream_cs); if (res) - { - ERR("ICDecompressEnd() failed, error %Id.\n", res); return E_FAIL; - } } return S_OK; diff --git a/dlls/quartz/tests/avidec.c b/dlls/quartz/tests/avidec.c index 74f02e63dd7..1472c5f21c6 100644 --- a/dlls/quartz/tests/avidec.c +++ b/dlls/quartz/tests/avidec.c @@ -2169,22 +2169,19 @@ static void test_connect_pin(void) SetRect(&format->rcTarget, 10, 20, 40, 60); hr = IPin_QueryAccept(source, &req_mt); - todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); format->bmiHeader.biCompression = mmioFOURCC('N','V','1','2'); source_bitmap_info = format->bmiHeader; hr = IPin_QueryAccept(source, &req_mt); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n"); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n"); - test_sample_processing(control, meminput, &testsink); - } + test_sample_processing(control, meminput, &testsink); hr = IFilterGraph2_Disconnect(graph, sink); ok(hr == S_OK, "Got hr %#lx.\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/ir50_32/tests/ir50_32.c | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/dlls/ir50_32/tests/ir50_32.c b/dlls/ir50_32/tests/ir50_32.c index 8817423279e..00106fb2700 100644 --- a/dlls/ir50_32/tests/ir50_32.c +++ b/dlls/ir50_32/tests/ir50_32.c @@ -91,7 +91,15 @@ static void test_formats(void) out->bmiHeader.biWidth = 640; ret = ICDecompressQuery(hic, &in, out); ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + out->bmiHeader.biHeight = 480; + ret = ICDecompressQuery(hic, &in, out); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + out->bmiHeader.biWidth = 160; + out->bmiHeader.biHeight = 120; + ret = ICDecompressQuery(hic, &in, out); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); out->bmiHeader.biWidth = 320; + out->bmiHeader.biHeight = 240; out->bmiHeader.biBitCount = 8; ret = ICDecompressQuery(hic, &in, out); @@ -137,6 +145,37 @@ static void test_formats(void) ret = ICDecompressEnd(hic); ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 32, 24, NULL, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 20, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 20, 320, 240, NULL, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 0, 0); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 320, 240); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 160, 120); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + + out->bmiHeader.biWidth = 640; + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 240); + todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + out->bmiHeader.biHeight = 480; + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 480); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + + ret = ICDecompressExBegin(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICDecompressExEnd(hic); + todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ret = ICClose(hic); ok(!ret, "Got %Id.\n", ret); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
From: Elizabeth Figura <zfigura(a)codeweavers.com> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59097 --- dlls/ir50_32/ir50.c | 110 ++++++++++++++++++++++++----------- dlls/ir50_32/tests/ir50_32.c | 16 ++--- 2 files changed, 84 insertions(+), 42 deletions(-) diff --git a/dlls/ir50_32/ir50.c b/dlls/ir50_32/ir50.c index 29e6e0968d1..4959fd6b44f 100644 --- a/dlls/ir50_32/ir50.c +++ b/dlls/ir50_32/ir50.c @@ -63,16 +63,16 @@ IV50_Open( const ICINFO *icinfo ) return (LRESULT)decoder; } -static LRESULT -IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) +static LRESULT decompress_query( ICDECOMPRESSEX *params ) { - TRACE("ICM_DECOMPRESS_QUERY %p %p\n", in, out); + const BITMAPINFO *in = (BITMAPINFO *)params->lpbiSrc, *out = (BITMAPINFO *)params->lpbiDst; TRACE("in->planes = %d\n", in->bmiHeader.biPlanes); TRACE("in->bpp = %d\n", in->bmiHeader.biBitCount); TRACE("in->height = %ld\n", in->bmiHeader.biHeight); TRACE("in->width = %ld\n", in->bmiHeader.biWidth); TRACE("in->compr = %#lx\n", in->bmiHeader.biCompression); + TRACE("in offset (%d,%d), size %dx%d\n", params->xSrc, params->ySrc, params->dxSrc, params->dySrc); if (compare_fourcc(in->bmiHeader.biCompression, IV50_MAGIC)) { @@ -80,6 +80,13 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) return ICERR_BADFORMAT; } + if (params->xSrc || params->ySrc || params->dxSrc != in->bmiHeader.biWidth + || params->dySrc != in->bmiHeader.biHeight) + { + TRACE("nontrivial source rect\n"); + return ICERR_BADFORMAT; + } + /* output must be same dimensions as input */ if ( out ) { @@ -88,6 +95,7 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) TRACE("out->height = %ld\n", out->bmiHeader.biHeight); TRACE("out->width = %ld\n", out->bmiHeader.biWidth); TRACE("out->compr = %#lx\n", out->bmiHeader.biCompression); + TRACE("out offset (%d,%d), size %dx%d\n", params->xDst, params->yDst, params->dxDst, params->dyDst); if (out->bmiHeader.biCompression == BI_RGB) { @@ -107,8 +115,7 @@ IV50_DecompressQuery( LPBITMAPINFO in, LPBITMAPINFO out ) return ICERR_BADFORMAT; } - if (in->bmiHeader.biHeight != abs(out->bmiHeader.biHeight) - || in->bmiHeader.biWidth != out->bmiHeader.biWidth) + if (in->bmiHeader.biWidth != params->dxDst || in->bmiHeader.biHeight != params->dyDst) { TRACE("incompatible output dimensions requested\n"); return ICERR_BADPARAM; @@ -142,14 +149,15 @@ IV50_DecompressGetFormat( LPBITMAPINFO in, LPBITMAPINFO out ) return offsetof(BITMAPINFO, bmiColors[256]); } -static LRESULT IV50_DecompressBegin( IMFTransform *decoder, LPBITMAPINFO in, LPBITMAPINFO out ) +static LRESULT decompress_begin( IMFTransform *decoder, ICDECOMPRESSEX *params ) { + const BITMAPINFO *in = (BITMAPINFO *)params->lpbiSrc, *out = (BITMAPINFO *)params->lpbiDst; IMFMediaType *input_type, *output_type; const GUID *output_subtype; LRESULT r = ICERR_INTERNAL; unsigned int stride; - TRACE("ICM_DECOMPRESS_BEGIN %p %p %p\n", decoder, in, out); + TRACE( "decoder %p, in %p, out %p.\n", decoder, in, out ); if ( !decoder ) return ICERR_BADPARAM; @@ -189,9 +197,8 @@ static LRESULT IV50_DecompressBegin( IMFTransform *decoder, LPBITMAPINFO in, LPB if ( FAILED(IMFMediaType_SetGUID( output_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video )) || FAILED(IMFMediaType_SetGUID( output_type, &MF_MT_SUBTYPE, output_subtype )) ) goto done; - if ( FAILED(IMFMediaType_SetUINT64( - output_type, &MF_MT_FRAME_SIZE, - make_uint64( out->bmiHeader.biWidth, abs(out->bmiHeader.biHeight) ) )) ) + if (FAILED(IMFMediaType_SetUINT64( output_type, &MF_MT_FRAME_SIZE, + make_uint64( params->dxDst, params->dyDst ) ))) goto done; if ( FAILED(IMFMediaType_SetUINT32( output_type, &MF_MT_DEFAULT_STRIDE, stride)) ) goto done; @@ -208,7 +215,7 @@ done: return r; } -static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD size ) +static LRESULT decompress( IMFTransform *decoder, ICDECOMPRESSEX *params ) { IMFSample *in_sample = NULL, *out_sample = NULL; IMFMediaBuffer *in_buf = NULL, *out_buf = NULL; @@ -218,12 +225,12 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD HRESULT hr; LRESULT r = ICERR_INTERNAL; - TRACE("ICM_DECOMPRESS %p %p %lu\n", decoder, icd, size); + TRACE( "decoder %p, params %p.\n", decoder, params ); if ( FAILED(MFCreateSample( &in_sample )) ) return ICERR_INTERNAL; - if ( FAILED(MFCreateMemoryBuffer( icd->lpbiInput->biSizeImage, &in_buf )) ) + if ( FAILED(MFCreateMemoryBuffer( params->lpbiSrc->biSizeImage, &in_buf )) ) goto done; if ( FAILED(IMFSample_AddBuffer( in_sample, in_buf )) ) @@ -232,7 +239,7 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( FAILED(MFCreateSample( &out_sample )) ) goto done; - if ( FAILED(MFCreateMemoryBuffer( icd->lpbiOutput->biSizeImage, &out_buf )) ) + if ( FAILED(MFCreateMemoryBuffer( params->lpbiDst->biSizeImage, &out_buf )) ) goto done; if ( FAILED(IMFSample_AddBuffer( out_sample, out_buf )) ) @@ -241,12 +248,12 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( FAILED(IMFMediaBuffer_Lock( in_buf, &data, NULL, NULL ))) goto done; - memcpy( data, icd->lpInput, icd->lpbiInput->biSizeImage ); + memcpy( data, params->lpSrc, params->lpbiSrc->biSizeImage ); if ( FAILED(IMFMediaBuffer_Unlock( in_buf )) ) goto done; - if ( FAILED(IMFMediaBuffer_SetCurrentLength( in_buf, icd->lpbiInput->biSizeImage )) ) + if ( FAILED(IMFMediaBuffer_SetCurrentLength( in_buf, params->lpbiSrc->biSizeImage )) ) goto done; if ( FAILED(IMFTransform_ProcessInput( decoder, 0, in_sample, 0 )) ) @@ -261,15 +268,17 @@ static LRESULT IV50_Decompress( IMFTransform *decoder, ICDECOMPRESS *icd, DWORD if ( SUCCEEDED(hr) ) { - LONG width = icd->lpbiOutput->biWidth * (icd->lpbiOutput->biBitCount / 8); - LONG height = abs( icd->lpbiOutput->biHeight ); + LONG depth = params->lpbiDst->biBitCount / 8; + LONG width = params->lpbiDst->biWidth * depth; LONG stride = (width + 3) & ~3; - BYTE *output = (BYTE *)icd->lpOutput; + BYTE *output = params->lpDst; if ( FAILED(IMFMediaBuffer_Lock( out_buf, &data, NULL, NULL ))) goto done; - MFCopyImage( output, stride, data, stride, width, height ); + output += params->yDst * stride; + output += params->xDst * depth; + MFCopyImage( output, stride, data, stride, params->dxDst * depth, params->dyDst ); IMFMediaBuffer_Unlock( out_buf ); r = ICERR_OK; @@ -314,6 +323,21 @@ static LRESULT IV50_GetInfo( ICINFO *icinfo, DWORD dwSize ) return sizeof(ICINFO); } +static void fill_decompressex_params( ICDECOMPRESSEX *params, + BITMAPINFOHEADER *src, BITMAPINFOHEADER *dst ) +{ + memset( params, 0, sizeof(*params) ); + params->lpbiSrc = src; + params->lpbiDst = dst; + params->dxSrc = src->biWidth; + params->dySrc = src->biHeight; + if (dst) + { + params->dxDst = dst->biWidth; + params->dyDst = abs(dst->biHeight); + } +} + /*********************************************************************** * DriverProc (IR50_32.@) */ @@ -353,8 +377,15 @@ LRESULT WINAPI IV50_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, break; case ICM_DECOMPRESS_QUERY: - r = IV50_DecompressQuery( (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); - break; + { + ICDECOMPRESSEX params; + + fill_decompressex_params( ¶ms, (BITMAPINFOHEADER *)lParam1, (BITMAPINFOHEADER *)lParam2 ); + return decompress_query( ¶ms ); + } + + case ICM_DECOMPRESSEX_QUERY: + return decompress_query( (ICDECOMPRESSEX *)lParam1 ); case ICM_DECOMPRESS_GET_FORMAT: r = IV50_DecompressGetFormat( (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); @@ -365,23 +396,34 @@ LRESULT WINAPI IV50_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, break; case ICM_DECOMPRESS: - r = IV50_Decompress( decoder, (ICDECOMPRESS *) lParam1, (DWORD) lParam2 ); - break; + { + const ICDECOMPRESS *params = (ICDECOMPRESS *)lParam1; + ICDECOMPRESSEX ex_params; + + fill_decompressex_params( &ex_params, params->lpbiInput, params->lpbiOutput ); + ex_params.dwFlags = params->dwFlags; + ex_params.lpSrc = params->lpInput; + ex_params.lpDst = params->lpOutput; + return decompress( decoder, &ex_params ); + } + + case ICM_DECOMPRESSEX: + return decompress( decoder, (ICDECOMPRESSEX *)lParam1 ); case ICM_DECOMPRESS_BEGIN: - r = IV50_DecompressBegin( decoder, (LPBITMAPINFO) lParam1, (LPBITMAPINFO) lParam2 ); - break; + { + ICDECOMPRESSEX params; - case ICM_DECOMPRESS_END: - r = ICERR_OK; - break; + fill_decompressex_params( ¶ms, (BITMAPINFOHEADER *)lParam1, (BITMAPINFOHEADER *)lParam2 ); + return decompress_begin( decoder, ¶ms ); + } - case ICM_DECOMPRESSEX_QUERY: - FIXME("ICM_DECOMPRESSEX_QUERY\n"); - break; + case ICM_DECOMPRESSEX_BEGIN: + return decompress_begin( decoder, (ICDECOMPRESSEX *)lParam1 ); - case ICM_DECOMPRESSEX: - FIXME("ICM_DECOMPRESSEX\n"); + case ICM_DECOMPRESS_END: + case ICM_DECOMPRESSEX_END: + r = ICERR_OK; break; case ICM_COMPRESS_QUERY: diff --git a/dlls/ir50_32/tests/ir50_32.c b/dlls/ir50_32/tests/ir50_32.c index 00106fb2700..510660a2b30 100644 --- a/dlls/ir50_32/tests/ir50_32.c +++ b/dlls/ir50_32/tests/ir50_32.c @@ -146,7 +146,7 @@ static void test_formats(void) ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, NULL, NULL, 0, 0, 0, 0); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 32, 24, NULL, NULL, 0, 0, 0, 0); todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0); @@ -156,25 +156,25 @@ static void test_formats(void) ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 20, 320, 240, NULL, NULL, 0, 0, 0, 0); todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 0, 0); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 160, 120); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); out->bmiHeader.biWidth = 640; ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 240); - todo_wine ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); + ok(ret == ICERR_BADPARAM, "Got %Id.\n", ret); out->bmiHeader.biHeight = 480; ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 0, 0, 640, 480); todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExQuery(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExBegin(hic, 0, &in, NULL, 0, 0, 320, 240, &out->bmiHeader, NULL, 20, 20, 320, 240); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICDecompressExEnd(hic); - todo_wine ok(ret == ICERR_OK, "Got %Id.\n", ret); + ok(ret == ICERR_OK, "Got %Id.\n", ret); ret = ICClose(hic); ok(!ret, "Got %Id.\n", ret); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9718
participants (2)
-
Elizabeth Figura -
Elizabeth Figura (@zfigura)