From: Ziqing Hui zhui@codeweavers.com
--- dlls/mf/tests/transform.c | 5 +- dlls/winegstreamer/wmv_decoder.c | 78 ++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index a2e8d1d6e0b..47045112fbf 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1229,6 +1229,7 @@ static void check_dmo_get_output_type(IMediaObject *media_object, const DMO_MEDI hr = IMediaObject_GetOutputType(media_object, 0, count - 1, NULL); ok(hr == S_OK, "GetOutputType returned unexpected hr %#lx.\n", hr); hr = IMediaObject_GetOutputType(media_object, 0, count - 1, &media_type); + todo_wine ok(hr == S_OK, "GetOutputType returned unexpected hr %#lx.\n", hr); if (hr == S_OK) MoFreeMediaType(&media_type); @@ -1242,7 +1243,9 @@ static void check_dmo_get_output_type(IMediaObject *media_object, const DMO_MEDI winetest_pop_context(); }
+ todo_wine ok(hr == DMO_E_NO_MORE_ITEMS, "GetOutputType returned unexpected hr %#lx.\n", hr); + todo_wine ok(i == count, "%lu types.\n", i); }
@@ -4965,7 +4968,6 @@ 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 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. */ @@ -4988,7 +4990,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_dmo_get_output_type(media_object, expected_output_types, ARRAY_SIZE(expected_output_types));
winetest_pop_context(); diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index 1b03d9aa639..7421721d374 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -29,21 +29,38 @@
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[] = { - &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 enum wg_video_format wmv_decoder_output_formats[] = +{ + WG_VIDEO_FORMAT_NV12, + WG_VIDEO_FORMAT_YV12, + WG_VIDEO_FORMAT_IYUV, + WG_VIDEO_FORMAT_I420, + WG_VIDEO_FORMAT_YUY2, + WG_VIDEO_FORMAT_UYVY, + WG_VIDEO_FORMAT_YVYU, + WG_VIDEO_FORMAT_NV11, + WG_VIDEO_FORMAT_BGRx, + WG_VIDEO_FORMAT_BGR , + WG_VIDEO_FORMAT_RGB16, + WG_VIDEO_FORMAT_RGB15, + WG_VIDEO_FORMAT_RGB8, };
struct wmv_decoder @@ -59,6 +76,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 +409,44 @@ 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); + struct wg_format output_format; + 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_formats)) + 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; + memset(&output_format, 0, sizeof(output_format)); + output_format.major_type = WG_MAJOR_TYPE_VIDEO; + output_format.u.video.format = wmv_decoder_output_formats[type_index]; + output_format.u.video.width = width; + output_format.u.video.height = height; + + if (!amt_from_wg_format((AM_MEDIA_TYPE *)type, &output_format, TRUE)) + return E_OUTOFMEMORY; + + if (FAILED(hr = MFCalculateImageSize(&type->subtype, width, height, &image_size))) + { + FIXME("Failed to get image size of subtype %s.\n", debugstr_guid(&type->subtype)); + return hr; + } + + type->lSampleSize = image_size; + ((VIDEOINFOHEADER *)type->pbFormat)->bmiHeader.biSizeImage = image_size; + + return S_OK; }
static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index,