v4l2: Add an error return to _try/_set_format
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 7 Jun 2016 20:04:52 +0000 (16:04 -0400)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 7 Jun 2016 21:02:43 +0000 (17:02 -0400)
This way one can easily ignore errors. Previously, error were always
posted ont he bus.

https://bugzilla.gnome.org/show_bug.cgi?id=766172

sys/v4l2/gstv4l2object.c
sys/v4l2/gstv4l2object.h
sys/v4l2/gstv4l2sink.c
sys/v4l2/gstv4l2src.c
sys/v4l2/gstv4l2transform.c
sys/v4l2/gstv4l2videodec.c

index 0f51106..c4d3dac 100644 (file)
@@ -3090,7 +3090,7 @@ gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
 
 static gboolean
 gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
-    gboolean try_only)
+    gboolean try_only, GstV4l2Error * error)
 {
   gint fd = v4l2object->video_fd;
   struct v4l2_format format;
@@ -3498,7 +3498,7 @@ invalid_caps:
 try_fmt_failed:
   {
     if (errno == EBUSY) {
-      GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, BUSY,
+      GST_V4L2_ERROR (error, RESOURCE, BUSY,
           (_("Device '%s' is busy"), v4l2object->videodev),
           ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
               GST_FOURCC_ARGS (pixelformat), width, height,
@@ -3509,13 +3509,13 @@ try_fmt_failed:
 set_fmt_failed:
   {
     if (errno == EBUSY) {
-      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, BUSY,
+      GST_V4L2_ERROR (error, RESOURCE, BUSY,
           (_("Device '%s' is busy"), v4l2object->videodev),
           ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
               GST_FOURCC_ARGS (pixelformat), width, height,
               g_strerror (errno)));
     } else {
-      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+      GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
           (_("Device '%s' cannot capture at %dx%d"),
               v4l2object->videodev, width, height),
           ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
@@ -3527,7 +3527,7 @@ set_fmt_failed:
 invalid_dimensions:
   {
     if (!try_only) {
-      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+      GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
           (_("Device '%s' cannot capture at %dx%d"),
               v4l2object->videodev, width, height),
           ("Tried to capture at %dx%d, but device returned size %dx%d",
@@ -3538,7 +3538,7 @@ invalid_dimensions:
 invalid_pixelformat:
   {
     if (!try_only) {
-      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+      GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
           (_("Device '%s' cannot capture in the specified format"),
               v4l2object->videodev),
           ("Tried to capture in %" GST_FOURCC_FORMAT
@@ -3551,7 +3551,7 @@ invalid_pixelformat:
 invalid_planes:
   {
     if (!try_only) {
-      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
+      GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
           (_("Device '%s' does support non-contiguous planes"),
               v4l2object->videodev),
           ("Device wants %d planes", format.fmt.pix_mp.num_planes));
@@ -3562,7 +3562,7 @@ get_parm_failed:
   {
     /* it's possible that this call is not supported */
     if (errno != EINVAL && errno != ENOTTY) {
-      GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+      GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
           (_("Could not get parameters on device '%s'"),
               v4l2object->videodev), GST_ERROR_SYSTEM);
     }
@@ -3570,7 +3570,7 @@ get_parm_failed:
   }
 set_parm_failed:
   {
-    GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
+    GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
         (_("Video device did not accept new frame rate setting.")),
         GST_ERROR_SYSTEM);
     goto done;
@@ -3583,15 +3583,17 @@ pool_failed:
 }
 
 gboolean
-gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
+gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps,
+    GstV4l2Error * error)
 {
-  return gst_v4l2_object_set_format_full (v4l2object, caps, FALSE);
+  return gst_v4l2_object_set_format_full (v4l2object, caps, FALSE, error);
 }
 
 gboolean
-gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps)
+gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps,
+    GstV4l2Error * error)
 {
-  return gst_v4l2_object_set_format_full (v4l2object, caps, TRUE);
+  return gst_v4l2_object_set_format_full (v4l2object, caps, TRUE, error);
 }
 
 /**
index e3728c4..7117d43 100644 (file)
@@ -25,6 +25,7 @@
 #define __GST_V4L2_OBJECT_H__
 
 #include "ext/videodev2.h"
+#include "v4l2-utils.h"
 
 #include <gst/gst.h>
 #include <gst/base/gstpushsrc.h>
@@ -250,8 +251,8 @@ GstCaps*      gst_v4l2_object_get_codec_caps (void);
 gint          gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
                                                   gint plane, gint stride);
 
-gboolean      gst_v4l2_object_set_format  (GstV4l2Object * v4l2object, GstCaps * caps);
-gboolean      gst_v4l2_object_try_format  (GstV4l2Object * v4l2object, GstCaps * caps);
+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);
 
index 7587aa9..ae4a3c2 100644 (file)
@@ -493,6 +493,7 @@ gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
 static gboolean
 gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
 {
+  GstV4l2Error error = GST_V4L2_ERROR_INIT;
   GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
   GstV4l2Object *obj = v4l2sink->v4l2object;
 
@@ -510,7 +511,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
   if (!gst_v4l2_object_stop (obj))
     goto stop_failed;
 
-  if (!gst_v4l2_object_set_format (obj, caps))
+  if (!gst_v4l2_object_set_format (obj, caps, &error))
     goto invalid_format;
 
   gst_v4l2sink_sync_overlay_fields (v4l2sink);
@@ -538,6 +539,7 @@ stop_failed:
 invalid_format:
   {
     /* error already posted */
+    gst_v4l2_error (v4l2sink, &error);
     GST_DEBUG_OBJECT (v4l2sink, "can't set format");
     return FALSE;
   }
index 348ab7f..a6d34b1 100644 (file)
@@ -425,6 +425,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
 static gboolean
 gst_v4l2src_set_format (GstV4l2Src * v4l2src, GstCaps * caps)
 {
+  GstV4l2Error error = GST_V4L2_ERROR_INIT;
   GstV4l2Object *obj;
 
   obj = v4l2src->v4l2object;
@@ -432,9 +433,10 @@ gst_v4l2src_set_format (GstV4l2Src * v4l2src, GstCaps * caps)
   g_signal_emit (v4l2src, gst_v4l2_signals[SIGNAL_PRE_SET_FORMAT], 0,
       v4l2src->v4l2object->video_fd, caps);
 
-  if (!gst_v4l2_object_set_format (obj, caps))
-    /* error already posted */
+  if (!gst_v4l2_object_set_format (obj, caps, &error)) {
+    gst_v4l2_error (v4l2src, &error);
     return FALSE;
+  }
 
   return TRUE;
 }
@@ -453,17 +455,20 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
     return TRUE;
 
   if (GST_V4L2_IS_ACTIVE (obj)) {
+    GstV4l2Error error = GST_V4L2_ERROR_INIT;
     /* Just check if the format is acceptable, once we know
      * no buffers should be outstanding we try S_FMT.
      *
      * Basesrc will do an allocation query that
      * should indirectly reclaim buffers, after that we can
      * set the format and then configure our pool */
-    if (gst_v4l2_object_try_format (obj, caps)) {
+    if (gst_v4l2_object_try_format (obj, caps, &error)) {
       v4l2src->renegotiation_adjust = v4l2src->offset + 1;
       v4l2src->pending_set_fmt = TRUE;
-    } else
+    } else {
+      gst_v4l2_error (v4l2src, &error);
       return FALSE;
+    }
   } else {
     /* make sure we stop capturing and dealloc buffers */
     if (!gst_v4l2_object_stop (obj))
index 864b64f..96e8ef5 100644 (file)
@@ -195,6 +195,7 @@ static gboolean
 gst_v4l2_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps,
     GstCaps * outcaps)
 {
+  GstV4l2Error error = GST_V4L2_ERROR_INIT;
   GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
 
   if (self->incaps && self->outcaps) {
@@ -212,10 +213,10 @@ gst_v4l2_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps,
   gst_caps_replace (&self->incaps, incaps);
   gst_caps_replace (&self->outcaps, outcaps);
 
-  if (!gst_v4l2_object_set_format (self->v4l2output, incaps))
+  if (!gst_v4l2_object_set_format (self->v4l2output, incaps, &error))
     goto incaps_failed;
 
-  if (!gst_v4l2_object_set_format (self->v4l2capture, outcaps))
+  if (!gst_v4l2_object_set_format (self->v4l2capture, outcaps, &error))
     goto outcaps_failed;
 
   /* FIXME implement fallback if crop not supported */
@@ -231,6 +232,7 @@ incaps_failed:
   {
     GST_ERROR_OBJECT (self, "failed to set input caps: %" GST_PTR_FORMAT,
         incaps);
+    gst_v4l2_error (self, &error);
     goto failed;
   }
 outcaps_failed:
@@ -238,6 +240,7 @@ outcaps_failed:
     gst_v4l2_object_stop (self->v4l2output);
     GST_ERROR_OBJECT (self, "failed to set output caps: %" GST_PTR_FORMAT,
         outcaps);
+    gst_v4l2_error (self, &error);
     goto failed;
   }
 failed:
index 547ccbf..344df49 100644 (file)
@@ -229,6 +229,7 @@ static gboolean
 gst_v4l2_video_dec_set_format (GstVideoDecoder * decoder,
     GstVideoCodecState * state)
 {
+  GstV4l2Error error = GST_V4L2_ERROR_INIT;
   gboolean ret = TRUE;
   GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
 
@@ -245,10 +246,12 @@ gst_v4l2_video_dec_set_format (GstVideoDecoder * decoder,
     /* FIXME we probably need to do more work if pools are active */
   }
 
-  ret = gst_v4l2_object_set_format (self->v4l2output, state->caps);
+  ret = gst_v4l2_object_set_format (self->v4l2output, state->caps, &error);
 
   if (ret)
     self->input_state = gst_video_codec_state_ref (state);
+  else
+    gst_v4l2_error (self, &error);
 
 done:
   return ret;
@@ -516,6 +519,7 @@ static GstFlowReturn
 gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
     GstVideoCodecFrame * frame)
 {
+  GstV4l2Error error = GST_V4L2_ERROR_INIT;
   GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
   GstFlowReturn ret = GST_FLOW_OK;
 
@@ -527,7 +531,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
   if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2output))) {
     if (!self->input_state)
       goto not_negotiated;
-    if (!gst_v4l2_object_set_format (self->v4l2output, self->input_state->caps))
+    if (!gst_v4l2_object_set_format (self->v4l2output, self->input_state->caps,
+          &error))
       goto not_negotiated;
   }
 
@@ -615,8 +620,10 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
     GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
 
     /* Try to set negotiated format, on success replace acquired format */
-    if (gst_v4l2_object_set_format (self->v4l2capture, caps))
+    if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error))
       gst_video_info_from_caps (&info, caps);
+    else
+      gst_v4l2_clear_error (&error);
     gst_caps_unref (caps);
 
     output_state = gst_video_decoder_set_output_state (decoder,
@@ -686,6 +693,7 @@ not_negotiated:
   {
     GST_ERROR_OBJECT (self, "not negotiated");
     ret = GST_FLOW_NOT_NEGOTIATED;
+    gst_v4l2_error (self, &error);
     goto drop;
   }
 activate_failed: