diff options
author | Haihua Hu <jared.hu@nxp.com> | 2020-07-22 04:46:47 +0300 |
---|---|---|
committer | Haihua Hu <jared.hu@nxp.com> | 2020-07-22 09:21:42 +0300 |
commit | 0a453cc4a4a17df669ff725e2f66dcac4ae78b3e (patch) | |
tree | 7e93582e816617a97c5a5bc6ab6bcf1dd9b229a9 /sys | |
parent | c943be8b251d9f16b436d0c11197d84c466660ff (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.h | 1 | ||||
-rw-r--r-- | sys/v4l2/v4l2_calls.c | 77 |
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; } |