diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 1079c43011..0658e7ca50 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -2416,9 +2416,12 @@ return_data: "height", G_TYPE_INT, (gint) height, NULL); gst_v4l2_object_add_aspect_ratio (v4l2object, s); - gst_v4l2_object_add_interlace_mode (v4l2object, s, width, height, - pixelformat); - gst_v4l2_object_add_colorspace (v4l2object, s, width, height, pixelformat); + + if (!v4l2object->skip_try_fmt_probes) { + gst_v4l2_object_add_interlace_mode (v4l2object, s, width, height, + pixelformat); + gst_v4l2_object_add_colorspace (v4l2object, s, width, height, pixelformat); + } if (G_IS_VALUE (&rates)) { gst_v4l2src_value_simplify (&rates); @@ -2738,13 +2741,17 @@ default_frame_sizes: else gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL); - /* We could consider setting interlace mode from min and max. */ - gst_v4l2_object_add_interlace_mode (v4l2object, tmp, max_w, max_h, - pixelformat); gst_v4l2_object_add_aspect_ratio (v4l2object, tmp); - /* We could consider to check colorspace for min too, in case it depends on - * the size. But in this case, min and max could not be enough */ - gst_v4l2_object_add_colorspace (v4l2object, tmp, max_w, max_h, pixelformat); + + if (!v4l2object->skip_try_fmt_probes) { + /* We could consider setting interlace mode from min and max. */ + gst_v4l2_object_add_interlace_mode (v4l2object, tmp, max_w, max_h, + pixelformat); + /* We could consider to check colorspace for min too, in case it depends on + * the size. But in this case, min and max could not be enough */ + gst_v4l2_object_add_colorspace (v4l2object, tmp, max_w, max_h, + pixelformat); + } gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp); return ret; @@ -3110,6 +3117,10 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps, enum v4l2_quantization range = 0; enum v4l2_ycbcr_encoding matrix = 0; enum v4l2_xfer_func transfer = 0; + GstStructure *s; + + g_return_val_if_fail (!v4l2object->skip_try_fmt_probes || + gst_caps_is_writable (caps), FALSE); GST_V4L2_CHECK_OPEN (v4l2object); if (!try_only) @@ -3418,6 +3429,20 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps, gst_structure_get_string (s, "colorimetry"))) goto invalid_colorimetry; + /* In case we have skipped the try_fmt probes, we'll need to set the + * colorimetry and interlace-mode back into the caps. */ + if (v4l2object->skip_try_fmt_probes) { + if (!gst_structure_has_field (s, "colorimetry")) { + gchar *str = gst_video_colorimetry_to_string (&info.colorimetry); + gst_structure_set (s, "colorimetry", G_TYPE_STRING, str, NULL); + g_free (str); + } + + if (!gst_structure_has_field (s, "interlace-mode")) + gst_structure_set (s, "interlace-mode", G_TYPE_STRING, + gst_video_interlace_mode_to_string (info.interlace_mode), NULL); + } + if (try_only) /* good enough for trying only */ return TRUE; diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index a0c74b46ec..0df840e604 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -218,6 +218,10 @@ struct _GstV4l2Object { /* Allow to skip reading initial format through G_FMT. Some devices * just fails if you don't call S_FMT first. (ex: M2M decoders) */ gboolean no_initial_format; + /* Avoid any try_fmt probe. This is used by v4l2src to speedup start up time + * on slow USB firmwares. When this is set, gst_v4l2_set_format() will modify + * the caps to reflect what was negotiated during fixation */ + gboolean skip_try_fmt_probes; }; struct _GstV4l2ObjectClassHelper {