mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 20:59:44 +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),
|
v4l2obj = gst_v4l2_object_new (NULL, GST_OBJECT (provider),
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, device_path, NULL, NULL, NULL);
|
V4L2_BUF_TYPE_VIDEO_CAPTURE, device_path, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (!gst_v4l2_open (v4l2obj))
|
if (!gst_v4l2_open (v4l2obj, NULL))
|
||||||
goto destroy;
|
goto destroy;
|
||||||
|
|
||||||
gst_structure_set (props, "device.api", G_TYPE_STRING, "v4l2", NULL);
|
gst_structure_set (props, "device.api", G_TYPE_STRING, "v4l2", NULL);
|
||||||
|
|
|
@ -896,9 +896,9 @@ gst_v4l2_set_defaults (GstV4l2Object * v4l2object)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
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);
|
gst_v4l2_set_defaults (v4l2object);
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -274,7 +274,7 @@ gboolean gst_v4l2_object_get_property_helper (GstV4l2Object *v4l2objec
|
||||||
guint prop_id, GValue * value,
|
guint prop_id, GValue * value,
|
||||||
GParamSpec * pspec);
|
GParamSpec * pspec);
|
||||||
/* open/close */
|
/* 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_open_shared (GstV4l2Object * v4l2object, GstV4l2Object * other);
|
||||||
gboolean gst_v4l2_object_close (GstV4l2Object * v4l2object);
|
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 */
|
/* TODO Move to proper namespace */
|
||||||
/* open/close the device */
|
/* 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_dup (GstV4l2Object * v4l2object, GstV4l2Object * other);
|
||||||
gboolean gst_v4l2_close (GstV4l2Object * v4l2object);
|
gboolean gst_v4l2_close (GstV4l2Object * v4l2object);
|
||||||
|
|
||||||
|
|
|
@ -350,12 +350,12 @@ gst_v4l2radio_finalize (GstV4l2Radio * radio)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2radio_open (GstV4l2Radio * radio)
|
gst_v4l2radio_open (GstV4l2Radio * radio, GstV4l2Error * error)
|
||||||
{
|
{
|
||||||
GstV4l2Object *v4l2object;
|
GstV4l2Object *v4l2object;
|
||||||
|
|
||||||
v4l2object = radio->v4l2object;
|
v4l2object = radio->v4l2object;
|
||||||
if (gst_v4l2_open (v4l2object))
|
if (gst_v4l2_open (v4l2object, error))
|
||||||
return gst_v4l2radio_fill_channel_list (radio);
|
return gst_v4l2radio_fill_channel_list (radio);
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -406,9 +406,9 @@ gst_v4l2radio_set_defaults (GstV4l2Radio * radio)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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;
|
return FALSE;
|
||||||
|
|
||||||
gst_v4l2radio_set_defaults (radio);
|
gst_v4l2radio_set_defaults (radio);
|
||||||
|
@ -429,13 +429,14 @@ static GstStateChangeReturn
|
||||||
gst_v4l2radio_change_state (GstElement * element, GstStateChange transition)
|
gst_v4l2radio_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstV4l2Radio *radio;
|
GstV4l2Radio *radio;
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
|
|
||||||
radio = GST_V4L2RADIO (element);
|
radio = GST_V4L2RADIO (element);
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
/*start radio */
|
/*start radio */
|
||||||
if (!gst_v4l2radio_start (radio))
|
if (!gst_v4l2radio_start (radio, &error))
|
||||||
ret = GST_STATE_CHANGE_FAILURE;
|
ret = GST_STATE_CHANGE_FAILURE;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
|
@ -457,6 +458,7 @@ gst_v4l2radio_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_v4l2_error (radio, &error);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -437,6 +437,7 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (element);
|
GstV4l2Sink *v4l2sink = GST_V4L2SINK (element);
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2sink, "%d -> %d",
|
GST_DEBUG_OBJECT (v4l2sink, "%d -> %d",
|
||||||
GST_STATE_TRANSITION_CURRENT (transition),
|
GST_STATE_TRANSITION_CURRENT (transition),
|
||||||
|
@ -445,8 +446,10 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
/* open the device */
|
/* 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;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -794,12 +794,15 @@ gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
GstV4l2Src *v4l2src = GST_V4L2SRC (element);
|
GstV4l2Src *v4l2src = GST_V4L2SRC (element);
|
||||||
GstV4l2Object *obj = v4l2src->v4l2object;
|
GstV4l2Object *obj = v4l2src->v4l2object;
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
/* open the device */
|
/* 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;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -115,9 +115,11 @@ gst_v4l2_transform_get_property (GObject * object,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_transform_open (GstV4l2Transform * self)
|
gst_v4l2_transform_open (GstV4l2Transform * self)
|
||||||
{
|
{
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening");
|
GST_DEBUG_OBJECT (self, "Opening");
|
||||||
|
|
||||||
if (!gst_v4l2_object_open (self->v4l2output))
|
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
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_srccaps, NULL);
|
||||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||||
|
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,11 +119,12 @@ static gboolean
|
||||||
gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
|
gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstCaps *codec_caps;
|
GstCaps *codec_caps;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening");
|
GST_DEBUG_OBJECT (self, "Opening");
|
||||||
|
|
||||||
if (!gst_v4l2_object_open (self->v4l2output))
|
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
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_srccaps, NULL);
|
||||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||||
|
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,11 +110,12 @@ static gboolean
|
||||||
gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
|
gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
|
GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
|
||||||
|
GstV4l2Error error = GST_V4L2_ERROR_INIT;
|
||||||
GstCaps *codec_caps;
|
GstCaps *codec_caps;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening");
|
GST_DEBUG_OBJECT (self, "Opening");
|
||||||
|
|
||||||
if (!gst_v4l2_object_open (self->v4l2output))
|
if (!gst_v4l2_object_open (self->v4l2output, &error))
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
|
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_srccaps, NULL);
|
||||||
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
gst_caps_replace (&self->probed_sinkcaps, NULL);
|
||||||
|
|
||||||
|
gst_v4l2_error (self, &error);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -516,7 +516,7 @@ gst_v4l2_adjust_buf_type (GstV4l2Object * v4l2object)
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_open (GstV4l2Object * v4l2object)
|
gst_v4l2_open (GstV4l2Object * v4l2object, GstV4l2Error * error)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int libv4l2_fd = -1;
|
int libv4l2_fd = -1;
|
||||||
|
@ -605,46 +605,43 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
stat_failed:
|
stat_failed:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||||
(_("Cannot identify device '%s'."), v4l2object->videodev),
|
(_("Cannot identify device '%s'."), v4l2object->videodev),
|
||||||
GST_ERROR_SYSTEM);
|
GST_ERROR_SYSTEM);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
no_device:
|
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),
|
(_("This isn't a device '%s'."), v4l2object->videodev),
|
||||||
GST_ERROR_SYSTEM);
|
GST_ERROR_SYSTEM);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
not_open:
|
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."),
|
(_("Could not open device '%s' for reading and writing."),
|
||||||
v4l2object->videodev), GST_ERROR_SYSTEM);
|
v4l2object->videodev), GST_ERROR_SYSTEM);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
not_capture:
|
not_capture:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||||
(_("Device '%s' is not a capture device."),
|
(_("Device '%s' is not a capture device."), v4l2object->videodev),
|
||||||
v4l2object->videodev),
|
|
||||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
not_output:
|
not_output:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||||
(_("Device '%s' is not a output device."),
|
(_("Device '%s' is not a output device."), v4l2object->videodev),
|
||||||
v4l2object->videodev),
|
|
||||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
not_m2m:
|
not_m2m:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND,
|
GST_V4L2_ERROR (error, RESOURCE, NOT_FOUND,
|
||||||
(_("Device '%s' is not a M2M device."),
|
(_("Device '%s' is not a M2M device."), v4l2object->videodev),
|
||||||
v4l2object->videodev),
|
|
||||||
("Capabilities: 0x%x", v4l2object->device_caps));
|
("Capabilities: 0x%x", v4l2object->device_caps));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue