GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("other/tensor, "
- "rank = (int) [ 1, 4 ], "
- "dimension = (int) [ 0, 65536 ], (int) [ 0, 65536 ], (int) [ 0, 65536 ], (int) [0, 65536 ], "
+ "rank = (uint) [ 1, 4 ], "
+ "dim1 = (uint) [ 1, 65535 ], "
+ "dim2 = (uint) [ 1, 65535 ], "
+ "dim3 = (uint) [ 1, 65535 ], "
+ "dim4 = (uint) [ 1, 65535 ], "
"type = (string) { float32, float64, int32, uint32, int16, uint16, int8, uint8 }, "
"framerate = (fraction) [ 0, 1024 ], ")
);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
filter->silent = FALSE;
+ filter->tensorConfigured = FALSE;
}
static void
}
}
-/* GstElement vmethod implementations */
+/******************************************************************
+ * GstElement vmethod implementations
+ */
+#define return_false_if_fail(x) \
+ ret = (x); \
+ if (!ret) \
+ return FALSE; \
+ ;
/* Configure tensor metadata from sink caps */
static gboolean
-gst_convert2tensor_configure_tensor(const GstCaps *caps, GstConvert2Tensor *myself) {
+gst_convert2tensor_configure_tensor(const GstCaps *caps, GstConvert2Tensor *filter) {
+ GstStructure *structure;
+ gint rank;
+ gint dimension[GST_CONVERT2TENSOR_TENSOR_RANK_LIMIT];
+ tensor_type type;
+ gint framerate_numerator;
+ gint framerate_denominator;
+ gboolean ret;
+ GstCaps *outcaps;
+ int i;
+
+ /* This caps is coming from video/x-raw */
+ structure = gst_caps_get_structure(caps, 0);
+ rank = 3; /* [color-space][height][width] */
+ return_false_if_fail(gst_structure_get_int(structure, "width", &dimension[0]));
+ return_false_if_fail(gst_structure_get_int(structure, "height", &dimension[1]));
+ return_false_if_fail(gst_structure_get_fraction(structure, "framerate", &framerate_numerator, &framerate_denominator));
+ type = _C2T_UINT8; /* Assume color depth per component is 8 bit */
+ dimension[2] = 3; /* R G B */
+ dimension[3] = 1; /* This is 3-D Tensor */
+ /* Refer: https://gstreamer.freedesktop.org/documentation/design/mediatype-video-raw.html */
+
+ if (filter->tensorConfigured == TRUE) {
+ /* It has been already configured. Check if they are consistent */
+ if (rank == filter->rank &&
+ type == filter->type &&
+ framerate_numerator == filter->framerate_numerator &&
+ framerate_denominator == filter->framerate_denominator) {
+ for (i = 0; i < GST_CONVERT2TENSOR_TENSOR_RANK_LIMIT; i++)
+ if (dimension[i] != filter->dimension[i])
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ filter->rank = rank;
+ for (i = 0; i < GST_CONVERT2TENSOR_TENSOR_RANK_LIMIT; i++)
+ filter->dimension[i] = dimension[i];
+ filter->type = type;
+ filter->framerate_numerator = framerate_numerator;
+ filter->framerate_denominator = framerate_denominator;
+
+ filter->tensorConfigured = TRUE;
+ return TRUE;
}
GstCaps * caps;
gst_event_parse_caps (event, &caps);
- /* @TODO Construct tensor metadata from sink caps */
ret = gst_convert2tensor_configure_tensor(caps, filter);
-
+ if (ret == FALSE) {
+ g_printerr("Cannot parse sinkpad caps properly for tensor metadata\n");
+ break; /* REPORT THIS INCIDENT! */
+ }
/* and forward */
ret = gst_pad_event_default (pad, parent, event);
typedef struct _GstConvert2TensorClass GstConvert2TensorClass;
+#define GST_CONVERT2TENSOR_TENSOR_RANK_LIMIT (4)
+typedef enum _tensor_type {
+ _C2T_INT32 = 0,
+ _C2T_UINT32,
+ _C2T_INT16,
+ _C2T_UINT16,
+ _C2T_INT8,
+ _C2T_UINT8,
+ _C2T_FLOAT64,
+ _C2T_FLOAT32,
+
+ _C2T_END,
+} tensor_type;
struct _GstConvert2Tensor
{
GstElement element; /**< This element itself is the convert2tensor filter */
GstPad *srcpad; /**< Tensor stream output */
gboolean silent; /**< True if logging is minimized */
gboolean tensorConfigured; /**< True if sinkpad has successfully configured tensor metadata */
- int rank; /**< Tensor Rank (# dimensions) */
- int dimension[4]; /**< Dimensions. We support up to 4th ranks */
- enum {
- _C2T_INT32 = 0,
- _C2T_UINT32,
- _C2T_INT16,
- _C2T_UINT16,
- _C2T_INT8,
- _C2T_UINT8,
- _C2T_FLOAT64,
- _C2T_FLOAT32,
- } type; /**< Type of each element in the tensor. User must designate this. Otherwise, this is UINT8 for video/x-raw byte stream */
+ gint rank; /**< Tensor Rank (# dimensions) */
+ gint dimension[GST_CONVERT2TENSOR_TENSOR_RANK_LIMIT]; /**< Dimensions. We support up to 4th ranks */
+ tensor_type type; /**< Type of each element in the tensor. User must designate this. Otherwise, this is UINT8 for video/x-raw byte stream */
+ gint framerate_numerator; /**< framerate is in fraction, which is numerator/denominator */
+ gint framerate_denominator; /**< framerate is in fraction, which is numerator/denominator */
};
-unsigned int GstConvert2TensorDataSize[] = {
+const unsigned int GstConvert2TensorDataSize[] = {
[_C2T_INT32] = 4,
[_C2T_UINT32] = 4,
[_C2T_INT16] = 2,
[_C2T_FLOAT64] = 8,
[_C2T_FLOAT32] = 4,
};
+const gchar* GstConvert2TensorDataTypeName[] = {
+ [_C2T_INT32] = "int32",
+ [_C2T_UINT32] = "uint32",
+ [_C2T_INT16] = "int16",
+ [_C2T_UINT16] = "uint16",
+ [_C2T_INT8] = "int8",
+ [_C2T_UINT8] = "uint8",
+ [_C2T_FLOAT64] = "float64",
+ [_C2T_FLOAT32] = "float32",
+};
+
struct _GstConvert2TensorClass
{