From 6663901517917ba05539d16f82622fdf1fe05fda Mon Sep 17 00:00:00 2001 From: gichan-jang Date: Thu, 28 May 2020 10:45:33 +0900 Subject: [PATCH] [Converter] Change tensor config to tensors config Change tensor config to tensors config. Assume single tensor only except subplugin. Signed-off-by: gichan-jang --- .../include/nnstreamer_plugin_api_converter.h | 14 +- gst/nnstreamer/tensor_converter/tensor_converter.c | 281 +++++++++++---------- gst/nnstreamer/tensor_converter/tensor_converter.h | 5 +- 3 files changed, 164 insertions(+), 136 deletions(-) diff --git a/gst/nnstreamer/include/nnstreamer_plugin_api_converter.h b/gst/nnstreamer/include/nnstreamer_plugin_api_converter.h index 5358828..0ea89ec 100644 --- a/gst/nnstreamer/include/nnstreamer_plugin_api_converter.h +++ b/gst/nnstreamer/include/nnstreamer_plugin_api_converter.h @@ -43,30 +43,32 @@ typedef struct _NNStreamerExternalConverter const char *media_type_name; /** 1. chain func, data handling. */ - GstBuffer *(*convert) (GstBuffer * buf, gsize * frame_size, + GstBuffer *(*convert) (GstBuffer * in_buf, gsize * frame_size, guint * frames_in, GstTensorsConfig * config); /**< Convert the given input stream to tensor/tensors stream. * @param[in] buf The input stream buffer * @param[out] frame_size The size of each frame (output buffer) * @param[out] frames_in The number of frames in the given input buffer. * @param[out] config tensors config structure to be filled - * @retval Return inbuf if the data is to be kept untouched. + * @retval Return input buffer(in_buf) if the data is to be kept untouched. * @retval Retrun a new GstBuf if the data is to be modified. */ - /** 2. get_caps (type conv, input(media) to output(tensor)) */ - gboolean (*get_caps) (const GstStructure * st, GstTensorConfig * config); + /** 2. get_caps (type conf, input(media) to output(tensor)) */ + gboolean (*get_caps) (const GstStructure * st, GstTensorsConfig * config); /**< Set the tensor config structure from the given stream frame * @param[in] st The input (original/media data) stream's metadata * @param[out] config The output (tensor/tensors) metadata + * @retval Retrun True if get caps successfully, FALSE if not. */ - /** 3. query_cap (tpye conf, output(tensor) to input(media)) */ - GstCaps * (*query_caps) (const GstTensorConfig * config, + /** 3. query_cap (type conf, output(tensor) to input(media)) */ + GstCaps * (*query_caps) (const GstTensorsConfig * config, GstStructure * st); /**< Filters (narrows down) the GstCap (st) with the given config. * @param[in] config The config of output tensor/tensors * @param[in/out] st The gstcap of input to be filtered with config. + * @retval Retrun subplugin default caps */ } NNStreamerExternalConverter; diff --git a/gst/nnstreamer/tensor_converter/tensor_converter.c b/gst/nnstreamer/tensor_converter/tensor_converter.c index 3779c38..459e6f8 100644 --- a/gst/nnstreamer/tensor_converter/tensor_converter.c +++ b/gst/nnstreamer/tensor_converter/tensor_converter.c @@ -30,7 +30,7 @@ * SECTION:element-tensor_converter * * A filter that converts media stream to tensor stream for NN frameworks. - * The output is always in the format of other/tensor. + * The output is always in the format of other/tensor or other/tensors. * * * Example launch line @@ -176,7 +176,8 @@ static GstCaps *gst_tensor_converter_query_caps (GstTensorConverter * self, GstPad * pad, GstCaps * filter); static gboolean gst_tensor_converter_parse_caps (GstTensorConverter * self, const GstCaps * caps); - +static gboolean gst_tensor_converter_update_caps (GstTensorConverter * self, + GstPad * pad, GstTensorsConfig * config); static const NNStreamerExternalConverter *findExternalConverter (const char *media_type_name); static const gchar *getExternalConverterName (const char *name); @@ -454,22 +455,15 @@ gst_tensor_converter_sink_event (GstPad * pad, GstObject * parent, case GST_EVENT_CAPS: { GstCaps *in_caps; - GstCaps *out_caps; gst_event_parse_caps (event, &in_caps); silent_debug_caps (in_caps, "in-caps"); if (gst_tensor_converter_parse_caps (self, in_caps)) { - out_caps = gst_tensor_caps_from_config (&self->tensor_config); - silent_debug_caps (out_caps, "out-caps"); - - gst_pad_set_caps (self->srcpad, out_caps); - + gboolean ret = gst_tensor_converter_update_caps (self, self->srcpad, + &self->tensors_config); gst_event_unref (event); - event = gst_event_new_caps (out_caps); - - gst_caps_unref (out_caps); - return gst_pad_push_event (self->srcpad, event); + return ret; } break; } @@ -599,7 +593,7 @@ gst_tensor_converter_src_query (GstPad * pad, GstObject * parent, /** @brief Chain function's private routine */ static void _gst_tensor_converter_chain_segment (GstTensorConverter * self, - gboolean have_framerate, GstTensorConfig * config, gsize frame_size) + gboolean have_framerate, GstTensorsConfig * config, gsize frame_size) { if (self->need_segment) { GstSegment seg; @@ -627,7 +621,7 @@ _gst_tensor_converter_chain_segment (GstTensorConverter * self, /** @brief Chain function's private routine */ static void _gst_tensor_converter_chain_timestamp (GstTensorConverter * self, - gboolean have_framerate, GstTensorConfig * config, GstBuffer * inbuf, + gboolean have_framerate, GstTensorsConfig * config, GstBuffer * inbuf, GstClockTime * duration, GstClockTime * pts, guint frames_in) { if (self->set_timestamp) { @@ -682,8 +676,7 @@ static GstFlowReturn gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstTensorConverter *self; - GstTensorConfig *config; - GstTensorsConfig tensors_config; + GstTensorsConfig *config; GstAdapter *adapter; GstBuffer *inbuf; gsize avail, buf_size, frame_size, out_size; @@ -691,7 +684,6 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) GstFlowReturn ret = GST_FLOW_OK; GstClockTime pts, dts, duration; gboolean have_framerate; - GstCaps *curr_caps, *peer_caps, *out_caps = NULL; buf_size = gst_buffer_get_size (buf); g_return_val_if_fail (buf_size > 0, GST_FLOW_ERROR); @@ -699,8 +691,8 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) self = GST_TENSOR_CONVERTER (parent); /** This is an internal logic error. */ - g_assert (self->tensor_configured); - config = &self->tensor_config; + g_assert (self->tensors_configured); + config = &self->tensors_config; have_framerate = (config->rate_n > 0 && config->rate_d > 0); @@ -713,10 +705,10 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) guint color, width, height; gsize type; - color = config->info.dimension[0]; - width = config->info.dimension[1]; - height = config->info.dimension[2]; - type = gst_tensor_get_element_size (config->info.type); + color = config->info.info[0].dimension[0]; + width = config->info.info[0].dimension[1]; + height = config->info.info[0].dimension[2]; + type = gst_tensor_get_element_size (config->info.info[0].type); /** colorspace * width * height * type */ frame_size = color * width * height * type; @@ -823,47 +815,29 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) break; case _NNS_MEDIA_PLUGINS: { + GstTensorsConfig new_config; + if (self->externalConverter == NULL || self->externalConverter->convert == NULL) return GST_FLOW_NOT_SUPPORTED; inbuf = self->externalConverter->convert (buf, &frame_size, &frames_in, - &tensors_config); - - self->tensors_config = tensors_config; - if (tensors_config.info.num_tensors == 1) { - GstStructure *st; - - peer_caps = gst_pad_peer_query_caps (self->srcpad, NULL); - silent_debug_caps (peer_caps, "peer caps"); + &new_config); - st = gst_caps_get_structure (peer_caps, 0); - - if (g_strcmp0 (gst_structure_get_name (st), "other/tensor") == 0) { - self->tensor_config.info = tensors_config.info.info[0]; - self->tensor_config.rate_n = tensors_config.rate_n; - self->tensor_config.rate_d = tensors_config.rate_d; - out_caps = gst_tensor_caps_from_config (&self->tensor_config); + if (gst_tensors_config_is_equal (config, &new_config) != TRUE) { + if (gst_tensor_converter_update_caps (self, self->srcpad, + &new_config) == TRUE) { + self->tensors_config = new_config; + } else { + return GST_FLOW_ERROR; } } - /* caps for tensors */ - if (out_caps == NULL) - out_caps = gst_tensors_caps_from_config (&self->tensors_config); - - silent_debug_caps (out_caps, "out-caps"); - - /* Update source pad caps. If it is different */ - curr_caps = gst_pad_get_current_caps (self->srcpad); - if (gst_caps_is_equal (curr_caps, out_caps) != TRUE) { - gst_pad_set_caps (self->srcpad, out_caps); - } g_assert (inbuf != NULL); g_assert (frame_size > 0); - gst_caps_unref (curr_caps); - gst_caps_unref (out_caps); - gst_buffer_unref (buf); + if (inbuf != buf) + gst_buffer_unref (buf); break; } @@ -988,8 +962,8 @@ gst_tensor_converter_reset (GstTensorConverter * self) gst_adapter_clear (self->adapter); } - self->tensor_configured = FALSE; - gst_tensor_config_init (&self->tensor_config); + self->tensors_configured = FALSE; + gst_tensors_config_init (&self->tensors_config); self->have_segment = FALSE; self->need_segment = FALSE; @@ -1049,16 +1023,16 @@ gst_tensor_converter_video_stride (GstVideoFormat format, gint width) } /** - * @brief Set the tensor config structure from video info (internal static function) + * @brief Set the tensors config structure from video info (internal static function) * @param self this pointer to GstTensorConverter - * @param config tensor config structure to be filled + * @param config tensors config structure to be filled * @param info video info structure * @note Change dimension if tensor contains N frames. * @return TRUE if supported type */ static gboolean gst_tensor_converter_parse_video (GstTensorConverter * self, - GstTensorConfig * config, const GstVideoInfo * info) + GstTensorsConfig * config, const GstVideoInfo * info) { /** * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/image @@ -1069,7 +1043,8 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, guint i; g_return_val_if_fail (config != NULL, FALSE); - gst_tensor_config_init (config); + gst_tensors_config_init (config); + config->info.num_tensors = 1; g_return_val_if_fail (info != NULL, FALSE); @@ -1078,13 +1053,13 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, /* [color-space][width][height][frames] */ switch (format) { case GST_VIDEO_FORMAT_GRAY8: - config->info.type = _NNS_UINT8; - config->info.dimension[0] = 1; + config->info.info[0].type = _NNS_UINT8; + config->info.info[0].dimension[0] = 1; break; case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_BGR: - config->info.type = _NNS_UINT8; - config->info.dimension[0] = 3; + config->info.info[0].type = _NNS_UINT8; + config->info.info[0].dimension[0] = 3; break; case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_BGRx: @@ -1094,8 +1069,8 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ABGR: - config->info.type = _NNS_UINT8; - config->info.dimension[0] = 4; + config->info.info[0].type = _NNS_UINT8; + config->info.info[0].dimension[0] = 4; break; default: /* unsupported format */ @@ -1104,31 +1079,31 @@ gst_tensor_converter_parse_video (GstTensorConverter * self, break; } - config->info.dimension[1] = GST_VIDEO_INFO_WIDTH (info); - config->info.dimension[2] = GST_VIDEO_INFO_HEIGHT (info); + config->info.info[0].dimension[1] = GST_VIDEO_INFO_WIDTH (info); + config->info.info[0].dimension[2] = GST_VIDEO_INFO_HEIGHT (info); /* Supposed 1 frame in tensor, change dimension[3] if tensor contains N frames. */ for (i = 3; i < NNS_TENSOR_RANK_LIMIT; i++) { - config->info.dimension[i] = 1; + config->info.info[0].dimension[i] = 1; } config->rate_n = GST_VIDEO_INFO_FPS_N (info); config->rate_d = GST_VIDEO_INFO_FPS_D (info); - return (config->info.type != _NNS_END); + return (config->info.info[0].type != _NNS_END); } /** - * @brief Set the tensor config structure from audio info (internal static function) + * @brief Set the tensors config structure from audio info (internal static function) * @param self this pointer to GstTensorConverter - * @param config tensor config structure to be filled + * @param config tensors config structure to be filled * @param info audio info structure * @note Change dimension if tensor contains N frames. * @return TRUE if supported type */ static gboolean gst_tensor_converter_parse_audio (GstTensorConverter * self, - GstTensorConfig * config, const GstAudioInfo * info) + GstTensorsConfig * config, const GstAudioInfo * info) { /** * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/audio @@ -1139,7 +1114,8 @@ gst_tensor_converter_parse_audio (GstTensorConverter * self, guint i; g_return_val_if_fail (config != NULL, FALSE); - gst_tensor_config_init (config); + gst_tensors_config_init (config); + config->info.num_tensors = 1; g_return_val_if_fail (info != NULL, FALSE); @@ -1148,28 +1124,28 @@ gst_tensor_converter_parse_audio (GstTensorConverter * self, /* [channels][frames] */ switch (format) { case GST_AUDIO_FORMAT_S8: - config->info.type = _NNS_INT8; + config->info.info[0].type = _NNS_INT8; break; case GST_AUDIO_FORMAT_U8: - config->info.type = _NNS_UINT8; + config->info.info[0].type = _NNS_UINT8; break; case GST_AUDIO_FORMAT_S16: - config->info.type = _NNS_INT16; + config->info.info[0].type = _NNS_INT16; break; case GST_AUDIO_FORMAT_U16: - config->info.type = _NNS_UINT16; + config->info.info[0].type = _NNS_UINT16; break; case GST_AUDIO_FORMAT_S32: - config->info.type = _NNS_INT32; + config->info.info[0].type = _NNS_INT32; break; case GST_AUDIO_FORMAT_U32: - config->info.type = _NNS_UINT32; + config->info.info[0].type = _NNS_UINT32; break; case GST_AUDIO_FORMAT_F32: - config->info.type = _NNS_FLOAT32; + config->info.info[0].type = _NNS_FLOAT32; break; case GST_AUDIO_FORMAT_F64: - config->info.type = _NNS_FLOAT64; + config->info.info[0].type = _NNS_FLOAT64; break; default: /* unsupported format */ @@ -1178,30 +1154,30 @@ gst_tensor_converter_parse_audio (GstTensorConverter * self, break; } - config->info.dimension[0] = GST_AUDIO_INFO_CHANNELS (info); + config->info.info[0].dimension[0] = GST_AUDIO_INFO_CHANNELS (info); /* Supposed 1 frame in tensor, change dimension[1] if tensor contains N frames. */ for (i = 1; i < NNS_TENSOR_RANK_LIMIT; i++) { - config->info.dimension[i] = 1; + config->info.info[0].dimension[i] = 1; } config->rate_n = GST_AUDIO_INFO_RATE (info); config->rate_d = 1; - return (config->info.type != _NNS_END); + return (config->info.info[0].type != _NNS_END); } /** - * @brief Set the tensor config structure from text info (internal static function) + * @brief Set the tensors config structure from text info (internal static function) * @param self this pointer to GstTensorConverter - * @param config tensor config structure to be filled + * @param config tensors config structure to be filled * @param structure caps structure - * @note Change dimension if tensor contains N frames. + * @note Change dimension if tensors contains N frames. * @return TRUE if supported type */ static gboolean gst_tensor_converter_parse_text (GstTensorConverter * self, - GstTensorConfig * config, const GstStructure * structure) + GstTensorsConfig * config, const GstStructure * structure) { /** * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/text @@ -1211,14 +1187,15 @@ gst_tensor_converter_parse_text (GstTensorConverter * self, guint i; g_return_val_if_fail (config != NULL, FALSE); - gst_tensor_config_init (config); + gst_tensors_config_init (config); + config->info.num_tensors = 1; g_return_val_if_fail (structure != NULL, FALSE); format_string = gst_structure_get_string (structure, "format"); if (format_string) { if (g_ascii_strcasecmp (format_string, "utf8") == 0) { - config->info.type = _NNS_UINT8; + config->info.info[0].type = _NNS_UINT8; } else { /* unsupported format */ GST_WARNING_OBJECT (self, "Unsupported format = %s\n", format_string); @@ -1227,11 +1204,11 @@ gst_tensor_converter_parse_text (GstTensorConverter * self, /* [size][frames] */ /* Fixed size of string, we cannot get the size from caps. */ - config->info.dimension[0] = 0; + config->info.info[0].dimension[0] = 0; /* Supposed 1 frame in tensor, change dimension[1] if tensor contains N frames. */ for (i = 1; i < NNS_TENSOR_RANK_LIMIT; i++) { - config->info.dimension[i] = 1; + config->info.info[0].dimension[i] = 1; } if (gst_structure_has_field (structure, "framerate")) { @@ -1243,32 +1220,33 @@ gst_tensor_converter_parse_text (GstTensorConverter * self, config->rate_d = 1; } - return (config->info.type != _NNS_END); + return (config->info.info[0].type != _NNS_END); } /** - * @brief Set the tensor config structure from octet stream (internal static function) + * @brief Set the tensors configs structure from octet stream (internal static function) * @param self this pointer to GstTensorConverter - * @param config tensor config structure to be filled + * @param config tensors config structure to be filled * @param structure caps structure - * @note Change tensor dimension and type. + * @note Change tensors dimension and type. * @return TRUE if supported type */ static gboolean gst_tensor_converter_parse_octet (GstTensorConverter * self, - GstTensorConfig * config, const GstStructure * structure) + GstTensorsConfig * config, const GstStructure * structure) { g_return_val_if_fail (config != NULL, FALSE); - gst_tensor_config_init (config); + gst_tensors_config_init (config); + config->info.num_tensors = 1; g_return_val_if_fail (structure != NULL, FALSE); /** * Raw byte-stream (application/octet-stream) - * We cannot get the exact tensor info from caps. - * All tensor info should be updated. + * We cannot get the exact tensors info from caps. + * All tensors info should be updated. */ - config->info.type = _NNS_UINT8; + config->info.info[0].type = _NNS_UINT8; if (gst_structure_has_field (structure, "framerate")) { gst_structure_get_fraction (structure, "framerate", &config->rate_n, @@ -1279,7 +1257,7 @@ gst_tensor_converter_parse_octet (GstTensorConverter * self, config->rate_d = 1; } - return (config->info.type != _NNS_END); + return (config->info.info[0].type != _NNS_END); } /** @@ -1342,14 +1320,14 @@ gst_tensor_converter_get_possible_media_caps (GstTensorConverter * self) silent_debug_caps (peer_caps, "peer caps"); if (gst_caps_get_size (peer_caps) > 0) { - GstTensorConfig config; + GstTensorsConfig config; GstStructure *st; guint i, caps_len; media_type type; - /* get tensor info from peer caps */ + /* get tensors info from peer caps */ st = gst_caps_get_structure (peer_caps, 0); - gst_tensor_config_from_structure (&config, st); + gst_tensors_config_from_structure (&config, st); /* convert peer caps to possible media caps */ caps_len = gst_caps_get_size (media_caps); @@ -1361,11 +1339,12 @@ gst_tensor_converter_get_possible_media_caps (GstTensorConverter * self) switch (type) { case _NNS_VIDEO: /* video caps from tensor info */ - if (is_video_supported (self) && config.info.type == _NNS_UINT8) { + if (is_video_supported (self) + && config.info.info[0].type == _NNS_UINT8) { GValue supported_formats = G_VALUE_INIT; gint colorspace, width, height; - colorspace = config.info.dimension[0]; + colorspace = config.info.info[0].dimension[0]; switch (colorspace) { case 1: gst_tensor_converter_get_format_list (&supported_formats, @@ -1391,11 +1370,11 @@ gst_tensor_converter_get_possible_media_caps (GstTensorConverter * self) } g_value_unset (&supported_formats); - if ((width = config.info.dimension[1]) > 0) { + if ((width = config.info.info[0].dimension[1]) > 0) { gst_structure_set (st, "width", G_TYPE_INT, width, NULL); } - if ((height = config.info.dimension[2]) > 0) { + if ((height = config.info.info[0].dimension[2]) > 0) { gst_structure_set (st, "height", G_TYPE_INT, height, NULL); } @@ -1407,11 +1386,12 @@ gst_tensor_converter_get_possible_media_caps (GstTensorConverter * self) break; case _NNS_AUDIO: /* audio caps from tensor info */ - if (is_audio_supported (self) && config.info.type != _NNS_END) { + if (is_audio_supported (self) + && config.info.info[0].type != _NNS_END) { gint ch, rate; GstAudioFormat aformat; - switch (config.info.type) { + switch (config.info.info[0].type) { case _NNS_INT8: aformat = GST_AUDIO_FORMAT_S8; break; @@ -1446,7 +1426,7 @@ gst_tensor_converter_get_possible_media_caps (GstTensorConverter * self) gst_structure_set (st, "format", G_TYPE_STRING, gst_audio_format_to_string (aformat), NULL); - if ((ch = config.info.dimension[0]) > 0) { + if ((ch = config.info.info[0].dimension[0]) > 0) { gst_structure_set (st, "channels", G_TYPE_INT, ch, NULL); } @@ -1516,16 +1496,16 @@ gst_tensor_converter_query_caps (GstTensorConverter * self, GstPad * pad, } /** - * @brief Parse caps and set tensor info. + * @brief Parse caps and set tensors info. */ static gboolean gst_tensor_converter_parse_caps (GstTensorConverter * self, const GstCaps * caps) { GstStructure *structure; - GstTensorConfig config; + GstTensorsConfig config; media_type in_type; - gint frames_dim = -1; /** dimension index of frames in configured tensor */ + gint frames_dim = -1; /** dimension index of frames in configured tensors */ g_return_val_if_fail (caps != NULL, FALSE); g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE); @@ -1614,15 +1594,15 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self, return FALSE; } - config.info.dimension[0] = self->tensor_info.dimension[0]; + config.info.info[0].dimension[0] = self->tensor_info.dimension[0]; frames_dim = 1; - self->frame_size = gst_tensor_info_get_size (&config.info); + self->frame_size = gst_tensor_info_get_size (&config.info.info[0]); break; } case _NNS_OCTET: { if (!gst_tensor_converter_parse_octet (self, &config, structure)) { - GST_ERROR_OBJECT (self, "Failed to configure tensor from octet info."); + GST_ERROR_OBJECT (self, "Failed to configure tensors from octet info."); return FALSE; } @@ -1637,8 +1617,8 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self, return FALSE; } - config.info = self->tensor_info; - self->frame_size = gst_tensor_info_get_size (&config.info); + config.info.info[0] = self->tensor_info; + self->frame_size = gst_tensor_info_get_size (&config.info.info[0]); break; } default: @@ -1660,7 +1640,7 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self, if (NULL == ex->get_caps || !ex->get_caps (structure, &config)) { GST_ERROR_OBJECT (self, - "Failed to get tensor info from %s. Check the given options.", + "Failed to get tensors info from %s. Check the given options.", ext_conv_name); ml_loge ("Please set the options property correctly.\n"); self->externalConverter = NULL; @@ -1676,26 +1656,73 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self, /** set the number of frames in dimension */ if (frames_dim >= 0) { - config.info.dimension[frames_dim] = self->frames_per_tensor; + config.info.info[0].dimension[frames_dim] = self->frames_per_tensor; } - if (!gst_tensor_config_validate (&config)) { + if (!gst_tensors_config_validate (&config)) { /** not fully configured */ - GST_ERROR_OBJECT (self, "Failed to configure tensor info.\n"); + GST_ERROR_OBJECT (self, "Failed to configure tensors info.\n"); return FALSE; } - if (gst_tensor_info_validate (&self->tensor_info)) { /** compare tensor info */ - if (!gst_tensor_info_is_equal (&self->tensor_info, &config.info)) { + if (!gst_tensor_info_is_equal (&self->tensor_info, &config.info.info[0])) { GST_ERROR_OBJECT (self, "Failed, mismatched tensor info.\n"); return FALSE; } } self->in_media_type = in_type; - self->tensor_configured = TRUE; - self->tensor_config = config; + self->tensors_configured = TRUE; + self->tensors_config = config; + return TRUE; +} + +/** + * @brief Update pas caps from tensors config + */ +static gboolean +gst_tensor_converter_update_caps (GstTensorConverter * self, + GstPad * pad, GstTensorsConfig * config) +{ + GstStructure *st; + GstCaps *curr_caps, *out_caps = NULL; + + if (config->info.num_tensors == 1) { + GstCaps *peer_caps = gst_pad_peer_query_caps (pad, NULL); + silent_debug_caps (peer_caps, "peer caps"); + + if (peer_caps != NULL) { + st = gst_caps_get_structure (peer_caps, 0); + + if (g_strcmp0 (gst_structure_get_name (st), "other/tensor") == 0) { + GstTensorConfig tensor_config; + + tensor_config.info = config->info.info[0]; + tensor_config.rate_n = config->rate_n; + tensor_config.rate_d = config->rate_d; + out_caps = gst_tensor_caps_from_config (&tensor_config); + } + gst_caps_unref (peer_caps); + } else { + GST_WARNING_OBJECT (self, "Failed to get peer caps \n"); + return FALSE; + } + } + + /* caps for tensors */ + if (out_caps == NULL) + out_caps = gst_tensors_caps_from_config (config); + silent_debug_caps (out_caps, "out-caps"); + + /* Update pad caps. If it is different */ + curr_caps = gst_pad_get_current_caps (pad); + if (gst_caps_is_equal (curr_caps, out_caps) != TRUE) { + gst_pad_set_caps (pad, out_caps); + } + gst_caps_unref (out_caps); + gst_caps_unref (curr_caps); + return TRUE; } diff --git a/gst/nnstreamer/tensor_converter/tensor_converter.h b/gst/nnstreamer/tensor_converter/tensor_converter.h index 343b2bc..25483d4 100644 --- a/gst/nnstreamer/tensor_converter/tensor_converter.h +++ b/gst/nnstreamer/tensor_converter/tensor_converter.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include "nnstreamer_plugin_api_converter.h" G_BEGIN_DECLS @@ -78,8 +78,7 @@ struct _GstTensorConverter gsize frame_size; /**< size of one frame */ gboolean remove_padding; /**< If true, zero-padding must be removed */ - gboolean tensor_configured; /**< True if already successfully configured tensor metadata */ - GstTensorConfig tensor_config; /**< output tensor info */ + gboolean tensors_configured; /**< True if already successfully configured tensors metadata */ GstTensorsConfig tensors_config; /**< output tensors info */ gboolean have_segment; /**< True if received segment */ -- 2.7.4