From 3b5cac3659884f37bf338305517fc418c4f51e76 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 7 Jun 2016 16:04:52 -0400 Subject: [PATCH] v4l2: Add an error return to _try/_set_format 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 | 28 +++++++++++++++------------- sys/v4l2/gstv4l2object.h | 5 +++-- sys/v4l2/gstv4l2sink.c | 4 +++- sys/v4l2/gstv4l2src.c | 13 +++++++++---- sys/v4l2/gstv4l2transform.c | 7 +++++-- sys/v4l2/gstv4l2videodec.c | 14 +++++++++++--- 6 files changed, 46 insertions(+), 25 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 0f51106db6..c4d3dac4cb 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -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); } /** diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index e3728c4779..7117d4386e 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -25,6 +25,7 @@ #define __GST_V4L2_OBJECT_H__ #include "ext/videodev2.h" +#include "v4l2-utils.h" #include #include @@ -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); diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c index 7587aa9bde..ae4a3c2438 100644 --- a/sys/v4l2/gstv4l2sink.c +++ b/sys/v4l2/gstv4l2sink.c @@ -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; } diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 348ab7fbbd..a6d34b1d4c 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -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)) diff --git a/sys/v4l2/gstv4l2transform.c b/sys/v4l2/gstv4l2transform.c index 864b64f52c..96e8ef56a5 100644 --- a/sys/v4l2/gstv4l2transform.c +++ b/sys/v4l2/gstv4l2transform.c @@ -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: diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c index 547ccbfee8..344df49bc0 100644 --- a/sys/v4l2/gstv4l2videodec.c +++ b/sys/v4l2/gstv4l2videodec.c @@ -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: