Module: wine Branch: master Commit: 3dd3535a2c5ba0970602106a9fe8f4544f412701 URL: https://gitlab.winehq.org/wine/wine/-/commit/3dd3535a2c5ba0970602106a9fe8f45...
Author: Rémi Bernon rbernon@codeweavers.com Date: Mon Jun 3 10:22:50 2024 +0200
winegstreamer: Use a caps to store the desired output format.
---
dlls/winegstreamer/wg_transform.c | 85 +++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 35 deletions(-)
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 25bfb453dd4..98d3cf8760c 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -56,10 +56,10 @@ struct wg_transform bool input_is_flipped; GstElement *video_flip;
- struct wg_format output_format; GstAtomicQueue *output_queue; GstSample *output_sample; bool output_caps_changed; + GstCaps *desired_caps; GstCaps *output_caps; };
@@ -188,28 +188,53 @@ static gboolean transform_sink_query_allocation(struct wg_transform *transform, return true; }
-static GstCaps *transform_format_to_caps(struct wg_transform *transform, const struct wg_format *format) +static void caps_remove_field(GstCaps *caps, const char *field) { - struct wg_format copy = *format; + guint i;
- if (format->major_type == WG_MAJOR_TYPE_VIDEO) + for (i = 0; i < gst_caps_get_size(caps); ++i) { - if (transform->attrs.allow_format_change) - copy.u.video.width = copy.u.video.height = 0; - copy.u.video.fps_n = copy.u.video.fps_d = 0; + GstStructure *structure = gst_caps_get_structure(caps, i); + gst_structure_remove_fields(structure, field, NULL); } +} + +static GstCaps *caps_strip_fields(GstCaps *caps, bool strip_size) +{ + if (stream_type_from_caps(caps) != GST_STREAM_TYPE_VIDEO) + return gst_caps_ref(caps); + + if ((caps = gst_caps_copy(caps))) + { + if (strip_size) + { + caps_remove_field(caps, "width"); + caps_remove_field(caps, "height"); + }
- return wg_format_to_caps(©); + /* strip fields which we do not support and could cause pipeline failure or spurious format changes */ + caps_remove_field(caps, "framerate"); + caps_remove_field(caps, "colorimetry"); + caps_remove_field(caps, "chroma-site"); + caps_remove_field(caps, "interlace-mode"); + caps_remove_field(caps, "pixel-aspect-ratio"); + } + + return caps; }
static gboolean transform_sink_query_caps(struct wg_transform *transform, GstQuery *query) { GstCaps *caps, *filter, *temp; + bool strip_size = false;
GST_LOG("transform %p, %"GST_PTR_FORMAT, transform, query);
gst_query_parse_caps(query, &filter); - if (!(caps = transform_format_to_caps(transform, &transform->output_format))) + if (filter && gst_structure_has_field(gst_caps_get_structure(filter, 0), "width")) + strip_size = transform->attrs.allow_format_change; + + if (!(caps = caps_strip_fields(transform->desired_caps, strip_size))) return false;
if (filter) @@ -248,23 +273,6 @@ static gboolean transform_sink_query_cb(GstPad *pad, GstObject *parent, GstQuery return gst_pad_query_default(pad, parent, query); }
-static gboolean transform_output_caps_is_compatible(struct wg_transform *transform, GstCaps *caps) -{ - GstCaps *copy = gst_caps_copy(caps); - gboolean ret; - gsize i; - - for (i = 0; i < gst_caps_get_size(copy); ++i) - { - GstStructure *structure = gst_caps_get_structure(copy, i); - gst_structure_remove_fields(structure, "framerate", NULL); - } - - ret = gst_caps_is_always_compatible(transform->output_caps, copy); - gst_caps_unref(copy); - return ret; -} - static void transform_sink_event_caps(struct wg_transform *transform, GstEvent *event) { GstCaps *caps; @@ -274,6 +282,8 @@ static void transform_sink_event_caps(struct wg_transform *transform, GstEvent * gst_event_parse_caps(event, &caps);
transform->output_caps_changed = true; + gst_caps_unref(transform->desired_caps); + transform->desired_caps = gst_caps_ref(caps); gst_caps_unref(transform->output_caps); transform->output_caps = gst_caps_ref(caps); } @@ -318,6 +328,7 @@ NTSTATUS wg_transform_destroy(void *args) g_object_unref(transform->my_sink); g_object_unref(transform->my_src); gst_query_unref(transform->drain_query); + gst_caps_unref(transform->desired_caps); gst_caps_unref(transform->output_caps); gst_atomic_queue_unref(transform->output_queue); free(transform); @@ -409,9 +420,8 @@ NTSTATUS wg_transform_create(void *args) if (!(transform->allocator = wg_allocator_create())) goto out; transform->attrs = *params->attrs; - transform->output_format = output_format;
- if (!(src_caps = transform_format_to_caps(transform, &input_format))) + if (!(src_caps = wg_format_to_caps(&input_format))) goto out; if (!(template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps))) goto out; @@ -425,8 +435,9 @@ NTSTATUS wg_transform_create(void *args) gst_pad_set_element_private(transform->my_src, transform); gst_pad_set_query_function(transform->my_src, transform_src_query_cb);
- if (!(transform->output_caps = transform_format_to_caps(transform, &output_format))) + if (!(transform->output_caps = wg_format_to_caps(&output_format))) goto out; + transform->desired_caps = gst_caps_ref(transform->output_caps); if (!(template = gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, transform->output_caps))) goto out; transform->my_sink = gst_pad_new_from_template(template, "sink"); @@ -575,6 +586,8 @@ NTSTATUS wg_transform_create(void *args) out: if (transform->my_sink) gst_object_unref(transform->my_sink); + if (transform->desired_caps) + gst_caps_unref(transform->desired_caps); if (transform->output_caps) gst_caps_unref(transform->output_caps); if (transform->my_src) @@ -608,23 +621,25 @@ NTSTATUS wg_transform_set_output_format(void *args) struct wg_transform_set_output_format_params *params = args; struct wg_transform *transform = get_transform(params->transform); const struct wg_format *format = params->format; + GstCaps *caps, *stripped; GstSample *sample; - GstCaps *caps;
- if (!(caps = transform_format_to_caps(transform, format))) + if (!(caps = wg_format_to_caps(format))) { GST_ERROR("Failed to convert format %p to caps.", format); return STATUS_UNSUCCESSFUL; } - transform->output_format = *format;
GST_INFO("transform %p output caps %"GST_PTR_FORMAT, transform, caps);
- if (transform_output_caps_is_compatible(transform, caps)) + stripped = caps_strip_fields(caps, transform->attrs.allow_format_change); + if (gst_caps_is_always_compatible(transform->output_caps, stripped)) { + gst_caps_unref(stripped); gst_caps_unref(caps); return STATUS_SUCCESS; } + gst_caps_unref(stripped);
if (!gst_pad_peer_query(transform->my_src, transform->drain_query)) { @@ -632,8 +647,8 @@ NTSTATUS wg_transform_set_output_format(void *args) return STATUS_UNSUCCESSFUL; }
- gst_caps_unref(transform->output_caps); - transform->output_caps = caps; + gst_caps_unref(transform->desired_caps); + transform->desired_caps = caps;
if (transform->video_flip) {