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;