LCOV - code coverage report
Current view: top level - nnstreamer-2.4.2/gst/nnstreamer/elements - gsttensor_sink.c (source / functions) Coverage Total Hit
Test: nnstreamer 2.4.2-0 nnstreamer/nnstreamer#eca68b8d050408568af95d831a8eef62aaee7784 Lines: 91.1 % 180 164
Test Date: 2025-03-14 05:36:58 Functions: 95.2 % 21 20

            Line data    Source code
       1              : /**
       2              :  * GStreamer
       3              :  * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
       4              :  * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
       5              :  * Copyright (C) 2018 Samsung Electronics Co., Ltd.
       6              :  *
       7              :  * This library is free software; you can redistribute it and/or
       8              :  * modify it under the terms of the GNU Library General Public
       9              :  * License as published by the Free Software Foundation;
      10              :  * version 2.1 of the License.
      11              :  *
      12              :  * This library is distributed in the hope that it will be useful,
      13              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              :  * Library General Public License for more details.
      16              :  */
      17              : 
      18              : /**
      19              :  * SECTION:element-tensor_sink
      20              :  *
      21              :  * Sink element to handle tensor stream
      22              :  *
      23              :  * @file        gsttensor_sink.c
      24              :  * @date        15 June 2018
      25              :  * @brief       GStreamer plugin to handle tensor stream
      26              :  * @see         https://github.com/nnstreamer/nnstreamer
      27              :  * @author      Jaeyun Jung <jy1210.jung@samsung.com>
      28              :  * @bug         No known bugs except for NYI items
      29              :  */
      30              : 
      31              : #ifdef HAVE_CONFIG_H
      32              : #include <config.h>
      33              : #endif
      34              : 
      35              : #include "gsttensor_sink.h"
      36              : 
      37              : /**
      38              :  * @brief Macro for debug mode.
      39              :  */
      40              : #ifndef DBG
      41              : #define DBG (!self->silent)
      42              : #endif
      43              : 
      44              : #define silent_debug_timestamp(self, buf) do { \
      45              :   if (DBG) { \
      46              :     GST_DEBUG_OBJECT (self, "pts = %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (buf))); \
      47              :     GST_DEBUG_OBJECT (self, "dts = %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DTS (buf))); \
      48              :     GST_DEBUG_OBJECT (self, "duration = %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); \
      49              :   } \
      50              : } while (0)
      51              : 
      52              : GST_DEBUG_CATEGORY_STATIC (gst_tensor_sink_debug);
      53              : #define GST_CAT_DEFAULT gst_tensor_sink_debug
      54              : 
      55              : /**
      56              :  * @brief tensor_sink signals.
      57              :  */
      58              : enum
      59              : {
      60              :   SIGNAL_NEW_DATA,
      61              :   SIGNAL_STREAM_START,
      62              :   SIGNAL_EOS,
      63              :   LAST_SIGNAL
      64              : };
      65              : 
      66              : /**
      67              :  * @brief tensor_sink properties.
      68              :  */
      69              : enum
      70              : {
      71              :   PROP_0,
      72              :   PROP_SIGNAL_RATE,
      73              :   PROP_EMIT_SIGNAL,
      74              :   PROP_SILENT
      75              : };
      76              : 
      77              : /**
      78              :  * @brief Flag to emit signals.
      79              :  */
      80              : #define DEFAULT_EMIT_SIGNAL TRUE
      81              : 
      82              : /**
      83              :  * @brief New data signals per second.
      84              :  */
      85              : #define DEFAULT_SIGNAL_RATE 0
      86              : 
      87              : /**
      88              :  * @brief Flag to print minimized log.
      89              :  */
      90              : #define DEFAULT_SILENT TRUE
      91              : 
      92              : /**
      93              :  * @brief Flag for qos event.
      94              :  *
      95              :  * See GstBaseSink::qos property for more details.
      96              :  */
      97              : #define DEFAULT_QOS TRUE
      98              : 
      99              : /**
     100              :  * @brief Flag to synchronize on the clock (Default FALSE).
     101              :  * It may be delayed with tensor_filter element, to invoke neural network model.
     102              :  * See GstBaseSink::sync property for more details.
     103              :  */
     104              : #define DEFAULT_SYNC FALSE
     105              : 
     106              : /**
     107              :  * @brief Variable for signal ids.
     108              :  */
     109              : static guint _tensor_sink_signals[LAST_SIGNAL] = { 0 };
     110              : 
     111              : /** GObject method implementation */
     112              : static void gst_tensor_sink_set_property (GObject * object, guint prop_id,
     113              :     const GValue * value, GParamSpec * pspec);
     114              : static void gst_tensor_sink_get_property (GObject * object, guint prop_id,
     115              :     GValue * value, GParamSpec * pspec);
     116              : static void gst_tensor_sink_finalize (GObject * object);
     117              : 
     118              : /** GstBaseSink method implementation */
     119              : static gboolean gst_tensor_sink_event (GstBaseSink * sink, GstEvent * event);
     120              : static gboolean gst_tensor_sink_query (GstBaseSink * sink, GstQuery * query);
     121              : static GstFlowReturn gst_tensor_sink_render (GstBaseSink * sink,
     122              :     GstBuffer * buffer);
     123              : static GstFlowReturn gst_tensor_sink_render_list (GstBaseSink * sink,
     124              :     GstBufferList * buffer_list);
     125              : 
     126              : /** internal functions */
     127              : static void gst_tensor_sink_render_buffer (GstTensorSink * self,
     128              :     GstBuffer * buffer);
     129              : static void gst_tensor_sink_set_last_render_time (GstTensorSink * self,
     130              :     GstClockTime now);
     131              : static GstClockTime gst_tensor_sink_get_last_render_time (GstTensorSink * self);
     132              : static void gst_tensor_sink_set_signal_rate (GstTensorSink * self, guint rate);
     133              : static guint gst_tensor_sink_get_signal_rate (GstTensorSink * self);
     134              : static void gst_tensor_sink_set_emit_signal (GstTensorSink * self,
     135              :     gboolean emit);
     136              : static gboolean gst_tensor_sink_get_emit_signal (GstTensorSink * self);
     137              : static void gst_tensor_sink_set_silent (GstTensorSink * self, gboolean silent);
     138              : static gboolean gst_tensor_sink_get_silent (GstTensorSink * self);
     139              : 
     140              : #define gst_tensor_sink_parent_class parent_class
     141        38339 : G_DEFINE_TYPE (GstTensorSink, gst_tensor_sink, GST_TYPE_BASE_SINK);
     142              : 
     143              : /**
     144              :  * @brief Initialize tensor_sink class.
     145              :  */
     146              : static void
     147           19 : gst_tensor_sink_class_init (GstTensorSinkClass * klass)
     148              : {
     149              :   GObjectClass *gobject_class;
     150              :   GstElementClass *element_class;
     151              :   GstBaseSinkClass *bsink_class;
     152              :   GstPadTemplate *pad_template;
     153              :   GstCaps *pad_caps;
     154              : 
     155           19 :   GST_DEBUG_CATEGORY_INIT (gst_tensor_sink_debug, "tensor_sink", 0,
     156              :       "Sink element to handle tensor stream");
     157              : 
     158           19 :   gobject_class = G_OBJECT_CLASS (klass);
     159           19 :   element_class = GST_ELEMENT_CLASS (klass);
     160           19 :   bsink_class = GST_BASE_SINK_CLASS (klass);
     161              : 
     162              :   /** GObject methods */
     163           19 :   gobject_class->set_property = gst_tensor_sink_set_property;
     164           19 :   gobject_class->get_property = gst_tensor_sink_get_property;
     165           19 :   gobject_class->finalize = gst_tensor_sink_finalize;
     166              : 
     167              :   /**
     168              :    * GstTensorSink::signal-rate:
     169              :    *
     170              :    * The number of new data signals per second (Default 0 for unlimited, MAX 500)
     171              :    * If signal-rate is larger than 0, GstTensorSink calculates the time to emit a signal with this property.
     172              :    * If set 0 (default value), all the received buffers will be passed to the application.
     173              :    *
     174              :    * Please note that this property does not guarantee the periodic signals.
     175              :    * This means if GstTensorSink cannot get the buffers in time, it will pass all the buffers. (working like default 0)
     176              :    */
     177           19 :   g_object_class_install_property (gobject_class, PROP_SIGNAL_RATE,
     178              :       g_param_spec_uint ("signal-rate", "Signal rate",
     179              :           "New data signals per second (0 for unlimited, max 500)", 0, 500,
     180              :           DEFAULT_SIGNAL_RATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     181              : 
     182              :   /**
     183              :    * GstTensorSink::emit-signal:
     184              :    *
     185              :    * The flag to emit the signals for new data, stream start, and eos.
     186              :    */
     187           19 :   g_object_class_install_property (gobject_class, PROP_EMIT_SIGNAL,
     188              :       g_param_spec_boolean ("emit-signal", "Emit signal",
     189              :           "Emit signal for new data, stream start, eos", DEFAULT_EMIT_SIGNAL,
     190              :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     191              : 
     192              :   /**
     193              :    * GstTensorSink::silent:
     194              :    *
     195              :    * The flag to enable/disable debugging messages.
     196              :    */
     197           19 :   g_object_class_install_property (gobject_class, PROP_SILENT,
     198              :       g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
     199              :           DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     200              : 
     201              :   /**
     202              :    * GstTensorSink::new-data:
     203              :    *
     204              :    * Signal to get the buffer from GstTensorSink.
     205              :    */
     206           19 :   _tensor_sink_signals[SIGNAL_NEW_DATA] =
     207           19 :       g_signal_new ("new-data", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
     208              :       G_STRUCT_OFFSET (GstTensorSinkClass, new_data), NULL, NULL, NULL,
     209              :       G_TYPE_NONE, 1, GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
     210              : 
     211              :   /**
     212              :    * GstTensorSink::stream-start:
     213              :    *
     214              :    * Signal to indicate the start of a new stream.
     215              :    * Optional. An application can use this signal to detect the start of a new stream, instead of the message GST_MESSAGE_STREAM_START from pipeline.
     216              :    */
     217           19 :   _tensor_sink_signals[SIGNAL_STREAM_START] =
     218           19 :       g_signal_new ("stream-start", G_TYPE_FROM_CLASS (klass),
     219              :       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTensorSinkClass, stream_start),
     220              :       NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE);
     221              : 
     222              :   /**
     223              :    * GstTensorSink::eos:
     224              :    *
     225              :    * Signal to indicate the end-of-stream.
     226              :    * Optional. An application can use this signal to detect the EOS (end-of-stream), instead of the message GST_MESSAGE_EOS from pipeline.
     227              :    */
     228           19 :   _tensor_sink_signals[SIGNAL_EOS] =
     229           19 :       g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
     230              :       G_STRUCT_OFFSET (GstTensorSinkClass, eos), NULL, NULL, NULL,
     231              :       G_TYPE_NONE, 0, G_TYPE_NONE);
     232              : 
     233           19 :   gst_element_class_set_static_metadata (element_class,
     234              :       "TensorSink",
     235              :       "Sink/Tensor",
     236              :       "Sink element to handle tensor stream", "Samsung Electronics Co., Ltd.");
     237              : 
     238              :   /** pad template */
     239           19 :   pad_caps = gst_caps_from_string (GST_TENSOR_CAP_DEFAULT ";"
     240              :       GST_TENSORS_CAP_MAKE ("{ static, flexible, sparse }"));
     241           19 :   pad_template = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
     242              :       pad_caps);
     243           19 :   gst_element_class_add_pad_template (element_class, pad_template);
     244           19 :   gst_caps_unref (pad_caps);
     245              : 
     246              :   /** GstBaseSink methods */
     247           19 :   bsink_class->event = GST_DEBUG_FUNCPTR (gst_tensor_sink_event);
     248           19 :   bsink_class->query = GST_DEBUG_FUNCPTR (gst_tensor_sink_query);
     249           19 :   bsink_class->render = GST_DEBUG_FUNCPTR (gst_tensor_sink_render);
     250           19 :   bsink_class->render_list = GST_DEBUG_FUNCPTR (gst_tensor_sink_render_list);
     251           19 : }
     252              : 
     253              : /**
     254              :  * @brief Initialize tensor_sink element.
     255              :  */
     256              : static void
     257          213 : gst_tensor_sink_init (GstTensorSink * self)
     258              : {
     259              :   GstBaseSink *bsink;
     260              : 
     261          213 :   bsink = GST_BASE_SINK (self);
     262              : 
     263          213 :   g_mutex_init (&self->mutex);
     264              : 
     265              :   /** init properties */
     266          213 :   self->silent = DEFAULT_SILENT;
     267          213 :   self->emit_signal = DEFAULT_EMIT_SIGNAL;
     268          213 :   self->signal_rate = DEFAULT_SIGNAL_RATE;
     269          213 :   self->last_render_time = GST_CLOCK_TIME_NONE;
     270              : 
     271              :   /** enable qos */
     272          213 :   gst_base_sink_set_qos_enabled (bsink, DEFAULT_QOS);
     273              : 
     274              :   /* set 'sync' to synchronize on the clock or not */
     275          213 :   gst_base_sink_set_sync (bsink, DEFAULT_SYNC);
     276          213 : }
     277              : 
     278              : /**
     279              :  * @brief Setter for tensor_sink properties.
     280              :  *
     281              :  * GObject method implementation.
     282              :  */
     283              : static void
     284            6 : gst_tensor_sink_set_property (GObject * object, guint prop_id,
     285              :     const GValue * value, GParamSpec * pspec)
     286              : {
     287              :   GstTensorSink *self;
     288              : 
     289            6 :   self = GST_TENSOR_SINK (object);
     290              : 
     291            6 :   switch (prop_id) {
     292            2 :     case PROP_SIGNAL_RATE:
     293            2 :       gst_tensor_sink_set_signal_rate (self, g_value_get_uint (value));
     294            2 :       break;
     295              : 
     296            2 :     case PROP_EMIT_SIGNAL:
     297            2 :       gst_tensor_sink_set_emit_signal (self, g_value_get_boolean (value));
     298            2 :       break;
     299              : 
     300            2 :     case PROP_SILENT:
     301            2 :       gst_tensor_sink_set_silent (self, g_value_get_boolean (value));
     302            2 :       break;
     303              : 
     304            0 :     default:
     305            0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     306            0 :       break;
     307              :   }
     308            6 : }
     309              : 
     310              : /**
     311              :  * @brief Getter for tensor_sink properties.
     312              :  *
     313              :  * GObject method implementation.
     314              :  */
     315              : static void
     316            6 : gst_tensor_sink_get_property (GObject * object, guint prop_id,
     317              :     GValue * value, GParamSpec * pspec)
     318              : {
     319              :   GstTensorSink *self;
     320              : 
     321            6 :   self = GST_TENSOR_SINK (object);
     322              : 
     323            6 :   switch (prop_id) {
     324            2 :     case PROP_SIGNAL_RATE:
     325            2 :       g_value_set_uint (value, gst_tensor_sink_get_signal_rate (self));
     326            2 :       break;
     327              : 
     328            2 :     case PROP_EMIT_SIGNAL:
     329            2 :       g_value_set_boolean (value, gst_tensor_sink_get_emit_signal (self));
     330            2 :       break;
     331              : 
     332            2 :     case PROP_SILENT:
     333            2 :       g_value_set_boolean (value, gst_tensor_sink_get_silent (self));
     334            2 :       break;
     335              : 
     336            0 :     default:
     337            0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     338            0 :       break;
     339              :   }
     340            6 : }
     341              : 
     342              : /**
     343              :  * @brief Function to finalize instance.
     344              :  *
     345              :  * GObject method implementation.
     346              :  */
     347              : static void
     348          178 : gst_tensor_sink_finalize (GObject * object)
     349              : {
     350              :   GstTensorSink *self;
     351              : 
     352          178 :   self = GST_TENSOR_SINK (object);
     353              : 
     354          178 :   g_mutex_clear (&self->mutex);
     355              : 
     356          178 :   G_OBJECT_CLASS (parent_class)->finalize (object);
     357          178 : }
     358              : 
     359              : /**
     360              :  * @brief Handle events.
     361              :  *
     362              :  * GstBaseSink method implementation.
     363              :  */
     364              : static gboolean
     365          631 : gst_tensor_sink_event (GstBaseSink * sink, GstEvent * event)
     366              : {
     367              :   GstTensorSink *self;
     368              :   GstEventType type;
     369              : 
     370          631 :   self = GST_TENSOR_SINK (sink);
     371          631 :   type = GST_EVENT_TYPE (event);
     372              : 
     373          631 :   GST_DEBUG_OBJECT (self, "Received %s event: %" GST_PTR_FORMAT,
     374              :       GST_EVENT_TYPE_NAME (event), event);
     375              : 
     376          631 :   switch (type) {
     377          175 :     case GST_EVENT_STREAM_START:
     378          175 :       if (gst_tensor_sink_get_emit_signal (self)) {
     379          174 :         silent_debug (self, "Emit signal for stream start");
     380              : 
     381          174 :         g_signal_emit (self, _tensor_sink_signals[SIGNAL_STREAM_START], 0);
     382              :       }
     383          175 :       break;
     384              : 
     385          137 :     case GST_EVENT_EOS:
     386          137 :       if (gst_tensor_sink_get_emit_signal (self)) {
     387          136 :         silent_debug (self, "Emit signal for eos");
     388              : 
     389          136 :         g_signal_emit (self, _tensor_sink_signals[SIGNAL_EOS], 0);
     390              :       }
     391          137 :       break;
     392              : 
     393          319 :     default:
     394          319 :       break;
     395              :   }
     396              : 
     397          631 :   return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
     398              : }
     399              : 
     400              : /**
     401              :  * @brief Handle queries.
     402              :  *
     403              :  * GstBaseSink method implementation.
     404              :  */
     405              : static gboolean
     406         1475 : gst_tensor_sink_query (GstBaseSink * sink, GstQuery * query)
     407              : {
     408              :   GstTensorSink *self;
     409              :   GstQueryType type;
     410              :   GstFormat format;
     411              : 
     412         1475 :   self = GST_TENSOR_SINK (sink);
     413         1475 :   type = GST_QUERY_TYPE (query);
     414              : 
     415         1475 :   GST_DEBUG_OBJECT (self, "Received %s query: %" GST_PTR_FORMAT,
     416              :       GST_QUERY_TYPE_NAME (query), query);
     417              : 
     418         1475 :   switch (type) {
     419            0 :     case GST_QUERY_SEEKING:
     420              :       /** tensor sink does not support seeking */
     421            0 :       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
     422            0 :       gst_query_set_seeking (query, format, FALSE, 0, -1);
     423         1475 :       return TRUE;
     424              : 
     425         1475 :     default:
     426         1475 :       break;
     427              :   }
     428              : 
     429         1475 :   return GST_BASE_SINK_CLASS (parent_class)->query (sink, query);
     430              : }
     431              : 
     432              : /**
     433              :  * @brief Handle buffer.
     434              :  *
     435              :  * GstBaseSink method implementation.
     436              :  */
     437              : static GstFlowReturn
     438         6968 : gst_tensor_sink_render (GstBaseSink * sink, GstBuffer * buffer)
     439              : {
     440              :   GstTensorSink *self;
     441              : 
     442         6968 :   self = GST_TENSOR_SINK (sink);
     443         6968 :   gst_tensor_sink_render_buffer (self, buffer);
     444              : 
     445         6968 :   return GST_FLOW_OK;
     446              : }
     447              : 
     448              : /**
     449              :  * @brief Handle list of buffers.
     450              :  *
     451              :  * GstBaseSink method implementation.
     452              :  */
     453              : static GstFlowReturn
     454            0 : gst_tensor_sink_render_list (GstBaseSink * sink, GstBufferList * buffer_list)
     455              : {
     456              :   GstTensorSink *self;
     457              :   GstBuffer *buffer;
     458              :   guint i;
     459              :   guint num_buffers;
     460              : 
     461            0 :   self = GST_TENSOR_SINK (sink);
     462            0 :   num_buffers = gst_buffer_list_length (buffer_list);
     463              : 
     464            0 :   for (i = 0; i < num_buffers; i++) {
     465            0 :     buffer = gst_buffer_list_get (buffer_list, i);
     466            0 :     gst_tensor_sink_render_buffer (self, buffer);
     467              :   }
     468              : 
     469            0 :   return GST_FLOW_OK;
     470              : }
     471              : 
     472              : /**
     473              :  * @brief Handle buffer data.
     474              :  * @return None
     475              :  * @param self pointer to GstTensorSink
     476              :  * @param buffer pointer to GstBuffer to be handled
     477              :  */
     478              : static void
     479         6968 : gst_tensor_sink_render_buffer (GstTensorSink * self, GstBuffer * buffer)
     480              : {
     481         6968 :   GstClockTime now = GST_CLOCK_TIME_NONE;
     482              :   guint signal_rate;
     483         6968 :   gboolean notify = FALSE;
     484              : 
     485         6968 :   g_return_if_fail (GST_IS_TENSOR_SINK (self));
     486              : 
     487         6968 :   signal_rate = gst_tensor_sink_get_signal_rate (self);
     488              : 
     489         6968 :   if (signal_rate) {
     490              :     GstClock *clock;
     491              :     GstClockTime render_time;
     492              :     GstClockTime last_render_time;
     493              : 
     494            6 :     clock = gst_element_get_clock (GST_ELEMENT (self));
     495              : 
     496            6 :     if (clock) {
     497            6 :       now = gst_clock_get_time (clock);
     498            6 :       last_render_time = gst_tensor_sink_get_last_render_time (self);
     499              : 
     500              :       /** time for next signal */
     501            6 :       render_time = (1000 / signal_rate) * GST_MSECOND + last_render_time;
     502              : 
     503            6 :       if (!GST_CLOCK_TIME_IS_VALID (last_render_time) ||
     504            5 :           GST_CLOCK_DIFF (now, render_time) <= 0) {
     505              :         /** send data after render time, or firstly received buffer */
     506            1 :         notify = TRUE;
     507              :       }
     508              : 
     509            6 :       gst_object_unref (clock);
     510              :     }
     511              :   } else {
     512              :     /** send data if signal rate is 0 */
     513         6962 :     notify = TRUE;
     514              :   }
     515              : 
     516         6968 :   if (notify) {
     517         6963 :     gst_tensor_sink_set_last_render_time (self, now);
     518              : 
     519         6963 :     if (gst_tensor_sink_get_emit_signal (self)) {
     520         6958 :       silent_debug (self,
     521              :           "Emit signal for new data [%" GST_TIME_FORMAT "] rate [%d]",
     522              :           GST_TIME_ARGS (now), signal_rate);
     523              : 
     524         6958 :       g_signal_emit (self, _tensor_sink_signals[SIGNAL_NEW_DATA], 0, buffer);
     525              :     }
     526              :   }
     527              : 
     528         6968 :   silent_debug_timestamp (self, buffer);
     529              : }
     530              : 
     531              : /**
     532              :  * @brief Setter for value last_render_time.
     533              :  */
     534              : static void
     535         6963 : gst_tensor_sink_set_last_render_time (GstTensorSink * self, GstClockTime now)
     536              : {
     537         6963 :   g_return_if_fail (GST_IS_TENSOR_SINK (self));
     538              : 
     539         6963 :   g_mutex_lock (&self->mutex);
     540         6963 :   self->last_render_time = now;
     541         6963 :   g_mutex_unlock (&self->mutex);
     542              : }
     543              : 
     544              : /**
     545              :  * @brief Getter for value last_render_time.
     546              :  */
     547              : static GstClockTime
     548            6 : gst_tensor_sink_get_last_render_time (GstTensorSink * self)
     549              : {
     550              :   GstClockTime last_render_time;
     551              : 
     552            6 :   g_return_val_if_fail (GST_IS_TENSOR_SINK (self), GST_CLOCK_TIME_NONE);
     553              : 
     554            6 :   g_mutex_lock (&self->mutex);
     555            6 :   last_render_time = self->last_render_time;
     556            6 :   g_mutex_unlock (&self->mutex);
     557              : 
     558            6 :   return last_render_time;
     559              : }
     560              : 
     561              : /**
     562              :  * @brief Setter for value signal_rate.
     563              :  */
     564              : static void
     565            2 : gst_tensor_sink_set_signal_rate (GstTensorSink * self, guint rate)
     566              : {
     567            2 :   g_return_if_fail (GST_IS_TENSOR_SINK (self));
     568              : 
     569            2 :   GST_INFO_OBJECT (self, "set signal_rate to %d", rate);
     570            2 :   g_mutex_lock (&self->mutex);
     571            2 :   self->signal_rate = rate;
     572            2 :   g_mutex_unlock (&self->mutex);
     573              : }
     574              : 
     575              : /**
     576              :  * @brief Getter for value signal_rate.
     577              :  */
     578              : static guint
     579         6970 : gst_tensor_sink_get_signal_rate (GstTensorSink * self)
     580              : {
     581              :   guint rate;
     582              : 
     583         6970 :   g_return_val_if_fail (GST_IS_TENSOR_SINK (self), 0);
     584              : 
     585         6970 :   g_mutex_lock (&self->mutex);
     586         6970 :   rate = self->signal_rate;
     587         6970 :   g_mutex_unlock (&self->mutex);
     588              : 
     589         6970 :   return rate;
     590              : }
     591              : 
     592              : /**
     593              :  * @brief Setter for flag emit_signal.
     594              :  */
     595              : static void
     596            2 : gst_tensor_sink_set_emit_signal (GstTensorSink * self, gboolean emit)
     597              : {
     598            2 :   g_return_if_fail (GST_IS_TENSOR_SINK (self));
     599              : 
     600            2 :   GST_INFO_OBJECT (self, "set emit_signal to %d", emit);
     601            2 :   g_mutex_lock (&self->mutex);
     602            2 :   self->emit_signal = emit;
     603            2 :   g_mutex_unlock (&self->mutex);
     604              : }
     605              : 
     606              : /**
     607              :  * @brief Getter for flag emit_signal.
     608              :  */
     609              : static gboolean
     610         7277 : gst_tensor_sink_get_emit_signal (GstTensorSink * self)
     611              : {
     612              :   gboolean res;
     613              : 
     614         7277 :   g_return_val_if_fail (GST_IS_TENSOR_SINK (self), FALSE);
     615              : 
     616         7277 :   g_mutex_lock (&self->mutex);
     617         7277 :   res = self->emit_signal;
     618         7277 :   g_mutex_unlock (&self->mutex);
     619              : 
     620         7277 :   return res;
     621              : }
     622              : 
     623              : /**
     624              :  * @brief Setter for flag silent.
     625              :  */
     626              : static void
     627            2 : gst_tensor_sink_set_silent (GstTensorSink * self, gboolean silent)
     628              : {
     629            2 :   g_return_if_fail (GST_IS_TENSOR_SINK (self));
     630              : 
     631            2 :   GST_INFO_OBJECT (self, "set silent to %d", silent);
     632            2 :   self->silent = silent;
     633              : }
     634              : 
     635              : /**
     636              :  * @brief Getter for flag silent.
     637              :  */
     638              : static gboolean
     639            2 : gst_tensor_sink_get_silent (GstTensorSink * self)
     640              : {
     641            2 :   g_return_val_if_fail (GST_IS_TENSOR_SINK (self), TRUE);
     642              : 
     643            2 :   return self->silent;
     644              : }
        

Generated by: LCOV version 2.0-1