Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/GStreamer/gst-plugins-good.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHaihua Hu <jared.hu@nxp.com>2020-07-22 04:46:47 +0300
committerHaihua Hu <jared.hu@nxp.com>2020-07-22 09:21:42 +0300
commit0a453cc4a4a17df669ff725e2f66dcac4ae78b3e (patch)
tree7e93582e816617a97c5a5bc6ab6bcf1dd9b229a9 /sys
parentc943be8b251d9f16b436d0c11197d84c466660ff (diff)
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>
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/gstv4l2object.h1
-rw-r--r--sys/v4l2/v4l2_calls.c77
2 files changed, 73 insertions, 5 deletions
diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
index 758060846..779c5590a 100644
--- a/sys/v4l2/gstv4l2object.h
+++ b/sys/v4l2/gstv4l2object.h
@@ -337,6 +337,7 @@ gboolean gst_v4l2_signal_strength (GstV4l2Object * v4l2object, gint tunernum
/* attribute control */
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_string_attribute (GstV4l2Object * v4l2object, int attribute_num, const char *value);
gboolean gst_v4l2_set_controls (GstV4l2Object * v4l2object, GstStructure * controls);
G_END_DECLS
diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c
index 53e2e7d1d..e1f52e89d 100644
--- a/sys/v4l2/v4l2_calls.c
+++ b/sys/v4l2/v4l2_calls.c
@@ -330,7 +330,8 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
case V4L2_CTRL_TYPE_BITMASK:
- case V4L2_CTRL_TYPE_BUTTON:{
+ case V4L2_CTRL_TYPE_BUTTON:
+ case V4L2_CTRL_TYPE_STRING:{
control.name[31] = '\0';
gst_v4l2_normalise_control_name ((gchar *) control.name);
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
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));
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,
- "'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;
}
- gst_v4l2_set_attribute (v4l2object, GPOINTER_TO_INT (d),
- g_value_get_int (value));
return TRUE;
}