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;
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,
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",
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",
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
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));
{
/* 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);
}
}
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;
}
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);
}
/**
#define __GST_V4L2_OBJECT_H__
#include "ext/videodev2.h"
+#include "v4l2-utils.h"
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
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);
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;
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);
invalid_format:
{
/* error already posted */
+ gst_v4l2_error (v4l2sink, &error);
GST_DEBUG_OBJECT (v4l2sink, "can't set format");
return FALSE;
}
static gboolean
gst_v4l2src_set_format (GstV4l2Src * v4l2src, GstCaps * caps)
{
+ GstV4l2Error error = GST_V4L2_ERROR_INIT;
GstV4l2Object *obj;
obj = v4l2src->v4l2object;
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;
}
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))
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) {
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 */
{
GST_ERROR_OBJECT (self, "failed to set input caps: %" GST_PTR_FORMAT,
incaps);
+ gst_v4l2_error (self, &error);
goto failed;
}
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:
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);
/* 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;
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;
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;
}
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,
{
GST_ERROR_OBJECT (self, "not negotiated");
ret = GST_FLOW_NOT_NEGOTIATED;
+ gst_v4l2_error (self, &error);
goto drop;
}
activate_failed: