v4l2object: Introduce quirk to skip slow probes

skip_try_fmt_probes quirk is set, V4L2 object will not probe for
interlace-mode and colorimetry to avoid relying on try_fmt. This quirk
will be used by v4l2src to avoid desastrous startup time with slow
USB webcams.

When this quirk is enabled, caller will have to iterate over the
negotiated caps as it may contains unsupported formats. If the peer
didn't choose a specific interlace-mode, or colorimetry, the value
chosen by the driver is set into the caps. For this reason, when this
mode is enabled, gst_v4l2_object_set_format() will require writable
caps.

https://bugzilla.gnome.org/show_bug.cgi?id=785156
This commit is contained in:
Nicolas Dufresne 2017-07-19 22:09:38 -04:00
parent 7d3b2628df
commit cae0b9a2d2
2 changed files with 38 additions and 9 deletions

View file

@ -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;

View file

@ -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 {