From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 7 +++--- dlls/winegstreamer/video_decoder.c | 35 +++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 1ca6652598d..febb1e33365 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -5909,7 +5909,7 @@ static void test_wmv_decoder(void) .expect_output_info = &expect_output_info, .output_sample_desc = &output_sample_desc_nv12_todo_time, .result_bitmap = L"nv12frame.bmp", - .delta = 0, .todo = TRUE, + .delta = 0, },
{ @@ -5935,14 +5935,14 @@ static void test_wmv_decoder(void) },
{ - /* WMV1 -> RGB (positive stride */ + /* WMV1 -> RGB (positive stride) */ .output_type_desc = output_type_desc_rgb_positive_stride, .expect_output_type_desc = expect_output_type_desc_rgb, .expect_input_info = &expect_input_info_rgb, .expect_output_info = &expect_output_info_rgb, .output_sample_desc = &output_sample_desc_rgb, .result_bitmap = L"rgb32frame-flip.bmp", - .delta = 5, .todo = TRUE, + .delta = 5, },
}; @@ -6115,7 +6115,6 @@ static void test_wmv_decoder(void)
ret = check_mf_sample_collection(output_samples, transform_tests[j].output_sample_desc, transform_tests[j].result_bitmap); - todo_wine_if(transform_tests[j].todo) ok(ret <= transform_tests[j].delta, "got %lu%% diff\n", ret); IMFCollection_Release(output_samples);
diff --git a/dlls/winegstreamer/video_decoder.c b/dlls/winegstreamer/video_decoder.c index 948fc6ab0ec..22b21b94bb1 100644 --- a/dlls/winegstreamer/video_decoder.c +++ b/dlls/winegstreamer/video_decoder.c @@ -238,7 +238,23 @@ static struct video_decoder *impl_from_IMFTransform(IMFTransform *iface) return CONTAINING_RECORD(iface, struct video_decoder, IMFTransform_iface); }
-static HRESULT try_create_wg_transform(struct video_decoder *decoder) +static HRESULT video_decoder_set_default_stride(IMFMediaType *media_type, IMFMediaType **ret) +{ + DMO_MEDIA_TYPE amt; + HRESULT hr; + + if (SUCCEEDED(hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo, &amt))) + { + VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)amt.pbFormat; + vih->bmiHeader.biHeight = abs(vih->bmiHeader.biHeight); + hr = MFCreateMediaTypeFromRepresentation(AM_MEDIA_TYPE_REPRESENTATION, &amt, ret); + FreeMediaType(&amt); + } + + return hr; +} + +static HRESULT try_create_wg_transform(struct video_decoder *decoder, IMFMediaType *output_type) { /* Call of Duty: Black Ops 3 doesn't care about the ProcessInput/ProcessOutput * return values, it calls them in a specific order and expects the decoder @@ -256,7 +272,7 @@ static HRESULT try_create_wg_transform(struct video_decoder *decoder) if (SUCCEEDED(IMFAttributes_GetUINT32(decoder->attributes, &MF_LOW_LATENCY, &low_latency))) decoder->wg_transform_attrs.low_latency = !!low_latency;
- return wg_transform_create_mf(decoder->input_type, decoder->output_type, &decoder->wg_transform_attrs, &decoder->wg_transform); + return wg_transform_create_mf(decoder->input_type, output_type, &decoder->wg_transform_attrs, &decoder->wg_transform); }
static HRESULT create_output_media_type(struct video_decoder *decoder, const GUID *subtype, @@ -612,6 +628,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF { struct video_decoder *decoder = impl_from_IMFTransform(iface); UINT64 frame_size, stream_frame_size; + IMFMediaType *output_type; GUID major, subtype; HRESULT hr; ULONG i; @@ -662,25 +679,33 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF IMFMediaType_Release(decoder->output_type); IMFMediaType_AddRef((decoder->output_type = type));
+ /* WMV decoder outputs RGB formats with default stride forced to negative, likely a result of internal conversion to DMO media type */ + if (!decoder->IMediaObject_iface.lpVtbl || FAILED(video_decoder_set_default_stride(decoder->output_type, &output_type))) + { + output_type = decoder->output_type; + IMFMediaType_AddRef(output_type); + } + if (decoder->wg_transform) { struct wg_format output_format; - mf_media_type_to_wg_format(decoder->output_type, &output_format); + mf_media_type_to_wg_format(output_type, &output_format);
if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN || !wg_transform_set_output_format(decoder->wg_transform, &output_format)) { IMFMediaType_Release(decoder->output_type); decoder->output_type = NULL; - return MF_E_INVALIDMEDIATYPE; + hr = MF_E_INVALIDMEDIATYPE; } } - else if (FAILED(hr = try_create_wg_transform(decoder))) + else if (FAILED(hr = try_create_wg_transform(decoder, output_type))) { IMFMediaType_Release(decoder->output_type); decoder->output_type = NULL; }
+ IMFMediaType_Release(output_type); return hr; }