-- v3: winegstreamer: Implement media_object_SetInputType for WMV decoder. winegstreamer: Add WMV support to wg_format. mf/tests: Test IMediaObject_SetInputType for WMV decoder.
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 240 +++++++++++++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 82817724a78..ce0ccd6fb7f 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) + 4; /* 4 bytes codec data. */ + 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,178 @@ 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[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 SetInputType tests for video subtype %s.\n", debugstr_guid(subtype)); + continue; + } + + 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. */ + memset(&media_type, 0, sizeof(media_type)); + init_dmo_media_type_video(input_type, &expected_input_types[0].subtype, 96, 96); + 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/winegstreamer/mfplat.c | 1 + dlls/winegstreamer/quartz_parser.c | 47 ++++++++++++++++++++++++++++++ dlls/winegstreamer/unixlib.h | 7 +++++ dlls/winegstreamer/wg_format.c | 22 ++++++++++++++ dlls/winegstreamer/wg_transform.c | 2 ++ dlls/winegstreamer/wm_reader.c | 4 +++ 6 files changed, 83 insertions(+)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index d7d6810965e..a09c67b4f11 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -554,6 +554,7 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_CINEPAK: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 2a7845be737..6e31f2736fe 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -36,7 +36,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz);
static const GUID MEDIASUBTYPE_CVID = {mmioFOURCC('c','v','i','d'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +static const GUID MEDIASUBTYPE_VC1S = {mmioFOURCC('V','C','1','S'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; static const GUID MEDIASUBTYPE_MP3 = {WAVE_FORMAT_MPEGLAYER3, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +static const GUID MEDIASUBTYPE_WMV_Unknown = {0x7ce12ca9, 0xbfbf, 0x43d9, {0x9d, 0x00, 0x82, 0xb8, 0xed, 0x54, 0x31, 0x6b}};
struct parser { @@ -362,6 +364,7 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format->major_type); return 0;
@@ -532,6 +535,7 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: @@ -723,12 +727,55 @@ static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *fo return false; }
+static bool amt_to_wg_format_video_wmv(const AM_MEDIA_TYPE *mt, struct wg_format *format) +{ + const VIDEOINFOHEADER *video_format = (const VIDEOINFOHEADER *)mt->pbFormat; + + if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)) + { + FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype)); + return false; + } + if (mt->cbFormat < sizeof(VIDEOINFOHEADER) || !mt->pbFormat) + { + ERR("Unexpected format size %lu.\n", mt->cbFormat); + return false; + } + + format->major_type = WG_MAJOR_TYPE_VIDEO_WMV; + format->u.video_wmv.width = video_format->bmiHeader.biWidth; + format->u.video_wmv.height = video_format->bmiHeader.biHeight; + format->u.video_wmv.fps_n = 10000000; + format->u.video_wmv.fps_d = video_format->AvgTimePerFrame; + + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV1)) + format->u.video_wmv.version = 1; + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV2)) + format->u.video_wmv.version = 2; + else + format->u.video_wmv.version = 3; + + return true; +} + bool amt_to_wg_format(const AM_MEDIA_TYPE *mt, struct wg_format *format) { memset(format, 0, sizeof(*format));
if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)) + { + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV1) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV2) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMVA) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMVP) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WVP2) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV_Unknown) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WVC1) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV3) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_VC1S)) + return amt_to_wg_format_video_wmv(mt, format); return amt_to_wg_format_video(mt, format); + } if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) { if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload)) diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 09aa68eb4cc..a97d74df7ca 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -42,6 +42,7 @@ struct wg_format WG_MAJOR_TYPE_VIDEO, WG_MAJOR_TYPE_VIDEO_CINEPAK, WG_MAJOR_TYPE_VIDEO_H264, + WG_MAJOR_TYPE_VIDEO_WMV, } major_type;
union @@ -126,6 +127,12 @@ struct wg_format uint32_t profile; uint32_t level; } video_h264; + struct + { + int32_t width, height; + uint32_t fps_n, fps_d; + uint32_t version; + } video_wmv; } u; };
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 7f28b4d2c90..a7876977d6c 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -554,6 +554,25 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format) return caps; }
+static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) +{ + GstCaps *caps; + + if (!(caps = gst_caps_new_empty_simple("video/x-wmv"))) + return NULL; + + if (format->u.video_wmv.width) + gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_wmv.width, NULL); + if (format->u.video_wmv.height) + gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_wmv.height, NULL); + if (format->u.video_wmv.fps_d || format->u.video_wmv.fps_n) + gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_wmv.fps_n, format->u.video_wmv.fps_d, NULL); + if (format->u.video_wmv.version) + gst_caps_set_simple(caps, "wmvversion", G_TYPE_INT, format->u.video_wmv.version, NULL); + + return caps; +} + GstCaps *wg_format_to_caps(const struct wg_format *format) { switch (format->major_type) @@ -574,6 +593,8 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) return wg_format_to_caps_video_cinepak(format); case WG_MAJOR_TYPE_VIDEO_H264: return wg_format_to_caps_video_h264(format); + case WG_MAJOR_TYPE_VIDEO_WMV: + return wg_format_to_caps_video_wmv(format); } assert(0); return NULL; @@ -590,6 +611,7 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: GST_FIXME("Format %u not implemented!", a->major_type); /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index a52d7e1f722..302a64eb57b 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -439,6 +439,7 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_VIDEO: break; case WG_MAJOR_TYPE_UNKNOWN: + case WG_MAJOR_TYPE_VIDEO_WMV: GST_FIXME("Format %u not implemented!", input_format.major_type); gst_caps_unref(raw_caps); goto out; @@ -480,6 +481,7 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_VIDEO_CINEPAK: case WG_MAJOR_TYPE_VIDEO_H264: case WG_MAJOR_TYPE_UNKNOWN: + case WG_MAJOR_TYPE_VIDEO_WMV: GST_FIXME("Format %u not implemented!", output_format.major_type); goto out; } diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 804af4a9aed..f069b4fb118 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1575,6 +1575,8 @@ static const char *get_major_type_string(enum wg_major_type type) return "cinepak"; case WG_MAJOR_TYPE_VIDEO_H264: return "h264"; + case WG_MAJOR_TYPE_VIDEO_WMV: + return "wmv"; case WG_MAJOR_TYPE_UNKNOWN: return "unknown"; } @@ -1928,6 +1930,7 @@ static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface, case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_CINEPAK: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format.major_type); break; case WG_MAJOR_TYPE_UNKNOWN: @@ -1968,6 +1971,7 @@ static HRESULT WINAPI reader_GetOutputFormatCount(IWMSyncReader2 *iface, DWORD o case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_CINEPAK: case WG_MAJOR_TYPE_VIDEO_H264: + case WG_MAJOR_TYPE_VIDEO_WMV: FIXME("Format %u not implemented!\n", format.major_type); /* fallthrough */ case WG_MAJOR_TYPE_AUDIO:
From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 15 ------------ dlls/winegstreamer/wmv_decoder.c | 39 ++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index ce0ccd6fb7f..09c0e83a7dc 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4669,10 +4669,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; @@ -4683,41 +4681,35 @@ 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. */ @@ -4751,7 +4743,6 @@ static void test_wmv_decoder_media_object(void) 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. */ @@ -4766,11 +4757,9 @@ static void test_wmv_decoder_media_object(void) 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. */ @@ -4781,15 +4770,12 @@ static void test_wmv_decoder_media_object(void) 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(); @@ -4813,7 +4799,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..1b03d9aa639 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -55,6 +55,8 @@ struct wmv_decoder IPropertyStore IPropertyStore_iface; IUnknown *outer; LONG refcount; + + struct wg_format input_format; };
static inline struct wmv_decoder *impl_from_IUnknown(IUnknown *iface) @@ -392,8 +394,41 @@ 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); + 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->input_format, 0, sizeof(decoder->input_format)); + return S_OK; + } + return DMO_E_TYPE_NOT_ACCEPTED; + } + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) + 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; + + 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->input_format = wg_format; + + return S_OK; }
static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD index,
v3:
* Patch1: In V2 version of SetInputType tests, I forgot to use index i in the for loop, this version fixes it. And then I found that some subtypes will fail on Windows, I tried many many times with different settings of VIDEOINFOHEADER but they still fails. I don't think it's worth wasting time on it. So I have to skip them for now. * Patch2: Implement wmv format to caps. Remove duplicate majortype setting. * Patch3: Change `wg_format` to `input_format`.