-- v3: winegstreamer: Implement GetOutputSizeInfo for WMV decoder. mf/tests: Test GetOutputSizeInfo for WMV decoder. winegstreamer: Implement SetOutputType for WMV decoder. winegstreamer: Implement GetOutputType for WMV decoder. mfplat: Support YVYU, NV11, MEDIASUBTYPE_RGB* media types. mfplat: Fix stride calculation for RGB24.
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mfplat/mediatype.c | 2 +- dlls/mfplat/tests/mfplat.c | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index c1c8d0048c3..fe884d34aad 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2631,7 +2631,7 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void *
static const struct uncompressed_video_format video_formats[] = { - { &MFVideoFormat_RGB24, 4, 3, 1, 0 }, + { &MFVideoFormat_RGB24, 3, 3, 1, 0 }, { &MFVideoFormat_ARGB32, 4, 3, 1, 0 }, { &MFVideoFormat_RGB32, 4, 3, 1, 0 }, { &MFVideoFormat_RGB565, 2, 3, 1, 0 }, diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index f1f61e25d00..962a9fd2251 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -4393,8 +4393,7 @@ static void test_MFCalculateImageSize(void) todo_wine_if(is_MEDIASUBTYPE_RGB(ptr->subtype) || IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr); todo_wine_if(is_MEDIASUBTYPE_RGB(ptr->subtype) - || IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11) - || (IsEqualGUID(ptr->subtype, &MFVideoFormat_RGB24) && ptr->width % 4 == 0)) + || IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4)); } @@ -4426,8 +4425,7 @@ static void test_MFGetPlaneSize(void)
hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size); ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11) - || (IsEqualGUID(ptr->subtype, &MFVideoFormat_RGB24) && ptr->width % 4 == 0)) + todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size, ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4)); } @@ -5994,13 +5992,11 @@ static void test_MFCreate2DMediaBuffer(void)
hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length); ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_RGB24) && ptr->width % 4 == 0) ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %lu for %u x %u, format %s.\n", i, length, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL); ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_RGB24) && ptr->width % 4 == 0) ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n", i, length2, ptr->width, ptr->height, wine_dbgstr_guid(ptr->subtype));
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 4 ++-- dlls/mfplat/buffer.c | 3 +++ dlls/mfplat/mediatype.c | 11 +++++++++++ dlls/mfplat/tests/mfplat.c | 12 ------------ 4 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 3c068aae743..12a4e5c6ac9 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -5752,8 +5752,8 @@ static void test_video_processor(void) && !IsEqualGUID(&guid, &MEDIASUBTYPE_Y42T)) { hr = MFCalculateImageSize(&guid, 16, 16, (UINT32 *)&input_info.cbSize); - todo_wine_if(IsEqualGUID(&guid, &MFVideoFormat_NV11) || IsEqualGUID(&guid, &MFVideoFormat_YVYU) - || IsEqualGUID(&guid, &MFVideoFormat_Y216) || IsEqualGUID(&guid, &MFVideoFormat_v410) + todo_wine_if(IsEqualGUID(&guid, &MFVideoFormat_Y216) + || IsEqualGUID(&guid, &MFVideoFormat_v410) || IsEqualGUID(&guid, &MFVideoFormat_Y41P)) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); } diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index e3d38438b88..a221c6d55b8 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -1357,6 +1357,7 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bo break; case MAKEFOURCC('I','M','C','2'): case MAKEFOURCC('I','M','C','4'): + case MAKEFOURCC('N','V','1','1'): plane_size = stride * 3 / 2 * height; break; case MAKEFOURCC('N','V','1','2'): @@ -1379,6 +1380,7 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bo case MAKEFOURCC('I','M','C','3'): case MAKEFOURCC('I','M','C','4'): case MAKEFOURCC('Y','V','1','2'): + case MAKEFOURCC('N','V','1','1'): row_alignment = MF_128_BYTE_ALIGNMENT; break; default: @@ -1397,6 +1399,7 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bo case MAKEFOURCC('Y','V','1','2'): case MAKEFOURCC('I','M','C','2'): case MAKEFOURCC('I','M','C','4'): + case MAKEFOURCC('N','V','1','1'): max_length = pitch * height * 3 / 2; break; default: diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index fe884d34aad..245922ba068 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2646,13 +2646,20 @@ static const struct uncompressed_video_format video_formats[] = { &MFVideoFormat_IMC3, 2, 3, 0, 1 }, { &MFVideoFormat_IMC4, 1, 0, 0, 1 }, { &MFVideoFormat_IYUV, 1, 0, 0, 1 }, + { &MFVideoFormat_NV11, 1, 0, 0, 1 }, { &MFVideoFormat_NV12, 1, 0, 0, 1 }, { &MFVideoFormat_D16, 2, 3, 0, 0 }, { &MFVideoFormat_L16, 2, 3, 0, 0 }, { &MFVideoFormat_UYVY, 2, 0, 0, 1 }, { &MFVideoFormat_YUY2, 2, 0, 0, 1 }, { &MFVideoFormat_YV12, 1, 0, 0, 1 }, + { &MFVideoFormat_YVYU, 2, 0, 0, 1 }, { &MFVideoFormat_A16B16G16R16F, 8, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB8, 1, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB565, 2, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB555, 2, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB24, 3, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB32, 4, 3, 1, 0 }, };
static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype) @@ -2732,6 +2739,9 @@ HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height /* 2 x 2 block, interleaving UV for half the height */ *size = ((width + 1) & ~1) * height * 3 / 2; break; + case MAKEFOURCC('N','V','1','1'): + *size = ((width + 3) & ~3) * height * 3 / 2; + break; case D3DFMT_L8: case D3DFMT_L16: case D3DFMT_D16: @@ -2772,6 +2782,7 @@ HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *si case MAKEFOURCC('Y','V','1','2'): case MAKEFOURCC('I','4','2','0'): case MAKEFOURCC('I','Y','U','V'): + case MAKEFOURCC('N','V','1','1'): *size = stride * height * 3 / 2; break; default: diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 962a9fd2251..33b17b8df41 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -4390,10 +4390,7 @@ static void test_MFCalculateImageSize(void) IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size); - todo_wine_if(is_MEDIASUBTYPE_RGB(ptr->subtype) || IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr); - todo_wine_if(is_MEDIASUBTYPE_RGB(ptr->subtype) - || IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4)); } @@ -4425,7 +4422,6 @@ static void test_MFGetPlaneSize(void)
hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size); ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(size == plane_size, "%u: unexpected plane size %lu, expected %u. Size %u x %u, format %s.\n", i, size, plane_size, ptr->width, ptr->height, wine_dbgstr_an((char*)&ptr->subtype->Data1, 4)); } @@ -5762,9 +5758,7 @@ static void test_MFGetStrideForBitmapInfoHeader(void) for (i = 0; i < ARRAY_SIZE(stride_tests); ++i) { hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride); - todo_wine_if(IsEqualGUID(stride_tests[i].subtype, &MFVideoFormat_NV11)) ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr); - todo_wine_if(IsEqualGUID(stride_tests[i].subtype, &MFVideoFormat_NV11)) ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i, wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride); } @@ -5977,10 +5971,7 @@ static void test_MFCreate2DMediaBuffer(void) continue;
hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr); - if (hr != S_OK) - continue;
hr = IMFMediaBuffer_GetMaxLength(buffer, &length); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -6121,10 +6112,7 @@ static void test_MFCreate2DMediaBuffer(void) continue;
hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->subtype->Data1, FALSE, &buffer); - todo_wine_if(IsEqualGUID(ptr->subtype, &MFVideoFormat_NV11)) ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr); - if (hr != S_OK) - continue;
hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer); ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 5 +- dlls/winegstreamer/wmv_decoder.c | 99 ++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 12 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 12a4e5c6ac9..71ab00c2944 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1178,9 +1178,11 @@ static void check_video_info_header_(int line, VIDEOINFOHEADER *info, const VIDE ok_(__FILE__, line)(info->bmiHeader.biYPelsPerMeter == expected->bmiHeader.biYPelsPerMeter, "Got unexpected bmiHeader.xxxxxx %ld, expected %ld.\n", info->bmiHeader.biYPelsPerMeter, expected->bmiHeader.biYPelsPerMeter); + todo_wine_if(expected->bmiHeader.biClrUsed != 0) ok_(__FILE__, line)(info->bmiHeader.biClrUsed == expected->bmiHeader.biClrUsed, "Got unexpected bmiHeader.biClrUsed %lu, expected %lu.\n", info->bmiHeader.biClrUsed, expected->bmiHeader.biClrUsed); + todo_wine_if(expected->bmiHeader.biClrImportant != 0) ok_(__FILE__, line)(info->bmiHeader.biClrImportant == expected->bmiHeader.biClrImportant, "Got unexpected bmiHeader.biClrImportant %lu, expected %lu.\n", info->bmiHeader.biClrImportant, expected->bmiHeader.biClrImportant); @@ -1208,6 +1210,7 @@ static void check_dmo_media_type_(int line, DMO_MEDIA_TYPE *media_type, const DM "Got unexpected formattype %s.\n", debugstr_guid(&media_type->formattype)); ok_(__FILE__, line)(media_type->pUnk == NULL, "Got unexpected pUnk %p.\n", media_type->pUnk); + todo_wine_if(expected->cbFormat && expected->cbFormat != sizeof(VIDEOINFOHEADER)) ok_(__FILE__, line)(media_type->cbFormat == expected->cbFormat, "Got unexpected cbFormat %lu, expected %lu.\n", media_type->cbFormat, expected->cbFormat); @@ -5062,14 +5065,12 @@ static void test_wmv_decoder_media_object(void) hr = IMediaObject_SetInputType(media_object, 0, NULL, DMO_SET_TYPEF_CLEAR); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputType(media_object, 0, 0, &media_type); - todo_wine ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputType returned %#lx.\n", hr);
/* Test GetOutputType after setting input type. */ init_dmo_media_type_video(input_type, &expected_input_types[0].subtype, 16, 16); hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - todo_wine check_dmo_get_output_type(media_object, expected_output_types, ARRAY_SIZE(expected_output_types));
/* Test SetOutputType without setting input type. */ diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 1b03d9aa639..3aacede1345 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -29,21 +29,45 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
-extern const GUID MFVideoFormat_VC1S; +extern const GUID MEDIASUBTYPE_VC1S;
-DEFINE_GUID(MFVideoFormat_WMV_Unknown, 0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b); +DEFINE_GUID(MEDIASUBTYPE_WMV_Unknown, 0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b); + +struct decoder_type +{ + const GUID *subtype; + WORD bpp; + DWORD compression; +};
static const GUID *const wmv_decoder_input_types[] = { - &MFVideoFormat_WMV1, - &MFVideoFormat_WMV2, + &MEDIASUBTYPE_WMV1, + &MEDIASUBTYPE_WMV2, &MEDIASUBTYPE_WMVA, &MEDIASUBTYPE_WMVP, &MEDIASUBTYPE_WVP2, - &MFVideoFormat_WMV_Unknown, - &MFVideoFormat_WVC1, - &MFVideoFormat_WMV3, - &MFVideoFormat_VC1S, + &MEDIASUBTYPE_WMV_Unknown, + &MEDIASUBTYPE_WVC1, + &MEDIASUBTYPE_WMV3, + &MEDIASUBTYPE_VC1S, +}; + +static const struct decoder_type wmv_decoder_output_types[] = +{ + { &MEDIASUBTYPE_NV12, 12, MAKEFOURCC('N', 'V', '1', '2') }, + { &MEDIASUBTYPE_YV12, 12, MAKEFOURCC('Y', 'V', '1', '2') }, + { &MEDIASUBTYPE_IYUV, 12, MAKEFOURCC('I', 'Y', 'U', 'V') }, + { &MEDIASUBTYPE_I420, 12, MAKEFOURCC('I', '4', '2', '0') }, + { &MEDIASUBTYPE_YUY2, 16, MAKEFOURCC('Y', 'U', 'Y', '2') }, + { &MEDIASUBTYPE_UYVY, 16, MAKEFOURCC('U', 'Y', 'V', 'Y') }, + { &MEDIASUBTYPE_YVYU, 16, MAKEFOURCC('Y', 'V', 'Y', 'U') }, + { &MEDIASUBTYPE_NV11, 12, MAKEFOURCC('N', 'V', '1', '1') }, + { &MEDIASUBTYPE_RGB32, 32, BI_RGB }, + { &MEDIASUBTYPE_RGB24, 24, BI_RGB }, + { &MEDIASUBTYPE_RGB565, 16, BI_BITFIELDS }, + { &MEDIASUBTYPE_RGB555, 16, BI_RGB }, + { &MEDIASUBTYPE_RGB8, 8, BI_RGB }, };
struct wmv_decoder @@ -59,6 +83,11 @@ struct wmv_decoder struct wg_format input_format; };
+static bool wg_format_is_set(struct wg_format *format) +{ + return format->major_type != WG_MAJOR_TYPE_UNKNOWN; +} + static inline struct wmv_decoder *impl_from_IUnknown(IUnknown *iface) { return CONTAINING_RECORD(iface, struct wmv_decoder, IUnknown_inner); @@ -387,8 +416,58 @@ static HRESULT WINAPI media_object_GetInputType(IMediaObject *iface, DWORD index static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) { - FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface, index, type_index, type); - return E_NOTIMPL; + struct wmv_decoder *decoder = impl_from_IMediaObject(iface); + VIDEOINFOHEADER *info; + const GUID *subtype; + LONG width, height; + UINT32 image_size; + HRESULT hr; + + TRACE("iface %p, index %lu, type_index %lu, type %p.\n", iface, index, type_index, type); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + if (type_index >= ARRAY_SIZE(wmv_decoder_output_types)) + return DMO_E_NO_MORE_ITEMS; + if (!type) + return S_OK; + if (!wg_format_is_set(&decoder->input_format)) + return DMO_E_TYPE_NOT_SET; + + width = decoder->input_format.u.video_wmv.width; + height = decoder->input_format.u.video_wmv.height; + subtype = wmv_decoder_output_types[type_index].subtype; + if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &image_size))) + { + FIXME("Failed to get image size of subtype %s.\n", debugstr_guid(subtype)); + return hr; + } + + memset(type, 0, sizeof(*type)); + type->majortype = MFMediaType_Video; + type->subtype = *subtype; + type->bFixedSizeSamples = TRUE; + type->bTemporalCompression = FALSE; + type->lSampleSize = image_size; + type->formattype = FORMAT_VideoInfo; + type->cbFormat = sizeof(VIDEOINFOHEADER); + type->pbFormat = CoTaskMemAlloc(type->cbFormat); + memset(type->pbFormat, 0, type->cbFormat); + + info = (VIDEOINFOHEADER *)type->pbFormat; + info->rcSource.right = width; + info->rcSource.bottom = height; + info->rcTarget.right = width; + info->rcTarget.bottom = height; + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = height; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = wmv_decoder_output_types[type_index].bpp; + info->bmiHeader.biCompression = wmv_decoder_output_types[type_index].compression; + info->bmiHeader.biSizeImage = image_size; + + return S_OK; }
static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index,
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 2 -- dlls/winegstreamer/wmv_decoder.c | 41 ++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 71ab00c2944..79da3d2fd1d 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -5077,14 +5077,12 @@ static void test_wmv_decoder_media_object(void) hr = IMediaObject_SetInputType(media_object, 0, NULL, DMO_SET_TYPEF_CLEAR); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_SetOutputType(media_object, 0, &media_type, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr);
/* Test SetOutputType after setting input type. */ init_dmo_media_type_video(input_type, &expected_input_types[0].subtype, 16, 16); hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - todo_wine check_dmo_set_output_type(media_object, &MEDIASUBTYPE_RGB24);
ret = IMediaObject_Release(media_object); diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 3aacede1345..4be36d803ba 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -81,6 +81,7 @@ struct wmv_decoder LONG refcount;
struct wg_format input_format; + struct wg_format output_format; };
static bool wg_format_is_set(struct wg_format *format) @@ -513,8 +514,44 @@ static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) { - FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface, index, type, flags); - return E_NOTIMPL; + struct wmv_decoder *decoder = impl_from_IMediaObject(iface); + struct wg_format wg_format; + unsigned int i; + + TRACE("iface %p, index %lu, type %p, flags %#lx,\n", iface, index, type, flags); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + + if (!type) + { + if (flags & DMO_SET_TYPEF_CLEAR) + { + memset(&decoder->output_format, 0, sizeof(decoder->output_format)); + return S_OK; + } + return E_POINTER; + } + + if (!wg_format_is_set(&decoder->input_format)) + return DMO_E_TYPE_NOT_SET; + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) + return DMO_E_TYPE_NOT_ACCEPTED; + + for (i = 0; i < ARRAY_SIZE(wmv_decoder_output_types); ++i) + if (IsEqualGUID(&type->subtype, wmv_decoder_output_types[i].subtype)) + break; + if (i == ARRAY_SIZE(wmv_decoder_output_types)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!amt_to_wg_format((const AM_MEDIA_TYPE *)type, &wg_format)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!(flags & DMO_SET_TYPEF_TEST_ONLY)) + decoder->output_format = wg_format; + + return S_OK; }
static HRESULT WINAPI media_object_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 61 ++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 79da3d2fd1d..4049e9afbd0 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4999,11 +4999,12 @@ static void test_wmv_decoder_media_object(void) {MFMediaType_Video, MEDIASUBTYPE_RGB555, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88, (BYTE *)&expected_output_info[11]}, {MFMediaType_Video, MEDIASUBTYPE_RGB8, TRUE, FALSE, 256, FORMAT_VideoInfo, NULL, 1112, (BYTE *)&expected_output_info[12]}, }; - DMO_MEDIA_TYPE media_type, *input_type; + const POINT test_size[] = {{16, 16}, {96, 96}, {320, 240}}; + DWORD in_count, out_count, size, expected_size, alignment; + DMO_MEDIA_TYPE media_type, *type; IMediaObject *media_object; - DWORD in_count, out_count; char buffer[1024]; - ULONG ret, i; + ULONG ret, i, j; HRESULT hr;
winetest_push_context("wmvdec"); @@ -5015,7 +5016,7 @@ static void test_wmv_decoder_media_object(void) return; }
- input_type = (DMO_MEDIA_TYPE *)buffer; + type = (DMO_MEDIA_TYPE *)buffer;
hr = CoInitialize(NULL); ok(hr == S_OK, "CoInitialize failed, hr %#lx.\n", hr); @@ -5068,8 +5069,8 @@ static void test_wmv_decoder_media_object(void) ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputType returned %#lx.\n", hr);
/* Test GetOutputType after setting input type. */ - init_dmo_media_type_video(input_type, &expected_input_types[0].subtype, 16, 16); - hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); + init_dmo_media_type_video(type, &expected_input_types[0].subtype, 16, 16); + hr = IMediaObject_SetInputType(media_object, 0, type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); check_dmo_get_output_type(media_object, expected_output_types, ARRAY_SIZE(expected_output_types));
@@ -5080,11 +5081,55 @@ static void test_wmv_decoder_media_object(void) ok(hr == DMO_E_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr);
/* Test SetOutputType after setting input type. */ - init_dmo_media_type_video(input_type, &expected_input_types[0].subtype, 16, 16); - hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); + init_dmo_media_type_video(type, &expected_input_types[0].subtype, 16, 16); + hr = IMediaObject_SetInputType(media_object, 0, type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); check_dmo_set_output_type(media_object, &MEDIASUBTYPE_RGB24);
+ /* Test GetOutputSizeInfo. */ + hr = IMediaObject_SetOutputType(media_object, 0, NULL, DMO_SET_TYPEF_CLEAR); + ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(media_object, 0, &size, &alignment); + todo_wine + ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputSizeInfo returned %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(expected_output_types); ++i) + { + const GUID *subtype = &expected_output_types[i].subtype; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565) + || IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)) + { + skip("Skipping GetOutputSizeInfo tests for video subtype %s.\n", debugstr_guid(subtype)); + continue; + } + + winetest_push_context("out %lu", i); + for (j = 0; j < ARRAY_SIZE(test_size); ++j) + { + init_dmo_media_type_video(type, &expected_output_types[i].subtype, test_size[j].x, test_size[j].y); + hr = IMediaObject_SetOutputType(media_object, 0, type, 0); + todo_wine_if(IsEqualGUID(subtype, &MEDIASUBTYPE_NV11) + || IsEqualGUID(subtype, &MEDIASUBTYPE_IYUV)) + ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); + if (hr != S_OK) + continue; + + size = 0xdeadbeef; + alignment = 0xdeadbeef; + hr = MFCalculateImageSize(subtype, test_size[j].x, test_size[j].y, (UINT32 *)&expected_size); + ok(hr == S_OK, "MFCalculateImageSize returned %#lx.\n", hr); + + hr = IMediaObject_GetOutputSizeInfo(media_object, 0, &size, &alignment); + todo_wine + { + ok(hr == S_OK, "GetOutputSizeInfo returned %#lx.\n", hr); + ok(size == expected_size, "Got unexpected size %lu, expected %lu.\n", size, expected_size); + ok(alignment == 1, "Got unexpected alignment %lu.\n", alignment); + } + } + winetest_pop_context(); + } + ret = IMediaObject_Release(media_object); ok(ret == 0, "Release returned %lu\n", ret); CoUninitialize();
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 4 ---- dlls/winegstreamer/wmv_decoder.c | 25 +++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 4049e9afbd0..370b58def2b 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -5090,7 +5090,6 @@ static void test_wmv_decoder_media_object(void) hr = IMediaObject_SetOutputType(media_object, 0, NULL, DMO_SET_TYPEF_CLEAR); ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputSizeInfo(media_object, 0, &size, &alignment); - todo_wine ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputSizeInfo returned %#lx.\n", hr);
for (i = 0; i < ARRAY_SIZE(expected_output_types); ++i) @@ -5120,12 +5119,9 @@ static void test_wmv_decoder_media_object(void) ok(hr == S_OK, "MFCalculateImageSize returned %#lx.\n", hr);
hr = IMediaObject_GetOutputSizeInfo(media_object, 0, &size, &alignment); - todo_wine - { ok(hr == S_OK, "GetOutputSizeInfo returned %#lx.\n", hr); ok(size == expected_size, "Got unexpected size %lu, expected %lu.\n", size, expected_size); ok(alignment == 1, "Got unexpected alignment %lu.\n", alignment); - } } winetest_pop_context(); } diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 4be36d803ba..473fabab867 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -82,6 +82,7 @@ struct wmv_decoder
struct wg_format input_format; struct wg_format output_format; + GUID output_subtype; };
static bool wg_format_is_set(struct wg_format *format) @@ -549,7 +550,10 @@ static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD inde return DMO_E_TYPE_NOT_ACCEPTED;
if (!(flags & DMO_SET_TYPEF_TEST_ONLY)) + { + decoder->output_subtype = type->subtype; decoder->output_format = wg_format; + }
return S_OK; } @@ -576,8 +580,25 @@ static HRESULT WINAPI media_object_GetInputSizeInfo(IMediaObject *iface, DWORD i
static HRESULT WINAPI media_object_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) { - FIXME("iface %p, index %lu, size %p, alignment %p stub!\n", iface, index, size, alignment); - return E_NOTIMPL; + struct wmv_decoder *decoder = impl_from_IMediaObject(iface); + HRESULT hr; + + TRACE("iface %p, index %lu, size %p, alignment %p.\n", iface, index, size, alignment); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + if (!wg_format_is_set(&decoder->output_format)) + return DMO_E_TYPE_NOT_SET; + + if (FAILED(hr = MFCalculateImageSize(&decoder->output_subtype, + decoder->output_format.u.video.width, decoder->output_format.u.video.height, (UINT32 *)size))) + { + FIXME("Failed to get image size of subtype %s.\n", debugstr_guid(&decoder->output_subtype)); + return hr; + } + *alignment = 1; + + return S_OK; }
static HRESULT WINAPI media_object_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency)
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=128887
Your paranoid android.
=== w10pro64_zh_CN (64 bit report) ===
mfplat: mfplat.c:3362: Test failed: Unexpected return value 0x102. mfplat.c:2720: Test failed: Failed to get event, hr 0xc00d3e85. mfplat.c:2723: Test failed: Failed to get event, hr 0xc00d3e85. mfplat.c:2726: Test failed: Failed to finalize GetEvent, hr 0xc00d3e85. mfplat.c:2729: Test failed: Unexpected result, hr 0xc00d3e85.
V3: duplicate MEDIASUBTYPE_* entries as Nikolay said in PATCH 2.
This merge request was approved by Nikolay Sivov.