summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2017-09-13 16:05:08 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2017-09-13 16:05:08 -0400
commita08d7cdef5e20b88f93674a5b1053dc6edee7e18 (patch)
tree5b9474f7dded8429f982c99d7db67ac469b80daa /sys
parentc56eb21a82617f2cc54b97dbfb4fc64ba428851c (diff)
v4l2src: Ensure all caps a fixated
The code relied on the list compare function to fixate the caps but if the caps only has one structure, the compare function will never get called. Capture device for which there is only one structure in the caps would then get some assertion and later fail badly. Instead, fixate before inserting into the list and split the reading and the fixation of the structures.
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/gstv4l2src.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
index e98cb7985..9ed87849c 100644
--- a/sys/v4l2/gstv4l2src.c
+++ b/sys/v4l2/gstv4l2src.c
@@ -277,46 +277,47 @@ gst_vl42_src_fixate_fields (GQuark field_id, GValue * value, gpointer user_data)
static void
gst_v4l2_src_fixate_struct_with_preference (GstStructure * s,
- struct PreferedCapsInfo *pref, gint * width, gint * height,
- gint * fps_n, gint * fps_d)
+ struct PreferedCapsInfo *pref)
{
- if (gst_structure_has_field (s, "width")) {
+ if (gst_structure_has_field (s, "width"))
gst_structure_fixate_field_nearest_int (s, "width", pref->width);
- if (width)
- gst_structure_get_int (s, "width", width);
- }
-
- if (gst_structure_has_field (s, "height")) {
+ if (gst_structure_has_field (s, "height"))
gst_structure_fixate_field_nearest_int (s, "height", pref->height);
- if (height)
- gst_structure_get_int (s, "height", height);
- }
-
- if (gst_structure_has_field (s, "framerate")) {
+ if (gst_structure_has_field (s, "framerate"))
gst_structure_fixate_field_nearest_fraction (s, "framerate", pref->fps_n,
pref->fps_d);
- if (fps_n && fps_d)
- gst_structure_get_fraction (s, "framerate", fps_n, fps_d);
- }
-
/* Finally, fixate everything else except the interlace-mode and colorimetry
* which still need further negotiation as it wasn't probed */
gst_structure_map_in_place (s, gst_vl42_src_fixate_fields, s);
}
+static void
+gst_v4l2_src_parse_fixed_struct (GstStructure * s,
+ gint * width, gint * height, gint * fps_n, gint * fps_d)
+{
+ if (gst_structure_has_field (s, "width") && width)
+ gst_structure_get_int (s, "width", width);
+
+ if (gst_structure_has_field (s, "height") && height)
+ gst_structure_get_int (s, "height", height);
+
+ if (gst_structure_has_field (s, "framerate") && fps_n && fps_d)
+ gst_structure_get_fraction (s, "framerate", fps_n, fps_d);
+}
+
/* TODO Consider framerate */
static gint
-gst_v4l2src_caps_fixate_and_compare (GstStructure * a, GstStructure * b,
+gst_v4l2src_fixed_caps_compare (GstStructure * a, GstStructure * b,
struct PreferedCapsInfo *pref)
{
gint aw = G_MAXINT, ah = G_MAXINT, ad = G_MAXINT;
gint bw = G_MAXINT, bh = G_MAXINT, bd = G_MAXINT;
- gst_v4l2_src_fixate_struct_with_preference (a, pref, &aw, &ah, NULL, NULL);
- gst_v4l2_src_fixate_struct_with_preference (b, pref, &bw, &bh, NULL, NULL);
+ gst_v4l2_src_parse_fixed_struct (a, &aw, &ah, NULL, NULL);
+ gst_v4l2_src_parse_fixed_struct (b, &bw, &bh, NULL, NULL);
/* When both are smaller then pref, just append to the end */
if ((bw < pref->width || bh < pref->height)
@@ -380,16 +381,19 @@ gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps, GstStructure * pref_s)
* transformation to happen downstream. */
if (pref_s) {
pref_s = gst_structure_copy (pref_s);
- gst_v4l2_src_fixate_struct_with_preference (pref_s, &pref, &pref.width,
- &pref.height, &pref.fps_n, &pref.fps_d);
+ gst_v4l2_src_fixate_struct_with_preference (pref_s, &pref);
+ gst_v4l2_src_parse_fixed_struct (pref_s, &pref.width, &pref.height,
+ &pref.fps_n, &pref.fps_d);
gst_structure_free (pref_s);
}
/* Sort the structures to get the caps that is nearest to our preferences,
* first */
- while ((s = gst_caps_steal_structure (caps, 0)))
+ while ((s = gst_caps_steal_structure (caps, 0))) {
+ gst_v4l2_src_fixate_struct_with_preference (s, &pref);
caps_list = g_list_insert_sorted_with_data (caps_list, s,
- (GCompareDataFunc) gst_v4l2src_caps_fixate_and_compare, &pref);
+ (GCompareDataFunc) gst_v4l2src_fixed_caps_compare, &pref);
+ }
while (caps_list) {
s = caps_list->data;