mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-27 11:32:51 +00:00
v4l2: use GstV4l2Error in gst_v4l2_open()
gst_v4l2_open() is called by gst_v4l2_device_provider_probe_device(), where the GstV4l2Object is created without an associated GstElement. If gst_v4l2_open() fails, it raises a bus message, but without an element, a precondition check fails on gst_element_message_full_with_details() generating a crash if running with fatal-warnings debug mode. GstV4l2Error is a helper to raise error bus messages when it is appropiated. This patch changes the direct bus messages to this helper, and the elements will actually send the error message. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/694>
This commit is contained in:
parent
c95cc6a015
commit
078560e70a
10 changed files with 43 additions and 28 deletions
|
@ -116,7 +116,7 @@ gst_v4l2_device_provider_probe_device (GstV4l2DeviceProvider * provider,
|
|||
v4l2obj = gst_v4l2_object_new (NULL, GST_OBJECT (provider),
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, device_path, NULL, NULL, NULL);
|
||||
|
||||
if (!gst_v4l2_open (v4l2obj))
|
||||
if (!gst_v4l2_open (v4l2obj, NULL))
|
||||
goto destroy;
|
||||
|
||||
gst_structure_set (props, "device.api", G_TYPE_STRING, "v4l2", NULL);
|
||||
|
|
|
@ -896,9 +896,9 @@ gst_v4l2_set_defaults (GstV4l2Object * v4l2object)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_v4l2_object_open (GstV4l2Object * v4l2object)
|
||||
gst_v4l2_object_open (GstV4l2Object * v4l2object, GstV4l2Error * error)
|
||||
{
|
||||
if (gst_v4l2_open (v4l2object))
|
||||
if (gst_v4l2_open (v4l2object, error))
|
||||
gst_v4l2_set_defaults (v4l2object);
|
||||
else
|
||||
return FALSE;
|
||||
|
|
|
@ -274,7 +274,7 @@ gboolean gst_v4l2_object_get_property_helper (GstV4l2Object *v4l2objec
|
|||
guint prop_id, GValue * value,
|
||||
GParamSpec * pspec);
|
||||
/* open/close */
|
||||
gboolean gst_v4l2_object_open (GstV4l2Object * v4l2object);
|
||||
gboolean gst_v4l2_object_open (GstV4l2Object * v4l2object, GstV4l2Error * error);
|
||||
gboolean gst_v4l2_object_open_shared (GstV4l2Object * v4l2object, GstV4l2Object * other);
|
||||
gboolean gst_v4l2_object_close (GstV4l2Object * v4l2object);
|
||||
|
||||
|
@ -317,7 +317,7 @@ GstStructure * gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
|
|||
|
||||
/* TODO Move to proper namespace */
|
||||
/* open/close the device */
|
||||
gboolean gst_v4l2_open (GstV4l2Object * v4l2object);
|
||||
gboolean gst_v4l2_open (GstV4l2Object * v4l2object, GstV4l2Error * error);
|
||||
gboolean gst_v4l2_dup (GstV4l2Object * v4l2object, GstV4l2Object * other);
|
||||
gboolean gst_v4l2_close (GstV4l2Object * v4l2object);
|
||||
|
||||
|
|
|
@ -350,12 +350,12 @@ gst_v4l2radio_finalize (GstV4l2Radio * radio)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_v4l2radio_open (GstV4l2Radio * radio)
|
||||
gst_v4l2radio_open (GstV4l2Radio * radio, GstV4l2Error * error)
|
||||
{
|
||||
GstV4l2Object *v4l2object;
|
||||
|
||||
v4l2object = radio->v4l2object;
|
||||
if (gst_v4l2_open (v4l2object))
|
||||
if (gst_v4l2_open (v4l2object, error))
|
||||
return gst_v4l2radio_fill_channel_list (radio);
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -406,9 +406,9 @@ gst_v4l2radio_set_defaults (GstV4l2Radio * radio)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_v4l2radio_start (GstV4l2Radio * radio)
|
||||
gst_v4l2radio_start (GstV4l2Radio * radio, GstV4l2Error * error)
|
||||
{
|
||||
if (!gst_v4l2radio_open (radio))
|
||||
if (!gst_v4l2radio_open (radio, error))
|
||||
return FALSE;
|
||||
|
||||
gst_v4l2radio_set_defaults (radio);
|
||||
|
@ -429,13 +429,14 @@ static GstStateChangeReturn
|
|||
gst_v4l2radio_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstV4l2Radio *radio;
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||
|
||||
radio = GST_V4L2RADIO (element);
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
/*start radio */
|
||||
if (!gst_v4l2radio_start (radio))
|
||||
if (!gst_v4l2radio_start (radio, &error))
|
||||
ret = GST_STATE_CHANGE_FAILURE;
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
|
@ -457,6 +458,7 @@ gst_v4l2radio_change_state (GstElement * element, GstStateChange transition)
|
|||
break;
|
||||
}
|
||||
|
||||
gst_v4l2_error (radio, &error);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -437,6 +437,7 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
|
|||
{
|
||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (element);
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
|
||||
GST_DEBUG_OBJECT (v4l2sink, "%d -> %d",
|
||||
GST_STATE_TRANSITION_CURRENT (transition),
|
||||
|
@ -445,8 +446,10 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
|
|||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
/* open the device */
|
||||
if (!gst_v4l2_object_open (v4l2sink->v4l2object))
|
||||
if (!gst_v4l2_object_open (v4l2sink->v4l2object, &error)) {
|
||||
gst_v4l2_error (v4l2sink, &error);
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -794,12 +794,15 @@ gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
|
|||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||
GstV4l2Src *v4l2src = GST_V4L2SRC (element);
|
||||
GstV4l2Object *obj = v4l2src->v4l2object;
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
/* open the device */
|
||||
if (!gst_v4l2_object_open (obj))
|
||||
if (!gst_v4l2_object_open (obj, &error)) {
|
||||
gst_v4l2_error (v4l2src, &error);
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -115,9 +115,11 @@ gst_v4l2_transform_get_property (GObject * object,
|
|||
static gboolean
|
||||
gst_v4l2_transform_open (GstV4l2Transform * self)
|
||||
{
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Opening");
|
||||
|
||||
if (!gst_v4l2_object_open (self->v4l2output))
|
||||
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||
goto failure;
|
||||
|
||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
||||
|
@ -160,6 +162,8 @@ failure:
|
|||
gst_caps_replace (&self->probed_srccaps, NULL);
|
||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||
|
||||
gst_v4l2_error (self, &error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,11 +119,12 @@ static gboolean
|
|||
gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
|
||||
{
|
||||
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
GstCaps *codec_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Opening");
|
||||
|
||||
if (!gst_v4l2_object_open (self->v4l2output))
|
||||
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||
goto failure;
|
||||
|
||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
||||
|
@ -155,6 +156,8 @@ failure:
|
|||
gst_caps_replace (&self->probed_srccaps, NULL);
|
||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||
|
||||
gst_v4l2_error (self, &error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,11 +110,12 @@ static gboolean
|
|||
gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
|
||||
{
|
||||
GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
|
||||
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||
GstCaps *codec_caps;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Opening");
|
||||
|
||||
if (!gst_v4l2_object_open (self->v4l2output))
|
||||
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||
goto failure;
|
||||
|
||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
||||
|
@ -159,6 +160,8 @@ failure:
|
|||
gst_caps_replace (&self->probed_srccaps, NULL);
|
||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||
|
||||
gst_v4l2_error (self, &error);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ gst_v4l2_adjust_buf_type (GstV4l2Object * v4l2object)
|
|||
* return value: TRUE on success, FALSE on error
|
||||
******************************************************/
|
||||
gboolean
|
||||
gst_v4l2_open (GstV4l2Object * v4l2object)
|
||||
gst_v4l2_open (GstV4l2Object * v4l2object, GstV4l2Error * error)
|
||||
{
|
||||
struct stat st;
|
||||
int libv4l2_fd = -1;
|
||||
|
@ -605,46 +605,43 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
|
|||
/* ERRORS */
|
||||
stat_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
||||
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||
(_("Cannot identify device '%s'."), v4l2object->videodev),
|
||||
GST_ERROR_SYSTEM);
|
||||
goto error;
|
||||
}
|
||||
no_device:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
||||
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||
(_("This isn't a device '%s'."), v4l2object->videodev),
|
||||
GST_ERROR_SYSTEM);
|
||||
goto error;
|
||||
}
|
||||
not_open:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE,
|
||||
GST_V4L2_ERROR (error, RESOURCE, OPEN_READ_WRITE,
|
||||
(_("Could not open device '%s' for reading and writing."),
|
||||
v4l2object->videodev), GST_ERROR_SYSTEM);
|
||||
goto error;
|
||||
}
|
||||
not_capture:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a capture device."),
|
||||
v4l2object->videodev),
|
||||
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a capture device."), v4l2object->videodev),
|
||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||
goto error;
|
||||
}
|
||||
not_output:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a output device."),
|
||||
v4l2object->videodev),
|
||||
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a output device."), v4l2object->videodev),
|
||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||
goto error;
|
||||
}
|
||||
not_m2m:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a M2M device."),
|
||||
v4l2object->videodev),
|
||||
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||
(_("Device '%s' is not a M2M device."), v4l2object->videodev),
|
||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||
goto error;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue