mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
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
This commit is contained in:
parent
e228430788
commit
3b5cac3659
6 changed files with 46 additions and 25 deletions
|
@ -3090,7 +3090,7 @@ gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
gboolean try_only)
|
gboolean try_only, GstV4l2Error * error)
|
||||||
{
|
{
|
||||||
gint fd = v4l2object->video_fd;
|
gint fd = v4l2object->video_fd;
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
@ -3498,7 +3498,7 @@ invalid_caps:
|
||||||
try_fmt_failed:
|
try_fmt_failed:
|
||||||
{
|
{
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, BUSY,
|
GST_V4L2_ERROR (error, RESOURCE, BUSY,
|
||||||
(_("Device '%s' is busy"), v4l2object->videodev),
|
(_("Device '%s' is busy"), v4l2object->videodev),
|
||||||
("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
||||||
GST_FOURCC_ARGS (pixelformat), width, height,
|
GST_FOURCC_ARGS (pixelformat), width, height,
|
||||||
|
@ -3509,13 +3509,13 @@ try_fmt_failed:
|
||||||
set_fmt_failed:
|
set_fmt_failed:
|
||||||
{
|
{
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, BUSY,
|
GST_V4L2_ERROR (error, RESOURCE, BUSY,
|
||||||
(_("Device '%s' is busy"), v4l2object->videodev),
|
(_("Device '%s' is busy"), v4l2object->videodev),
|
||||||
("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
||||||
GST_FOURCC_ARGS (pixelformat), width, height,
|
GST_FOURCC_ARGS (pixelformat), width, height,
|
||||||
g_strerror (errno)));
|
g_strerror (errno)));
|
||||||
} else {
|
} else {
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
|
||||||
(_("Device '%s' cannot capture at %dx%d"),
|
(_("Device '%s' cannot capture at %dx%d"),
|
||||||
v4l2object->videodev, width, height),
|
v4l2object->videodev, width, height),
|
||||||
("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
||||||
|
@ -3527,7 +3527,7 @@ set_fmt_failed:
|
||||||
invalid_dimensions:
|
invalid_dimensions:
|
||||||
{
|
{
|
||||||
if (!try_only) {
|
if (!try_only) {
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
|
||||||
(_("Device '%s' cannot capture at %dx%d"),
|
(_("Device '%s' cannot capture at %dx%d"),
|
||||||
v4l2object->videodev, width, height),
|
v4l2object->videodev, width, height),
|
||||||
("Tried to capture at %dx%d, but device returned size %dx%d",
|
("Tried to capture at %dx%d, but device returned size %dx%d",
|
||||||
|
@ -3538,7 +3538,7 @@ invalid_dimensions:
|
||||||
invalid_pixelformat:
|
invalid_pixelformat:
|
||||||
{
|
{
|
||||||
if (!try_only) {
|
if (!try_only) {
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
|
||||||
(_("Device '%s' cannot capture in the specified format"),
|
(_("Device '%s' cannot capture in the specified format"),
|
||||||
v4l2object->videodev),
|
v4l2object->videodev),
|
||||||
("Tried to capture in %" GST_FOURCC_FORMAT
|
("Tried to capture in %" GST_FOURCC_FORMAT
|
||||||
|
@ -3551,7 +3551,7 @@ invalid_pixelformat:
|
||||||
invalid_planes:
|
invalid_planes:
|
||||||
{
|
{
|
||||||
if (!try_only) {
|
if (!try_only) {
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
|
||||||
(_("Device '%s' does support non-contiguous planes"),
|
(_("Device '%s' does support non-contiguous planes"),
|
||||||
v4l2object->videodev),
|
v4l2object->videodev),
|
||||||
("Device wants %d planes", format.fmt.pix_mp.num_planes));
|
("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 */
|
/* it's possible that this call is not supported */
|
||||||
if (errno != EINVAL && errno != ENOTTY) {
|
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'"),
|
(_("Could not get parameters on device '%s'"),
|
||||||
v4l2object->videodev), GST_ERROR_SYSTEM);
|
v4l2object->videodev), GST_ERROR_SYSTEM);
|
||||||
}
|
}
|
||||||
|
@ -3570,7 +3570,7 @@ get_parm_failed:
|
||||||
}
|
}
|
||||||
set_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.")),
|
(_("Video device did not accept new frame rate setting.")),
|
||||||
GST_ERROR_SYSTEM);
|
GST_ERROR_SYSTEM);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -3583,15 +3583,17 @@ pool_failed:
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
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
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#define __GST_V4L2_OBJECT_H__
|
#define __GST_V4L2_OBJECT_H__
|
||||||
|
|
||||||
#include "ext/videodev2.h"
|
#include "ext/videodev2.h"
|
||||||
|
#include "v4l2-utils.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstpushsrc.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 gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
|
||||||
gint plane, gint stride);
|
gint plane, gint stride);
|
||||||
|
|
||||||
gboolean gst_v4l2_object_set_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);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -493,6 +493,7 @@ gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
|
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
|
||||||
GstV4l2Object *obj = v4l2sink->v4l2object;
|
GstV4l2Object *obj = v4l2sink->v4l2object;
|
||||||
|
|
||||||
|
@ -510,7 +511,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
if (!gst_v4l2_object_stop (obj))
|
if (!gst_v4l2_object_stop (obj))
|
||||||
goto stop_failed;
|
goto stop_failed;
|
||||||
|
|
||||||
if (!gst_v4l2_object_set_format (obj, caps))
|
if (!gst_v4l2_object_set_format (obj, caps, &error))
|
||||||
goto invalid_format;
|
goto invalid_format;
|
||||||
|
|
||||||
gst_v4l2sink_sync_overlay_fields (v4l2sink);
|
gst_v4l2sink_sync_overlay_fields (v4l2sink);
|
||||||
|
@ -538,6 +539,7 @@ stop_failed:
|
||||||
invalid_format:
|
invalid_format:
|
||||||
{
|
{
|
||||||
/* error already posted */
|
/* error already posted */
|
||||||
|
gst_v4l2_error (v4l2sink, &error);
|
||||||
GST_DEBUG_OBJECT (v4l2sink, "can't set format");
|
GST_DEBUG_OBJECT (v4l2sink, "can't set format");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,6 +425,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2src_set_format (GstV4l2Src * v4l2src, GstCaps * caps)
|
gst_v4l2src_set_format (GstV4l2Src * v4l2src, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstV4l2Object *obj;
|
GstV4l2Object *obj;
|
||||||
|
|
||||||
obj = v4l2src->v4l2object;
|
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,
|
g_signal_emit (v4l2src, gst_v4l2_signals[SIGNAL_PRE_SET_FORMAT], 0,
|
||||||
v4l2src->v4l2object->video_fd, caps);
|
v4l2src->v4l2object->video_fd, caps);
|
||||||
|
|
||||||
if (!gst_v4l2_object_set_format (obj, caps))
|
if (!gst_v4l2_object_set_format (obj, caps, &error)) {
|
||||||
/* error already posted */
|
gst_v4l2_error (v4l2src, &error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -453,17 +455,20 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (GST_V4L2_IS_ACTIVE (obj)) {
|
if (GST_V4L2_IS_ACTIVE (obj)) {
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
/* Just check if the format is acceptable, once we know
|
/* Just check if the format is acceptable, once we know
|
||||||
* no buffers should be outstanding we try S_FMT.
|
* no buffers should be outstanding we try S_FMT.
|
||||||
*
|
*
|
||||||
* Basesrc will do an allocation query that
|
* Basesrc will do an allocation query that
|
||||||
* should indirectly reclaim buffers, after that we can
|
* should indirectly reclaim buffers, after that we can
|
||||||
* set the format and then configure our pool */
|
* 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->renegotiation_adjust = v4l2src->offset + 1;
|
||||||
v4l2src->pending_set_fmt = TRUE;
|
v4l2src->pending_set_fmt = TRUE;
|
||||||
} else
|
} else {
|
||||||
|
gst_v4l2_error (v4l2src, &error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* make sure we stop capturing and dealloc buffers */
|
/* make sure we stop capturing and dealloc buffers */
|
||||||
if (!gst_v4l2_object_stop (obj))
|
if (!gst_v4l2_object_stop (obj))
|
||||||
|
|
|
@ -195,6 +195,7 @@ static gboolean
|
||||||
gst_v4l2_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps,
|
gst_v4l2_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps,
|
||||||
GstCaps * outcaps)
|
GstCaps * outcaps)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
|
GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
|
||||||
|
|
||||||
if (self->incaps && self->outcaps) {
|
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->incaps, incaps);
|
||||||
gst_caps_replace (&self->outcaps, outcaps);
|
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;
|
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;
|
goto outcaps_failed;
|
||||||
|
|
||||||
/* FIXME implement fallback if crop not supported */
|
/* 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,
|
GST_ERROR_OBJECT (self, "failed to set input caps: %" GST_PTR_FORMAT,
|
||||||
incaps);
|
incaps);
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
outcaps_failed:
|
outcaps_failed:
|
||||||
|
@ -238,6 +240,7 @@ outcaps_failed:
|
||||||
gst_v4l2_object_stop (self->v4l2output);
|
gst_v4l2_object_stop (self->v4l2output);
|
||||||
GST_ERROR_OBJECT (self, "failed to set output caps: %" GST_PTR_FORMAT,
|
GST_ERROR_OBJECT (self, "failed to set output caps: %" GST_PTR_FORMAT,
|
||||||
outcaps);
|
outcaps);
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
failed:
|
failed:
|
||||||
|
|
|
@ -229,6 +229,7 @@ static gboolean
|
||||||
gst_v4l2_video_dec_set_format (GstVideoDecoder * decoder,
|
gst_v4l2_video_dec_set_format (GstVideoDecoder * decoder,
|
||||||
GstVideoCodecState * state)
|
GstVideoCodecState * state)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
gboolean ret = TRUE;
|
gboolean ret = TRUE;
|
||||||
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
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 */
|
/* 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)
|
if (ret)
|
||||||
self->input_state = gst_video_codec_state_ref (state);
|
self->input_state = gst_video_codec_state_ref (state);
|
||||||
|
else
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -516,6 +519,7 @@ static GstFlowReturn
|
||||||
gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
|
gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GstVideoCodecFrame * frame)
|
GstVideoCodecFrame * frame)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
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 (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2output))) {
|
||||||
if (!self->input_state)
|
if (!self->input_state)
|
||||||
goto not_negotiated;
|
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;
|
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);
|
GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
/* Try to set negotiated format, on success replace acquired format */
|
/* 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);
|
gst_video_info_from_caps (&info, caps);
|
||||||
|
else
|
||||||
|
gst_v4l2_clear_error (&error);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
output_state = gst_video_decoder_set_output_state (decoder,
|
output_state = gst_video_decoder_set_output_state (decoder,
|
||||||
|
@ -686,6 +693,7 @@ not_negotiated:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (self, "not negotiated");
|
GST_ERROR_OBJECT (self, "not negotiated");
|
||||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
activate_failed:
|
activate_failed:
|
||||||
|
|
Loading…
Reference in a new issue