From: jijoong.moon Date: Thu, 1 Nov 2018 22:47:15 +0000 (+0900) Subject: [Merge/Mux] Extract Common Functions & Data Type X-Git-Tag: v0.0.3~141 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=191ce346a544c6ca4087deb8d52f5cd67e92e81b;p=platform%2Fupstream%2Fnnstreamer.git [Merge/Mux] Extract Common Functions & Data Type There are duplicated function call such as gst_tensor_mux(merge)_collect_buffer(). It could be extracted and rewrite as common function. Also there is duplicated structure definition called GstTensorMux(Merge)PadData. It is placed in tensor_common.h. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: jijoong.moon --- diff --git a/gst/nnstreamer/tensor_common.c b/gst/nnstreamer/tensor_common.c index f178f3f..bba74a7 100644 --- a/gst/nnstreamer/tensor_common.c +++ b/gst/nnstreamer/tensor_common.c @@ -1108,3 +1108,147 @@ gst_tensors_typefind_function (GstTypeFind * tf, gpointer pdata) gst_caps_new_simple ("other/tensorsave", NULL, NULL)); } } + +/** + * @brief A function call to decide current timestamp among collected pads based on PTS. + * It will decide current timestamp according to synch option. + */ +gboolean +gst_tensor_set_current_time (GstCollectPads * collect, + GstClockTime * current_time, tensor_time_synch_mode synch) +{ + GSList *walk = NULL; + walk = collect->data; + gboolean isEOS = FALSE; + + while (walk) { + GstCollectData *data = (GstCollectData *) walk->data; + walk = g_slist_next (walk); + GstBuffer *buf = NULL; + buf = gst_collect_pads_peek (collect, data); + + if (buf == NULL) { + isEOS = TRUE; + return isEOS; + } + + switch (synch) { + case SYNCH_SLOWEST: + if (*current_time < GST_BUFFER_PTS (buf)) + *current_time = GST_BUFFER_PTS (buf); + gst_buffer_unref (buf); + break; + case SYNCH_BASEPAD: + break; + default: + break; + } + } + + return isEOS; +} + +/** + * @brief A function call to make tensors from collected pads. + * It decide which buffer is going to be used according to synch option. + */ +gboolean +gst_gen_tensors_from_collectpad (GstCollectPads * collect, + tensor_time_synch_mode synch, GstClockTime current_time, + gboolean * need_buffer, GstBuffer * tensors_buf, GstTensorsConfig * configs) +{ + GSList *walk = NULL; + GstMemory *mem; + gboolean isEOS = FALSE; + gint old_numerator = G_MAXINT; + gint old_denominator = G_MAXINT; + gint counting = 0; + GstTensorConfig config; + + walk = collect->data; + while (walk) { + GstCollectData *data = (GstCollectData *) walk->data; + GstTensorCollectPadData *pad = (GstTensorCollectPadData *) data; + GstCaps *caps = gst_pad_get_current_caps (pad->pad); + GstStructure *s = gst_caps_get_structure (caps, 0); + + gst_tensor_config_from_structure (&config, s); + g_assert (gst_tensor_config_validate (&config)); + + if (config.rate_d < old_denominator) + old_denominator = config.rate_d; + if (config.rate_n < old_numerator) + old_numerator = config.rate_n; + + gst_caps_unref (caps); + + walk = g_slist_next (walk); + + GstBuffer *buf = NULL; + + buf = gst_collect_pads_peek (collect, data); + + if (buf == NULL && pad->buffer == NULL) { + isEOS = TRUE; + return isEOS; + } + + switch (synch) { + case SYNCH_SLOWEST: + { + if (buf != NULL) { + if (GST_BUFFER_PTS (buf) < current_time) { + gst_buffer_unref (buf); + if (pad->buffer != NULL) + gst_buffer_unref (pad->buffer); + pad->buffer = gst_collect_pads_pop (collect, data); + *need_buffer = TRUE; + return FALSE; + } + + if (pad->buffer != NULL && + (ABS (GST_CLOCK_DIFF (current_time, + GST_BUFFER_PTS (pad->buffer))) < + ABS (GST_CLOCK_DIFF (current_time, GST_BUFFER_PTS (buf))))) { + gst_buffer_unref (buf); + buf = pad->buffer; + } else { + gst_buffer_unref (buf); + buf = gst_collect_pads_pop (collect, data); + if (pad->buffer != NULL) + gst_buffer_unref (pad->buffer); + pad->buffer = buf; + } + } else { + buf = pad->buffer; + } + + } + break; + default: + gst_buffer_unref (buf); + buf = gst_collect_pads_pop (collect, data); + } + + if (GST_IS_BUFFER (buf)) { + mem = gst_buffer_get_memory (buf, 0); + gst_buffer_append_memory (tensors_buf, mem); + + if (synch == SYNCH_NOSYNCH) + gst_buffer_unref (buf); + else + pad->buffer = buf; + } else { + isEOS = TRUE; + } + + configs->info.info[counting] = config.info; + counting++; + } + + configs->rate_d = old_denominator; + configs->rate_n = old_numerator; + + GST_BUFFER_PTS (tensors_buf) = current_time; + return isEOS; +} diff --git a/gst/nnstreamer/tensor_common.h b/gst/nnstreamer/tensor_common.h index aa26c2d..58bb88c 100644 --- a/gst/nnstreamer/tensor_common.h +++ b/gst/nnstreamer/tensor_common.h @@ -31,6 +31,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -146,6 +147,30 @@ typedef struct } GstTensorsConfig; /** + * @brief time synchronization options + */ + +typedef enum +{ + SYNCH_NOSYNCH = 0, + SYNCH_SLOWEST = 1, + SYNCH_BASEPAD = 2, + SYNCH_END, +} tensor_time_synch_mode; + +/** + * @brief Internal data structure for Collect Pad in mux / merge + */ +typedef struct +{ + GstCollectData collect; + GstClockTime pts_timestamp; + GstClockTime dts_timestamp; + GstBuffer *buffer; + GstPad *pad; +} GstTensorCollectPadData; + +/** * @brief String representations for each tensor element type. */ extern const gchar *tensor_element_typename[]; @@ -398,5 +423,29 @@ extern void gst_tensors_typefind_function (GstTypeFind * tf, gpointer pdata); static gboolean G_PASTE(G_PASTE(gst_, name), _plugin_init) (GstPlugin * plugin) #endif + +/** + * @brief A function call to decide current timestamp among collected pads based on PTS. + * It will decide current timestamp according to synch option. + * @return True / False if EOS, it return TRUE. + * @param collect Collect pad. + * @param current_time Current time + * @param synch Synchronization Option (NOSYNCH, SLOWEST, BASEPAD, END) + */ +extern gboolean gst_tensor_set_current_time(GstCollectPads *collect, GstClockTime *current_time, tensor_time_synch_mode synch); + +/** + * @brief A function call to make tensors from collected pads + * It decide which buffer is going to be used according to synch option. + * @return True / False if EOS, it return TRUE. + * @param collect Collect pad. + * @param synch Synchronization Option (NOSYNCH, SLOWEST, BASEPAD, END) + * @param current_time Current Timestamp + * @param need_buffer Boolean for Update Collect Pads + * @param tensors_buf Generated GstBuffer for Collected Buffer + * @param configs Configuration Info for Collected Buffer + */ +extern gboolean gst_gen_tensors_from_collectpad (GstCollectPads * collect, tensor_time_synch_mode synch, GstClockTime current_time, gboolean *need_buffer, GstBuffer *tensors_buf, GstTensorsConfig *configs); + G_END_DECLS #endif /* __GST_TENSOR_COMMON_H__ */ diff --git a/gst/tensor_merge/gsttensormerge.c b/gst/tensor_merge/gsttensormerge.c index 5d2b801..e3b5bbf 100644 --- a/gst/tensor_merge/gsttensormerge.c +++ b/gst/tensor_merge/gsttensormerge.c @@ -294,11 +294,11 @@ gst_tensor_merge_request_new_pad (GstElement * element, GstPadTemplate * templ, if (newpad) { - GstTensorMergePadData *tensormergepad; + GstTensorCollectPadData *tensormergepad; - tensormergepad = (GstTensorMergePadData *) + tensormergepad = (GstTensorCollectPadData *) gst_collect_pads_add_pad (tensor_merge->collect, newpad, - sizeof (GstTensorMergePadData), NULL, TRUE); + sizeof (GstTensorCollectPadData), NULL, TRUE); tensormergepad->pad = newpad; gst_pad_set_element_private (newpad, tensormergepad); @@ -352,44 +352,6 @@ gst_tensor_merge_sink_event (GstCollectPads * pads, GstCollectData * data, } /** - * @brief Compare dts & pts time and find earliest - * @param tensor_merge tensor merger - * @param old_data previous merge pad data - * @param new_data current merge pad data - * @return if > 0, new is earlier than old - */ -static gint -gst_tensor_merge_compare_pads (GstTensorMerge * tensor_merge, - GstTensorMergePadData * old_data, GstTensorMergePadData * new_data) -{ - guint64 oldtime, newtime; - if (old_data == NULL) - return 1; - if (new_data == NULL) - return -1; - if (GST_CLOCK_TIME_IS_VALID (old_data->dts_timestamp) && - GST_CLOCK_TIME_IS_VALID (new_data->dts_timestamp)) { - oldtime = old_data->dts_timestamp; - newtime = new_data->dts_timestamp; - } else { - oldtime = old_data->pts_timestamp; - newtime = new_data->pts_timestamp; - } - - if (!GST_CLOCK_TIME_IS_VALID (oldtime)) - return -1; - if (!GST_CLOCK_TIME_IS_VALID (newtime)) - return 1; - - if (newtime < oldtime) - return 1; - else if (newtime > oldtime) - return -1; - - return 0; -} - -/** * @brief Generate TensorConfig with TensorsConfig * @param tensor_merge tensor merger * @param configs Tensors Config Data @@ -453,125 +415,30 @@ static gboolean gst_tensor_merge_collect_buffer (GstTensorMerge * tensor_merge, GstBuffer * tensors_buf, GstClockTime * pts_time, GstClockTime * dts_time) { - GSList *walk = NULL; - GstTensorMergePadData *bestpad = NULL; - GstMemory *mem; gboolean isEOS = FALSE; - gint old_numerator = G_MAXINT; - gint old_denominator = G_MAXINT; - gint counting = 0; - GstTensorConfig config; - - walk = tensor_merge->collect->data; - + int synch_option = 0; + if (tensor_merge->synch) + synch_option = SYNCH_SLOWEST; + /* TODO Should set synch option properly. Currently SLOWEST is default */ if (tensor_merge->synch && tensor_merge->need_set_time) { - while (walk) { - GstCollectData *data = (GstCollectData *) walk->data; - walk = g_slist_next (walk); - - GstBuffer *buf = NULL; - - buf = gst_collect_pads_peek (tensor_merge->collect, data); + if (gst_tensor_set_current_time (tensor_merge->collect, + &tensor_merge->current_time, synch_option)) + return TRUE; - if (buf == NULL) - return TRUE; - - if (tensor_merge->current_time < GST_BUFFER_PTS (buf)) - tensor_merge->current_time = GST_BUFFER_PTS (buf); - gst_buffer_unref (buf); - } tensor_merge->need_set_time = FALSE; } + /* TODO Should set synch option properly. Currently SLOWEST is default */ + isEOS = + gst_gen_tensors_from_collectpad (tensor_merge->collect, synch_option, + tensor_merge->current_time, &tensor_merge->need_buffer, tensors_buf, + &tensor_merge->tensors_config); - walk = tensor_merge->collect->data; - - while (walk) { - GstCollectData *data = (GstCollectData *) walk->data; - GstTensorMergePadData *pad = (GstTensorMergePadData *) data; - GstCaps *caps = gst_pad_get_current_caps (pad->pad); - GstStructure *s = gst_caps_get_structure (caps, 0); - - gst_tensor_config_from_structure (&config, s); - g_assert (gst_tensor_config_validate (&config)); - - if (config.rate_d < old_denominator) - old_denominator = config.rate_d; - if (config.rate_n < old_numerator) - old_numerator = config.rate_n; - - gst_caps_unref (caps); - - walk = g_slist_next (walk); - - GstBuffer *buf = NULL; - - if (tensor_merge->synch) { - buf = gst_collect_pads_peek (tensor_merge->collect, data); - - if (buf == NULL && pad->buffer == NULL) - return TRUE; - - if (buf != NULL) { - if (GST_BUFFER_PTS (buf) < tensor_merge->current_time) { - gst_buffer_unref (buf); - if (pad->buffer != NULL) - gst_buffer_unref (pad->buffer); - pad->buffer = gst_collect_pads_pop (tensor_merge->collect, data); - silent_debug ("Fame Dropped : %lu", GST_BUFFER_PTS (pad->buffer)); - tensor_merge->need_buffer = TRUE; - return FALSE; - } - - if (pad->buffer != NULL && - (ABS (GST_CLOCK_DIFF (tensor_merge->current_time, - GST_BUFFER_PTS (pad->buffer))) < - ABS (GST_CLOCK_DIFF (tensor_merge->current_time, - GST_BUFFER_PTS (buf))))) { - gst_buffer_unref (buf); - buf = pad->buffer; - } else { - gst_buffer_unref (buf); - buf = gst_collect_pads_pop (tensor_merge->collect, data); - if (pad->buffer != NULL) - gst_buffer_unref (pad->buffer); - pad->buffer = buf; - } - } else { - buf = pad->buffer; - } - } else { - buf = gst_collect_pads_pop (tensor_merge->collect, data); - } - - if (GST_IS_BUFFER (buf)) { - mem = gst_buffer_get_memory (buf, 0); - gst_buffer_append_memory (tensors_buf, mem); - pad->buffer = buf; - silent_debug ("Append Memory # %d (PTS : %lu)", - gst_buffer_n_memory (tensors_buf), GST_BUFFER_PTS (buf)); - - if (gst_tensor_merge_compare_pads (tensor_merge, bestpad, pad) > 0) { - bestpad = pad; - *pts_time = bestpad->pts_timestamp; - *dts_time = bestpad->dts_timestamp; - } - - if (!tensor_merge->synch) - gst_buffer_unref (buf); - } else { - isEOS = TRUE; - } - - tensor_merge->tensors_config.info.info[counting] = config.info; - counting++; - } + if (tensor_merge->need_buffer) + return FALSE; - tensor_merge->tensors_config.rate_d = old_denominator; - tensor_merge->tensors_config.rate_n = old_numerator; + *pts_time = GST_BUFFER_PTS (tensors_buf); + *dts_time = GST_BUFFER_DTS (tensors_buf); - /* set timestamp */ - GST_BUFFER_PTS (tensors_buf) = *pts_time; - GST_BUFFER_DTS (tensors_buf) = *dts_time; return isEOS; } diff --git a/gst/tensor_merge/gsttensormerge.h b/gst/tensor_merge/gsttensormerge.h index 2e7f26a..3f1d20f 100644 --- a/gst/tensor_merge/gsttensormerge.h +++ b/gst/tensor_merge/gsttensormerge.h @@ -29,7 +29,6 @@ #define __GST_TENSOR_MERGE_H__ #include -#include #include G_BEGIN_DECLS @@ -66,16 +65,6 @@ typedef struct _tensor_merge_linear { tensor_merge_linear_mode direction; } tensor_merge_linear; - -typedef struct -{ - GstCollectData collect; - GstClockTime pts_timestamp; - GstClockTime dts_timestamp; - GstBuffer *buffer; - GstPad *pad; -} GstTensorMergePadData; - /** * @brief Tensor Merge data structure */ diff --git a/gst/tensor_mux/gsttensormux.c b/gst/tensor_mux/gsttensormux.c index ebc5fe8..7fc80cd 100644 --- a/gst/tensor_mux/gsttensormux.c +++ b/gst/tensor_mux/gsttensormux.c @@ -246,10 +246,10 @@ gst_tensor_mux_request_new_pad (GstElement * element, GstPadTemplate * templ, g_free (name); if (newpad) { - GstTensorMuxPadData *tensormuxpad; - tensormuxpad = - (GstTensorMuxPadData *) gst_collect_pads_add_pad (tensor_mux->collect, - newpad, sizeof (GstTensorMuxPadData), NULL, TRUE); + GstTensorCollectPadData *tensormuxpad; + tensormuxpad = (GstTensorCollectPadData *) + gst_collect_pads_add_pad (tensor_mux->collect, newpad, + sizeof (GstTensorCollectPadData), NULL, TRUE); tensormuxpad->pad = newpad; gst_pad_set_element_private (newpad, tensormuxpad); tensor_mux->tensors_config.info.num_tensors++; @@ -302,44 +302,6 @@ gst_tensor_mux_sink_event (GstCollectPads * pads, GstCollectData * data, } /** - * @brief Compare dts & pts time and find earliest - * @param tensor_mux tensor muxer - * @param old_data previous mux pad data - * @param new_data current mux pad data - * @return if > 0, new is earlier than old - */ -static gint -gst_tensor_mux_compare_pads (GstTensorMux * tensor_mux, - GstTensorMuxPadData * old_data, GstTensorMuxPadData * new_data) -{ - guint64 oldtime, newtime; - if (old_data == NULL) - return 1; - if (new_data == NULL) - return -1; - if (GST_CLOCK_TIME_IS_VALID (old_data->dts_timestamp) && - GST_CLOCK_TIME_IS_VALID (new_data->dts_timestamp)) { - oldtime = old_data->dts_timestamp; - newtime = new_data->dts_timestamp; - } else { - oldtime = old_data->pts_timestamp; - newtime = new_data->pts_timestamp; - } - - if (!GST_CLOCK_TIME_IS_VALID (oldtime)) - return -1; - if (!GST_CLOCK_TIME_IS_VALID (newtime)) - return 1; - - if (newtime < oldtime) - return 1; - else if (newtime > oldtime) - return -1; - - return 0; -} - -/** * @brief Looping to generete outbut buffer for srcpad * @param tensor_mux tensor muxer * @param tensors_buf output buffer for srcpad @@ -351,131 +313,31 @@ static gboolean gst_tensor_mux_collect_buffer (GstTensorMux * tensor_mux, GstBuffer * tensors_buf, GstClockTime * pts_time, GstClockTime * dts_time) { - GSList *walk = NULL; - GstTensorMuxPadData *bestpad = NULL; - GstMemory *mem; gboolean isEOS = FALSE; - gint old_numerator = G_MAXINT; - gint old_denominator = G_MAXINT; - gint counting = 0; - GstTensorConfig config; - - walk = tensor_mux->collect->data; - + int synch_option = 0; + if (tensor_mux->synch) + synch_option = SYNCH_SLOWEST; if (tensor_mux->synch && tensor_mux->need_set_time) { - while (walk) { - GstCollectData *data = (GstCollectData *) walk->data; - walk = g_slist_next (walk); - - GstBuffer *buf = NULL; - buf = gst_collect_pads_peek (tensor_mux->collect, data); - - if (buf == NULL) - return TRUE; - - if (tensor_mux->current_time < GST_BUFFER_PTS (buf)) - tensor_mux->current_time = GST_BUFFER_PTS (buf); - gst_buffer_unref (buf); - } + /* TODO Should set synch option properly. Currently SLOWEST is default */ + if (gst_tensor_set_current_time (tensor_mux->collect, + &tensor_mux->current_time, synch_option)) + return TRUE; tensor_mux->need_set_time = FALSE; silent_debug ("Current Time : %lu", tensor_mux->current_time); } - walk = tensor_mux->collect->data; - - while (walk) { - GstCollectData *data = (GstCollectData *) walk->data; - GstTensorMuxPadData *pad = (GstTensorMuxPadData *) data; - GstCaps *caps = gst_pad_get_current_caps (pad->pad); - GstStructure *s = gst_caps_get_structure (caps, 0); - - gst_tensor_config_from_structure (&config, s); - g_assert (gst_tensor_config_validate (&config)); - - if (config.rate_d < old_denominator) - old_denominator = config.rate_d; - if (config.rate_n < old_numerator) - old_numerator = config.rate_n; - - gst_caps_unref (caps); - - walk = g_slist_next (walk); - - GstBuffer *buf = NULL; - - if (tensor_mux->synch) { - buf = gst_collect_pads_peek (tensor_mux->collect, data); - if (buf == NULL && pad->buffer == NULL) - return TRUE; - - if (buf != NULL) { - if (GST_BUFFER_PTS (buf) < tensor_mux->current_time) { - gst_buffer_unref (buf); - if (pad->buffer != NULL) - gst_buffer_unref (pad->buffer); - pad->buffer = gst_collect_pads_pop (tensor_mux->collect, data); - silent_debug ("Fame Dropped (# %d) : %lu", counting, - GST_BUFFER_PTS (pad->buffer)); - tensor_mux->need_buffer = TRUE; - return FALSE; - } - - if (pad->buffer != NULL && - (ABS (GST_CLOCK_DIFF (tensor_mux->current_time, - GST_BUFFER_PTS (pad->buffer))) < - ABS (GST_CLOCK_DIFF (tensor_mux->current_time, - GST_BUFFER_PTS (buf))))) { - gst_buffer_unref (buf); - buf = pad->buffer; - } else { - gst_buffer_unref (buf); - buf = gst_collect_pads_pop (tensor_mux->collect, data); - if (pad->buffer != NULL) - gst_buffer_unref (pad->buffer); - pad->buffer = buf; - } - } else { - buf = pad->buffer; - } - } else { - buf = gst_collect_pads_pop (tensor_mux->collect, data); - } - - if (GST_IS_BUFFER (buf)) { - mem = gst_buffer_get_memory (buf, 0); - gst_buffer_append_memory (tensors_buf, mem); - pad->buffer = buf; - - silent_debug ("Append Memory # %d (PTS : %lu)", - gst_buffer_n_memory (tensors_buf), GST_BUFFER_PTS (buf)); - - if (gst_tensor_mux_compare_pads (tensor_mux, bestpad, pad) > 0) { - bestpad = pad; - *pts_time = bestpad->pts_timestamp; - *dts_time = bestpad->dts_timestamp; - } - - if (!tensor_mux->synch) - gst_buffer_unref (buf); - } else { - isEOS = TRUE; - } - - tensor_mux->tensors_config.info.info[counting] = config.info; - counting++; - } + /* TODO Should set synch option properly. Currently SLOWEST is default */ + isEOS = + gst_gen_tensors_from_collectpad (tensor_mux->collect, synch_option, + tensor_mux->current_time, &tensor_mux->need_buffer, tensors_buf, + &tensor_mux->tensors_config); - tensor_mux->tensors_config.rate_d = old_denominator; - tensor_mux->tensors_config.rate_n = old_numerator; + if (tensor_mux->need_buffer) + return FALSE; - debug_print (!tensor_mux->silent, "pts %" GST_TIME_FORMAT, - GST_TIME_ARGS (*pts_time)); - debug_print (!tensor_mux->silent, "dts %" GST_TIME_FORMAT, - GST_TIME_ARGS (*dts_time)); + *pts_time = GST_BUFFER_PTS (tensors_buf); + *dts_time = GST_BUFFER_DTS (tensors_buf); - /* set timestamp */ - GST_BUFFER_PTS (tensors_buf) = *pts_time; - GST_BUFFER_DTS (tensors_buf) = *dts_time; return isEOS; } diff --git a/gst/tensor_mux/gsttensormux.h b/gst/tensor_mux/gsttensormux.h index f62395d..e19b0d2 100644 --- a/gst/tensor_mux/gsttensormux.h +++ b/gst/tensor_mux/gsttensormux.h @@ -29,7 +29,6 @@ #define __GST_TENSOR_MUX_H__ #include -#include #include G_BEGIN_DECLS @@ -43,17 +42,6 @@ G_BEGIN_DECLS typedef struct _GstTensorMux GstTensorMux; typedef struct _GstTensorMuxClass GstTensorMuxClass; - - -typedef struct -{ - GstCollectData collect; - GstClockTime pts_timestamp; - GstClockTime dts_timestamp; - GstBuffer *buffer; - GstPad *pad; -} GstTensorMuxPadData; - /** * @brief Tensor Muxer data structure */