+ /* We consider the first structure from peercaps to be a preference. This is
+ * useful for matching a reported native display, or simply to avoid
+ * transformation to happen downstream. */
+ if (pref_s) {
+ pref_s = gst_structure_copy (pref_s);
+ 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);
+ }
+
+ GST_DEBUG_OBJECT (basesrc, "Prefered size %ix%i", pref.width, pref.height);
+
+ /* Sort the structures to get the caps that is nearest to our preferences,
+ * first. Use single struct caps for sorting so we preserve the features. */
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ GstCaps *tmp = gst_caps_copy_nth (caps, i);
+
+ s = gst_caps_get_structure (tmp, 0);
+ gst_v4l2_src_fixate_struct_with_preference (s, &pref);
+
+ caps_list = g_list_insert_sorted_with_data (caps_list, tmp,
+ (GCompareDataFunc) gst_v4l2src_fixed_caps_compare, &pref);
+ }
+
+ gst_caps_unref (caps);
+ caps = gst_caps_new_empty ();
+
+ while (caps_list) {
+ GstCaps *tmp = caps_list->data;
+ caps_list = g_list_delete_link (caps_list, caps_list);
+ gst_caps_append (caps, tmp);
+ }
+
+ GST_DEBUG_OBJECT (basesrc, "sorted and normalized caps %" GST_PTR_FORMAT,
+ caps);
+
+ /* Each structure in the caps has been fixated, except for the
+ * interlace-mode and colorimetry. Now normalize the caps so we can
+ * enumerate the possibilities */
+ caps = gst_caps_normalize (caps);
+
+ for (i = 0; i < gst_caps_get_size (caps); ++i) {
+ gst_v4l2_clear_error (&error);
+ if (fcaps)
+ gst_caps_unref (fcaps);
+
+ fcaps = gst_caps_copy_nth (caps, i);
+
+ /* try hard to avoid TRY_FMT since some UVC camera just crash when this
+ * is called at run-time. */
+ if (gst_v4l2_object_caps_is_subset (obj, fcaps)) {
+ gst_caps_unref (fcaps);
+ fcaps = gst_v4l2_object_get_current_caps (obj);