gst_harness_teardown (h);
}
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_1)
+{
+ GstHarness *h;
+ GstBuffer *in_buf, *out_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ GstMemory *mem;
+ GstMapInfo info;
+ guint i;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "3:4:2:2,3:4:2:2",
+ "input-type", "int32,int32", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:2", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+
+ mem = gst_buffer_peek_memory (in_buf, 0);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE));
+
+ memcpy (info.data, aggr_test_frames, data_size);
+
+ gst_memory_unmap (mem, &info);
+
+ EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK);
+
+ /* get output buffer */
+ out_buf = gst_harness_pull (h);
+
+ ASSERT_TRUE (out_buf != NULL);
+ ASSERT_EQ (gst_buffer_n_memory (out_buf), 2U);
+ ASSERT_EQ (gst_buffer_get_size (out_buf), data_size);
+
+ /* 1st tensor */
+ mem = gst_buffer_peek_memory (out_buf, 0);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 0; i < 48; i++)
+ EXPECT_EQ (((gint *) info.data)[i], aggr_test_frames[0][i]);
+ gst_memory_unmap (mem, &info);
+
+ /* 2nd tensor */
+ mem = gst_buffer_peek_memory (out_buf, 1);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 0; i < 48; i++)
+ EXPECT_EQ (((gint *) info.data)[i], aggr_test_frames[1][i]);
+ gst_memory_unmap (mem, &info);
+
+ gst_buffer_unref (out_buf);
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 1U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_2)
+{
+ GstHarness *h;
+ GstBuffer *in_buf, *out_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ GstMemory *mem;
+ GstMapInfo info;
+ guint i;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "3:4:2:1,3:4:2:1,3:4:2:1,3:4:2:1",
+ "input-type", "int32,int32,int32,int32", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 4;
+
+ config.info.info[0].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:1", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:1", config.info.info[1].dimension);
+ config.info.info[2].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:1", config.info.info[2].dimension);
+ config.info.info[3].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("3:4:2:1", config.info.info[3].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+
+ mem = gst_buffer_peek_memory (in_buf, 0);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_WRITE));
+
+ memcpy (info.data, aggr_test_frames, data_size);
+
+ gst_memory_unmap (mem, &info);
+
+ EXPECT_EQ (gst_harness_push (h, in_buf), GST_FLOW_OK);
+
+ /* get output buffer */
+ out_buf = gst_harness_pull (h);
+
+ ASSERT_TRUE (out_buf != NULL);
+ ASSERT_EQ (gst_buffer_n_memory (out_buf), 4U);
+ ASSERT_EQ (gst_buffer_get_size (out_buf), data_size);
+
+ /* 1st tensor */
+ mem = gst_buffer_peek_memory (out_buf, 0);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 0; i < 24; i++)
+ EXPECT_EQ (((gint *) info.data)[i], aggr_test_frames[0][i]);
+ gst_memory_unmap (mem, &info);
+
+ /* 2nd tensor */
+ mem = gst_buffer_peek_memory (out_buf, 1);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 24; i < 48; i++)
+ EXPECT_EQ (((gint *) info.data)[i - 24], aggr_test_frames[0][i]);
+ gst_memory_unmap (mem, &info);
+
+ /* 3rd tensor */
+ mem = gst_buffer_peek_memory (out_buf, 2);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 0; i < 24; i++)
+ EXPECT_EQ (((gint *) info.data)[i], aggr_test_frames[1][i]);
+ gst_memory_unmap (mem, &info);
+
+ /* 4th tensor */
+ mem = gst_buffer_peek_memory (out_buf, 3);
+ ASSERT_TRUE (gst_memory_map (mem, &info, GST_MAP_READ));
+ for (i = 24; i < 48; i++)
+ EXPECT_EQ (((gint *) info.data)[i - 24], aggr_test_frames[1][i]);
+ gst_memory_unmap (mem, &info);
+
+ gst_buffer_unref (out_buf);
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 1U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_dim_01_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "2:2:2:2",
+ "input-type", "int32,uint64", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_UINT64;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_dim_02_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "2:2:2:2,2:0:1",
+ "input-type", "int32,float32", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_INT32;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_FLOAT32;
+ gst_tensor_parse_dimension ("2:2:1:1", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_type_01_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-type", "int64",
+ "input-dim", "2:2:2:2,2:2:2:2", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_INT64;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_UINT64;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_type_02_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "2:2:2:2,2:2:1:1",
+ "input-type", "int16,invalid", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_INT16;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_INT16;
+ gst_tensor_parse_dimension ("2:2:1:1", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_type_03_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "1:1:1:1,2:1:1:1,3",
+ "input-type", "int16,uint16", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 3;
+
+ config.info.info[0].type = _NNS_INT16;
+ gst_tensor_parse_dimension ("1:1:1:1", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_UINT16;
+ gst_tensor_parse_dimension ("2:1:1:1", config.info.info[1].dimension);
+ config.info.info[1].type = _NNS_UINT8;
+ gst_tensor_parse_dimension ("3:1:1:1", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_size_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "2:2:2:2,1:1:1:1",
+ "input-type", "float32,float64", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_FLOAT32;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_FLOAT64;
+ gst_tensor_parse_dimension ("2:2:1:1", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
+/**
+ * @brief Test for tensor_converter (bytes to multi tensors)
+ */
+TEST (test_tensor_converter, bytes_to_multi_invalid_frames_n)
+{
+ GstHarness *h;
+ GstBuffer *in_buf;
+ GstTensorsConfig config;
+ GstCaps *caps;
+ gsize data_size;
+
+ h = gst_harness_new ("tensor_converter");
+
+ g_object_set (h->element, "input-dim", "2:2:2:2,1:1:1:1",
+ "input-type", "float32,float64", "frames-per-tensor", "2", NULL);
+
+ /* in/out caps and tensors info */
+ caps = gst_caps_from_string ("application/octet-stream");
+ gst_harness_set_src_caps (h, caps);
+
+ gst_tensors_config_init (&config);
+ config.rate_n = 0;
+ config.rate_d = 1;
+ config.info.num_tensors = 2;
+
+ config.info.info[0].type = _NNS_FLOAT32;
+ gst_tensor_parse_dimension ("2:2:2:2", config.info.info[0].dimension);
+ config.info.info[1].type = _NNS_FLOAT64;
+ gst_tensor_parse_dimension ("1:1:1:1", config.info.info[1].dimension);
+
+ data_size = gst_tensors_info_get_size (&config.info, -1);
+
+ /* push buffers */
+ in_buf = gst_harness_create_buffer (h, data_size);
+ EXPECT_DEATH (gst_harness_push (h, in_buf), "");
+
+ EXPECT_EQ (gst_harness_buffers_received (h), 0U);
+ gst_harness_teardown (h);
+}
+
#ifdef HAVE_ORC
#include "transform-orc.h"
TEST_TYPE_OCTET_VALID_TS, /**< pipeline for octet stream, valid timestamp */
TEST_TYPE_OCTET_INVALID_TS, /**< pipeline for octet stream, invalid timestamp */
TEST_TYPE_OCTET_2F, /**< pipeline for octet stream, 2 frames */
+ TEST_TYPE_OCTET_MULTI_TENSORS, /**< pipeline for octet stream, byte array to multi tensors */
TEST_TYPE_TENSORS, /**< pipeline for tensors with tensor_mux */
TEST_TYPE_TENSORS_MIX_1, /**< pipeline for tensors with tensor_mux, tensor_demux */
TEST_TYPE_TENSORS_MIX_2, /**< pipeline for tensors with tensor_mux, tensor_demux pick 0,2 */
("appsrc name=appsrc caps=application/octet-stream,framerate=(fraction)10/1 ! "
"tensor_converter name=convert input-dim=1:5 input-type=int8 ! tensor_sink name=test_sink");
break;
+ case TEST_TYPE_OCTET_MULTI_TENSORS:
+ /** byte stream, byte array to multi tensors */
+ str_pipeline =
+ g_strdup_printf
+ ("appsrc name=appsrc caps=application/octet-stream,framerate=(fraction)10/1 ! "
+ "tensor_converter name=convert input-dim=2,2 input-type=int32,int8 ! tensor_sink name=test_sink");
+ break;
case TEST_TYPE_TENSORS:
/** other/tensors with tensor_mux */
str_pipeline =
}
/**
+ * @brief Test for octet stream.
+ */
+TEST (tensor_stream_test, octet_multi_tensors)
+{
+ const guint num_buffers = 10;
+ TestOption option = { num_buffers, TEST_TYPE_OCTET_MULTI_TENSORS };
+ GstElement *convert;
+ gchar *prop_str;
+ guint prop_uint;
+ guint timeout_id;
+
+ ASSERT_TRUE (_setup_pipeline (option));
+
+ /* tensor_converter properties */
+ convert = gst_bin_get_by_name (GST_BIN (g_test_data.pipeline), "convert");
+ ASSERT_TRUE (convert != NULL);
+
+ g_object_get (convert, "input-dim", &prop_str, NULL);
+ EXPECT_STREQ (prop_str, "2:1:1:1,2:1:1:1");
+ g_free (prop_str);
+
+ g_object_get (convert, "input-type", &prop_str, NULL);
+ EXPECT_STREQ (prop_str, "int32,int8");
+ g_free (prop_str);
+
+ g_object_get (convert, "frames-per-tensor", &prop_uint, NULL);
+ EXPECT_EQ (prop_uint, 1U);
+
+ gst_object_unref (convert);
+
+ gst_element_set_state (g_test_data.pipeline, GST_STATE_PLAYING);
+
+ g_timeout_add (100, _test_src_push_timer_cb, GINT_TO_POINTER (TRUE));
+
+ timeout_id = g_timeout_add (5000, _test_src_eos_timer_cb, g_test_data.loop);
+ g_main_loop_run (g_test_data.loop);
+ g_source_remove (timeout_id);
+
+ EXPECT_TRUE (_wait_pipeline_process_buffers (num_buffers));
+ gst_element_set_state (g_test_data.pipeline, GST_STATE_NULL);
+
+ /** check eos message */
+ EXPECT_EQ (g_test_data.status, TEST_EOS);
+
+ /** check received buffers */
+ EXPECT_EQ (g_test_data.received, num_buffers);
+ EXPECT_EQ (g_test_data.mem_blocks, 2U);
+ EXPECT_EQ (g_test_data.received_size, 10U);
+
+ /** check caps name */
+ EXPECT_STREQ (g_test_data.caps_name, "other/tensors");
+
+ /** check timestamp */
+ EXPECT_FALSE (g_test_data.invalid_timestamp);
+
+ /** check tensor config for multi tensors */
+ EXPECT_TRUE (gst_tensors_config_validate (&g_test_data.tensors_config));
+ EXPECT_EQ (g_test_data.tensors_config.info.num_tensors, 2U);
+
+ EXPECT_EQ (g_test_data.tensors_config.info.info[0].type, _NNS_INT32);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[0], 2U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[1], 1U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[2], 1U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[0].dimension[3], 1U);
+
+ EXPECT_EQ (g_test_data.tensors_config.info.info[1].type, _NNS_INT8);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[0], 2U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[1], 1U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[2], 1U);
+ EXPECT_EQ (g_test_data.tensors_config.info.info[1].dimension[3], 1U);
+
+ EXPECT_EQ (g_test_data.tensors_config.rate_n, 10);
+ EXPECT_EQ (g_test_data.tensors_config.rate_d, 1);
+
+ EXPECT_FALSE (g_test_data.test_failed);
+ _free_test_data ();
+}
+
+/**
* @brief Test for other/tensor, passthrough custom filter.
*/
TEST (tensor_stream_test, custom_filter_tensor)