In this patch set, GetOutputType() currently fails for NV11 and the following RGB types because MFCalculateImageSize() fails for them. I'll fix MFCalculateImageSize() for them recently (but not in this patch set).
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 203 +++++++++++++++++++++++++++----------- 1 file changed, 144 insertions(+), 59 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 09c0e83a7dc..53c0914c98c 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -26,7 +26,7 @@
#include "control.h" #include "d3d9types.h" -#include "dmoreg.h" +#include "dmo.h" #include "mferror.h" #include "mfidl.h" #include "mftransform.h" @@ -55,6 +55,12 @@ DEFINE_GUID(MFVideoFormat_WMV_Unknown,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0x
DEFINE_GUID(mft_output_sample_incomplete,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+typedef enum +{ + INPUT_FUNC, + OUTPUT_FUNC, +} FUNC_TYPE; + static void load_resource(const WCHAR *filename, const BYTE **data, DWORD *length) { HRSRC resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA); @@ -1071,31 +1077,84 @@ DWORD check_mf_sample_collection_(const char *file, int line, IMFCollection *sam return ctx.diff / count; }
-#define check_dmo_media_type(a, b) check_dmo_media_type_(__LINE__, a, b) -static void check_dmo_media_type_(int line, DMO_MEDIA_TYPE *media_type, const DMO_MEDIA_TYPE *expected) +static void check_media_object_get_type(IMediaObject *media_object, + FUNC_TYPE type, const DMO_MEDIA_TYPE *expected_type, ULONG count) { - ok_(__FILE__, line)(IsEqualGUID(&media_type->majortype, &expected->majortype), - "Got unexpected majortype %s, expected %s.\n", - debugstr_guid(&media_type->majortype), debugstr_guid(&expected->majortype)); - ok_(__FILE__, line)(IsEqualGUID(&media_type->subtype, &expected->subtype), - "Got unexpected subtype %s, expected %s.\n", - debugstr_guid(&media_type->subtype), debugstr_guid(&expected->subtype)); - ok_(__FILE__, line)(media_type->bFixedSizeSamples == expected->bFixedSizeSamples, - "Got unexpected bFixedSizeSamples %d, expected %d.\n", - media_type->bFixedSizeSamples, expected->bFixedSizeSamples); - ok_(__FILE__, line)(media_type->bTemporalCompression == expected->bTemporalCompression, - "Got unexpected bTemporalCompression %d, expected %d.\n", - media_type->bTemporalCompression, expected->bTemporalCompression); - ok_(__FILE__, line)(media_type->lSampleSize == expected->lSampleSize, - "Got unexpected lSampleSize %lu, expected %lu.\n", - media_type->lSampleSize, expected->lSampleSize); - - ok_(__FILE__, line)(IsEqualGUID(&media_type->formattype, &GUID_NULL), - "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); - ok_(__FILE__, line)(media_type->cbFormat == 0, "Got unexpected cbFormat %lu.\n", media_type->cbFormat); - ok_(__FILE__, line)(media_type->pbFormat == NULL, "Got unexpected pbFormat %p.\n", media_type->pbFormat); + HRESULT (*get_type)(IMediaObject* media_object, DWORD stream_index, DWORD type_index, DMO_MEDIA_TYPE *media_type); + DMO_MEDIA_TYPE media_type; + HRESULT hr; + DWORD i; + + if (type == INPUT_FUNC) + { + winetest_push_context("GetInputType"); + get_type = IMediaObject_GetInputType; + } + else + { + winetest_push_context("GetOutputType"); + get_type = IMediaObject_GetOutputType; + } + + hr = get_type(media_object, 1, 0, NULL); + ok(hr == DMO_E_INVALIDSTREAMINDEX, "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 1, 0, &media_type); + ok(hr == DMO_E_INVALIDSTREAMINDEX, "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 1, count, &media_type); + ok(hr == DMO_E_INVALIDSTREAMINDEX, "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 0, count, &media_type); + ok(hr == DMO_E_NO_MORE_ITEMS, "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 0, count, NULL); + ok(hr == DMO_E_NO_MORE_ITEMS || broken(hr == S_OK && type == OUTPUT_FUNC), + "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 0, 0xdeadbeef, NULL); + ok(hr == DMO_E_NO_MORE_ITEMS || broken(hr == S_OK && type == OUTPUT_FUNC), + "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 0, count - 1, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + hr = get_type(media_object, 0, count - 1, &media_type); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + if (hr == S_OK) + MoFreeMediaType(&media_type); + + i = -1; + while (SUCCEEDED(hr = get_type(media_object, 0, ++i, &media_type))) + { + const DMO_MEDIA_TYPE *expected = &expected_type[i]; + + winetest_push_context("Type %lu", i); + + ok(IsEqualGUID(&media_type.majortype, &expected->majortype), + "Got unexpected majortype %s, expected %s.\n", + debugstr_guid(&media_type.majortype), debugstr_guid(&expected->majortype)); + ok(IsEqualGUID(&media_type.subtype, &expected->subtype), + "Got unexpected subtype %s, expected %s.\n", + debugstr_guid(&media_type.subtype), debugstr_guid(&expected->subtype)); + ok(media_type.bFixedSizeSamples == expected->bFixedSizeSamples, + "Got unexpected bFixedSizeSamples %d, expected %d.\n", + media_type.bFixedSizeSamples, expected->bFixedSizeSamples); + ok(media_type.bTemporalCompression == expected->bTemporalCompression, + "Got unexpected bTemporalCompression %d, expected %d.\n", + media_type.bTemporalCompression, expected->bTemporalCompression); + ok(media_type.lSampleSize == expected->lSampleSize, + "Got unexpected lSampleSize %lu, expected %lu.\n", + media_type.lSampleSize, expected->lSampleSize); + ok(IsEqualGUID(&media_type.formattype, &expected->formattype), + "Got unexpected formattype %s.\n", + debugstr_guid(&media_type.formattype)); + ok(media_type.pUnk == NULL, "Got unexpected pUnk %p.\n", media_type.pUnk); + ok(media_type.cbFormat == expected->cbFormat, + "Got unexpected cbFormat %lu, expected %lu.\n", + media_type.cbFormat, expected->cbFormat); + + MoFreeMediaType(&media_type); + winetest_pop_context(); + } + + ok(hr == DMO_E_NO_MORE_ITEMS, "Got unexpected hr %#lx.\n", hr); + ok(i == count, "%lu types.\n", i); + + winetest_pop_context(); }
static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj) @@ -4531,15 +4590,31 @@ static void test_wmv_decoder_media_object(void) const GUID *const class_id = &CLSID_CWMVDecMediaObject; const DMO_MEDIA_TYPE expected_input_types[] = { - {MFMediaType_Video, MFVideoFormat_WMV1, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MFVideoFormat_WMV2, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MEDIASUBTYPE_WMVA, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MEDIASUBTYPE_WMVP, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MEDIASUBTYPE_WVP2, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MFVideoFormat_WMV_Unknown, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MFVideoFormat_WVC1, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MFVideoFormat_WMV3, FALSE, TRUE, FALSE}, - {MFMediaType_Video, MFVideoFormat_VC1S, FALSE, TRUE, FALSE}, + {MFMediaType_Video, MEDIASUBTYPE_WMV1, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WMV2, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WMVA, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WMVP, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WVP2, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MFVideoFormat_WMV_Unknown, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WVC1, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MEDIASUBTYPE_WMV3, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + {MFMediaType_Video, MFVideoFormat_VC1S, FALSE, TRUE, 0, GUID_NULL, NULL, 0}, + }; + const DMO_MEDIA_TYPE expected_output_types[] = + { + {MFMediaType_Video, MEDIASUBTYPE_NV12, TRUE, FALSE, 384, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_YV12, TRUE, FALSE, 384, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_IYUV, TRUE, FALSE, 384, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_I420, TRUE, FALSE, 384, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_YUY2, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_UYVY, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_YVYU, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_NV11, TRUE, FALSE, 384, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_RGB32, TRUE, FALSE, 1024, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_RGB24, TRUE, FALSE, 768, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_RGB565, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 100}, + {MFMediaType_Video, MEDIASUBTYPE_RGB555, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, + {MFMediaType_Video, MEDIASUBTYPE_RGB8, TRUE, FALSE, 256, FORMAT_VideoInfo, NULL, 1112}, }; const struct set_type_arg { @@ -4590,7 +4665,7 @@ static void test_wmv_decoder_media_object(void) ULONG ret, i; HRESULT hr;
- winetest_push_context("wmvdec"); + winetest_push_context("WMV decoder");
if (!has_video_processor) { @@ -4622,30 +4697,7 @@ static void test_wmv_decoder_media_object(void) ok(in_count == 0xdeadbeef, "Got unexpected in_count %lu.\n", in_count);
/* Test GetInputType. */ - i = -1; - while (SUCCEEDED(hr = IMediaObject_GetInputType(media_object, 0, ++i, &media_type))) - { - winetest_push_context("in %lu", i); - check_dmo_media_type(&media_type, &expected_input_types[i]); - winetest_pop_context(); - } - ok(i == ARRAY_SIZE(expected_input_types), "%lu input types.\n", i); - - /* Test GetInputType with invalid arguments. */ - hr = IMediaObject_GetInputType(media_object, 0, ARRAY_SIZE(expected_input_types) - 1, &media_type); - ok(hr == S_OK, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 0, ARRAY_SIZE(expected_input_types), &media_type); - ok(hr == DMO_E_NO_MORE_ITEMS, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 1, 0, &media_type); - ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 0, 0, NULL); - ok(hr == S_OK, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 1, ARRAY_SIZE(expected_input_types), &media_type); - ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 0, ARRAY_SIZE(expected_input_types), NULL); - ok(hr == DMO_E_NO_MORE_ITEMS, "GetInputType returned unexpected hr %#lx.\n", hr); - hr = IMediaObject_GetInputType(media_object, 1, 0, NULL); - ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetInputType returned unexpected hr %#lx.\n", hr); + check_media_object_get_type(media_object, INPUT_FUNC, expected_input_types, ARRAY_SIZE(expected_input_types));
/* Test SetInputType. */ input_type = (DMO_MEDIA_TYPE *)buffer; @@ -4804,6 +4856,39 @@ static void test_wmv_decoder_media_object(void) winetest_pop_context(); }
+ /* Test GetOutputType without setting input type. */ + hr = IMediaObject_SetInputType(media_object, 0, NULL, DMO_SET_TYPEF_CLEAR); + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + hr = IMediaObject_GetOutputType(media_object, 0, 0, &media_type); + todo_wine + ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputType returned unexpected hr %#lx.\n", hr); + + /* Test GetOutputType after setting input type. */ + for (i = 0; i < ARRAY_SIZE(expected_input_types); ++i) + { + const GUID *subtype = &expected_input_types[i].subtype; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_WMV2) + || IsEqualGUID(subtype, &MEDIASUBTYPE_WMVA) + || IsEqualGUID(subtype, &MEDIASUBTYPE_WVP2) + || IsEqualGUID(subtype, &MEDIASUBTYPE_WVC1) + || IsEqualGUID(subtype, &MFVideoFormat_VC1S)) + { + skip("Skipping GetOutputType tests for input subtype %s.\n", debugstr_guid(subtype)); + continue; + } + + winetest_push_context("Input %lu", i); + + init_dmo_media_type_video(input_type, &expected_input_types[i].subtype, 16, 16); + hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + + todo_wine + check_media_object_get_type(media_object, OUTPUT_FUNC, expected_output_types, ARRAY_SIZE(expected_output_types)); + + 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 | 90 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 53c0914c98c..702411e07de 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1077,8 +1077,69 @@ DWORD check_mf_sample_collection_(const char *file, int line, IMFCollection *sam return ctx.diff / count; }
+#define check_video_info_header(a, b) check_video_info_header_(__LINE__, a, b) +static void check_video_info_header_(int line, VIDEOINFOHEADER *info, const VIDEOINFOHEADER *expected) +{ + ok_(__FILE__, line)(info->rcSource.left == expected->rcSource.left + && info->rcSource.top == expected->rcSource.top + && info->rcSource.right == expected->rcSource.right + && info->rcSource.bottom == expected->rcSource.bottom, + "Got unexpected rcSource {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n", + info->rcSource.left, info->rcSource.top, info->rcSource.right, info->rcSource.bottom, + expected->rcSource.left, expected->rcSource.top, expected->rcSource.right, expected->rcSource.bottom); + ok_(__FILE__, line)(info->rcTarget.left == expected->rcTarget.left + && info->rcTarget.top == expected->rcTarget.top + && info->rcTarget.right == expected->rcTarget.right + && info->rcTarget.bottom == expected->rcTarget.bottom, + "Got unexpected rcTarget {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n", + info->rcTarget.left, info->rcTarget.top, info->rcTarget.right, info->rcTarget.bottom, + expected->rcTarget.left, expected->rcTarget.top, expected->rcTarget.right, expected->rcTarget.bottom); + ok_(__FILE__, line)(info->dwBitRate == expected->dwBitRate, + "Got unexpected dwBitRate %lu, expected %lu.\n", + info->dwBitRate, expected->dwBitRate); + ok_(__FILE__, line)(info->dwBitErrorRate == expected->dwBitErrorRate, + "Got unexpected dwBitErrorRate %lu, expected %lu.\n", + info->dwBitErrorRate, expected->dwBitErrorRate); + ok_(__FILE__, line)(info->AvgTimePerFrame == expected->AvgTimePerFrame, + "Got unexpected AvgTimePerFrame %I64d, expected %I64d.\n", + info->AvgTimePerFrame, expected->AvgTimePerFrame); + ok_(__FILE__, line)(info->bmiHeader.biSize == expected->bmiHeader.biSize, + "Got unexpected bmiHeader.biSize %lu, expected %lu.\n", + info->bmiHeader.biSize, expected->bmiHeader.biSize); + ok_(__FILE__, line)(info->bmiHeader.biWidth == expected->bmiHeader.biWidth, + "Got unexpected bmiHeader.biWidth %ld, expected %ld.\n", + info->bmiHeader.biWidth, expected->bmiHeader.biWidth); + ok_(__FILE__, line)(info->bmiHeader.biHeight == expected->bmiHeader.biHeight, + "Got unexpected bmiHeader.biHeight %ld, expected %ld.\n", + info->bmiHeader.biHeight, expected->bmiHeader.biHeight); + ok_(__FILE__, line)(info->bmiHeader.biPlanes == expected->bmiHeader.biPlanes, + "Got unexpected bmiHeader.biPlanes %u, expected %u.\n", + info->bmiHeader.biPlanes, expected->bmiHeader.biPlanes); + ok_(__FILE__, line)(info->bmiHeader.biBitCount == expected->bmiHeader.biBitCount, + "Got unexpected bmiHeader.biBitCount %u, expected %u.\n", + info->bmiHeader.biBitCount, expected->bmiHeader.biBitCount); + ok_(__FILE__, line)(info->bmiHeader.biCompression == expected->bmiHeader.biCompression, + "Got unexpected bmiHeader.biCompression %#lx, expected %#lx.\n", + info->bmiHeader.biCompression, expected->bmiHeader.biCompression); + ok_(__FILE__, line)(info->bmiHeader.biSizeImage == expected->bmiHeader.biSizeImage, + "Got unexpected bmiHeader.biSizeImage %lu, expected %lu.\n", + info->bmiHeader.biSizeImage, expected->bmiHeader.biSizeImage); + ok_(__FILE__, line)(info->bmiHeader.biXPelsPerMeter == expected->bmiHeader.biXPelsPerMeter, + "Got unexpected bmiHeader.biXPelsPerMeter %ld, expected %ld.\n", + info->bmiHeader.biXPelsPerMeter, expected->bmiHeader.biXPelsPerMeter); + ok_(__FILE__, line)(info->bmiHeader.biYPelsPerMeter == expected->bmiHeader.biYPelsPerMeter, + "Got unexpected bmiHeader.xxxxxx %ld, expected %ld.\n", + info->bmiHeader.biYPelsPerMeter, expected->bmiHeader.biYPelsPerMeter); + ok_(__FILE__, line)(info->bmiHeader.biClrUsed == expected->bmiHeader.biClrUsed, + "Got unexpected bmiHeader.biClrUsed %lu, expected %lu.\n", + info->bmiHeader.biClrUsed, expected->bmiHeader.biClrUsed); + ok_(__FILE__, line)(info->bmiHeader.biClrImportant == expected->bmiHeader.biClrImportant, + "Got unexpected bmiHeader.biClrImportant %lu, expected %lu.\n", + info->bmiHeader.biClrImportant, expected->bmiHeader.biClrImportant); +} + static void check_media_object_get_type(IMediaObject *media_object, - FUNC_TYPE type, const DMO_MEDIA_TYPE *expected_type, ULONG count) + FUNC_TYPE type, const DMO_MEDIA_TYPE *expected_type, const void *expected_info, ULONG count) { HRESULT (*get_type)(IMediaObject* media_object, DWORD stream_index, DWORD type_index, DMO_MEDIA_TYPE *media_type); DMO_MEDIA_TYPE media_type; @@ -1147,6 +1208,12 @@ static void check_media_object_get_type(IMediaObject *media_object, "Got unexpected cbFormat %lu, expected %lu.\n", media_type.cbFormat, expected->cbFormat);
+ if (expected_info && media_type.cbFormat) + { + if (IsEqualGUID(&expected_type->majortype, &MEDIATYPE_Video)) + check_video_info_header((VIDEOINFOHEADER *)media_type.pbFormat, (VIDEOINFOHEADER *)expected_info + i); + } + MoFreeMediaType(&media_type); winetest_pop_context(); } @@ -4616,6 +4683,22 @@ static void test_wmv_decoder_media_object(void) {MFMediaType_Video, MEDIASUBTYPE_RGB555, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, {MFMediaType_Video, MEDIASUBTYPE_RGB8, TRUE, FALSE, 256, FORMAT_VideoInfo, NULL, 1112}, }; + const VIDEOINFOHEADER expected_output_info[] = + { + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('N', 'V', '1', '2'), 384, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('Y', 'V', '1', '2'), 384, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('I', 'Y', 'U', 'V'), 384, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('I', '4', '2', '0'), 384, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('Y', 'U', 'Y', '2'), 512, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('U', 'Y', 'V', 'Y'), 512, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('Y', 'V', 'Y', 'U'), 512, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('N', 'V', '1', '1'), 384, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 32, BI_RGB, 1024, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 24, BI_RGB, 768, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_BITFIELDS, 512, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_RGB, 512, 0, 0, 0, 0}}, + {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 8, BI_RGB, 256, 0, 0, 226, 226}}, + }; const struct set_type_arg { DWORD stream_index; @@ -4697,7 +4780,7 @@ static void test_wmv_decoder_media_object(void) ok(in_count == 0xdeadbeef, "Got unexpected in_count %lu.\n", in_count);
/* Test GetInputType. */ - check_media_object_get_type(media_object, INPUT_FUNC, expected_input_types, ARRAY_SIZE(expected_input_types)); + check_media_object_get_type(media_object, INPUT_FUNC, expected_input_types, NULL, ARRAY_SIZE(expected_input_types));
/* Test SetInputType. */ input_type = (DMO_MEDIA_TYPE *)buffer; @@ -4884,7 +4967,8 @@ static void test_wmv_decoder_media_object(void) ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
todo_wine - check_media_object_get_type(media_object, OUTPUT_FUNC, expected_output_types, ARRAY_SIZE(expected_output_types)); + check_media_object_get_type(media_object, OUTPUT_FUNC, + expected_output_types, expected_output_info, ARRAY_SIZE(expected_output_types));
winetest_pop_context(); }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 5 +- dlls/winegstreamer/wmv_decoder.c | 104 ++++++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 17 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 702411e07de..5f32a0e7392 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1174,6 +1174,7 @@ static void check_media_object_get_type(IMediaObject *media_object, hr = get_type(media_object, 0, count - 1, NULL); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); hr = get_type(media_object, 0, count - 1, &media_type); + todo_wine_if(type == OUTPUT_FUNC) ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); if (hr == S_OK) MoFreeMediaType(&media_type); @@ -1218,8 +1219,11 @@ static void check_media_object_get_type(IMediaObject *media_object, winetest_pop_context(); }
+ todo_wine_if(type == OUTPUT_FUNC) + { ok(hr == DMO_E_NO_MORE_ITEMS, "Got unexpected hr %#lx.\n", hr); ok(i == count, "%lu types.\n", i); + }
winetest_pop_context(); } @@ -4966,7 +4970,6 @@ static void test_wmv_decoder_media_object(void) hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
- todo_wine check_media_object_get_type(media_object, OUTPUT_FUNC, expected_output_types, expected_output_info, ARRAY_SIZE(expected_output_types));
diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 1b03d9aa639..1d43e212fe9 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);
-static const GUID *const wmv_decoder_input_types[] = +struct decoder_type { - &MFVideoFormat_WMV1, - &MFVideoFormat_WMV2, - &MEDIASUBTYPE_WMVA, - &MEDIASUBTYPE_WMVP, - &MEDIASUBTYPE_WVP2, - &MFVideoFormat_WMV_Unknown, - &MFVideoFormat_WVC1, - &MFVideoFormat_WMV3, - &MFVideoFormat_VC1S, + const GUID *subtype; + WORD bpp; + DWORD compression; +}; + +static const struct decoder_type wmv_decoder_input_types[] = +{ + { &MEDIASUBTYPE_WMV1 }, + { &MEDIASUBTYPE_WMV2 }, + { &MEDIASUBTYPE_WMVA }, + { &MEDIASUBTYPE_WMVP }, + { &MEDIASUBTYPE_WVP2 }, + { &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 @@ -376,7 +400,7 @@ static HRESULT WINAPI media_object_GetInputType(IMediaObject *iface, DWORD index
memset(type, 0, sizeof(*type)); type->majortype = MFMediaType_Video; - type->subtype = *wmv_decoder_input_types[type_index]; + type->subtype = *wmv_decoder_input_types[type_index].subtype; type->bFixedSizeSamples = FALSE; type->bTemporalCompression = TRUE; type->lSampleSize = 0; @@ -387,8 +411,56 @@ 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; + + 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, @@ -417,7 +489,7 @@ static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index return DMO_E_TYPE_NOT_ACCEPTED;
for (i = 0; i < ARRAY_SIZE(wmv_decoder_input_types); ++i) - if (IsEqualGUID(&type->subtype, wmv_decoder_input_types[i])) + if (IsEqualGUID(&type->subtype, wmv_decoder_input_types[i].subtype)) break; if (i == ARRAY_SIZE(wmv_decoder_input_types)) return DMO_E_TYPE_NOT_ACCEPTED;
Rémi Bernon (@rbernon) commented about dlls/mf/tests/transform.c:
- hr = get_type(media_object, 1, count, &media_type);
- ok(hr == DMO_E_INVALIDSTREAMINDEX, "Got unexpected hr %#lx.\n", hr);
- hr = get_type(media_object, 0, count, &media_type);
- ok(hr == DMO_E_NO_MORE_ITEMS, "Got unexpected hr %#lx.\n", hr);
- hr = get_type(media_object, 0, count, NULL);
- ok(hr == DMO_E_NO_MORE_ITEMS || broken(hr == S_OK && type == OUTPUT_FUNC),
"Got unexpected hr %#lx.\n", hr);
- hr = get_type(media_object, 0, 0xdeadbeef, NULL);
- ok(hr == DMO_E_NO_MORE_ITEMS || broken(hr == S_OK && type == OUTPUT_FUNC),
"Got unexpected hr %#lx.\n", hr);
- hr = get_type(media_object, 0, count - 1, NULL);
- ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- hr = get_type(media_object, 0, count - 1, &media_type);
- ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
- if (hr == S_OK)
MoFreeMediaType(&media_type);
I don't find this very readable. I think it would be better duplicating `check_dmo_get_input_type` / `check_dmo_get_output_type` while keeping the `check_dmo_media_type` helper to check the media type against the expected type.
Rémi Bernon (@rbernon) commented about dlls/mf/tests/transform.c:
ULONG ret, i; HRESULT hr;
- winetest_push_context("wmvdec");
- winetest_push_context("WMV decoder");
I think it would be better to keep these context string as short as possible. They tend to quickly add up and cause output overflows. What about `wmvdmod`?
Same with other context strings above, I think it'd be better to make them shorter (ie: `in %lu` / `out %lu` instead of `GetInputType` / `GetOutputType` + `Type %lu`).
If you think it's worth having more context I'd suggest changing the individual test messages to something more informative than `Got unexpected hr %#lx`. For instance `GetInputType returned %#lx` or something, although I'm not completely convinced it's really necessary.
Rémi Bernon (@rbernon) commented about dlls/mf/tests/transform.c:
- /* Test GetOutputType after setting input type. */
- for (i = 0; i < ARRAY_SIZE(expected_input_types); ++i)
- {
const GUID *subtype = &expected_input_types[i].subtype;
if (IsEqualGUID(subtype, &MEDIASUBTYPE_WMV2)
|| IsEqualGUID(subtype, &MEDIASUBTYPE_WMVA)
|| IsEqualGUID(subtype, &MEDIASUBTYPE_WVP2)
|| IsEqualGUID(subtype, &MEDIASUBTYPE_WVC1)
|| IsEqualGUID(subtype, &MFVideoFormat_VC1S))
{
skip("Skipping GetOutputType tests for input subtype %s.\n", debugstr_guid(subtype));
continue;
}
winetest_push_context("Input %lu", i);
Same here, `in %lu` should be enough.
Rémi Bernon (@rbernon) commented about dlls/mf/tests/transform.c:
{MFMediaType_Video, MEDIASUBTYPE_RGB555, TRUE, FALSE, 512, FORMAT_VideoInfo, NULL, 88}, {MFMediaType_Video, MEDIASUBTYPE_RGB8, TRUE, FALSE, 256, FORMAT_VideoInfo, NULL, 1112}, };
- const VIDEOINFOHEADER expected_output_info[] =
- {
I think the expected formats above should have each of these set in their `.pbFormat` / `.cbFormat` members.
Rémi Bernon (@rbernon) commented about dlls/mf/tests/transform.c:
"Got unexpected cbFormat %lu, expected %lu.\n", media_type.cbFormat, expected->cbFormat);
if (expected_info && media_type.cbFormat)
{
if (IsEqualGUID(&expected_type->majortype, &MEDIATYPE_Video))
check_video_info_header((VIDEOINFOHEADER *)media_type.pbFormat, (VIDEOINFOHEADER *)expected_info + i);
}
Then this should be part of the generic `check_dmo_media_type` check that I suggested to keep, checking that both the actual and the expected types have the same format.
Rémi Bernon (@rbernon) commented about dlls/winegstreamer/wmv_decoder.c:
+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 },
};
What about using a `struct wg_format` array here and `amt_from_wg_format` to create the DMO_MEDIA_TYPE, could it work and reduce the code duplication of DMO_MEDIA_TYPE creation?