mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
v4l2: enhance v4l2 control interface to support string type CID
add string type cid support for v4l2 implementation Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/676>
This commit is contained in:
parent
c943be8b25
commit
0a453cc4a4
2 changed files with 73 additions and 5 deletions
|
@ -337,6 +337,7 @@ gboolean gst_v4l2_signal_strength (GstV4l2Object * v4l2object, gint tunernum
|
||||||
/* attribute control */
|
/* attribute control */
|
||||||
gboolean gst_v4l2_get_attribute (GstV4l2Object * v4l2object, int attribute, int * value);
|
gboolean gst_v4l2_get_attribute (GstV4l2Object * v4l2object, int attribute, int * value);
|
||||||
gboolean gst_v4l2_set_attribute (GstV4l2Object * v4l2object, int attribute, const int value);
|
gboolean gst_v4l2_set_attribute (GstV4l2Object * v4l2object, int attribute, const int value);
|
||||||
|
gboolean gst_v4l2_set_string_attribute (GstV4l2Object * v4l2object, int attribute_num, const char *value);
|
||||||
gboolean gst_v4l2_set_controls (GstV4l2Object * v4l2object, GstStructure * controls);
|
gboolean gst_v4l2_set_controls (GstV4l2Object * v4l2object, GstStructure * controls);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -330,7 +330,8 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
|
||||||
case V4L2_CTRL_TYPE_MENU:
|
case V4L2_CTRL_TYPE_MENU:
|
||||||
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
||||||
case V4L2_CTRL_TYPE_BITMASK:
|
case V4L2_CTRL_TYPE_BITMASK:
|
||||||
case V4L2_CTRL_TYPE_BUTTON:{
|
case V4L2_CTRL_TYPE_BUTTON:
|
||||||
|
case V4L2_CTRL_TYPE_STRING:{
|
||||||
control.name[31] = '\0';
|
control.name[31] = '\0';
|
||||||
gst_v4l2_normalise_control_name ((gchar *) control.name);
|
gst_v4l2_normalise_control_name ((gchar *) control.name);
|
||||||
g_datalist_id_set_data (&v4l2object->controls,
|
g_datalist_id_set_data (&v4l2object->controls,
|
||||||
|
@ -970,6 +971,67 @@ ctrl_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
* gst_v4l2_set_string_attribute():
|
||||||
|
* try to set the string value of one specific attribute
|
||||||
|
* return value: TRUE on success, FALSE on error
|
||||||
|
******************************************************/
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_set_string_attribute (GstV4l2Object * v4l2object,
|
||||||
|
int attribute_num, const char *value)
|
||||||
|
{
|
||||||
|
struct v4l2_ext_controls ctrls = { {0}, 1 };
|
||||||
|
struct v4l2_ext_control ctrl;
|
||||||
|
struct v4l2_queryctrl control = { 0, };
|
||||||
|
|
||||||
|
if (!GST_V4L2_IS_OPEN (v4l2object))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
control.id = attribute_num;
|
||||||
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {
|
||||||
|
GST_WARNING_OBJECT (v4l2object,
|
||||||
|
"Failed to find control %d on device '%s'.",
|
||||||
|
attribute_num, v4l2object->videodev);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control.type != V4L2_CTRL_TYPE_STRING) {
|
||||||
|
GST_WARNING_OBJECT (v4l2object,
|
||||||
|
"control %d is not string type on device '%s'.",
|
||||||
|
attribute_num, v4l2object->videodev);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.id = attribute_num;
|
||||||
|
ctrl.size = strlen (value) + 1;
|
||||||
|
ctrl.string = g_malloc (ctrl.size);
|
||||||
|
strcpy (ctrl.string, value);
|
||||||
|
|
||||||
|
ctrls.which = V4L2_CTRL_ID2WHICH (attribute_num);
|
||||||
|
ctrls.count = 1;
|
||||||
|
ctrls.controls = &ctrl;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "setting value of attribute %d to %s",
|
||||||
|
attribute_num, value);
|
||||||
|
|
||||||
|
if (v4l2object->ioctl (v4l2object->video_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
|
||||||
|
goto ctrl_failed;
|
||||||
|
|
||||||
|
g_free (ctrl.string);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
ctrl_failed:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (v4l2object,
|
||||||
|
_("Failed to set value %s for control %d on device '%s'."),
|
||||||
|
value, attribute_num, v4l2object->videodev);
|
||||||
|
g_free (ctrl.string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
set_control (GQuark field_id, const GValue * value, gpointer user_data)
|
set_control (GQuark field_id, const GValue * value, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -1002,13 +1064,18 @@ set_control (GQuark field_id, const GValue * value, gpointer user_data)
|
||||||
g_quark_to_string (field_id));
|
g_quark_to_string (field_id));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (!G_VALUE_HOLDS (value, G_TYPE_INT)) {
|
if (G_VALUE_HOLDS (value, G_TYPE_INT)) {
|
||||||
|
gst_v4l2_set_attribute (v4l2object, GPOINTER_TO_INT (d),
|
||||||
|
g_value_get_int (value));
|
||||||
|
} else if (G_VALUE_HOLDS (value, G_TYPE_STRING)) {
|
||||||
|
gst_v4l2_set_string_attribute (v4l2object, GPOINTER_TO_INT (d),
|
||||||
|
g_value_get_string (value));
|
||||||
|
} else {
|
||||||
GST_WARNING_OBJECT (v4l2object,
|
GST_WARNING_OBJECT (v4l2object,
|
||||||
"'int' value expected for control '%s'.", g_quark_to_string (field_id));
|
"no compatible value expected for control '%s'.",
|
||||||
|
g_quark_to_string (field_id));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
gst_v4l2_set_attribute (v4l2object, GPOINTER_TO_INT (d),
|
|
||||||
g_value_get_int (value));
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue