Doxygen Book
gstdatareposrc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-only */
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 #include <gst/gst.h>
37 #include <gst/video/video-info.h>
38 #include <gst/audio/audio-info.h>
39 #include <glib/gstdio.h>
40 #include <nnstreamer_plugin_api.h>
41 #include <nnstreamer_util.h>
42 #include <stdio.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <errno.h>
46 #include <string.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <inttypes.h>
50 #include "gstdatareposrc.h"
51 
52 #define struct_stat struct stat
53 #ifndef S_ISREG
54 /* regular file */
55 #define S_ISREG(mode) ((mode)&_S_IFREG)
56 #endif
57 #ifndef S_ISDIR
58 #define S_ISDIR(mode) ((mode)&_S_IFDIR)
59 #endif
60 /* socket */
61 #ifndef S_ISSOCK
62 #define S_ISSOCK(x) (0)
63 #endif
64 #ifndef O_BINARY
65 #define O_BINARY (0)
66 #endif
67 
68 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
69  GST_PAD_SRC,
70  GST_PAD_ALWAYS,
71  GST_STATIC_CAPS_ANY);
72 
73 GST_DEBUG_CATEGORY_STATIC (gst_data_repo_src_debug);
74 #define GST_CAT_DEFAULT gst_data_repo_src_debug
75 
76 /* datareposrc signals and args */
77 enum
78 {
87  PROP_CAPS, /* for setting caps of sample data directly */
88 };
89 
90 #define DEFAULT_INDEX 0
91 #define DEFAULT_EPOCHS 1
92 #define DEFAULT_IS_SHUFFLE TRUE
93 
94 static void gst_data_repo_src_finalize (GObject * object);
95 static GstStateChangeReturn gst_data_repo_src_change_state (GstElement *
96  element, GstStateChange transition);
97 static void gst_data_repo_src_set_property (GObject * object, guint prop_id,
98  const GValue * value, GParamSpec * pspec);
99 static void gst_data_repo_src_get_property (GObject * object, guint prop_id,
100  GValue * value, GParamSpec * pspec);
101 static gboolean gst_data_repo_src_stop (GstBaseSrc * basesrc);
102 static GstCaps *gst_data_repo_src_get_caps (GstBaseSrc * basesrc,
103  GstCaps * filter);
104 static gboolean gst_data_repo_src_set_caps (GstBaseSrc * basesrc,
105  GstCaps * caps);
106 static GstFlowReturn gst_data_repo_src_create (GstPushSrc * pushsrc,
107  GstBuffer ** buffer);
108 #define _do_init \
109  GST_DEBUG_CATEGORY_INIT (gst_data_repo_src_debug, "datareposrc", 0, "datareposrc element");
110 
111 #define gst_data_repo_src_parent_class parent_class
112 G_DEFINE_TYPE_WITH_CODE (GstDataRepoSrc, gst_data_repo_src, GST_TYPE_PUSH_SRC,
113  _do_init);
114 
118 static void
120 {
121  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
122  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
123  GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
124  GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
125 
126  gobject_class->set_property =
127  GST_DEBUG_FUNCPTR (gst_data_repo_src_set_property);
128  gobject_class->get_property =
129  GST_DEBUG_FUNCPTR (gst_data_repo_src_get_property);
130 
131  g_object_class_install_property (gobject_class, PROP_LOCATION,
132  g_param_spec_string ("location", "File Location",
133  "Location of the file to read that is stored in MLOps Data Repository, "
134  "if the files are images, write the index of filename name "
135  "like %04ld or %04lld (e.g., filenmae%04ld.png)",
136  NULL,
137  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
138  GST_PARAM_MUTABLE_READY));
139 
140  g_object_class_install_property (gobject_class, PROP_JSON,
141  g_param_spec_string ("json", "Json file path",
142  "Json file path containing the meta information of the file "
143  "specified as location", NULL,
144  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
145  GST_PARAM_MUTABLE_READY));
146 
147  g_object_class_install_property (gobject_class, PROP_START_SAMPLE_INDEX,
148  g_param_spec_uint ("start-sample-index", "Start index of samples",
149  "Start index of sample to read, in case of image, "
150  "the starting index of the numbered files. start at 0."
151  "Set start index of range of samples or files to read",
152  0, G_MAXINT, DEFAULT_INDEX,
153  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
154  GST_PARAM_MUTABLE_READY));
155 
156  g_object_class_install_property (gobject_class, PROP_STOP_SAMPLE_INDEX,
157  g_param_spec_uint ("stop-sample-index", "Stop index of samples",
158  "Stop index of sample to read, in case of image, "
159  "the stopping index of the numbered files. start at 0."
160  "Set stop index of range of samples or files to read",
161  0, G_MAXINT, DEFAULT_INDEX,
162  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
163  GST_PARAM_MUTABLE_READY));
164 
165  g_object_class_install_property (gobject_class, PROP_EPOCHS,
166  g_param_spec_uint ("epochs", "Epochs",
167  "Repetition of range of files or samples to read, set number of repetitions",
168  0, G_MAXINT, DEFAULT_EPOCHS,
169  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
170  GST_PARAM_MUTABLE_READY));
171 
172  g_object_class_install_property (gobject_class, PROP_TENSORS_SEQUENCE,
173  g_param_spec_string ("tensors-sequence", "Tensors sequence",
174  "Tensors in a sample are read into gstBuffer according to tensors-sequence."
175  "Only read the set tensors among all tensors in a sample"
176  "e.g, if a sample has '1:1:1:1','1:1:10:1','1:1:784:1' and each index is '0,1,2', "
177  "'tensors-sequence=2,1' means that only '1:1:784:1' then '1:1:10:1' are read. "
178  "Use for other/tensors and the default value is NULL"
179  "(all tensors are read in the order stored in a sample).",
180  NULL,
181  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
182  GST_PARAM_MUTABLE_READY));
183 
184  g_object_class_install_property (gobject_class, PROP_IS_SHUFFLE,
185  g_param_spec_boolean ("is-shuffle", "Is shuffle",
186  "If the value is true, samples are shuffled",
188  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
189  GST_PARAM_MUTABLE_READY));
190 
191  g_object_class_install_property (gobject_class, PROP_CAPS,
192  g_param_spec_boxed ("caps", "Caps",
193  "Optional property, Caps describing the format of the sample data.",
194  GST_TYPE_CAPS,
195  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
196  GST_PARAM_MUTABLE_READY));
197 
198  gobject_class->finalize = gst_data_repo_src_finalize;
199  gstelement_class->change_state = gst_data_repo_src_change_state;
200 
201  gst_element_class_set_static_metadata (gstelement_class,
202  "NNStreamer MLOps Data Repository Source",
203  "Source/File",
204  "Read files in MLOps Data Repository into buffers",
205  "Samsung Electronics Co., Ltd.");
206  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
207 
208  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_data_repo_src_stop);
209  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_data_repo_src_get_caps);
210  gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_data_repo_src_set_caps);
211  gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_data_repo_src_create);
212 
213  if (sizeof (off_t) < 8) {
214  GST_LOG ("No large file support, sizeof (off_t) = %" G_GSIZE_FORMAT "!",
215  sizeof (off_t));
216  }
217 }
218 
222 static void
224 {
225  src->filename = NULL;
226  src->json_filename = NULL;
227  src->tensors_seq_str = NULL;
228  src->file_size = 0;
229  src->fd = 0;
231  src->fd_offset = 0;
232  src->start_offset = 0;
233  src->last_offset = 0;
234  src->successful_read = FALSE;
235  src->is_start = FALSE;
236  src->current_sample_index = 0;
237  src->start_sample_index = 0;
238  src->stop_sample_index = 0;
239  src->epochs = DEFAULT_EPOCHS;
240  src->shuffled_index_array = g_array_new (FALSE, FALSE, sizeof (guint));
241  src->array_index = 0;
242  src->sample_offset_array = NULL;
243  src->sample_offset_array_len = 0;
244  src->tensor_size_array = NULL;
245  src->tensor_size_array_len = 0;
246  src->tensor_count_array = NULL;
247  src->tensor_count_array_len = 0;
248  src->first_epoch_is_done = FALSE;
250  src->num_samples = 0;
251  src->total_samples = 0;
252  src->tensors_seq_cnt = 0;
253  src->caps = NULL;
254  src->sample_size = 0;
255  src->need_changed_caps = FALSE;
256  src->n_frame = 0;
257  src->running_time = 0;
258  src->parser = NULL;
260 
261  /* Filling the buffer should be pending until set_caps() */
262  gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
263  gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
264 }
265 
269 static void
270 gst_data_repo_src_finalize (GObject * object)
271 {
272  GstDataRepoSrc *src = GST_DATA_REPO_SRC (object);
273 
274  g_free (src->filename);
275  g_free (src->json_filename);
276  g_free (src->tensors_seq_str);
277 
278  /* close the file */
279  if (src->fd) {
280  g_close (src->fd, NULL);
281  src->fd = 0;
282  }
283 
284  if (src->parser)
285  g_object_unref (src->parser);
286 
287  if (src->shuffled_index_array)
288  g_array_free (src->shuffled_index_array, TRUE);
289 
290  if (src->caps)
291  gst_caps_replace (&src->caps, NULL);
292 
294 
295  G_OBJECT_CLASS (parent_class)->finalize (object);
296 }
297 
302 static gboolean
304 {
305  GstStructure *s;
306 
307  g_return_val_if_fail (src != NULL, FALSE);
308  g_return_val_if_fail (caps != NULL, FALSE);
309 
311  s = gst_caps_get_structure (caps, 0);
312 
313  switch (src->data_type) {
315  {
316  GstVideoInfo video_info;
317 
318  gst_video_info_init (&video_info);
319  gst_video_info_from_caps (&video_info, caps);
320 
321  /* https://gstreamer.freedesktop.org/documentation/additional/design/mediatype-video-raw.html?gi-language=c */
322  src->sample_size = (guint) GST_VIDEO_INFO_SIZE (&video_info);
323 
324  GST_DEBUG_OBJECT (src, "format(%s), width(%d), height(%d): %zd byte/frame",
325  gst_structure_get_string (s, "format"),
326  GST_VIDEO_INFO_WIDTH (&video_info),
327  GST_VIDEO_INFO_HEIGHT (&video_info), src->sample_size);
328  break;
329  }
331  {
332  GstAudioInfo audio_info;
333  gint rate, channel, depth;
334 
335  gst_audio_info_init (&audio_info);
336  gst_audio_info_from_caps (&audio_info, caps);
337 
338  rate = GST_AUDIO_INFO_RATE (&audio_info);
339  channel = GST_AUDIO_INFO_CHANNELS (&audio_info);
340  depth = GST_AUDIO_INFO_DEPTH (&audio_info);
341 
342  src->sample_size = (gsize) channel * (depth / 8) * rate;
343 
344  GST_DEBUG_OBJECT (src,
345  "format(%s), depth(%d), rate(%d), channel(%d): %zd bps",
346  gst_structure_get_string (s, "format"), depth, rate, channel,
347  src->sample_size);
348  break;
349  }
351  {
352  GstTensorInfo *_info;
353  guint i;
354 
355  /* Set current tensors information if given data type is tensor. */
358  src->sample_size = 0;
359 
360  for (i = 0; i < src->config.info.num_tensors; i++) {
361  src->tensors_offset[i] = src->sample_size;
362  _info = gst_tensors_info_get_nth_info (&src->config.info, i);
363  src->tensors_size[i] = gst_tensor_info_get_size (_info);
364  GST_DEBUG_OBJECT (src, "offset[%u]: %zd", i, src->tensors_offset[i]);
365  GST_DEBUG_OBJECT (src, "size[%u]: %zd", i, src->tensors_size[i]);
366  src->sample_size += src->tensors_size[i];
367  }
368  break;
369  }
370  default:
371  break;
372  }
373 
374  src->rate_n = 0;
375  src->rate_d = 1;
376  if (gst_structure_has_field (s, "framerate")) {
377  gst_structure_get_fraction (s, "framerate", &src->rate_n, &src->rate_d);
378  }
379 
380  GST_LOG_OBJECT (src, "framerate %d/%d", src->rate_n, src->rate_d);
381  GST_LOG_OBJECT (src, "data type: %d", src->data_type);
382 
383  /* This function always takes caps. */
385  gst_caps_take (&src->caps, caps);
386  else
387  gst_caps_unref (caps);
388 
389  return (src->data_type != GST_DATA_REPO_DATA_UNKNOWN);
390 }
391 
395 static gboolean
397  const gchar * file_path, GError ** err)
398 {
399  gchar *filename = NULL;
400  GstState state;
401 
402  g_return_val_if_fail (prop == PROP_LOCATION || prop == PROP_JSON, FALSE);
403 
404  /* the element must be stopped in order to do this */
405  GST_OBJECT_LOCK (src);
406  state = GST_STATE (src);
407  if (state != GST_STATE_READY && state != GST_STATE_NULL)
408  goto wrong_state;
409  GST_OBJECT_UNLOCK (src);
410 
411  /* clear the filename if we get a NULL */
412  if (file_path == NULL) {
413  filename = NULL;
414  } else {
415  /* should be UTF8 */
416  filename = g_strdup (file_path);
417  GST_INFO_OBJECT (src, "%sname : %s",
418  (prop == PROP_LOCATION) ? "file" : "json_file", filename);
419  }
420 
421  if (prop == PROP_LOCATION) {
422  g_free (src->filename);
423  src->filename = filename;
424  } else { /* PROP_JSON */
425  g_free (src->json_filename);
426  src->json_filename = filename;
427  }
428 
429  return TRUE;
430 
431  /* ERROR */
432 wrong_state:
433  {
434  g_warning
435  ("Changing the `location or json' property on datareposrc when a file is "
436  "open is not supported.");
437  if (err)
438  g_set_error (err, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
439  "Changing the `location or json' property on datareposrc when a file is "
440  "open is not supported.");
441  GST_OBJECT_UNLOCK (src);
442  return FALSE;
443  }
444 }
445 
449 static gboolean
451 {
452  g_auto (GStrv) strv = NULL;
453  guint length;
454  guint i = 0;
455 
456  g_return_val_if_fail (src != NULL, FALSE);
457  g_return_val_if_fail (src->tensors_seq_str != NULL, FALSE);
458 
459  GST_INFO_OBJECT (src, "tensors sequence = %s", src->tensors_seq_str);
460 
461  /* not use NNS_TENSOR_SIZE_LIMIT */
462  strv = g_strsplit (src->tensors_seq_str, ",", -1);
463 
464  length = g_strv_length (strv);
465  if (length > NNS_TENSOR_SIZE_LIMIT) {
466  GST_ERROR_OBJECT (src, "The total number of indices exceeded %d.",
468  goto error;
469  }
470 
471  while (strv[i] != NULL && strlen (strv[i]) > 0) {
472  src->tensors_seq[i] = (guint) g_ascii_strtoull (strv[i], NULL, 10);
473  if (src->tensors_seq[i] > src->config.info.num_tensors - 1) {
474  GST_ERROR_OBJECT (src, "Invalid index %d, max is %d", src->tensors_seq[i],
475  src->config.info.num_tensors - 1);
476  goto error;
477  }
478  GST_INFO_OBJECT (src, "%d", src->tensors_seq[i]);
479  i++;
480  }
481  src->tensors_seq_cnt = i;
482  GST_INFO_OBJECT (src, "The number of selected tensors is %d",
483  src->tensors_seq_cnt);
484 
485  /* num_tensors was calculated from JSON file */
486  if (src->config.info.num_tensors < src->tensors_seq_cnt) {
487  GST_ERROR_OBJECT (src,
488  "The number of tensors selected(%d) "
489  "is greater than the total number of tensors(%d) in a sample.",
491  goto error;
492  }
493  return TRUE;
494 
495 error:
496  src->tensors_seq_cnt = 0;
497  return FALSE;
498 }
499 
503 static guint64
505 {
506  guint64 offset;
507 
508  g_return_val_if_fail (src != NULL, 0);
509  g_return_val_if_fail (src->data_type != GST_DATA_REPO_DATA_IMAGE, 0);
510  g_return_val_if_fail (src->fd != 0, 0);
511 
512  offset = src->sample_size * sample_index;
513 
514  return offset;
515 }
516 
520 static void
522 {
523  guint i, j;
524  guint value_i, value_j;
525  g_return_if_fail (src != NULL);
526  g_return_if_fail (src->shuffled_index_array != NULL);
527 
528  GST_LOG_OBJECT (src, "samples index are shuffled");
529  /* Fisher-Yates algorithm */
530  /* The last index is the number of samples - 1. */
531  for (i = src->num_samples - 1; i > 0; i--) {
532  j = g_random_int_range (0, src->num_samples);
533  value_i = g_array_index (src->shuffled_index_array, guint, i);
534  value_j = g_array_index (src->shuffled_index_array, guint, j);
535 
536  /* shuffled_index_array->data type is gchar * */
537  *(guint *) (src->shuffled_index_array->data + (sizeof (guint) * i)) =
538  value_j;
539  *(guint *) (src->shuffled_index_array->data + (sizeof (guint) * j)) =
540  value_i;
541  }
542 
543  for (i = 0; i < src->shuffled_index_array->len; i++) {
544  GST_DEBUG_OBJECT (src, "%u -> %u", i,
545  g_array_index (src->shuffled_index_array, guint, i));
546  }
547 }
548 
552 static gboolean
554 {
555  g_return_val_if_fail (src != NULL, FALSE);
556  if (src->num_samples != src->array_index)
557  return FALSE;
558 
559  src->first_epoch_is_done = TRUE;
560  src->array_index = 0;
561  src->epochs--;
562 
563  return TRUE;
564 }
565 
569 static GstFlowReturn
570 gst_data_repo_src_read_tensors (GstDataRepoSrc * src, GstBuffer ** buffer)
571 {
572  GstFlowReturn ret = GST_FLOW_OK;
573  guint i = 0, seq_idx = 0;
574  GstBuffer *buf = NULL;
575  gsize to_read, byte_read;
576  gssize read_size;
577  guint8 *data;
578  GstMemory *mem = NULL;
579  GstMapInfo info;
580  guint shuffled_index = 0;
581  guint64 sample_offset = 0;
582  guint64 offset = 0; /* offset from 0 */
583 
584  g_return_val_if_fail (src->fd != 0, GST_FLOW_ERROR);
585  g_return_val_if_fail (src->shuffled_index_array != NULL, GST_FLOW_ERROR);
586 
588  if (src->epochs == 0) {
589  GST_LOG_OBJECT (src, "send EOS");
590  return GST_FLOW_EOS;
591  }
592  if (src->is_shuffle)
594  }
595 
596  /* only do for first epoch */
597  if (!src->first_epoch_is_done) {
598  /* append samples index to array */
599  g_array_append_val (src->shuffled_index_array, src->current_sample_index);
600  src->current_sample_index++;
601  }
602  shuffled_index =
603  g_array_index (src->shuffled_index_array, guint, src->array_index++);
604  GST_LOG_OBJECT (src, "shuffled_index [%d] -> %d", src->array_index - 1,
605  shuffled_index);
606 
607  /* sample offset from 0 */
608  sample_offset = gst_data_repo_src_get_file_offset (src, shuffled_index);
609  GST_LOG_OBJECT (src, "sample offset 0x%" G_GINT64_MODIFIER "x (%d size)",
610  sample_offset, (guint) sample_offset);
611 
612  buf = gst_buffer_new ();
613 
614  for (i = 0; i < src->tensors_seq_cnt; i++) {
615  seq_idx = src->tensors_seq[i];
616  mem = gst_allocator_alloc (NULL, src->tensors_size[seq_idx], NULL);
617 
618  if (!gst_memory_map (mem, &info, GST_MAP_WRITE)) {
619  GST_ERROR_OBJECT (src, "Could not map GstMemory[%d]", i);
620  ret = GST_FLOW_ERROR;
621  goto error;
622  }
623 
624  GST_INFO_OBJECT (src, "sequence index: %d", seq_idx);
625  GST_INFO_OBJECT (src, "tensor_size[%d]: %zd", seq_idx,
626  src->tensors_size[seq_idx]);
627  GST_INFO_OBJECT (src, "tensors_offset[%d]: %zd", seq_idx,
628  src->tensors_offset[seq_idx]);
629 
644  data = info.data;
645 
646  byte_read = 0;
647  to_read = src->tensors_size[seq_idx];
648  offset = sample_offset + src->tensors_offset[seq_idx];
649  src->fd_offset = lseek (src->fd, offset, SEEK_SET);
650 
651  while (to_read > 0) {
652  GST_LOG_OBJECT (src,
653  "Reading %zd bytes at offset 0x%" G_GINT64_MODIFIER "x (%zd size)",
654  to_read, src->fd_offset + byte_read,
655  (guint) src->fd_offset + byte_read);
656  errno = 0;
657  read_size = read (src->fd, data + byte_read, to_read);
658  GST_LOG_OBJECT (src, "Read: %zd", read_size);
659  if (read_size < 0) {
660  if (errno == EAGAIN || errno == EINTR)
661  continue;
662  GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
663  ret = GST_FLOW_ERROR;
664  goto error;
665  }
666  /* files should eos if they read 0 and more was requested */
667  if (read_size == 0) {
668  /* .. but first we should return any remaining data */
669  if (byte_read > 0)
670  break;
671  GST_DEBUG_OBJECT (src, "EOS");
672  ret = GST_FLOW_EOS;
673  goto error;
674  }
675  to_read -= read_size;
676  byte_read += read_size;
677 
678  src->read_position += read_size;
679  src->fd_offset += read_size;
680  }
681 
682  gst_memory_unmap (mem, &info);
683 
686  mem = NULL;
687  }
688 
689  *buffer = buf;
690 
691  return GST_FLOW_OK;
692 
693 error:
694  if (mem) {
695  gst_memory_unmap (mem, &info);
696  gst_memory_unref (mem);
697  }
698  if (buf)
699  gst_buffer_unref (buf);
700 
701  return ret;
702 }
703 
707 static guint
709 {
710  guint num_tensors = 0;
711  guint cur_idx_tensor_cnt = 0;
712  guint next_idx_tensor_cnt = 0;
713  gint64 val;
714 
715  g_return_val_if_fail (src != NULL, 0);
716 
717  val = json_array_get_int_element (src->tensor_count_array, shuffled_index);
718  g_return_val_if_fail (val >= 0, 0);
719 
720  cur_idx_tensor_cnt = (guint) val;
721  GST_DEBUG_OBJECT (src, "cur_idx_tensor_cnt:%u", cur_idx_tensor_cnt);
722 
723  if (shuffled_index + 1 == src->tensor_count_array_len) {
724  next_idx_tensor_cnt = src->tensor_size_array_len;
725  } else {
726  val = json_array_get_int_element (src->tensor_count_array,
727  shuffled_index + 1);
728  g_return_val_if_fail (val >= 0, 0);
729 
730  next_idx_tensor_cnt = (guint) val;
731  }
732  GST_DEBUG_OBJECT (src, "next_idx_tensor_cnt:%u", next_idx_tensor_cnt);
733 
734  num_tensors = next_idx_tensor_cnt - cur_idx_tensor_cnt;
735  GST_DEBUG_OBJECT (src, "num_tensors:%u", num_tensors);
736 
737  return num_tensors;
738 }
739 
743 static GstFlowReturn
745  GstBuffer ** buffer)
746 {
747  GstFlowReturn ret = GST_FLOW_OK;
748  guint i;
749  guint shuffled_index = 0;
750  gint64 val;
751  guint num_tensors = 0;
752  GstBuffer *buf = NULL;
753  GstMemory *mem = NULL;
754  GstMapInfo info;
755  GstTensorMetaInfo meta;
756  GstTensorInfo tinfo;
757  gsize to_read, byte_read;
758  gssize read_size;
759  guint8 *data;
760  guint tensor_count;
761  gsize tensor_size;
762 
763  g_return_val_if_fail (src->fd != 0, GST_FLOW_ERROR);
764  g_return_val_if_fail (src->shuffled_index_array != NULL, GST_FLOW_ERROR);
765 
767  if (src->epochs == 0) {
768  GST_LOG_OBJECT (src, "send EOS");
769  return GST_FLOW_EOS;
770  }
771  if (src->is_shuffle)
773  }
774 
775  /* only do for first epoch */
776  if (!src->first_epoch_is_done) {
777  /* append samples index to array */
778  g_array_append_val (src->shuffled_index_array, src->current_sample_index);
779  src->current_sample_index++;
780  }
781 
782  shuffled_index =
783  g_array_index (src->shuffled_index_array, guint, src->array_index++);
784  GST_LOG_OBJECT (src, "shuffled_index [%d] -> %d", src->array_index - 1,
785  shuffled_index);
786 
787  /* sample offset from 0 */
788  val = json_array_get_int_element (src->sample_offset_array, shuffled_index);
789  if (val < 0) {
790  GST_ERROR_OBJECT (src, "Could not get the sample offset from json.");
791  return GST_FLOW_ERROR;
792  }
793 
794  GST_LOG_OBJECT (src, "sample offset 0x%" G_GINT64_MODIFIER "x (%d size)",
795  val, (guint) val);
796 
797  src->fd_offset = lseek (src->fd, val, SEEK_SET);
798 
799  val = json_array_get_int_element (src->tensor_count_array, shuffled_index);
800  if (val < 0) {
801  GST_ERROR_OBJECT (src, "Could not get the tensor count from json.");
802  return GST_FLOW_ERROR;
803  }
804  tensor_count = (guint) val;
805 
806  num_tensors = gst_data_repo_src_get_num_tensors (src, shuffled_index);
807 
808  buf = gst_buffer_new ();
809 
810  for (i = 0; i < num_tensors; i++) {
811  val = json_array_get_int_element (src->tensor_size_array, tensor_count + i);
812  if (val < 0) {
813  GST_ERROR_OBJECT (src, "Could not get the size of tensor from json.");
814  ret = GST_FLOW_ERROR;
815  goto error;
816  }
817 
818  tensor_size = (gsize) val;
819  mem = gst_allocator_alloc (NULL, tensor_size, NULL);
820 
821  if (!gst_memory_map (mem, &info, GST_MAP_WRITE)) {
822  GST_ERROR_OBJECT (src, "Could not map GstMemory[%d]", i);
823  ret = GST_FLOW_ERROR;
824  goto error;
825  }
826 
827  data = info.data;
828  byte_read = 0;
829  to_read = tensor_size;
830  while (to_read > 0) {
831  GST_LOG_OBJECT (src,
832  "Reading %zd bytes at offset 0x%" G_GINT64_MODIFIER "x (%lld size)",
833  to_read, src->fd_offset + byte_read, (long long) src->fd_offset);
834  errno = 0;
835  read_size = read (src->fd, data + byte_read, to_read);
836  GST_LOG_OBJECT (src, "Read: %zd", read_size);
837  if (read_size < 0) {
838  if (errno == EAGAIN || errno == EINTR)
839  continue;
840  GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
841  ret = GST_FLOW_ERROR;
842  goto error;
843  }
844  /* files should eos if they read 0 and more was requested */
845  if (read_size == 0) {
846  /* .. but first we should return any remaining data */
847  if (byte_read > 0)
848  break;
849  GST_DEBUG_OBJECT (src, "EOS");
850  ret = GST_FLOW_EOS;
851  goto error;
852  }
853  to_read -= read_size;
854  byte_read += read_size;
855 
856  src->read_position += read_size;
857  src->fd_offset += read_size;
858  }
859 
860  /* check invalid flexible tensor */
861  if (!gst_tensor_meta_info_parse_header (&meta, info.data)) {
862  GST_ERROR_OBJECT (src, "Invalid flexible tensors");
863  ret = GST_FLOW_ERROR;
864  goto error;
865  }
866 
867  gst_memory_unmap (mem, &info);
868 
869  gst_tensor_meta_info_convert (&meta, &tinfo);
870  gst_tensor_buffer_append_memory (buf, mem, &tinfo);
871  gst_tensor_info_free (&tinfo);
872  mem = NULL;
873  }
874 
875  *buffer = buf;
876 
877  return GST_FLOW_OK;
878 
879 error:
880  if (mem) {
881  gst_memory_unmap (mem, &info);
882  gst_memory_unref (mem);
883  }
884  if (buf)
885  gst_buffer_unref (buf);
886 
887  return ret;
888 }
889 
893 static gchar *
895 {
896  gchar *filename = NULL;
897  guint shuffled_index = 0;
898  g_return_val_if_fail (src != NULL, NULL);
899  g_return_val_if_fail (src->data_type == GST_DATA_REPO_DATA_IMAGE, NULL);
900  g_return_val_if_fail (src->filename != NULL, NULL);
901  g_return_val_if_fail (src->shuffled_index_array != NULL, NULL);
902 
903  /* GST_DATA_REPO_DATA_IMAGE must have %d in src->filename */
904  if (src->shuffled_index_array->len > 0)
905  shuffled_index =
906  g_array_index (src->shuffled_index_array, guint, src->array_index);
907  else
908  shuffled_index = 0; /* Used for initial file open verification */
909 
910 #ifdef __GNUC__
911 #pragma GCC diagnostic push
912 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
913 #endif
914  /* let's set value by property */
915  filename = g_strdup_printf (src->filename, shuffled_index);
916 #ifdef __GNUC__
917 #pragma GCC diagnostic pop
918 #endif
919 
920  return filename;
921 }
922 
926 static GstFlowReturn
928 {
929  g_autofree gchar *filename = NULL;
930  gsize size;
931  gchar *data;
932  GstBuffer *buf;
933  gboolean read_size;
934  GError *error = NULL;
935 
936  g_return_val_if_fail (src->shuffled_index_array != NULL, GST_FLOW_ERROR);
937 
939  if (src->epochs == 0) {
940  GST_LOG_OBJECT (src, "send EOS");
941  return GST_FLOW_EOS;
942  }
943  if (src->is_shuffle)
945  }
946 
947  /* only do for first epoch */
948  if (!src->first_epoch_is_done) {
949  /* append samples index to array */
950  g_array_append_val (src->shuffled_index_array, src->current_sample_index);
951  src->current_sample_index++;
952  }
953 
954  filename = gst_data_repo_src_get_image_filename (src);
955  GST_DEBUG_OBJECT (src, "Reading from file \"%s\".", filename);
956  src->array_index++;
957 
958  /* Try to read one image */
959  read_size = g_file_get_contents (filename, &data, &size, &error);
960  if (!read_size) {
961  if (src->successful_read) {
962  /* If we've read at least one buffer successfully, not finding the next file is EOS. */
963  if (error != NULL)
964  g_error_free (error);
965  return GST_FLOW_EOS;
966  }
967  goto handle_error;
968  }
969 
970  /* Success reading on image */
971  src->successful_read = TRUE;
972  GST_DEBUG_OBJECT (src, "file size is %zd", size);
973 
974  buf = gst_buffer_new ();
975  gst_buffer_append_memory (buf,
976  gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
977 
978  *buffer = buf;
979 
980  return GST_FLOW_OK;
981 
982 handle_error:
983  {
984  if (error != NULL) {
985  GST_ELEMENT_ERROR (src, RESOURCE, READ,
986  ("Error while reading from file \"%s\".", filename),
987  ("%s", error->message));
988  g_error_free (error);
989  } else {
990  GST_ELEMENT_ERROR (src, RESOURCE, READ,
991  ("Error while reading from file \"%s\".", filename),
992  ("%s", g_strerror (errno)));
993  }
994  return GST_FLOW_ERROR;
995  }
996 }
997 
1001 static GstFlowReturn
1002 gst_data_repo_src_read_others (GstDataRepoSrc * src, GstBuffer ** buffer)
1003 {
1004  GstFlowReturn ret = GST_FLOW_OK;
1005  GstBuffer *buf;
1006  gsize to_read, byte_read;
1007  gssize read_size;
1008  guint8 *data;
1009  GstMemory *mem;
1010  GstMapInfo info;
1011  guint shuffled_index = 0;
1012  guint64 offset = 0;
1013 
1014  g_return_val_if_fail (src->fd != 0, GST_FLOW_ERROR);
1015  g_return_val_if_fail (src->shuffled_index_array != NULL, GST_FLOW_ERROR);
1016 
1017  if (gst_data_repo_src_epoch_is_done (src)) {
1018  if (src->epochs == 0) {
1019  GST_LOG_OBJECT (src, "send EOS");
1020  return GST_FLOW_EOS;
1021  }
1022  if (src->is_shuffle)
1024  }
1025 
1026  /* only do for first epoch */
1027  if (!src->first_epoch_is_done) {
1028  /* append samples index to array */
1029  g_array_append_val (src->shuffled_index_array, src->current_sample_index);
1030  src->current_sample_index++;
1031  }
1032 
1033  shuffled_index =
1034  g_array_index (src->shuffled_index_array, guint, src->array_index++);
1035  GST_LOG_OBJECT (src, "shuffled_index [%d] -> %d", src->array_index - 1,
1036  shuffled_index);
1037  offset = gst_data_repo_src_get_file_offset (src, shuffled_index);
1038  src->fd_offset = lseek (src->fd, offset, SEEK_SET);
1039 
1040  mem = gst_allocator_alloc (NULL, src->sample_size, NULL);
1041 
1042  if (!gst_memory_map (mem, &info, GST_MAP_WRITE)) {
1043  GST_ERROR_OBJECT (src, "Could not map GstMemory");
1044  gst_memory_unref (mem);
1045  return GST_FLOW_ERROR;
1046  }
1047 
1048  data = info.data;
1049 
1050  byte_read = 0;
1051  to_read = src->sample_size;
1052  while (to_read > 0) {
1053  GST_LOG_OBJECT (src, "Reading %zd bytes at offset 0x%" G_GINT64_MODIFIER "x",
1054  to_read, src->fd_offset + byte_read);
1055  errno = 0;
1056  read_size = read (src->fd, data + byte_read, to_read);
1057  GST_LOG_OBJECT (src, "Read: %zd", read_size);
1058  if (read_size < 0) {
1059  if (errno == EAGAIN || errno == EINTR)
1060  continue;
1061  GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
1062  ret = GST_FLOW_ERROR;
1063  goto error;
1064  }
1065  /* files should eos if they read 0 and more was requested */
1066  if (read_size == 0) {
1067  /* .. but first we should return any remaining data */
1068  if (byte_read > 0)
1069  break;
1070  GST_DEBUG_OBJECT (src, "EOS");
1071  ret = GST_FLOW_EOS;
1072  goto error;
1073  }
1074  to_read -= read_size;
1075  byte_read += read_size;
1076 
1077  src->read_position += read_size;
1078  src->fd_offset += read_size;
1079  }
1080 
1081  gst_memory_unmap (mem, &info);
1082 
1083  buf = gst_buffer_new ();
1084  gst_buffer_append_memory (buf, mem);
1085 
1086  *buffer = buf;
1087  return GST_FLOW_OK;
1088 
1089 error:
1090  if (mem) {
1091  gst_memory_unmap (mem, &info);
1092  gst_memory_unref (mem);
1093  }
1094 
1095  return ret;
1096 }
1097 
1101 static gboolean
1103 {
1104  g_autofree gchar *filename = NULL;
1105  struct_stat stat_results;
1106  int flags = O_RDONLY | O_BINARY;
1107 
1108  g_return_val_if_fail (src != NULL, FALSE);
1109 
1110  if (src->filename == NULL || src->filename[0] == '\0')
1111  goto no_filename;
1112 
1114  src->num_samples = src->stop_sample_index - src->start_sample_index + 1;
1115  GST_INFO_OBJECT (src,
1116  "The number of samples to be used out of the total samples in the file is %d, [%d] ~ [%d]",
1118  GST_INFO_OBJECT (src, "data type: %d", src->data_type);
1119  if (src->data_type == GST_DATA_REPO_DATA_IMAGE) {
1120  filename = gst_data_repo_src_get_image_filename (src);
1121  } else {
1122  filename = g_strdup (src->filename);
1123  }
1124 
1125  GST_INFO_OBJECT (src, "opening file %s", filename);
1126 
1127  /* open the file */
1128  src->fd = g_open (filename, flags, 0);
1129 
1130  if (src->fd < 0)
1131  goto open_failed;
1132 
1133  /* check if it is a regular file, otherwise bail out */
1134  if (fstat (src->fd, &stat_results) < 0)
1135  goto no_stat;
1136 
1137  src->file_size = stat_results.st_size;
1138  if (src->file_size == 0)
1139  goto error_close;
1140 
1141  if (S_ISDIR (stat_results.st_mode))
1142  goto was_directory;
1143 
1144  if (S_ISSOCK (stat_results.st_mode))
1145  goto was_socket;
1146 
1147  /* record if it's a regular (hence seekable and lengthable) file */
1148  if (!S_ISREG (stat_results.st_mode))
1149  goto error_close;
1150 
1151  src->read_position = 0;
1152 
1153  if (src->data_type == GST_DATA_REPO_DATA_IMAGE) {
1154  /* no longer used */
1155  g_close (src->fd, NULL);
1156  src->fd = 0;
1157  } else {
1158  /* set start offset and last offset */
1159  src->start_offset =
1161 
1162  /* If the user does not set stop_sample_index, datareposrc need to calculate the last offset */
1163  src->last_offset =
1165 
1166  src->fd_offset = lseek (src->fd, src->start_offset, SEEK_SET);
1167  GST_LOG_OBJECT (src, "Start file offset 0x%" G_GINT64_MODIFIER "x",
1168  src->fd_offset);
1169  }
1170 
1171  return TRUE;
1172 
1173  /* ERROR */
1174 no_filename:
1175  {
1176  GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
1177  ("No file name specified for reading."), (NULL));
1178  goto error_exit;
1179  }
1180 open_failed:
1181  {
1182  switch (errno) {
1183  case ENOENT:
1184  GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
1185  ("No such file \"%s\"", src->filename));
1186  break;
1187  default:
1188  GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
1189  (("Could not open file \"%s\" for reading."), src->filename),
1190  GST_ERROR_SYSTEM);
1191  break;
1192  }
1193  goto error_exit;
1194  }
1195 no_stat:
1196  {
1197  GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
1198  (("Could not get info on \"%s\"."), src->filename), (NULL));
1199  goto error_close;
1200  }
1201 was_directory:
1202  {
1203  GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
1204  (("\"%s\" is a directory."), src->filename), (NULL));
1205  goto error_close;
1206  }
1207 was_socket:
1208  {
1209  GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
1210  (("File \"%s\" is a socket."), src->filename), (NULL));
1211  goto error_close;
1212  }
1213 
1214 error_close:
1215  g_close (src->fd, NULL);
1216  src->fd = 0;
1217 error_exit:
1218  return FALSE;
1219 }
1220 
1224 static void
1226 {
1227 
1228  GstClockTime next_time;
1229  GstClockTime duration = GST_CLOCK_TIME_NONE;
1230 
1231  g_return_if_fail (src != NULL);
1232  g_return_if_fail (buffer != NULL);
1233 
1234  /* Unlike video, audio should control one sample by framerate. */
1235  if (src->data_type == GST_DATA_REPO_DATA_AUDIO) {
1236  GST_WARNING_OBJECT (src,
1237  "Use audiorate element for the framerate of audio");
1238  return;
1239  }
1240 
1241  duration = gst_util_uint64_scale_int (GST_SECOND, src->rate_d, src->rate_n);
1242  GST_BUFFER_DURATION (buffer) = duration;
1243  GST_BUFFER_TIMESTAMP (buffer) = src->running_time;
1244  gst_object_sync_values (GST_OBJECT (src), GST_BUFFER_TIMESTAMP (buffer));
1245 
1246  next_time =
1247  gst_util_uint64_scale (src->n_frame++, src->rate_d * GST_SECOND,
1248  src->rate_n);
1249  src->running_time = next_time;
1250 
1251  GST_LOG_OBJECT (src, "next_time %" GST_TIME_FORMAT "",
1252  GST_TIME_ARGS (next_time));
1253  GST_LOG_OBJECT (src,
1254  "timestamp [%" GST_TIME_FORMAT " dur %" GST_TIME_FORMAT "]",
1255  GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
1256  GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1257 }
1258 
1262 static GstFlowReturn
1263 gst_data_repo_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer)
1264 {
1265  GstFlowReturn ret = GST_FLOW_OK;
1266  GstDataRepoSrc *src;
1267  src = GST_DATA_REPO_SRC (pushsrc);
1268 
1271  if (!src->is_start) {
1272  if (!gst_data_repo_src_start (src)) {
1273  return GST_FLOW_ERROR;
1274  }
1275  src->is_start = TRUE;
1276  }
1277 
1278  switch (src->data_type) {
1283  ret = gst_data_repo_src_read_others (src, buffer);
1284  break;
1287  ret = gst_data_repo_src_read_tensors (src, buffer);
1288  else
1290  break;
1292  ret = gst_data_repo_src_read_multi_images (src, buffer);
1293  break;
1294  default:
1295  return GST_FLOW_ERROR;
1296  }
1297 
1298  if (ret != GST_FLOW_OK)
1299  return ret;
1300 
1301  if (src->rate_n)
1302  gst_data_repo_src_set_timestamp (src, *buffer);
1303 
1304  return GST_FLOW_OK;
1305 }
1306 
1310 static gboolean
1311 gst_data_repo_src_stop (GstBaseSrc * basesrc)
1312 {
1313  GstDataRepoSrc *src = GST_DATA_REPO_SRC (basesrc);
1314 
1315  /* close the file */
1316  g_close (src->fd, NULL);
1317  src->fd = 0;
1318 
1319  return TRUE;
1320 }
1321 
1325 static gboolean
1327 {
1328  GstStructure *s;
1329  GstTensorsConfig src_config, dst_config;
1330  GstTensorInfo *_src_info, *_dst_info;
1331  guint i;
1332  guint seq_num = 0;
1333  GstCaps *new_caps;
1334 
1335  g_return_val_if_fail (src != NULL, FALSE);
1336  g_return_val_if_fail (src->caps != NULL, FALSE);
1337 
1338  s = gst_caps_get_structure (src->caps, 0);
1339  if (!gst_tensors_config_from_structure (&src_config, s))
1340  return FALSE;
1341 
1342  gst_tensors_config_init (&dst_config);
1343 
1344  /* Copy selected tensors in sequence */
1345  for (i = 0; i < src->tensors_seq_cnt; i++) {
1346  seq_num = src->tensors_seq[i];
1347  _src_info = gst_tensors_info_get_nth_info (&src_config.info, seq_num);
1348  _dst_info = gst_tensors_info_get_nth_info (&dst_config.info, i);
1349  gst_tensor_info_copy (_dst_info, _src_info);
1350  }
1351  dst_config.rate_n = src_config.rate_n;
1352  dst_config.rate_d = src_config.rate_d;
1353  dst_config.info.format = src_config.info.format;
1354  dst_config.info.num_tensors = src->tensors_seq_cnt;
1355 
1356  new_caps = gst_tensors_caps_from_config (&dst_config);
1357 
1358  GST_DEBUG_OBJECT (src,
1359  "datareposrc caps by tensors_sequence %" GST_PTR_FORMAT, new_caps);
1360 
1361  gst_tensors_config_free (&dst_config);
1362  gst_tensors_config_free (&src_config);
1363 
1364  return gst_data_repo_src_parse_caps (src, new_caps);
1365 }
1366 
1370 static GstCaps *
1371 gst_data_repo_src_get_caps (GstBaseSrc * basesrc, GstCaps * filter)
1372 {
1373  GstDataRepoSrc *src = GST_DATA_REPO_SRC (basesrc);
1374 
1377  src->need_changed_caps = FALSE;
1378  }
1379 
1380  GST_DEBUG_OBJECT (src, "Current datareposrc caps %" GST_PTR_FORMAT,
1381  src->caps);
1382 
1383  if (src->caps) {
1384  if (filter)
1385  return gst_caps_intersect_full (filter, src->caps,
1386  GST_CAPS_INTERSECT_FIRST);
1387  else
1388  return gst_caps_ref (src->caps);
1389  } else {
1390  if (filter)
1391  return gst_caps_ref (filter);
1392  else
1393  return gst_caps_new_any ();
1394  }
1395 }
1396 
1400 static gboolean
1401 gst_data_repo_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps)
1402 {
1403  GstDataRepoSrc *src = GST_DATA_REPO_SRC (basesrc);
1404 
1405  GST_INFO_OBJECT (src, "set caps: %" GST_PTR_FORMAT, caps);
1406 
1407  return TRUE;
1408 }
1409 
1413 static gboolean
1415 {
1416  g_autofree gchar *contents = NULL;
1417  GError *error = NULL;
1418  GFile *file;
1419  JsonNode *root;
1420  JsonObject *object;
1421  const gchar *caps_str = NULL;
1422  GstCaps *new_caps;
1423  gint64 val;
1424 
1425  g_return_val_if_fail (src != NULL, FALSE);
1426  g_return_val_if_fail (src->json_filename != NULL, FALSE);
1427 
1428  if ((file = g_file_new_for_path (src->json_filename)) == NULL) {
1429  GST_ERROR_OBJECT (src, "Failed to get file object of %s.",
1430  src->json_filename);
1431  return FALSE;
1432  }
1433 
1434  if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) {
1435  GST_ERROR_OBJECT (src, "Failed to open %s: %s", src->json_filename,
1436  error ? error->message : "Unknown error");
1437  g_clear_error (&error);
1438  g_object_unref (file);
1439  return FALSE;
1440  }
1441 
1442  if (src->parser)
1443  g_object_unref (src->parser);
1444  src->parser = json_parser_new ();
1445 
1446  if (!json_parser_load_from_data (src->parser, contents, -1, NULL)) {
1447  GST_ERROR_OBJECT (src, "Failed to load data from %s", src->json_filename);
1448  goto error;
1449  }
1450 
1451  root = json_parser_get_root (src->parser);
1452  if (!JSON_NODE_HOLDS_OBJECT (root)) {
1453  GST_ERROR_OBJECT (src, "it does not contain a JsonObject: %s", contents);
1454  goto error;
1455  }
1456 
1457  object = json_node_get_object (root);
1458 
1459  GST_INFO_OBJECT (src, ">>>>>>> Start parsing JSON file(%s)",
1460  src->json_filename);
1461 
1462  if (!json_object_has_member (object, "gst_caps")) {
1463  GST_ERROR_OBJECT (src, "There is no gst_caps field: %s", contents);
1464  goto error;
1465  }
1466 
1467  caps_str = json_object_get_string_member (object, "gst_caps");
1468  GST_INFO_OBJECT (src, "caps_str : %s", caps_str);
1469 
1470  new_caps = gst_caps_from_string (caps_str);
1471 
1472  /* calculate media size from gst caps */
1473  if (!gst_data_repo_src_parse_caps (src, new_caps))
1474  goto error;
1475 
1476  GST_INFO_OBJECT (src, "gst_caps : %" GST_PTR_FORMAT, src->caps);
1477 
1478  /* In the case of below media type, get sample_size from JSON */
1481  || src->data_type == GST_DATA_REPO_DATA_IMAGE) {
1482  if (!json_object_has_member (object, "sample_size")) {
1483  GST_ERROR_OBJECT (src, "There is not sample_size field: %s", contents);
1484  goto error;
1485  }
1486 
1487  val = json_object_get_int_member (object, "sample_size");
1488  if (val < 0) {
1489  GST_ERROR_OBJECT (src, "Invalid sample_size: %" G_GINT64_FORMAT, val);
1490  goto error;
1491  }
1492 
1493  src->sample_size = (gsize) val;
1494  GST_INFO_OBJECT (src, "sample_size: %zd", src->sample_size);
1495  }
1496 
1497  if (src->data_type == GST_DATA_REPO_DATA_TENSOR &&
1499  if (!json_object_has_member (object, "sample_offset")) {
1500  GST_ERROR_OBJECT (src, "There is no sample_offset field: %s", contents);
1501  goto error;
1502  }
1503  src->sample_offset_array =
1504  json_object_get_array_member (object, "sample_offset");
1506  json_array_get_length (src->sample_offset_array);
1507 
1508  if (!json_object_has_member (object, "tensor_size")) {
1509  GST_ERROR_OBJECT (src, "There is no tensor_size field: %s", contents);
1510  goto error;
1511  }
1512  src->tensor_size_array =
1513  json_object_get_array_member (object, "tensor_size");
1514  src->tensor_size_array_len = json_array_get_length (src->tensor_size_array);
1515  GST_INFO_OBJECT (src, "tensor_size_array_len:%u",
1516  src->tensor_size_array_len);
1517 
1518  if (!json_object_has_member (object, "tensor_count")) {
1519  GST_ERROR_OBJECT (src, "There is no tensor_count field: %s", contents);
1520  goto error;
1521  }
1522  src->tensor_count_array =
1523  json_object_get_array_member (object, "tensor_count");
1524  src->tensor_count_array_len =
1525  json_array_get_length (src->tensor_count_array);
1526  GST_INFO_OBJECT (src, "tensor_count_array_len:%u",
1527  src->tensor_count_array_len);
1528  } else {
1529  if (src->sample_size == 0)
1530  goto error;
1531  }
1532 
1533  if (!json_object_has_member (object, "total_samples")) {
1534  GST_ERROR_OBJECT (src, "There is no total_samples field: %s", contents);
1535  goto error;
1536  }
1537 
1538  val = json_object_get_int_member (object, "total_samples");
1539  if (val <= 0) {
1540  GST_ERROR_OBJECT (src, "Invalid total_samples: %" G_GINT64_FORMAT, val);
1541  goto error;
1542  }
1543 
1544  src->total_samples = (guint) val;
1545  GST_INFO_OBJECT (src, "total_samples: %u", src->total_samples);
1546 
1547  g_object_unref (file);
1548 
1549  return TRUE;
1550 error:
1552  GST_ERROR_OBJECT (src, "Failed to parse %s", src->json_filename);
1553  g_object_unref (file);
1554 
1555  return FALSE;
1556 }
1557 
1561 static void
1562 gst_data_repo_src_set_property (GObject * object, guint prop_id,
1563  const GValue * value, GParamSpec * pspec)
1564 {
1565  GstDataRepoSrc *src;
1566  const GstCaps *caps;
1567 
1568  g_return_if_fail (GST_IS_DATA_REPO_SRC (object));
1569 
1570  src = GST_DATA_REPO_SRC (object);
1571 
1572  switch (prop_id) {
1573  case PROP_LOCATION:
1575  g_value_get_string (value), NULL);
1576  break;
1577  case PROP_JSON:
1579  g_value_get_string (value), NULL);
1582  if (!gst_data_repo_src_read_json_file (src)) {
1583  GST_ERROR_OBJECT (src, "Failed to get data format");
1584  }
1585  break;
1587  src->start_sample_index = g_value_get_uint (value);
1588  break;
1590  src->stop_sample_index = g_value_get_uint (value);
1591  break;
1592  case PROP_EPOCHS:
1593  src->epochs = g_value_get_uint (value);
1594  break;
1595  case PROP_IS_SHUFFLE:
1596  src->is_shuffle = g_value_get_boolean (value);
1597  break;
1598  case PROP_TENSORS_SEQUENCE:
1599  g_free (src->tensors_seq_str);
1600  src->tensors_seq_str = g_value_dup_string (value);
1602  GST_ERROR_OBJECT (src, "Failed to set tensors sequence");
1603  } else {
1604  src->need_changed_caps = TRUE;
1605  }
1606  break;
1607  case PROP_CAPS:
1608  caps = gst_value_get_caps (value);
1609  if (caps) {
1610  gst_data_repo_src_parse_caps (src, gst_caps_copy (caps));
1611  }
1615  if (src->tensors_seq_str) {
1617  src->need_changed_caps = TRUE;
1618  }
1619  break;
1620  default:
1621  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1622  break;
1623  }
1624 }
1625 
1629 static void
1630 gst_data_repo_src_get_property (GObject * object, guint prop_id, GValue * value,
1631  GParamSpec * pspec)
1632 {
1633  GstDataRepoSrc *src;
1634 
1635  g_return_if_fail (GST_IS_DATA_REPO_SRC (object));
1636 
1637  src = GST_DATA_REPO_SRC (object);
1638 
1639  switch (prop_id) {
1640  case PROP_LOCATION:
1641  g_value_set_string (value, src->filename);
1642  break;
1643  case PROP_JSON:
1644  g_value_set_string (value, src->json_filename);
1645  break;
1647  g_value_set_uint (value, src->start_sample_index);
1648  break;
1650  g_value_set_uint (value, src->stop_sample_index);
1651  break;
1652  case PROP_EPOCHS:
1653  g_value_set_uint (value, src->epochs);
1654  break;
1655  case PROP_IS_SHUFFLE:
1656  g_value_set_boolean (value, src->is_shuffle);
1657  break;
1658  case PROP_TENSORS_SEQUENCE:
1659  g_value_set_string (value, src->tensors_seq_str);
1660  break;
1661  case PROP_CAPS:
1662  gst_value_set_caps (value, src->caps);
1663  break;
1664  default:
1665  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1666  break;
1667  }
1668 }
1669 
1673 static GstStateChangeReturn
1674 gst_data_repo_src_change_state (GstElement * element, GstStateChange transition)
1675 {
1676  guint i;
1677  GstDataRepoSrc *src = GST_DATA_REPO_SRC (element);
1678  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1679  GstBaseSrc *basesrc = NULL;
1680  guint blocksize;
1681 
1682  switch (transition) {
1683  case GST_STATE_CHANGE_NULL_TO_READY:
1684  GST_INFO_OBJECT (src, "NULL_TO_READY");
1685 
1687  goto state_change_failed;
1688 
1692  if (src->sample_size == 0 && (src->data_type == GST_DATA_REPO_DATA_OCTET
1693  || src->data_type == GST_DATA_REPO_DATA_TEXT)) {
1694  basesrc = GST_BASE_SRC (src);
1695  g_object_get (G_OBJECT (basesrc), "blocksize", &blocksize, NULL);
1696  GST_DEBUG_OBJECT (src, "blocksize = %u", blocksize);
1697  if (blocksize == 0) {
1698  GST_ERROR_OBJECT (src, "Please set the 'blocksize' property "
1699  "when using the 'caps' property to set the sample format without JSON.");
1700  goto state_change_failed;
1701  }
1702  src->sample_size = blocksize;
1703  }
1704 
1706  if (src->total_samples == 0 && src->stop_sample_index == 0) {
1707  GST_ERROR_OBJECT (src, "Please set the 'stop-sample-index' property "
1708  "when using the 'caps' property to set the sample format without JSON.");
1709  goto state_change_failed;
1710  }
1711 
1712  /* total_samples -1 is the default value of 'stop-sample-index' property */
1713  if (src->stop_sample_index == 0)
1714  src->stop_sample_index = src->total_samples - 1;
1715 
1716  /* Check invalid property value */
1717  if (src->start_sample_index > (src->total_samples - 1)
1718  || src->stop_sample_index > (src->total_samples - 1)
1719  || src->epochs == 0) {
1720  GST_ERROR_OBJECT (src, "Check for invalid range values");
1721 
1722  goto state_change_failed;
1723  }
1724 
1725  /* If tensors-sequence properties is set */
1726  if (src->tensors_seq_str != NULL) {
1727  if (src->data_type != GST_DATA_REPO_DATA_TENSOR) {
1728  GST_ERROR_OBJECT (src,
1729  "tensors-sequence properties is only for tensor/others type(%d), current type(%d)",
1731  goto state_change_failed;
1732  }
1733  /* After gst_data_repo_src_set_tensors_sequence() */
1734  if (src->tensors_seq_cnt == 0)
1735  goto state_change_failed;
1736  } else {
1737  for (i = 0; i < src->config.info.num_tensors; i++)
1738  src->tensors_seq[i] = i;
1739  src->tensors_seq_cnt = i;
1740  }
1741 
1742  break;
1743 
1744  case GST_STATE_CHANGE_READY_TO_PAUSED:
1745  GST_INFO_OBJECT (src, "READY_TO_PAUSED");
1746  break;
1747 
1748  case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1749  GST_INFO_OBJECT (src, "PAUSED_TO_PLAYING");
1750  break;
1751 
1752  default:
1753  break;
1754  }
1755 
1756  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1757 
1758  switch (transition) {
1759  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1760  GST_INFO_OBJECT (src, "PLAYING_TO_PAUSED");
1761  break;
1762 
1763  case GST_STATE_CHANGE_PAUSED_TO_READY:
1764  GST_INFO_OBJECT (src, "PAUSED_TO_READY");
1765  break;
1766 
1767  case GST_STATE_CHANGE_READY_TO_NULL:
1768  GST_INFO_OBJECT (src, "READY_TO_NULL");
1769  break;
1770 
1771  default:
1772  break;
1773  }
1774 
1775  return ret;
1776 
1777 state_change_failed:
1778  GST_ERROR_OBJECT (src, "state change failed");
1779 
1780  return GST_STATE_CHANGE_FAILURE;
1781 }
_GstDataRepoSrc::epochs
guint epochs
Definition: gstdatareposrc.h:69
gst_video_info_init
#define gst_video_info_init(i)
Definition: gsttensor_converter_media_no_video.h:46
gst_data_repo_src_set_tensors_sequence
static gboolean gst_data_repo_src_set_tensors_sequence(GstDataRepoSrc *src)
Function to set tensors sequence.
Definition: gstdatareposrc.c:450
srctemplate
static GstStaticPadTemplate srctemplate
Definition: gstdatareposrc.c:68
GST_DATA_REPO_DATA_VIDEO
@ GST_DATA_REPO_DATA_VIDEO
Definition: gstdatarepo.h:26
gst_data_repo_src_epoch_is_done
static gboolean gst_data_repo_src_epoch_is_done(GstDataRepoSrc *src)
Function to check epoch and EOS.
Definition: gstdatareposrc.c:553
PROP_0
@ PROP_0
Definition: gstdatareposrc.c:79
S_ISSOCK
#define S_ISSOCK(x)
Definition: gstdatareposrc.c:62
_GstDataRepoSrc::shuffled_index_array
GArray * shuffled_index_array
Definition: gstdatareposrc.h:72
_GstDataRepoSrc::start_offset
guint64 start_offset
Definition: gstdatareposrc.h:52
_GstDataRepoSrc::tensor_size_array
JsonArray * tensor_size_array
Definition: gstdatareposrc.h:83
GstAudioInfo
#define GstAudioInfo
Definition: gsttensor_converter_media_no_audio.h:26
_GstDataRepoSrc::is_shuffle
gboolean is_shuffle
Definition: gstdatareposrc.h:70
gst_data_repo_src_class_init
static void gst_data_repo_src_class_init(GstDataRepoSrcClass *klass)
initialize the datareposrc's class
Definition: gstdatareposrc.c:119
data
svtc_1 data
Definition: gsttensor_if.c:844
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
NNS_TENSOR_SIZE_LIMIT
#define NNS_TENSOR_SIZE_LIMIT
The number of tensors NNStreamer supports is 256. The max memories of gst-buffer is 16 (See NNS_TENSO...
Definition: tensor_typedef.h:42
PROP_JSON
@ PROP_JSON
Definition: gstdatareposrc.c:81
_GstDataRepoSrc::tensors_seq_cnt
guint tensors_seq_cnt
Definition: gstdatareposrc.h:76
FALSE
return FALSE
Definition: gsttensor_transform.c:590
PROP_CAPS
@ PROP_CAPS
Definition: gstdatareposrc.c:87
struct_stat
#define struct_stat
Definition: gstdatareposrc.c:52
gst_data_repo_src_get_property
static void gst_data_repo_src_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Getter datareposrc properties.
Definition: gstdatareposrc.c:1630
_GstDataRepoSrc::current_sample_index
gint current_sample_index
Definition: gstdatareposrc.h:56
_GstDataRepoSrc::parser
JsonParser * parser
Definition: gstdatareposrc.h:85
G_DEFINE_TYPE_WITH_CODE
G_DEFINE_TYPE_WITH_CODE(GstDataRepoSrc, gst_data_repo_src, GST_TYPE_PUSH_SRC, _do_init)
prop
GstTensorSrcIIOChannelProperties * prop
DTYPE_UNSIGNED ( .
Definition: gsttensor_srciio.c:110
gst_data_repo_src_stop
static gboolean gst_data_repo_src_stop(GstBaseSrc *basesrc)
Stop datareposrc, unmap and close the file.
Definition: gstdatareposrc.c:1311
gst_tensor_info_copy
void gst_tensor_info_copy(GstTensorInfo *dest, const GstTensorInfo *src)
Copy tensor info.
Definition: nnstreamer_plugin_api_util_impl.c:248
GST_DATA_REPO_SRC
#define GST_DATA_REPO_SRC(obj)
Definition: gstdatareposrc.h:26
GstTensorMetaInfo
Data structure to describe a tensor data. This represents the basic information of a memory block for...
Definition: tensor_typedef.h:310
gst_data_repo_src_read_tensors
static GstFlowReturn gst_data_repo_src_read_tensors(GstDataRepoSrc *src, GstBuffer **buffer)
Function to read tensors.
Definition: gstdatareposrc.c:570
_GstDataRepoSrcClass
GstDataRepoSrcClass data structure.
Definition: gstdatareposrc.h:98
_GstDataRepoSrc::is_start
gboolean is_start
Definition: gstdatareposrc.h:46
GstTensorsConfig::rate_d
int rate_d
Definition: tensor_typedef.h:288
DEFAULT_IS_SHUFFLE
#define DEFAULT_IS_SHUFFLE
Definition: gstdatareposrc.c:92
_GstDataRepoSrc::read_position
guint64 read_position
Definition: gstdatareposrc.h:50
_GstDataRepoSrc::tensor_count_array
JsonArray * tensor_count_array
Definition: gstdatareposrc.h:84
GST_DATA_REPO_DATA_IMAGE
@ GST_DATA_REPO_DATA_IMAGE
Definition: gstdatarepo.h:31
DEFAULT_INDEX
#define DEFAULT_INDEX
Definition: gstdatareposrc.c:90
gst_data_repo_src_finalize
static void gst_data_repo_src_finalize(GObject *object)
Function to finalize instance.
Definition: gstdatareposrc.c:270
gst_data_repo_src_start
static gboolean gst_data_repo_src_start(GstDataRepoSrc *src)
Start datareposrc, open the file.
Definition: gstdatareposrc.c:1102
GST_DATA_REPO_DATA_TEXT
@ GST_DATA_REPO_DATA_TEXT
Definition: gstdatarepo.h:28
GST_AUDIO_INFO_RATE
#define GST_AUDIO_INFO_RATE(...)
Definition: gsttensor_converter_media_no_audio.h:46
_GstDataRepoSrc::caps
GstCaps * caps
Definition: gstdatareposrc.h:78
gst_audio_info_init
#define gst_audio_info_init(i)
Definition: gsttensor_converter_media_no_audio.h:40
_GstDataRepoSrc::tensor_size_array_len
guint tensor_size_array_len
Definition: gstdatareposrc.h:87
g_free
g_free(self->option[(opnum) - 1])
opnum: \
_GstDataRepoSrc::num_samples
guint num_samples
Definition: gstdatareposrc.h:59
g_value_set_string
g_value_set_string(value, self->option[opnum - 1])
opnum: \
_GstDataRepoSrc::rate_d
gint rate_d
Definition: gstdatareposrc.h:91
_GstDataRepoSrc::sample_size
gsize sample_size
Definition: gstdatareposrc.h:60
gst_tensor_meta_info_parse_header
gboolean gst_tensor_meta_info_parse_header(GstTensorMetaInfo *meta, gpointer header)
Parse header and fill the tensor meta.
Definition: nnstreamer_plugin_api_util_impl.c:1527
gst_data_repo_src_shuffle_samples_index
static void gst_data_repo_src_shuffle_samples_index(GstDataRepoSrc *src)
Function to shuffle samples index.
Definition: gstdatareposrc.c:521
S_ISDIR
#define S_ISDIR(mode)
Definition: gstdatareposrc.c:58
GstTensorsConfig::rate_n
int rate_n
Definition: tensor_typedef.h:287
S_ISREG
#define S_ISREG(mode)
Definition: gstdatareposrc.c:55
gst_data_repo_src_set_caps
static gboolean gst_data_repo_src_set_caps(GstBaseSrc *basesrc, GstCaps *caps)
caps after caps negotiation
Definition: gstdatareposrc.c:1401
GST_DATA_REPO_DATA_UNKNOWN
@ GST_DATA_REPO_DATA_UNKNOWN
Definition: gstdatarepo.h:25
gst_audio_info_from_caps
#define gst_audio_info_from_caps(...)
Definition: gsttensor_converter_media_no_audio.h:41
PROP_TENSORS_SEQUENCE
@ PROP_TENSORS_SEQUENCE
Definition: gstdatareposrc.c:86
gst_data_repo_src_read_flexible_or_sparse_tensors
static GstFlowReturn gst_data_repo_src_read_flexible_or_sparse_tensors(GstDataRepoSrc *src, GstBuffer **buffer)
Function to read flexible or sparse tensors.
Definition: gstdatareposrc.c:744
gst_video_info_from_caps
#define gst_video_info_from_caps(...)
Definition: gsttensor_converter_media_no_video.h:47
gst_data_repo_get_data_type_from_caps
GstDataRepoDataType gst_data_repo_get_data_type_from_caps(const GstCaps *caps)
Get data type from caps.
Definition: gstdatarepo.c:21
_GstDataRepoSrc::successful_read
gboolean successful_read
Definition: gstdatareposrc.h:47
gst_tensors_config_free
void gst_tensors_config_free(GstTensorsConfig *config)
Free allocated data in tensors config structure.
Definition: nnstreamer_plugin_api_util_impl.c:845
GST_IS_DATA_REPO_SRC
#define GST_IS_DATA_REPO_SRC(obj)
Definition: gstdatareposrc.h:30
_GstDataRepoSrc::last_offset
guint64 last_offset
Definition: gstdatareposrc.h:53
gst_data_repo_src_change_state
static GstStateChangeReturn gst_data_repo_src_change_state(GstElement *element, GstStateChange transition)
Change state of datareposrc.
Definition: gstdatareposrc.c:1674
GST_AUDIO_INFO_CHANNELS
#define GST_AUDIO_INFO_CHANNELS(...)
Definition: gsttensor_converter_media_no_audio.h:45
_GstDataRepoSrc::data_type
GstDataRepoDataType data_type
Definition: gstdatareposrc.h:61
GST_VIDEO_INFO_HEIGHT
#define GST_VIDEO_INFO_HEIGHT(...)
Definition: gsttensor_converter_media_no_video.h:52
gst_tensor_meta_info_convert
gboolean gst_tensor_meta_info_convert(GstTensorMetaInfo *meta, GstTensorInfo *info)
Convert GstTensorMetaInfo structure to GstTensorInfo.
Definition: nnstreamer_plugin_api_util_impl.c:1562
GstVideoInfo
#define GstVideoInfo
Definition: gsttensor_converter_media_no_video.h:26
GstTensorsConfig
Internal data structure for configured tensors info (for other/tensors).
Definition: tensor_typedef.h:284
_GstDataRepoSrc::array_index
guint array_index
Definition: gstdatareposrc.h:73
gst_data_repo_src_set_timestamp
static void gst_data_repo_src_set_timestamp(GstDataRepoSrc *src, GstBuffer *buffer)
Set timestamp.
Definition: gstdatareposrc.c:1225
_do_init
#define _do_init
Definition: gstdatareposrc.c:108
TRUE
return TRUE
Definition: gsttensor_if.c:897
_GstDataRepoSrc::json_filename
gchar * json_filename
Definition: gstdatareposrc.h:65
gst_data_repo_src_get_image_filename
static gchar * gst_data_repo_src_get_image_filename(GstDataRepoSrc *src)
Get image filename.
Definition: gstdatareposrc.c:894
_GstDataRepoSrc::tensors_size
gsize tensors_size[NNS_TENSOR_SIZE_LIMIT]
Definition: gstdatareposrc.h:54
_GstDataRepoSrc::tensors_seq
guint tensors_seq[NNS_TENSOR_SIZE_LIMIT]
Definition: gstdatareposrc.h:75
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
_GstDataRepoSrc::need_changed_caps
gboolean need_changed_caps
Definition: gstdatareposrc.h:77
_GstDataRepoSrc::fd
gint fd
Definition: gstdatareposrc.h:48
_GstDataRepoSrc::file_size
gint file_size
Definition: gstdatareposrc.h:49
gst_tensor_info_get_size
gsize gst_tensor_info_get_size(const GstTensorInfo *info)
Get data size of single tensor.
Definition: nnstreamer_plugin_api_util_impl.c:156
_GstDataRepoSrc::fd_offset
guint64 fd_offset
Definition: gstdatareposrc.h:51
gst_tensor_info_free
void gst_tensor_info_free(GstTensorInfo *info)
Free allocated data in tensor info structure.
Definition: nnstreamer_plugin_api_util_impl.c:140
_GstDataRepoSrc::tensors_seq_str
gchar * tensors_seq_str
Definition: gstdatareposrc.h:66
gst_tensors_info_get_nth_info
GstTensorInfo * gst_tensors_info_get_nth_info(GstTensorsInfo *info, guint index)
Get the pointer of nth tensor information.
Definition: nnstreamer_plugin_api_util_impl.c:296
_GstDataRepoSrc::first_epoch_is_done
gboolean first_epoch_is_done
Definition: gstdatareposrc.h:57
gst_tensors_caps_from_config
GstCaps * gst_tensors_caps_from_config(const GstTensorsConfig *config)
Get caps from tensors config (for other/tensors)
Definition: nnstreamer_plugin_api_impl.c:1372
PROP_EPOCHS
@ PROP_EPOCHS
Definition: gstdatareposrc.c:84
gst_data_repo_src_set_property
static void gst_data_repo_src_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Setter for datareposrc properties.
Definition: gstdatareposrc.c:1562
gst_data_repo_src_read_others
static GstFlowReturn gst_data_repo_src_read_others(GstDataRepoSrc *src, GstBuffer **buffer)
Function to read others media type (video, audio, octet and text)
Definition: gstdatareposrc.c:1002
_GstDataRepoSrc::rate_n
gint rate_n
Definition: gstdatareposrc.h:91
_GstDataRepoSrc::config
GstTensorsConfig config
Definition: gstdatareposrc.h:81
gst_data_repo_src_set_file_path
static gboolean gst_data_repo_src_set_file_path(GstDataRepoSrc *src, const int prop, const gchar *file_path, GError **err)
Function to set file path.
Definition: gstdatareposrc.c:396
_GstDataRepoSrc::sample_offset_array
JsonArray * sample_offset_array
Definition: gstdatareposrc.h:82
_GstDataRepoSrc::total_samples
guint total_samples
Definition: gstdatareposrc.h:58
GST_DATA_REPO_DATA_OCTET
@ GST_DATA_REPO_DATA_OCTET
Definition: gstdatarepo.h:29
GST_DATA_REPO_DATA_TENSOR
@ GST_DATA_REPO_DATA_TENSOR
Definition: gstdatarepo.h:30
_GstDataRepoSrc::start_sample_index
guint start_sample_index
Definition: gstdatareposrc.h:67
O_BINARY
#define O_BINARY
Definition: gstdatareposrc.c:65
GST_VIDEO_INFO_SIZE
#define GST_VIDEO_INFO_SIZE(...)
Definition: gsttensor_converter_media_no_video.h:53
gst_data_repo_src_init
static void gst_data_repo_src_init(GstDataRepoSrc *src)
Initialize datareposrc.
Definition: gstdatareposrc.c:223
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
gst_data_repo_src_read_json_file
static gboolean gst_data_repo_src_read_json_file(GstDataRepoSrc *src)
Read JSON file.
Definition: gstdatareposrc.c:1414
gst_data_repo_src_get_num_tensors
static guint gst_data_repo_src_get_num_tensors(GstDataRepoSrc *src, guint shuffled_index)
Function to get num_tensors from tensor_count_array.
Definition: gstdatareposrc.c:708
gst_data_repo_src_get_file_offset
static guint64 gst_data_repo_src_get_file_offset(GstDataRepoSrc *src, guint sample_index)
Function to get file offset with sample index.
Definition: gstdatareposrc.c:504
_GstDataRepoSrc::filename
gchar * filename
Definition: gstdatareposrc.h:64
gst_tensors_config_init
void gst_tensors_config_init(GstTensorsConfig *config)
Initialize the tensors config info structure (for other/tensors)
Definition: nnstreamer_plugin_api_util_impl.c:830
gst_data_repo_src_get_caps
static GstCaps * gst_data_repo_src_get_caps(GstBaseSrc *basesrc, GstCaps *filter)
Get caps for caps negotiation.
Definition: gstdatareposrc.c:1371
PROP_IS_SHUFFLE
@ PROP_IS_SHUFFLE
Definition: gstdatareposrc.c:85
_GstDataRepoSrc::tensor_count_array_len
guint tensor_count_array_len
Definition: gstdatareposrc.h:88
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_data_repo_src_debug)
GstTensorsConfig::info
GstTensorsInfo info
Definition: tensor_typedef.h:286
PROP_LOCATION
@ PROP_LOCATION
Definition: gstdatareposrc.c:80
GST_DATA_REPO_DATA_AUDIO
@ GST_DATA_REPO_DATA_AUDIO
Definition: gstdatarepo.h:27
_GstDataRepoSrc::sample_offset_array_len
guint sample_offset_array_len
Definition: gstdatareposrc.h:86
gst_tensors_config_from_structure
gboolean gst_tensors_config_from_structure(GstTensorsConfig *config, const GstStructure *structure)
Parse structure and set tensors config (for other/tensors)
Definition: nnstreamer_plugin_api_impl.c:1413
_GstDataRepoSrc::running_time
GstClockTime running_time
Definition: gstdatareposrc.h:90
_GstDataRepoSrc
GstDataRepoSrc data structure.
Definition: gstdatareposrc.h:41
gstdatareposrc.h
GStreamer plugin to read file in MLOps Data repository into buffers.
GST_VIDEO_INFO_WIDTH
#define GST_VIDEO_INFO_WIDTH(...)
Definition: gsttensor_converter_media_no_video.h:51
PROP_START_SAMPLE_INDEX
@ PROP_START_SAMPLE_INDEX
Definition: gstdatareposrc.c:82
_GstDataRepoSrc::n_frame
guint64 n_frame
Definition: gstdatareposrc.h:92
gst_data_repo_src_parse_caps
static gboolean gst_data_repo_src_parse_caps(GstDataRepoSrc *src, GstCaps *caps)
Parse gst-caps to get media type and data size.
Definition: gstdatareposrc.c:303
PROP_STOP_SAMPLE_INDEX
@ PROP_STOP_SAMPLE_INDEX
Definition: gstdatareposrc.c:83
gst_tensors_config_is_static
#define gst_tensors_config_is_static(c)
Macro to check stream format (static tensors for caps negotiation)
Definition: nnstreamer_plugin_api_util.h:274
gst_tensor_buffer_append_memory
gboolean gst_tensor_buffer_append_memory(GstBuffer *buffer, GstMemory *memory, const GstTensorInfo *info)
Append memory to given buffer.
Definition: nnstreamer_plugin_api_impl.c:1666
GstTensorsInfo::format
tensor_format format
Definition: tensor_typedef.h:278
_GstDataRepoSrc::tensors_offset
gsize tensors_offset[NNS_TENSOR_SIZE_LIMIT]
Definition: gstdatareposrc.h:55
gst_data_repo_src_create
static GstFlowReturn gst_data_repo_src_create(GstPushSrc *pushsrc, GstBuffer **buffer)
Function to create a buffer.
Definition: gstdatareposrc.c:1263
_GstDataRepoSrc::stop_sample_index
guint stop_sample_index
Definition: gstdatareposrc.h:68
nnstreamer_plugin_api.h
Optional/Additional NNStreamer APIs for sub-plugin writers. (Need Gst devel)
gst_data_repo_get_caps_by_tensors_sequence
static gboolean gst_data_repo_get_caps_by_tensors_sequence(GstDataRepoSrc *src)
Get caps with tensors_sequence applied.
Definition: gstdatareposrc.c:1326
DEFAULT_EPOCHS
#define DEFAULT_EPOCHS
Definition: gstdatareposrc.c:91
gst_data_repo_src_read_multi_images
static GstFlowReturn gst_data_repo_src_read_multi_images(GstDataRepoSrc *src, GstBuffer **buffer)
Function to read multi image files.
Definition: gstdatareposrc.c:927