Commit 9718a0b6 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

winegstreamer: In video_processor, activate a videoflip converter.

The app I'm considering opens a video_processor on its own, with a NV12 format on input and a ARGB32 format on output. Tested on Windows: the samples are flipped vertically. While Wine keeps them untouched. So added a videoflip in the video processor to be activated when needed. Signed-off-by: 's avatarEric Pouech <epouech@codeweavers.com>
parent 77a21bfb
...@@ -5978,7 +5978,6 @@ static void test_color_convert(void) ...@@ -5978,7 +5978,6 @@ static void test_color_convert(void)
ok(ref == 1, "Release returned %ld\n", ref); ok(ref == 1, "Release returned %ld\n", ref);
ret = check_mf_sample_collection(output_samples, &output_sample_desc, color_conversion_tests[i].result_bitmap); ret = check_mf_sample_collection(output_samples, &output_sample_desc, color_conversion_tests[i].result_bitmap);
todo_wine_if(i == 1)
ok(ret <= color_conversion_tests[i].delta, "got %lu%% diff\n", ret); ok(ret <= color_conversion_tests[i].delta, "got %lu%% diff\n", ret);
IMFCollection_Release(output_samples); IMFCollection_Release(output_samples);
...@@ -6223,7 +6222,7 @@ static void test_video_processor(void) ...@@ -6223,7 +6222,7 @@ static void test_video_processor(void)
.output_type_desc = output_type_desc, .output_type_desc = output_type_desc,
.expect_output_type_desc = output_type_desc, .expect_output_type_desc = output_type_desc,
.result_bitmap = L"rgb32frame-vp.bmp", .result_bitmap = L"rgb32frame-vp.bmp",
.delta = 0, .delta = 2, /* Windows returns 0, Wine needs 2 */
}, },
{ {
...@@ -6231,7 +6230,7 @@ static void test_video_processor(void) ...@@ -6231,7 +6230,7 @@ static void test_video_processor(void)
.output_type_desc = output_type_desc_negative_stride, .output_type_desc = output_type_desc_negative_stride,
.expect_output_type_desc = output_type_desc_negative_stride, .expect_output_type_desc = output_type_desc_negative_stride,
.result_bitmap = L"rgb32frame-vp.bmp", .result_bitmap = L"rgb32frame-vp.bmp",
.delta = 0, .delta = 2, /* Windows returns 0, Wine needs 2 */
}, },
{ {
...@@ -6623,7 +6622,6 @@ static void test_video_processor(void) ...@@ -6623,7 +6622,6 @@ static void test_video_processor(void)
ret = check_mf_sample_collection(output_samples, &output_sample_desc, ret = check_mf_sample_collection(output_samples, &output_sample_desc,
video_processor_tests[i].result_bitmap); video_processor_tests[i].result_bitmap);
todo_wine_if(i == 0 || i == 1)
ok(ret <= video_processor_tests[i].delta ok(ret <= video_processor_tests[i].delta
/* w1064v1507 / w1064v1809 incorrectly rescale */ /* w1064v1507 / w1064v1809 incorrectly rescale */
|| broken(ret == 25) || broken(ret == 32), || broken(ret == 25) || broken(ret == 32),
......
...@@ -363,6 +363,7 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM ...@@ -363,6 +363,7 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
struct color_convert *impl = impl_from_IMFTransform(iface); struct color_convert *impl = impl_from_IMFTransform(iface);
GUID major, subtype; GUID major, subtype;
UINT64 frame_size; UINT64 frame_size;
UINT32 stride;
HRESULT hr; HRESULT hr;
ULONG i; ULONG i;
...@@ -392,6 +393,19 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM ...@@ -392,6 +393,19 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
IMFMediaType_Release(impl->input_type); IMFMediaType_Release(impl->input_type);
impl->input_type = NULL; impl->input_type = NULL;
} }
if (FAILED(IMFMediaType_GetUINT32(impl->input_type, &MF_MT_DEFAULT_STRIDE, &stride)))
{
if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, frame_size >> 32, (LONG *)&stride)))
{
IMFMediaType_Release(impl->input_type);
impl->input_type = NULL;
}
if (FAILED(hr = IMFMediaType_SetUINT32(impl->input_type, &MF_MT_DEFAULT_STRIDE, abs((INT32)stride))))
{
IMFMediaType_Release(impl->input_type);
impl->input_type = NULL;
}
}
if (impl->output_type && FAILED(hr = try_create_wg_transform(impl))) if (impl->output_type && FAILED(hr = try_create_wg_transform(impl)))
{ {
...@@ -411,6 +425,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF ...@@ -411,6 +425,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
struct color_convert *impl = impl_from_IMFTransform(iface); struct color_convert *impl = impl_from_IMFTransform(iface);
GUID major, subtype; GUID major, subtype;
UINT64 frame_size; UINT64 frame_size;
UINT32 stride;
HRESULT hr; HRESULT hr;
ULONG i; ULONG i;
...@@ -440,6 +455,19 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF ...@@ -440,6 +455,19 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
IMFMediaType_Release(impl->output_type); IMFMediaType_Release(impl->output_type);
impl->output_type = NULL; impl->output_type = NULL;
} }
if (FAILED(IMFMediaType_GetUINT32(impl->output_type, &MF_MT_DEFAULT_STRIDE, &stride)))
{
if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, frame_size >> 32, (LONG *)&stride)))
{
IMFMediaType_Release(impl->output_type);
impl->output_type = NULL;
}
if (FAILED(hr = IMFMediaType_SetUINT32(impl->output_type, &MF_MT_DEFAULT_STRIDE, abs((INT32)stride))))
{
IMFMediaType_Release(impl->output_type);
impl->output_type = NULL;
}
}
if (impl->input_type && FAILED(hr = try_create_wg_transform(impl))) if (impl->input_type && FAILED(hr = try_create_wg_transform(impl)))
{ {
......
...@@ -52,6 +52,9 @@ struct wg_transform ...@@ -52,6 +52,9 @@ struct wg_transform
guint input_max_length; guint input_max_length;
GstAtomicQueue *input_queue; GstAtomicQueue *input_queue;
bool input_is_flipped;
GstElement *video_flip;
guint output_plane_align; guint output_plane_align;
struct wg_sample *output_wg_sample; struct wg_sample *output_wg_sample;
GstAtomicQueue *output_queue; GstAtomicQueue *output_queue;
...@@ -262,6 +265,11 @@ static struct wg_sample *transform_request_sample(gsize size, void *context) ...@@ -262,6 +265,11 @@ static struct wg_sample *transform_request_sample(gsize size, void *context)
return InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL); return InterlockedExchangePointer((void **)&transform->output_wg_sample, NULL);
} }
static bool wg_format_video_is_flipped(const struct wg_format *format)
{
return format->major_type == WG_MAJOR_TYPE_VIDEO && (format->u.video.height < 0);
}
NTSTATUS wg_transform_create(void *args) NTSTATUS wg_transform_create(void *args)
{ {
struct wg_transform_create_params *params = args; struct wg_transform_create_params *params = args;
...@@ -382,6 +390,12 @@ NTSTATUS wg_transform_create(void *args) ...@@ -382,6 +390,12 @@ NTSTATUS wg_transform_create(void *args)
case WG_MAJOR_TYPE_VIDEO: case WG_MAJOR_TYPE_VIDEO:
case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_WMV:
if (!(transform->video_flip = create_element("videoflip", "base"))
|| !append_element(transform->container, transform->video_flip, &first, &last))
goto out;
transform->input_is_flipped = wg_format_video_is_flipped(&input_format);
if (transform->input_is_flipped != wg_format_video_is_flipped(&output_format))
gst_util_set_object_arg(G_OBJECT(transform->video_flip), "method", "vertical-flip");
if (!(element = create_element("videoconvert", "base")) if (!(element = create_element("videoconvert", "base"))
|| !append_element(transform->container, element, &first, &last)) || !append_element(transform->container, element, &first, &last))
goto out; goto out;
...@@ -492,6 +506,15 @@ NTSTATUS wg_transform_set_output_format(void *args) ...@@ -492,6 +506,15 @@ NTSTATUS wg_transform_set_output_format(void *args)
gst_caps_unref(transform->output_caps); gst_caps_unref(transform->output_caps);
transform->output_caps = caps; transform->output_caps = caps;
if (transform->video_flip)
{
const char *value;
if (transform->input_is_flipped != wg_format_video_is_flipped(format))
value = "vertical-flip";
else
value = "none";
gst_util_set_object_arg(G_OBJECT(transform->video_flip), "method", value);
}
if (!gst_pad_push_event(transform->my_sink, gst_event_new_reconfigure())) if (!gst_pad_push_event(transform->my_sink, gst_event_new_reconfigure()))
{ {
GST_ERROR("Failed to reconfigure transform %p.", transform); GST_ERROR("Failed to reconfigure transform %p.", transform);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment