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)
ok(ref == 1, "Release returned %ld\n", ref);
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);
IMFCollection_Release(output_samples);
......@@ -6223,7 +6222,7 @@ static void test_video_processor(void)
.output_type_desc = output_type_desc,
.expect_output_type_desc = output_type_desc,
.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)
.output_type_desc = output_type_desc_negative_stride,
.expect_output_type_desc = output_type_desc_negative_stride,
.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)
ret = check_mf_sample_collection(output_samples, &output_sample_desc,
video_processor_tests[i].result_bitmap);
todo_wine_if(i == 0 || i == 1)
ok(ret <= video_processor_tests[i].delta
/* w1064v1507 / w1064v1809 incorrectly rescale */
|| broken(ret == 25) || broken(ret == 32),
......
......@@ -363,6 +363,7 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
struct color_convert *impl = impl_from_IMFTransform(iface);
GUID major, subtype;
UINT64 frame_size;
UINT32 stride;
HRESULT hr;
ULONG i;
......@@ -392,6 +393,19 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM
IMFMediaType_Release(impl->input_type);
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)))
{
......@@ -411,6 +425,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
struct color_convert *impl = impl_from_IMFTransform(iface);
GUID major, subtype;
UINT64 frame_size;
UINT32 stride;
HRESULT hr;
ULONG i;
......@@ -440,6 +455,19 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
IMFMediaType_Release(impl->output_type);
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)))
{
......
......@@ -52,6 +52,9 @@ struct wg_transform
guint input_max_length;
GstAtomicQueue *input_queue;
bool input_is_flipped;
GstElement *video_flip;
guint output_plane_align;
struct wg_sample *output_wg_sample;
GstAtomicQueue *output_queue;
......@@ -262,6 +265,11 @@ static struct wg_sample *transform_request_sample(gsize size, void *context)
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)
{
struct wg_transform_create_params *params = args;
......@@ -382,6 +390,12 @@ NTSTATUS wg_transform_create(void *args)
case WG_MAJOR_TYPE_VIDEO:
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"))
|| !append_element(transform->container, element, &first, &last))
goto out;
......@@ -492,6 +506,15 @@ NTSTATUS wg_transform_set_output_format(void *args)
gst_caps_unref(transform->output_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()))
{
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