80 #include <gst/gstinfo.h>
83 #include <glib/gstdio.h>
97 #define DBG (!self->silent)
101 #define GST_CAT_DEFAULT gst_tensor_src_iio_debug
106 #define PROCESS_SCANNED_DATA(DTYPE_UNSIGNED, DTYPE_SIGNED) \
114 gst_tensor_src_iio_process_scanned_data_from_
115 GstTensorSrcIIOChannelProperties *prop, DTYPE_UNSIGNED value_unsigned) { \
116 gfloat value_float; \
118 g_assert (sizeof (DTYPE_UNSIGNED) == sizeof (DTYPE_SIGNED)); \
120 value_unsigned >>= prop->shift; \
121 value_unsigned &= prop->mask; \
122 if (prop->is_signed) { \
123 DTYPE_SIGNED value_signed; \
125 shift_value = ((guint) (sizeof (DTYPE_UNSIGNED) * 8)) - prop->used_bits; \
126 value_signed = ((DTYPE_SIGNED) (value_unsigned << shift_value)) >> shift_value; \
127 value_float = ((gfloat) value_signed + prop->offset) * prop->scale; \
129 value_float = ((gfloat) value_unsigned + prop->offset) * prop->scale; \
131 return value_float; \
158 #define DEFAULT_PROP_BASE_DIRECTORY "/sys/bus/iio/devices"
159 #define DEFAULT_PROP_DEV_DIRECTORY "/dev"
164 #define CHANNELS_ENABLED_AUTO_CHAR "auto"
165 #define CHANNELS_ENABLED_ALL_CHAR "all"
166 #define DEFAULT_OPERATING_CHANNELS_ENABLED CHANNELS_ENABLED_AUTO_CHAR
171 #define MODE_ONE_SHOT "one-shot"
172 #define MODE_CONTINUOUS "continuous"
173 #define DEFAULT_OPERATING_MODE MODE_CONTINUOUS
178 #define DEFAULT_PROP_SILENT TRUE
183 #define DEFAULT_PROP_STRING NULL
188 #define MIN_BUFFER_CAPACITY 1
189 #define MAX_BUFFER_CAPACITY G_MAXUINT
190 #define DEFAULT_BUFFER_CAPACITY 1
196 #define MIN_FREQUENCY 0
197 #define MAX_FREQUENCY G_MAXULONG
198 #define DEFAULT_FREQUENCY 0
203 #define MIN_POLL_TIMEOUT -1
204 #define MAX_POLL_TIMEOUT G_MAXINT
205 #define DEFAULT_POLL_TIMEOUT 10000
210 #define DEFAULT_MERGE_CHANNELS TRUE
215 #define DEFAULT_PROP_DEVICE_NUM -1
216 #define DEFAULT_PROP_TRIGGER_NUM -1
226 #define DEVICE "device"
227 #define BUFFER "buffer"
228 #define TRIGGER "trigger"
229 #define CHANNELS "scan_elements"
231 #define TIMESTAMP "timestamp"
232 #define DEVICE_PREFIX IIO DEVICE
233 #define TRIGGER_PREFIX IIO TRIGGER
234 #define CURRENT_TRIGGER "current_trigger"
239 #define EN_SUFFIX "_en"
240 #define INDEX_SUFFIX "_index"
241 #define TYPE_SUFFIX "_type"
242 #define SCALE_SUFFIX "_scale"
243 #define OFFSET_SUFFIX "_offset"
248 #define NAME_FILE "name"
249 #define AVAIL_FREQUENCY_FILE "sampling_frequency_available"
250 #define SAMPLING_FREQUENCY "sampling_frequency"
260 const GValue * value, GParamSpec * pspec);
262 GValue * value, GParamSpec * pspec);
269 element, GstStateChange transition);
277 guint64 offset, guint size, GstBuffer ** buf);
279 guint size, GstBuffer * buf);
281 GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
285 #define gst_tensor_src_iio_parent_class parent_class
294 GObjectClass *gobject_class;
295 GstElementClass *gstelement_class;
296 GstBaseSrcClass *bsrc_class;
297 GstPadTemplate *pad_template;
300 GST_DEBUG_CATEGORY_INIT (gst_tensor_src_iio_debug,
"tensor_src_iio", 0,
301 "Source element to handle Linux Industrial I/O sensors as input");
303 gobject_class = G_OBJECT_CLASS (klass);
304 gstelement_class = GST_ELEMENT_CLASS (klass);
305 bsrc_class = GST_BASE_SRC_CLASS (klass);
312 g_object_class_install_property (gobject_class,
PROP_SILENT,
313 g_param_spec_boolean (
"silent",
"Silent",
315 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
317 g_object_class_install_property (gobject_class,
PROP_MODE,
318 g_param_spec_string (
"mode",
"Operating mode",
319 "Mode for the device to run in - one-shot or continuous",
323 g_param_spec_string (
"iio-base-dir",
"IIO Base Dir",
325 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
328 g_param_spec_string (
"dev-dir",
"Dev Dir",
330 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
332 g_object_class_install_property (gobject_class,
PROP_DEVICE,
333 g_param_spec_string (
"device",
"Device Name",
335 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
338 g_param_spec_int (
"device-number",
"Device Number",
339 "Number (numeric id) of the device to be opened",
342 g_object_class_install_property (gobject_class,
PROP_TRIGGER,
343 g_param_spec_string (
"trigger",
"Trigger Name",
345 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
348 g_param_spec_int (
"trigger-number",
"Trigger Number",
349 "Number (numeric id) of the trigger to be opened",
352 g_object_class_install_property (gobject_class,
PROP_CHANNELS,
353 g_param_spec_string (
"channels",
"Channels to be enabled",
354 "Specify channels to be enabled:"
355 " 1) auto: enable all channels when no channels are enabled automatically,"
356 " 2) all: enable all channels,"
357 " 3) x,y,z: list the idx of the channels to be enabled",
361 g_param_spec_uint (
"buffer-capacity",
"Buffer Capacity",
364 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
367 g_param_spec_ulong (
"frequency",
"Frequency",
372 g_param_spec_boolean (
"merge-channels-data",
"Merge Channels Data",
373 "Merge the data of channels into single tensor",
377 g_param_spec_int (
"poll-timeout",
"Poll Timeout",
381 gst_element_class_set_static_metadata (gstelement_class,
383 "Source/Tensor/Device",
384 "Src element to support linux IIO",
385 "Parichay Kapoor <pk.kapoor@samsung.com>");
390 pad_template = gst_pad_template_new (
"src", GST_PAD_SRC, GST_PAD_ALWAYS,
392 gst_element_class_add_pad_template (gstelement_class, pad_template);
393 gst_caps_unref (pad_caps);
395 gstelement_class->change_state =
447 self->configured =
FALSE;
448 self->channels = NULL;
449 self->custom_channel_table = NULL;
460 self->is_tensor =
FALSE;
461 self->tensors_config = NULL;
462 self->default_sampling_frequency = 0;
463 self->default_buffer_capacity = 0;
464 self->default_trigger = NULL;
471 gst_base_src_set_format (GST_BASE_SRC (
self), GST_FORMAT_TIME);
473 gst_base_src_set_live (GST_BASE_SRC (
self),
TRUE);
475 gst_base_src_set_do_timestamp (GST_BASE_SRC (
self),
TRUE);
480 gst_base_src_set_async (GST_BASE_SRC (
self),
TRUE);
499 guint info_idx, base_idx;
505 g_return_val_if_fail (size > 0, 0);
510 if (info[base_idx].dimension[dim_idx] == 1) {
516 for (info_idx = 0; info_idx < size; info_idx++) {
524 if (mismatch || !dim_avail) {
539 if (info[base_idx].dimension[dim_idx] == 1) {
544 }
else if (dir == 1) {
546 if (info[base_idx].dimension[dim_idx] == 1) {
551 }
else if (dir == 2) {
553 if (info[base_idx].dimension[dim_idx] != 1) {
554 merge_dim = dim_idx + 1;
582 const gchar * prefix)
585 GError *error = NULL;
586 struct dirent *dir_entry;
587 gchar *filename = NULL;
589 gchar *file_contents = NULL;
592 if (!g_file_test (dir_name, G_FILE_TEST_IS_DIR)) {
596 dptr = opendir (dir_name);
597 if (G_UNLIKELY (NULL == dptr)) {
598 GST_ERROR (
"Error in opening directory %s.\n", dir_name);
602 while ((dir_entry = readdir (dptr)) != NULL) {
604 if (g_str_has_prefix (dir_entry->d_name, prefix) &&
605 g_ascii_isdigit (dir_entry->d_name[strlen (prefix)])) {
607 id = (gint) g_ascii_strtoll (dir_entry->d_name + strlen (prefix), NULL,
610 g_build_filename (dir_name, dir_entry->d_name,
NAME_FILE, NULL);
612 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
613 GST_ERROR (
"Unable to read %s, error: %s.\n", filename, error->message);
614 g_error_free (error);
615 goto error_free_filename;
619 if (g_strcmp0 (file_contents, name) == 0) {
646 const gchar * prefix)
648 GError *error = NULL;
649 gchar *filename = NULL;
650 gchar *dev_dirname = NULL;
651 gchar *file_contents = NULL;
653 dev_dirname = g_strdup_printf (
"%s%d", prefix,
id);
654 filename = g_build_filename (dir_name, dev_dirname,
NAME_FILE, NULL);
657 if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
658 GST_ERROR (
"No device available with id %d.",
id);
659 goto exit_free_filename;
662 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
663 GST_ERROR (
"Unable to read %s, error: %s.\n", filename, error->message);
664 g_error_free (error);
665 goto exit_free_filename;
670 return file_contents;
683 const gchar * name,
const gchar * suffix, gfloat * value)
685 gchar *filename, *filepath, *file_contents = NULL;
688 filename = g_strdup_printf (
"%s%s", name, suffix);
689 filepath = g_build_filename (dirname, filename, NULL);
691 if (!g_file_get_contents (filepath, &file_contents, NULL, NULL)) {
692 GST_INFO (
"Unable to retrieve data from file %s.", filename);
694 *value = (gfloat) g_ascii_strtod (file_contents, NULL);
724 const gchar * contents)
726 gchar endianchar =
'\0', signchar =
'\0';
732 endianchar = contents[0];
733 if (endianchar ==
'b') {
735 }
else if (endianchar ==
'l') {
742 g_return_val_if_fail (contents[1] ==
'e',
FALSE);
743 g_return_val_if_fail (contents[2] ==
':',
FALSE);
746 signchar = contents[3];
747 if (signchar ==
's') {
749 }
else if (signchar ==
'u') {
756 start = (gchar *) contents + 4;
757 prop->
used_bits = (guint) g_ascii_strtoull (start, &end, base);
762 g_return_val_if_fail (end[0] ==
'/',
FALSE);
772 g_return_val_if_fail (end[0] ==
'>',
FALSE);
773 g_return_val_if_fail (end[1] ==
'>',
FALSE);
780 GST_WARNING (
"Storage bits are 0 for channel %s.",
prop->
name);
785 prop->
shift = (guint) g_ascii_strtoull (start, &end, base);
808 gsize channel_name_len = strlen (channel_name);
810 while (g_ascii_isdigit (channel_name[channel_name_len - digit_len])) {
813 generic_name = g_strndup (channel_name, channel_name_len - digit_len + 1);
831 gint compare_result = a_ch->
index - b_ch->
index;
832 return compare_result;
848 list_addr = (GList **) user_data;
852 *list_addr = g_list_remove (list,
data);
866 const gchar * dir_name)
869 GError *error = NULL;
870 const struct dirent *dir_entry;
871 gchar *filename = NULL;
872 gchar *file_contents = NULL;
875 guint num_channels_enabled = 0;
876 gboolean generic_val, specific_val;
877 gchar *generic_type_filename;
880 if (!g_file_test (dir_name, G_FILE_TEST_IS_DIR)) {
881 GST_ERROR_OBJECT (
self,
"No channels available.");
884 dptr = opendir (dir_name);
885 if (G_UNLIKELY (NULL == dptr)) {
886 GST_ERROR_OBJECT (
self,
"Error in opening directory %s.\n", dir_name);
890 while ((dir_entry = readdir (dptr)) != NULL) {
892 if (g_str_has_suffix (dir_entry->d_name,
EN_SUFFIX)) {
894 if (g_str_has_prefix (dir_entry->d_name,
TIMESTAMP)) {
899 if (channel_prop == NULL) {
900 GST_ERROR_OBJECT (
self,
"Failed to allocate for channel property.");
901 goto error_cleanup_list;
904 self->channels = g_list_prepend (self->channels, channel_prop);
907 channel_prop->
name = g_strndup (dir_entry->d_name,
908 strlen (dir_entry->d_name) - strlen (
EN_SUFFIX));
909 channel_prop->
base_dir = g_strdup (dir_name);
911 g_build_filename (dir_name, channel_prop->
name, NULL);
918 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
919 GST_ERROR_OBJECT (
self,
"Unable to read %s, error: %s.\n", filename,
921 goto error_free_filename;
925 value = (guint) g_ascii_strtoull (file_contents, NULL, 10);
930 num_channels_enabled += 1;
931 }
else if (value == 0) {
937 "Enable bit %u (out of range) in current state of channel %s.\n",
938 value, channel_prop->
name);
939 goto error_cleanup_list;
945 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
946 GST_ERROR_OBJECT (
self,
"Unable to read %s, error: %s.\n", filename,
948 goto error_free_filename;
952 value = (guint) g_ascii_strtoull (file_contents, NULL, 10);
954 channel_prop->
index = value;
958 if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
961 generic_type_filename =
964 g_build_filename (channel_prop->
base_dir, generic_type_filename,
966 g_free (generic_type_filename);
968 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
969 GST_ERROR_OBJECT (
self,
"Unable to read %s, error: %s.\n", filename,
971 goto error_free_filename;
976 GST_ERROR_OBJECT (
self,
977 "Error while setting up channel type for channel %s.\n",
980 goto error_cleanup_list;
985 channel_prop->
scale = 1.0;
993 if (!specific_val || !generic_val) {
994 goto error_cleanup_list;
998 channel_prop->
offset = 0.0;
1006 if (!specific_val || !generic_val) {
1007 goto error_cleanup_list;
1015 ret = num_channels_enabled;
1020 error_free_filename:
1021 g_error_free (error);
1026 self->channels = NULL;
1042 const guint64 frequency)
1044 GError *error = NULL;
1045 gchar *filename = NULL;
1046 gchar *file_contents = NULL;
1050 gchar **freq_list = NULL;
1055 if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
1056 GST_WARNING (
"Sampling frequency file does not exist for the file %s.\n",
1060 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
1061 GST_ERROR (
"Unable to read sampling frequency for device %s.\n", base_dir);
1062 g_error_free (error);
1067 freq_list = g_strsplit (file_contents,
" ", -1);
1068 num = g_strv_length (freq_list);
1070 GST_ERROR (
"No sampling frequencies for device %s.\n", base_dir);
1078 if (frequency == 0) {
1079 ret = g_ascii_strtoll (freq_list[0], NULL, 10);
1081 for (i = 0; i < num; i++) {
1082 val = g_ascii_strtoull (freq_list[i], NULL, 10);
1083 if (frequency == val) {
1091 g_strfreev (freq_list);
1104 const GValue * value, GParamSpec * pspec)
1107 GstStateChangeReturn ret;
1117 ret = gst_element_get_state (GST_ELEMENT (
self), &state, NULL,
1118 GST_CLOCK_TIME_NONE);
1119 if (ret == GST_STATE_CHANGE_FAILURE || ret == GST_STATE_CHANGE_ASYNC
1120 || state == GST_STATE_PLAYING || state == GST_STATE_PAUSED) {
1121 GST_ERROR_OBJECT (
self,
"Can only set property in NULL or READY state.");
1127 self->silent = g_value_get_boolean (value);
1132 const gchar *base_dir = g_value_get_string (value);
1134 if (g_path_is_absolute (base_dir)) {
1136 self->base_dir = g_strdup (base_dir);
1138 GST_ERROR_OBJECT (
self,
"%s is not an absolute path.", base_dir);
1145 const gchar *dev_dir = g_value_get_string (value);
1147 if (g_path_is_absolute (dev_dir)) {
1149 self->dev_dir = g_strdup (dev_dir);
1151 GST_ERROR_OBJECT (
self,
"%s is not an absolute path.", dev_dir);
1158 if (self->mode != NULL) {
1161 self->mode = g_value_dup_string (value);
1167 if (self->device.name != NULL) {
1168 g_free (self->device.name);
1170 self->device.name = g_value_dup_string (value);
1175 self->device.id = g_value_get_int (value);
1180 if (self->trigger.name != NULL) {
1181 g_free (self->trigger.name);
1183 self->trigger.name = g_value_dup_string (value);
1188 self->trigger.id = g_value_get_int (value);
1193 const gchar *param = g_value_get_string (value);
1204 gchar *endptr = NULL;
1205 gboolean status =
TRUE;
1211 self->custom_channel_table =
1212 g_hash_table_new (g_direct_hash, g_direct_equal);
1213 strv = g_strsplit_set (param,
",;", -1);
1214 num = g_strv_length (strv);
1215 for (i = 0; i < num; i++) {
1216 val = g_ascii_strtoll (strv[i], &endptr, 10);
1217 if (errno == ERANGE || errno == EINVAL || (endptr == strv[i]
1219 GST_ERROR_OBJECT (
self,
1220 "Cannot parse received custom channels %s. The property values for CHANNELS are ignored.",
1222 g_hash_table_destroy (self->custom_channel_table);
1223 self->custom_channel_table = NULL;
1227 if (!g_hash_table_insert (self->custom_channel_table,
1228 GINT_TO_POINTER (val), NULL)) {
1231 (
"tensor-src-iio's CHANNELS property value has a duplicated entry, '%s', which is registered only once.\n",
1244 self->buffer_capacity = g_value_get_uint (value);
1248 self->sampling_frequency = (guint64) g_value_get_ulong (value);
1252 self->merge_channels_data = g_value_get_boolean (value);
1256 self->poll_timeout = g_value_get_int (value);
1260 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
1270 GValue * value, GParamSpec * pspec)
1277 g_value_set_boolean (value, self->silent);
1297 g_value_set_int (value, self->device.id);
1305 g_value_set_int (value, self->trigger.id);
1315 GHashTableIter iter;
1318 GPtrArray *arr = g_ptr_array_new ();
1321 g_hash_table_iter_init (&iter, self->custom_channel_table);
1322 while (g_hash_table_iter_next (&iter, &key, NULL)) {
1323 g_ptr_array_add (arr, g_strdup_printf (
"%u", GPOINTER_TO_INT (key)));
1325 g_ptr_array_add (arr, NULL);
1327 strings = (gchar **) g_ptr_array_free (arr,
FALSE);
1328 p = g_strjoinv (
",", strings);
1329 g_strfreev (strings);
1330 g_value_take_string (value, p);
1337 g_value_set_uint (value, self->buffer_capacity);
1342 g_value_set_ulong (value, (gulong) self->sampling_frequency);
1346 g_value_set_boolean (value, self->merge_channels_data);
1350 g_value_set_int (value, self->poll_timeout);
1354 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
1369 g_free (self->device.name);
1370 g_free (self->trigger.name);
1373 if (self->custom_channel_table) {
1374 g_hash_table_destroy (self->custom_channel_table);
1377 G_OBJECT_CLASS (parent_class)->finalize (
object);
1390 const gchar * base_dir,
const gchar * contents)
1392 gchar *filename = NULL;
1393 gboolean ret =
FALSE;
1394 guint bytes_printed = 0;
1396 GError *error = NULL;
1398 filename = g_build_filename (base_dir, file, NULL);
1399 fd = g_fopen (filename,
"w");
1401 GST_ERROR_OBJECT (
self,
"Unable to open file to write %s.\n", filename);
1402 goto error_free_filename;
1405 bytes_printed = fprintf (fd,
"%s", contents);
1406 if (bytes_printed != strlen (contents)) {
1407 GST_ERROR_OBJECT (
self,
"Unable to write to file %s.\n", filename);
1408 goto error_close_file;
1410 if (fclose (fd) != 0) {
1411 GST_ERROR_OBJECT (
self,
"Unable to close file %s after write.\n", filename);
1412 goto error_free_filename;
1417 gchar *file_contents = NULL;
1419 if (!g_file_get_contents (filename, &file_contents, NULL, &error)) {
1420 GST_ERROR_OBJECT (
self,
"Unable to read file %s with error %s.\n",
1421 filename, error->message);
1422 g_error_free (error);
1423 goto error_free_filename;
1425 if (g_strcmp0 (contents, file_contents) == 0) {
1436 if (fclose (fd) != 0) {
1437 GST_ERROR_OBJECT (
self,
"Unable to close file %s.\n", filename);
1440 error_free_filename:
1455 const gchar * base_dir,
const gint contents)
1457 gchar *contents_char = NULL;
1460 contents_char = g_strdup_printf (
"%d", contents);
1477 gchar *filename = NULL;
1479 gboolean ret =
TRUE;
1481 for (ch_list = self->channels; ch_list != NULL; ch_list = ch_list->next) {
1483 filename = g_strdup_printf (
"%s%s", channel_prop->
name,
EN_SUFFIX);
1506 guint size_bytes = 0;
1511 for (list = channels; list != NULL; list = list->next) {
1515 channel_prop->
location = size_bytes;
1536 gint tensor_info_merged_size;
1547 GST_ERROR_OBJECT (tensor_src_iio,
"Failed to allocate caps config data.");
1552 for (list = tensor_src_iio->
channels; list != NULL; list = list->next) {
1558 info[info_idx].
name = channel_prop->
name;
1566 GST_ERROR_OBJECT (tensor_src_iio,
"The number of channel is different.");
1573 tensor_info_merged_size =
1579 if (tensor_info_merged_size < 0) {
1580 GST_ERROR_OBJECT (tensor_src_iio,
"Mismatch while merging tensor");
1582 }
else if (tensor_info_merged_size == 0) {
1583 GST_ERROR_OBJECT (tensor_src_iio,
"No info to be merged");
1586 GST_ERROR_OBJECT (tensor_src_iio,
1587 "Number of tensors required %u for data exceed the max limit",
1588 tensor_info_merged_size);
1593 tensor_src_iio->
is_tensor = (tensor_info_merged_size == 1);
1595 if (config == NULL) {
1599 for (info_idx = 0; info_idx < (guint) tensor_info_merged_size; info_idx++) {
1630 gchar *dirname = NULL;
1633 if (self->device.name != NULL) {
1637 }
else if (self->device.id >= 0) {
1641 GST_ERROR_OBJECT (
self,
"IIO device information not provided.");
1644 if (G_UNLIKELY (self->device.name == NULL || self->device.id < 0)) {
1645 GST_ERROR_OBJECT (
self,
"Cannot find the specified IIO device.");
1648 dirname = g_strdup_printf (
"%s%d",
DEVICE_PREFIX, self->device.id);
1649 self->device.base_dir = g_build_filename (self->base_dir, dirname, NULL);
1666 gchar *dirname = NULL;
1667 gchar *trigger_device_dir = NULL;
1668 gchar *filename = NULL;
1671 if (self->trigger.name != NULL || self->trigger.id >= 0) {
1673 trigger_device_dir =
1674 g_build_filename (self->device.base_dir,
TRIGGER, NULL);
1675 if (!g_file_test (trigger_device_dir, G_FILE_TEST_IS_DIR)) {
1676 GST_ERROR_OBJECT (
self,
"IIO device %s does not supports trigger.\n",
1678 g_free (trigger_device_dir);
1681 g_free (trigger_device_dir);
1684 if (self->trigger.name != NULL) {
1689 self->trigger.name =
1693 if (G_UNLIKELY (self->trigger.name == NULL || self->trigger.id < 0)) {
1694 GST_ERROR_OBJECT (
self,
"Cannot find the specified IIO trigger.");
1697 dirname = g_strdup_printf (
"%s%d",
TRIGGER_PREFIX, self->trigger.id);
1698 self->trigger.base_dir = g_build_filename (self->base_dir, dirname, NULL);
1705 if (!g_file_get_contents (filename, &self->default_trigger, NULL, NULL)) {
1706 GST_WARNING_OBJECT (
self,
"Unable to read default set trigger.");
1712 self->device.base_dir, self->trigger.name))) {
1713 GST_ERROR_OBJECT (
self,
1714 "Cannot set the IIO device trigger: %s for device: %s.\n",
1715 self->trigger.name, self->device.name);
1717 goto error_trigger_free;
1725 g_free (self->trigger.base_dir);
1726 g_free (self->default_trigger);
1727 self->trigger.base_dir = NULL;
1728 self->default_trigger = NULL;
1742 gchar *filename = NULL;
1743 gchar *file_contents = NULL;
1744 gchar *sampling_frequency_char = NULL;
1745 gint64 sampling_frequency;
1746 gboolean sampling_frequency_file_exist =
TRUE;
1750 sampling_frequency_file_exist =
1751 g_file_test (filename, G_FILE_TEST_IS_REGULAR);
1752 if (!sampling_frequency_file_exist) {
1753 GST_WARNING_OBJECT (
self,
"Cannot set sampling frequency, resetting it.");
1755 self->sampling_frequency = 0;
1758 if (!g_file_get_contents (filename, &file_contents, NULL, NULL)) {
1759 GST_WARNING_OBJECT (
self,
"Unable to read default sampling frequency.");
1760 }
else if (file_contents != NULL) {
1761 self->default_sampling_frequency =
1762 g_ascii_strtoull (file_contents, NULL, 10);
1772 sampling_frequency =
1774 self->sampling_frequency);
1776 if (-1 == sampling_frequency) {
1777 GST_ERROR_OBJECT (
self,
"Error in verifying frequency for device %s.",
1780 }
else if (sampling_frequency == 0 && self->default_sampling_frequency == 0) {
1781 GST_ERROR_OBJECT (
self,
"Sampling frequency unknown. Unknown stream rate.");
1784 if (0 == sampling_frequency) {
1786 GST_WARNING_OBJECT (
self,
1787 "Cannot verify against sampling frequency list.");
1788 self->sampling_frequency =
self->default_sampling_frequency;
1790 self->sampling_frequency = sampling_frequency;
1796 if (sampling_frequency_file_exist) {
1798 sampling_frequency_char =
1799 g_strdup_printf (
"%lu", (gulong) self->sampling_frequency);
1802 sampling_frequency_char))) {
1803 GST_ERROR_OBJECT (
self,
1804 "Cannot set the sampling frequency for device: %s.\n",
1806 g_free (sampling_frequency_char);
1809 g_free (sampling_frequency_char);
1814 g_assert (self->sampling_frequency > 0);
1829 gchar *dirname = NULL, *filename = NULL;
1830 gint num_channels_enabled;
1832 gboolean item_in_table =
FALSE;
1838 dirname = g_build_filename (self->device.base_dir,
CHANNELS, NULL);
1839 num_channels_enabled =
1842 if (G_UNLIKELY (num_channels_enabled == -1)) {
1843 GST_ERROR_OBJECT (
self,
"Error while scanning channels for device: %s.\n",
1848 if ((num_channels_enabled != (gint) g_list_length (self->channels)) &&
1849 (num_channels_enabled == 0
1853 GST_ERROR_OBJECT (
self,
"Enabling all channels failed for device: %s,"
1854 "disabling all the channels.\n", self->device.name);
1856 goto error_channels_free;
1862 for (ch_list = self->channels; ch_list != NULL; ch_list = ch_list->next) {
1864 item_in_table = g_hash_table_contains (self->custom_channel_table,
1865 GINT_TO_POINTER (channel_prop->
index));
1867 if (!item_in_table && channel_prop->
enabled) {
1870 }
else if (item_in_table && !channel_prop->
enabled) {
1874 if (channel_en >= 0) {
1875 filename = g_strdup_printf (
"%s%s", channel_prop->
name,
EN_SUFFIX);
1878 GST_ERROR_OBJECT (
self,
"Error enabling/disabling channel.");
1880 goto error_channels_free;
1891 self->num_channels_enabled = g_list_length (self->channels);
1894 gst_pad_use_fixed_caps (GST_BASE_SRC (
self)->srcpad);
1898 GST_ERROR_OBJECT (
self,
"Error creating config.\n");
1899 goto error_channels_free;
1904 error_channels_free:
1906 self->channels = NULL;
1920 gchar *dirname = NULL;
1921 gchar *filename = NULL;
1922 gchar *file_contents = NULL;
1924 gchar *device_name = NULL;
1927 dirname = g_build_filename (self->device.base_dir,
BUFFER, NULL);
1928 filename = g_build_filename (dirname,
"length", NULL);
1929 if (!g_file_get_contents (filename, &file_contents, &length, NULL)) {
1930 GST_WARNING_OBJECT (
self,
"Unable to read default buffer capacity.");
1931 }
else if (file_contents != NULL && length > 0) {
1932 self->default_buffer_capacity =
1933 (guint) g_ascii_strtoull (file_contents, NULL, 10);
1939 self->buffer_capacity))) {
1940 GST_ERROR_OBJECT (
self,
1941 "Cannot set the IIO device buffer capacity for device: %s.\n",
1949 device_name = g_strdup_printf (
"%s%d",
DEVICE_PREFIX, self->device.id);
1950 filename = g_build_filename (self->dev_dir, device_name, NULL);
1953 self->buffer_data_fp = g_new (
struct pollfd, 1);
1954 if (self->buffer_data_fp == NULL) {
1955 GST_ERROR_OBJECT (
self,
"Failed to allocate the file descriptor.");
1960 self->buffer_data_fp->events = POLLIN;
1961 self->buffer_data_fp->fd = open (filename, O_RDONLY | O_NONBLOCK);
1962 if (self->buffer_data_fp->fd < 0) {
1963 GST_ERROR_OBJECT (
self,
"Failed to open buffer %s for device %s.\n",
1964 filename, self->device.name);
1966 g_free (self->buffer_data_fp);
1991 GST_ERROR_OBJECT (
self,
"One-shot mode not yet supported.");
1996 GST_ERROR_OBJECT (
self,
"Error setting up IIO device.");
2001 GST_ERROR_OBJECT (
self,
"Error setting up IIO trigger for device.");
2002 goto error_device_free;
2006 GST_ERROR_OBJECT (
self,
"Error setting up sampling frequency for device.");
2007 goto error_trigger_free;
2011 GST_ERROR_OBJECT (
self,
"Error setting up scan channels for device.");
2012 goto error_trigger_free;
2016 GST_ERROR_OBJECT (
self,
"Error setting up data buffer for device.");
2017 goto error_config_free;
2020 self->configured =
TRUE;
2022 gst_base_src_set_dynamic_size (src,
FALSE);
2024 gst_base_src_start_complete (src, GST_FLOW_OK);
2029 g_free (self->tensors_config);
2032 self->channels = NULL;
2035 g_free (self->trigger.base_dir);
2036 g_free (self->default_trigger);
2037 self->trigger.base_dir = NULL;
2038 self->default_trigger = NULL;
2041 g_free (self->device.base_dir);
2042 self->device.base_dir = NULL;
2046 gst_base_src_start_complete (src, GST_FLOW_ERROR);
2057 gchar *filename = NULL, *dirname = NULL, *file_contents = NULL;
2061 for (ch_list = self->channels; ch_list != NULL; ch_list = ch_list->next) {
2063 filename = g_strdup_printf (
"%s%s", channel_prop->
name,
EN_SUFFIX);
2070 if (self->default_sampling_frequency > 0) {
2073 g_strdup_printf (
"%lu", (gulong) self->default_sampling_frequency);
2075 self->device.base_dir, file_contents);
2080 dirname = g_build_filename (self->device.base_dir,
BUFFER, NULL);
2081 if (self->default_buffer_capacity > 0) {
2083 self->default_buffer_capacity);
2090 if (self->default_trigger != NULL) {
2093 self->default_trigger);
2108 self->configured =
FALSE;
2113 close (self->buffer_data_fp->fd);
2114 g_free (self->buffer_data_fp);
2117 g_free (self->tensors_config);
2120 self->channels = NULL;
2122 g_free (self->trigger.base_dir);
2123 g_free (self->default_trigger);
2124 self->trigger.base_dir = NULL;
2125 self->default_trigger = NULL;
2127 g_free (self->device.base_dir);
2128 self->device.base_dir = NULL;
2140 return GST_BASE_SRC_CLASS (parent_class)->event (src, event);
2152 if (!gst_pad_set_caps (pad, caps)) {
2171 caps = gst_pad_get_current_caps (pad);
2173 caps = gst_pad_get_pad_template_caps (pad);
2177 GstCaps *intersection;
2179 gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
2180 gst_caps_unref (caps);
2181 caps = intersection;
2197 GstCaps *updated_caps, *fixated_caps;
2201 if (self->is_tensor) {
2207 if (fixated_caps == NULL) {
2208 GST_ERROR_OBJECT (
self,
"Error creating fixated caps from config.");
2211 silent_debug (
self,
"Fixated caps from device = %" GST_PTR_FORMAT,
2214 if (gst_caps_can_intersect (caps, fixated_caps)) {
2215 updated_caps = gst_caps_intersect (caps, fixated_caps);
2217 GST_ERROR_OBJECT (
self,
2218 "No intersection while fixating caps of the element.");
2219 gst_caps_unref (caps);
2220 gst_caps_unref (fixated_caps);
2224 gst_caps_unref (caps);
2225 gst_caps_unref (fixated_caps);
2226 return gst_caps_fixate (updated_caps);
2232 static GstStateChangeReturn
2234 GstStateChange transition)
2237 GstStateChangeReturn ret;
2238 gboolean buffer_state_change_success =
TRUE;
2239 gchar *dirname = NULL;
2243 switch (transition) {
2244 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2247 dirname = g_build_filename (self->device.base_dir,
BUFFER, NULL);
2249 GST_ERROR_OBJECT (
self,
2250 "Cannot enable the IIO device buffer for device: %s.\n",
2252 buffer_state_change_success =
FALSE;
2261 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2263 switch (transition) {
2264 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2267 dirname = g_build_filename (self->device.base_dir,
BUFFER, NULL);
2269 GST_ERROR_OBJECT (
self,
2270 "Error in disabling the IIO device buffer for device: %s.\n",
2272 buffer_state_change_success =
FALSE;
2281 if (!buffer_state_change_success) {
2282 ret = GST_STATE_CHANGE_FAILURE;
2304 GstClockTime * start, GstClockTime * end)
2306 GstClockTime timestamp;
2307 GstClockTime duration;
2310 timestamp = GST_BUFFER_DTS (buffer);
2311 duration = GST_BUFFER_DURATION (buffer);
2314 if (!GST_CLOCK_TIME_IS_VALID (timestamp))
2315 timestamp = GST_BUFFER_PTS (buffer);
2317 if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
2319 if (GST_CLOCK_TIME_IS_VALID (duration)) {
2320 *end = timestamp + duration;
2329 static GstFlowReturn
2331 guint size, GstBuffer ** buffer)
2334 GstFlowReturn ret = GST_FLOW_ERROR;
2343 buf = gst_buffer_new ();
2346 for (idx = 0; idx <
self->tensors_config->info.num_tensors; idx++) {
2351 mem = gst_allocator_alloc (NULL, buffer_size, NULL);
2353 GST_ERROR_OBJECT (
self,
"Error allocating memory for buffer.");
2363 if (ret == GST_FLOW_OK)
2366 gst_buffer_unref (buf);
2382 prop, gchar *
data, gfloat * buffer_map)
2384 guint64 storage_mask;
2392 gst_tensor_src_iio_process_scanned_data_from_guint8 (
prop, value);
2399 value = GUINT16_FROM_BE (value);
2403 value = GUINT16_FROM_LE (value);
2406 value &= storage_mask;
2409 gst_tensor_src_iio_process_scanned_data_from_guint16 (
prop, value);
2418 value = GUINT32_FROM_BE (value);
2422 value = GUINT32_FROM_LE (value);
2425 value &= storage_mask;
2428 gst_tensor_src_iio_process_scanned_data_from_guint32 (
prop, value);
2441 value = GUINT64_FROM_BE (value);
2445 value = GUINT64_FROM_LE (value);
2448 value &= storage_mask;
2451 gst_tensor_src_iio_process_scanned_data_from_guint64 (
prop, value);
2466 static GstFlowReturn
2471 GstFlowReturn ret = GST_FLOW_ERROR;
2472 gint status, bytes_to_read;
2473 guint idx, ch_idx, num_mapped;
2474 gchar *raw_data_base, *raw_data;
2475 gfloat *map_data_float;
2478 guint64 time_to_end, cur_time;
2479 guint64 safe_multiply;
2488 self->tensors_config->info.num_tensors);
2492 for (idx = 0; idx <
self->tensors_config->info.num_tensors; idx++) {
2494 if (!gst_memory_map (mem[idx], &map[idx], GST_MAP_WRITE)) {
2495 for (ch_idx = 0; ch_idx < num_mapped; ch_idx++) {
2496 gst_memory_unmap (mem[ch_idx], &map[ch_idx]);
2497 gst_memory_unref (mem[ch_idx]);
2499 gst_memory_unref (mem[idx]);
2500 return GST_FLOW_ERROR;
2502 num_mapped = idx + 1;
2505 bytes_to_read =
self->scan_size *
self->buffer_capacity;
2506 raw_data_base = g_malloc (bytes_to_read);
2507 if (raw_data_base == NULL) {
2508 GST_ERROR_OBJECT (
self,
"Failed to allocate memory to read raw data.");
2509 goto error_data_free;
2513 time_to_end = g_get_real_time () +
self->poll_timeout * 1000;
2515 if (self->trigger.name != NULL) {
2516 status = poll (self->buffer_data_fp, 1, self->poll_timeout);
2518 GST_ERROR_OBJECT (
self,
"Error %d while polling the buffer.", status);
2519 goto error_data_free;
2520 }
else if (status == 0) {
2521 GST_ERROR_OBJECT (
self,
"Timeout while polling the buffer.");
2522 goto error_data_free;
2523 }
else if (!(self->buffer_data_fp->revents & POLLIN)) {
2524 GST_ERROR_OBJECT (
self,
"Poll succeeded on an unexpected event %d.",
2525 self->buffer_data_fp->revents);
2526 goto error_data_free;
2528 self->buffer_data_fp->revents = 0;
2531 if (g_uint64_checked_mul (&safe_multiply, G_USEC_PER_SEC,
2532 self->buffer_capacity)) {
2533 g_usleep (MAX (1, safe_multiply / self->sampling_frequency));
2536 (self->buffer_capacity / self->sampling_frequency) *
2542 status = read (self->buffer_data_fp->fd, raw_data_base, bytes_to_read);
2543 if (status < bytes_to_read) {
2544 if (errno == EAGAIN) {
2545 GST_WARNING_OBJECT (
self,
"EAGAIN error, try again.");
2546 cur_time = g_get_real_time ();
2547 if (time_to_end >= cur_time) {
2550 GST_ERROR_OBJECT (
self,
"EAGAIN timeout expired.");
2551 goto error_data_free;
2554 GST_ERROR_OBJECT (
self,
2555 "Error no %d: read %d/%d bytes while reading from the buffer fd.",
2556 errno, status, bytes_to_read);
2557 goto error_data_free;
2563 raw_data = raw_data_base;
2569 for (idx = 0; idx <
self->buffer_capacity; idx++) {
2570 for (channels = self->channels, ch_idx = 0;
2571 ch_idx < self->num_channels_enabled;
2572 ch_idx++, channels = channels->next) {
2573 if (self->tensors_config->info.num_tensors == 1) {
2576 ((gfloat *) map[0].
data) + idx *
self->num_channels_enabled +
2580 map_data_float = ((gfloat *) map[ch_idx].
data) + idx;
2584 GST_ERROR_OBJECT (
self,
"Error while processing scanned data.");
2585 goto error_data_free;
2588 raw_data +=
self->scan_size;
2595 for (idx = 0; idx <
self->tensors_config->info.num_tensors; idx++) {
2596 gst_memory_unmap (mem[idx], &map[idx]);
2597 gst_memory_unref (mem[idx]);