From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 228 +++++++++++++++++++++++++++++++++++++- 1 file changed, 227 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 82817724a78..b29b050bb5f 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -34,6 +34,7 @@ #include "uuids.h" #include "wmcodecdsp.h" #include "mediaerr.h" +#include "amvideo.h"
#include "mf_test.h"
@@ -269,6 +270,28 @@ void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, } }
+static void init_dmo_media_type_video(DMO_MEDIA_TYPE *media_type, + const GUID *subtype, const LONG width, const LONG height) +{ + VIDEOINFOHEADER *header = (VIDEOINFOHEADER *)(media_type + 1); + + memset(header, 0, sizeof(*header)); + header->bmiHeader.biSize = sizeof(header->bmiHeader); + header->bmiHeader.biWidth = width; + header->bmiHeader.biHeight = height; + header->bmiHeader.biCompression = subtype->Data1; + + media_type->majortype = MEDIATYPE_Video; + media_type->subtype = *subtype; + media_type->bFixedSizeSamples = FALSE; + media_type->bTemporalCompression = TRUE; + media_type->lSampleSize = 0; + media_type->formattype = FORMAT_VideoInfo; + media_type->pUnk = NULL; + media_type->cbFormat = sizeof(*header); + media_type->pbFormat = (BYTE *)header; +} + static void check_mft_optional_methods(IMFTransform *transform, DWORD output_count) { DWORD in_id, out_id, in_count, out_count, in_min, in_max, out_min, out_max; @@ -4518,9 +4541,52 @@ static void test_wmv_decoder_media_object(void) {MFMediaType_Video, MFVideoFormat_WMV3, FALSE, TRUE, FALSE}, {MFMediaType_Video, MFVideoFormat_VC1S, FALSE, TRUE, FALSE}, }; + const struct set_type_arg + { + DWORD stream_index; + enum + { + MEDIA_TYPE_NULL = 0, + MEDIA_TYPE_GOOD = 1, + MEDIA_TYPE_BAD = 2, + } media_type; + DWORD flags; + HRESULT hr; + } + set_type_arg_tests[] = + { + {1, MEDIA_TYPE_NULL, 0, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_NULL, 0x4, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_NULL, DMO_SET_TYPEF_CLEAR, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_NULL, DMO_SET_TYPEF_TEST_ONLY, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_GOOD, 0, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_GOOD, 0x4, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_GOOD, DMO_SET_TYPEF_CLEAR, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_GOOD, DMO_SET_TYPEF_TEST_ONLY, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_BAD, 0, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_BAD, 0x4, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_BAD, DMO_SET_TYPEF_CLEAR, DMO_E_INVALIDSTREAMINDEX}, + {1, MEDIA_TYPE_BAD, DMO_SET_TYPEF_TEST_ONLY, DMO_E_INVALIDSTREAMINDEX}, + {0, MEDIA_TYPE_BAD, 0, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_BAD, 0x4, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_BAD, DMO_SET_TYPEF_CLEAR, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_BAD, DMO_SET_TYPEF_TEST_ONLY, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_NULL, 0, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_NULL, 0x4, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_NULL, DMO_SET_TYPEF_TEST_ONLY, DMO_E_TYPE_NOT_ACCEPTED}, + {0, MEDIA_TYPE_NULL, DMO_SET_TYPEF_CLEAR, S_OK}, + {0, MEDIA_TYPE_NULL, DMO_SET_TYPEF_CLEAR | 0x4, S_OK}, + {0, MEDIA_TYPE_NULL, DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY, S_OK}, + {0, MEDIA_TYPE_NULL, DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY | 0x4, S_OK}, + {0, MEDIA_TYPE_GOOD, 0x4, S_OK}, + {0, MEDIA_TYPE_GOOD, DMO_SET_TYPEF_CLEAR, S_OK}, + {0, MEDIA_TYPE_GOOD, DMO_SET_TYPEF_CLEAR | DMO_SET_TYPEF_TEST_ONLY, S_OK}, + }; + DMO_MEDIA_TYPE media_type, *input_type; IMediaObject *media_object; - DMO_MEDIA_TYPE media_type; DWORD in_count, out_count; + VIDEOINFOHEADER *header; + char buffer[1024]; ULONG ret, i; HRESULT hr;
@@ -4581,6 +4647,166 @@ static void test_wmv_decoder_media_object(void) hr = IMediaObject_GetInputType(media_object, 1, 0, NULL); ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetInputType returned unexpected hr %#lx.\n", hr);
+ /* Test SetInputType. */ + input_type = (DMO_MEDIA_TYPE *)buffer; + header = (VIDEOINFOHEADER *)(input_type + 1); + for (i = 0; i < ARRAY_SIZE(expected_input_types); ++i) + { + const GUID *subtype = &expected_input_types->subtype; + + winetest_push_context("Input %lu", i); + + /* Test setting the type. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + header->dwBitRate = 0xdeadbeef; + header->dwBitErrorRate = 0xdeadbeef; + header->AvgTimePerFrame = 0xdeadbeef; + header->bmiHeader.biPlanes = 0xdead; + header->bmiHeader.biBitCount = 0xdead; + header->bmiHeader.biSizeImage = 0xdeadbeef; + header->bmiHeader.biXPelsPerMeter = 0xdead; + header->bmiHeader.biYPelsPerMeter = 0xdead; + hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test invalid major type. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + input_type->majortype = MFMediaType_Default; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test invalid subtype. */ + init_dmo_media_type_video(input_type, &MEDIASUBTYPE_None, 96, 96); + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test invalid format type. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + input_type->formattype = FORMAT_None; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test invalid format size. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + input_type->cbFormat = 1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test NULL format pointer. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + input_type->pbFormat = NULL; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test video header struct size. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + header->bmiHeader.biSize = 0; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biSize = 1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biSize = 0xdeadbeef; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test width. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + header->bmiHeader.biWidth = 0; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biWidth = -1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biWidth = 4096 + 1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biWidth = 4096; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test height. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + header->bmiHeader.biHeight = 0; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biHeight = 4096 + 1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biHeight = 4096; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biHeight = -4096; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + + /* Test compression. */ + init_dmo_media_type_video(input_type, subtype, 96, 96); + header->bmiHeader.biCompression = 0; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biCompression = 1; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biCompression = 2; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + header->bmiHeader.biCompression = 0xdeadbeef; + hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); + todo_wine + ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); + + winetest_pop_context(); + } + + /* Test SetInputType arguments. */ + for (i = 0; i < ARRAY_SIZE(set_type_arg_tests); ++i) + { + const struct set_type_arg *test = &set_type_arg_tests[i]; + DMO_MEDIA_TYPE *type; + + winetest_push_context("Test %lu", i); + + if (test->media_type == MEDIA_TYPE_GOOD) + type = input_type; + else if (test->media_type == MEDIA_TYPE_BAD) + type = &media_type; + else + type = NULL; + + hr = IMediaObject_SetInputType(media_object, test->stream_index, type, test->flags); + todo_wine + ok(hr == test->hr, "SetInputType returned unexpected hr %#lx, expected %#lx.\n", hr, test->hr); + + 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 | 24 ------------- dlls/winegstreamer/wmv_decoder.c | 58 ++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 26 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index b29b050bb5f..3fd74c23222 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4659,10 +4659,8 @@ static void test_wmv_decoder_media_object(void) /* Test setting the type. */ init_dmo_media_type_video(input_type, subtype, 96, 96); hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); header->dwBitRate = 0xdeadbeef; header->dwBitErrorRate = 0xdeadbeef; @@ -4673,113 +4671,92 @@ static void test_wmv_decoder_media_object(void) header->bmiHeader.biXPelsPerMeter = 0xdead; header->bmiHeader.biYPelsPerMeter = 0xdead; hr = IMediaObject_SetInputType(media_object, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test invalid major type. */ init_dmo_media_type_video(input_type, subtype, 96, 96); input_type->majortype = MFMediaType_Default; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test invalid subtype. */ init_dmo_media_type_video(input_type, &MEDIASUBTYPE_None, 96, 96); hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test invalid format type. */ init_dmo_media_type_video(input_type, subtype, 96, 96); input_type->formattype = FORMAT_None; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test invalid format size. */ init_dmo_media_type_video(input_type, subtype, 96, 96); input_type->cbFormat = 1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test NULL format pointer. */ init_dmo_media_type_video(input_type, subtype, 96, 96); input_type->pbFormat = NULL; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test video header struct size. */ init_dmo_media_type_video(input_type, subtype, 96, 96); header->bmiHeader.biSize = 0; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biSize = 1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biSize = 0xdeadbeef; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test width. */ init_dmo_media_type_video(input_type, subtype, 96, 96); header->bmiHeader.biWidth = 0; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biWidth = -1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biWidth = 4096 + 1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biWidth = 4096; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test height. */ init_dmo_media_type_video(input_type, subtype, 96, 96); header->bmiHeader.biHeight = 0; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biHeight = 4096 + 1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biHeight = 4096; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biHeight = -4096; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
/* Test compression. */ init_dmo_media_type_video(input_type, subtype, 96, 96); header->bmiHeader.biCompression = 0; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biCompression = 1; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biCompression = 2; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr); header->bmiHeader.biCompression = 0xdeadbeef; hr = IMediaObject_SetInputType(media_object, 0, input_type, DMO_SET_TYPEF_TEST_ONLY); - todo_wine ok(hr == S_OK, "SetInputType returned unexpected hr %#lx.\n", hr);
winetest_pop_context(); @@ -4801,7 +4778,6 @@ static void test_wmv_decoder_media_object(void) type = NULL;
hr = IMediaObject_SetInputType(media_object, test->stream_index, type, test->flags); - todo_wine ok(hr == test->hr, "SetInputType returned unexpected hr %#lx, expected %#lx.\n", hr, test->hr);
winetest_pop_context(); diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 96a2839660a..c42795b2e37 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -55,6 +55,9 @@ struct wmv_decoder IPropertyStore IPropertyStore_iface; IUnknown *outer; LONG refcount; + + DMO_MEDIA_TYPE input_type; + VIDEOINFOHEADER input_info; };
static inline struct wmv_decoder *impl_from_IUnknown(IUnknown *iface) @@ -392,8 +395,59 @@ static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD inde static HRESULT WINAPI media_object_SetInputType(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); + VIDEOINFOHEADER *info; + 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->input_type, 0, sizeof(decoder->input_type)); + memset(&decoder->input_info, 0, sizeof(decoder->input_info)); + return S_OK; + } + return DMO_E_TYPE_NOT_ACCEPTED; + } + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video) + || !IsEqualGUID(&type->formattype, &FORMAT_VideoInfo) + || !type->pbFormat + || type->cbFormat != sizeof(*info)) + 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])) + break; + } + if (i == ARRAY_SIZE(wmv_decoder_input_types)) + return DMO_E_TYPE_NOT_ACCEPTED; + + info = (VIDEOINFOHEADER *)type->pbFormat; + if (info->bmiHeader.biSize != sizeof(info->bmiHeader) + || !info->bmiHeader.biWidth + || !info->bmiHeader.biHeight + || !info->bmiHeader.biCompression + || info->bmiHeader.biWidth > 4096 + || info->bmiHeader.biHeight > 4096 + || info->bmiHeader.biWidth < 0 + || info->bmiHeader.biHeight < -4096) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!(flags & DMO_SET_TYPEF_TEST_ONLY)) + { + memcpy(&decoder->input_type, type, sizeof(*type)); + decoder->input_type.pbFormat = (BYTE *)&decoder->input_info; + memcpy(&decoder->input_info, type, sizeof(*info)); + } + + return S_OK; }
static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD index,
Rémi Bernon (@rbernon) commented about dlls/winegstreamer/wmv_decoder.c:
- info = (VIDEOINFOHEADER *)type->pbFormat;
- if (info->bmiHeader.biSize != sizeof(info->bmiHeader)
|| !info->bmiHeader.biWidth
|| !info->bmiHeader.biHeight
|| !info->bmiHeader.biCompression
|| info->bmiHeader.biWidth > 4096
|| info->bmiHeader.biHeight > 4096
|| info->bmiHeader.biWidth < 0
|| info->bmiHeader.biHeight < -4096)
return DMO_E_TYPE_NOT_ACCEPTED;
- if (!(flags & DMO_SET_TYPEF_TEST_ONLY))
- {
memcpy(&decoder->input_type, type, sizeof(*type));
decoder->input_type.pbFormat = (BYTE *)&decoder->input_info;
memcpy(&decoder->input_info, type, sizeof(*info));
I think you may need to use strmbase `CopyMediaType` to do that correctly, the media type may have things like `pUnk` set, even though we probably won't use it.
Another option that may be more future proof regarding MF interop would be to keep a `struct wg_format` on the decoder rather than a `DMO_MEDIA_TYPE` and `VIDEOINFOHEADER`, and use `amt_to_wg_format` here. That would require adding WMV format support first, but you'll need that anyway at some point.
I'm also not completely sure we need all these checks (or the corresponding tests), but I don't mind too much.