v4l2src: Try to avoid TRY_FMT when camera is streaming

Some camera firmware crash is TRY_FMT is called during streaming. As a
side effect. This try and detect that the same format as currently
running is about to be tried, and skip renegotiation.

https://bugzilla.gnome.org/show_bug.cgi?id=796789
This commit is contained in:
Nicolas Dufresne 2018-07-11 12:21:44 -04:00
parent c87f9eb37b
commit b12b8b0b22
3 changed files with 51 additions and 1 deletions

View file

@ -4019,6 +4019,46 @@ gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps)
return ret;
}
gboolean
gst_v4l2_object_caps_is_subset (GstV4l2Object * v4l2object, GstCaps * caps)
{
GstStructure *config;
GstCaps *oldcaps;
gboolean ret;
if (!v4l2object->pool)
return FALSE;
config = gst_buffer_pool_get_config (v4l2object->pool);
gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
ret = oldcaps && gst_caps_is_subset (oldcaps, caps);
gst_structure_free (config);
return ret;
}
GstCaps *
gst_v4l2_object_get_current_caps (GstV4l2Object * v4l2object)
{
GstStructure *config;
GstCaps *oldcaps;
if (!v4l2object->pool)
return NULL;
config = gst_buffer_pool_get_config (v4l2object->pool);
gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
if (oldcaps)
gst_caps_ref (oldcaps);
gst_structure_free (config);
return oldcaps;
}
gboolean
gst_v4l2_object_unlock (GstV4l2Object * v4l2object)
{

View file

@ -278,7 +278,9 @@ gint gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finf
gboolean gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps, GstV4l2Error * error);
gboolean gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps, GstV4l2Error * error);
gboolean gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps);
gboolean gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps);
gboolean gst_v4l2_object_caps_is_subset (GstV4l2Object * v4l2object, GstCaps * caps);
GstCaps * gst_v4l2_object_get_current_caps (GstV4l2Object * v4l2object);
gboolean gst_v4l2_object_unlock (GstV4l2Object * v4l2object);
gboolean gst_v4l2_object_unlock_stop (GstV4l2Object * v4l2object);

View file

@ -447,6 +447,14 @@ gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps, GstStructure * pref_s)
fcaps = gst_caps_copy_nth (caps, i);
if (GST_V4L2_IS_ACTIVE (obj)) {
/* 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);
break;
}
/* Just check if the format is acceptable, once we know
* no buffers should be outstanding we try S_FMT.
*