v4l2: object: Fix support for format:Interlaced in caps probe

This notably follow the way we order the template and keeps the
format:Interlaced caps at the end. This change also fixes
an early skip check, that would skip if a driver only supports
alternate interlacing for a specific format. It also fixes
a bug where only the last resolution of a discrete frame size
was allowed to use format:Interlaced. Finally, similar to template
caps code, simplify the caps for earch featurs, making the debug output
manageable and (marginally) improve negotiation speed.

This change will make it easier to introduce memory:DMABuf.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7540>
This commit is contained in:
Nicolas Dufresne 2024-08-15 16:01:03 -04:00 committed by GStreamer Marge Bot
parent e97a954008
commit 2fe83fa2de

View file

@ -4851,7 +4851,7 @@ done:
GstCaps * GstCaps *
gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter) gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
{ {
GstCaps *ret; GstCaps *caps, *interlaced_caps;
GSList *walk; GSList *walk;
GSList *formats; GSList *formats;
guint32 fourcc = 0; guint32 fourcc = 0;
@ -4868,7 +4868,8 @@ gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
v4l2object->fmtdesc = v4l2object->fmtdesc =
gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc); gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
ret = gst_caps_new_empty (); caps = gst_caps_new_empty ();
interlaced_caps = gst_caps_new_empty ();
if (v4l2object->keep_aspect && !v4l2object->par) { if (v4l2object->keep_aspect && !v4l2object->par) {
struct v4l2_cropcap cropcap; struct v4l2_cropcap cropcap;
@ -4924,6 +4925,7 @@ gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
GstCaps *format_caps = gst_caps_new_empty (); GstCaps *format_caps = gst_caps_new_empty ();
gst_caps_append_structure (format_caps, gst_structure_copy (template)); gst_caps_append_structure (format_caps, gst_structure_copy (template));
add_alternate_variant (v4l2object, format_caps, template);
if (!gst_caps_can_intersect (format_caps, filter)) { if (!gst_caps_can_intersect (format_caps, filter)) {
gst_caps_unref (format_caps); gst_caps_unref (format_caps);
@ -4937,34 +4939,42 @@ gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
tmp = gst_v4l2_object_probe_caps_for_format (v4l2object, tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
format->pixelformat, template); format->pixelformat, template);
if (tmp) { if (tmp) {
gst_caps_append (ret, tmp);
/* Add a variant of the caps with the Interlaced feature so we can negotiate it if needed */ /* Add a variant of the caps with the Interlaced feature so we can negotiate it if needed */
add_alternate_variant (v4l2object, ret, gst_caps_get_structure (ret, gint i;
gst_caps_get_size (ret) - 1)); for (i = 0; i < gst_caps_get_size (tmp); i++) {
GstStructure *s = gst_caps_get_structure (tmp, i);
add_alternate_variant (v4l2object, interlaced_caps, s);
}
gst_caps_append (caps, tmp);
} }
gst_structure_free (template); gst_structure_free (template);
} }
caps = gst_caps_simplify (caps);
interlaced_caps = gst_caps_simplify (interlaced_caps);
gst_caps_append (caps, interlaced_caps);
if (filter) { if (filter) {
GstCaps *tmp; GstCaps *tmp;
tmp = ret; tmp = caps;
ret = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST); caps = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (tmp); gst_caps_unref (tmp);
} }
/* Add a variant of the caps without the colorimetry so that we can negotiate /* Add a variant of the caps without the colorimetry so that we can negotiate
successfully even if the detected colorimetry from upstream is not supported successfully even if the detected colorimetry from upstream is not supported
by the device */ by the device */
if (ret) { if (caps) {
add_non_colorimetry_caps (v4l2object, ret); add_non_colorimetry_caps (v4l2object, caps);
} }
GST_INFO_OBJECT (v4l2object->dbg_obj, "probed caps: %" GST_PTR_FORMAT, ret); GST_INFO_OBJECT (v4l2object->dbg_obj, "probed caps: %" GST_PTR_FORMAT, caps);
return ret; return caps;
} }
GstCaps * GstCaps *