LCOV - code coverage report
Current view: top level - nnstreamer-2.4.2/gst/nnstreamer/elements - gsttensor_debug.c (source / functions) Coverage Total Hit
Test: nnstreamer 2.4.2-0 nnstreamer/nnstreamer#eca68b8d050408568af95d831a8eef62aaee7784 Lines: 1.1 % 95 1
Test Date: 2025-03-14 05:36:58 Functions: 13.3 % 15 2

            Line data    Source code
       1              : /* SPDX-License-Identifier: LGPL-2.1-only */
       2              : /**
       3              :  * GStreamer/NNStreamer tensor_debug
       4              :  * Copyright (C) 2022 MyungJoo Ham <myungjoo.ham@samsung.com>
       5              :  */
       6              : /**
       7              :  * @file        gsttensor_debug.c
       8              :  * @date        23 Sep 2022
       9              :  * @brief       GStreamer plugin to help debug tensor streams.
      10              :  *
      11              :  * @see         https://github.com/nnstreamer/nnstreamer
      12              :  * @author      MyungJoo Ham <myungjoo.ham@samsung.com>
      13              :  * @bug         No known bugs except for NYI items
      14              :  */
      15              : 
      16              : /**
      17              :  * SECTION:element-tensor_debug
      18              :  *
      19              :  * A filter that generates debug messages for developer at the insertion
      20              :  * point of the given pipeline. An application writer using an nnstreamer
      21              :  * pipeline can use tensor_debug to debug or get profile information in their
      22              :  * applications.
      23              :  *
      24              :  * Note that this does not support other/tensor, but only supports other/tensors.
      25              :  *
      26              :  * <refsect2>
      27              :  * <title>Example launch line</title>
      28              :  * |[
      29              :  * gst-launch-1.0 videotestsrc ! video/x-raw,format=RGB,width=640,height=480 ! tensor_converter ! tensor_debug output-method=console-info capability=always ! tensor_sink
      30              :  * ]|
      31              :  * </refsect2>
      32              :  */
      33              : 
      34              : #ifdef HAVE_CONFIG_H
      35              : #include <config.h>
      36              : #endif
      37              : 
      38              : #include <string.h>
      39              : #include <nnstreamer_log.h>
      40              : #include <nnstreamer_util.h>
      41              : #include "gsttensor_debug.h"
      42              : #include "tensor_meta.h"
      43              : 
      44              : /**
      45              :  * @brief Macro for debug mode.
      46              :  */
      47              : #ifndef DBG
      48              : #define DBG (!self->silent)
      49              : #endif
      50              : 
      51              : GST_DEBUG_CATEGORY_STATIC (gst_tensor_debug_debug);
      52              : #define GST_CAT_DEFAULT gst_tensor_debug_debug
      53              : 
      54              : /**
      55              :  * This is a new element created after the obsoletion of other/tensor.
      56              :  * Use other/tensors if you want to use tensor_debug
      57              :  */
      58              : #define CAPS_STRING GST_TENSORS_CAP_MAKE(GST_TENSOR_FORMAT_ALL)
      59              : 
      60              : /**
      61              :  * @brief The capabilities of the inputs
      62              :  */
      63              : static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
      64              :     GST_PAD_SINK,
      65              :     GST_PAD_ALWAYS,
      66              :     GST_STATIC_CAPS (CAPS_STRING));
      67              : 
      68              : /**
      69              :  * @brief The capabilities of the outputs
      70              :  */
      71              : static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
      72              :     GST_PAD_SRC,
      73              :     GST_PAD_ALWAYS,
      74              :     GST_STATIC_CAPS (CAPS_STRING));
      75              : 
      76              : /**
      77              :  * @brief tensor_debug properties
      78              :  */
      79              : enum
      80              : {
      81              :   PROP_0,
      82              :   PROP_SILENT,
      83              :   PROP_OUTPUT,
      84              :   PROP_CAP,
      85              :   PROP_META,
      86              : };
      87              : 
      88              : #define C_FLAGS(v) ((guint) v)
      89              : 
      90              : #define TENSOR_DEBUG_TYPE_OUTPUT_FLAGS (tensor_debug_output_flags_get_type())
      91              : /**
      92              :  * @brief Flags for output_mode of GstTensorDebug
      93              :  */
      94              : static GType
      95            0 : tensor_debug_output_flags_get_type (void)
      96              : {
      97              :   static GType type = G_TYPE_INVALID;
      98              : 
      99            0 :   if (type == G_TYPE_INVALID) {
     100              :     static const GFlagsValue values[] = {
     101              :       {C_FLAGS (TDBG_OUTPUT_DISABLED),
     102              :             "Disable log output and write. Do not add other flags to have this flag effective.",
     103              :           "disabled"},
     104              :       {C_FLAGS (TDBG_OUTPUT_CONSOLE_I),
     105              :             "Console output with info. Cannot combine with other console flags",
     106              :           "console-info"},
     107              :       {C_FLAGS (TDBG_OUTPUT_CONSOLE_W),
     108              :             "Console output with warning. Cannot combine with other console flags",
     109              :           "console-warn"},
     110              :       {C_FLAGS (TDBG_OUTPUT_CONSOLE_E),
     111              :             "Console output with error. Cannot combine with other console flags",
     112              :           "console-error"},
     113              :       {C_FLAGS (TDBG_OUTPUT_GSTDBG_I),
     114              :             "Gstlog output with info. Cannot combine with other gstdbg flags",
     115              :           "gstdebug-info"},
     116              :       {C_FLAGS (TDBG_OUTPUT_GSTDBG_W),
     117              :             "Gstlog output with warning. Cannot combine with other gstdbg flags",
     118              :           "gstdebug-warn"},
     119              :       {C_FLAGS (TDBG_OUTPUT_GSTDBG_E),
     120              :             "Gstlog output with error. Cannot combine with other gstdbg flags",
     121              :           "gstdebug-error"},
     122              :       {C_FLAGS (TDBG_OUTPUT_CIRCULARBUF),
     123              :             "Store at gsttensor_debug circular buffer so that it can be retrieved by the application later (NYI)",
     124              :           "circularbuf"},
     125              :       {C_FLAGS (TDBG_OUTPUT_FILEWRITE),
     126              :           "Write to a file (NYI)", "filewrite"},
     127              :       {0, NULL, NULL}
     128              :     };
     129            0 :     type = g_flags_register_static ("gtd_output", values);
     130              :   }
     131              : 
     132            0 :   return type;
     133              : }
     134              : 
     135              : #define DEFAULT_TENSOR_DEBUG_OUTPUT_FLAGS (TDBG_OUTPUT_CONSOLE_I)
     136              : 
     137              : #define TENSOR_DEBUG_TYPE_CAPS (tensor_debug_cap_get_type())
     138              : /**
     139              :  * @brief Enums for cap_mode of GstTensorDebug
     140              :  */
     141              : static GType
     142            0 : tensor_debug_cap_get_type (void)
     143              : {
     144              :   static GType type = G_TYPE_INVALID;
     145            0 :   if (type == G_TYPE_INVALID) {
     146              :     static GEnumValue values[] = {
     147              :       {TDBG_CAP_DISABLED, "disabled", "Do not log stream capability"},
     148              :       {TDBG_CAP_SHOW_UPDATE, "updates",
     149              :           "Log stream capability if it is updated or initialized."},
     150              :       {TDBG_CAP_SHOW_UPDATE_F, "updates-full",
     151              :           "Log stream capability if the capability or dimensions of flexible/sparse tensors are updated. Logs dimension info of flexible/sparse tensors as well."},
     152              :       {TDBG_CAP_SHOW_ALWAYS, "always",
     153              :           "Always, log stream capability and tensor dimension information."},
     154              :       {0, NULL, NULL}
     155              :     };
     156            0 :     type = g_enum_register_static ("gtd_cap", values);
     157              :   }
     158            0 :   return type;
     159              : }
     160              : 
     161              : #define DEFAULT_TENSOR_DEBUG_CAP (TDBG_CAP_SHOW_UPDATE_F)
     162              : 
     163              : #define TENSOR_DEBUG_TYPE_META_FLAGS (tensor_debug_meta_flags_get_type())
     164              : /**
     165              :  * @brief Flags for meta_mode of GstTensorDebug
     166              :  */
     167              : static GType
     168            0 : tensor_debug_meta_flags_get_type (void)
     169              : {
     170              :   static GType type = G_TYPE_INVALID;
     171              : 
     172            0 :   if (type == G_TYPE_INVALID) {
     173              :     static const GFlagsValue values[] = {
     174              :       {C_FLAGS (TDBG_META_DISABLED),
     175              :           "Do not log stream metadata.", "disabled"},
     176              :       {C_FLAGS (TDBG_META_TIMESTAMP), "Log timestamp information", "timestamp"},
     177              :       {C_FLAGS (TDBG_META_QUERYSERVER),
     178              :           "Log tensor-query-server related information", "queryserver"},
     179              :       {0, NULL, NULL}
     180              :     };
     181            0 :     type = g_flags_register_static ("gtd_meta", values);
     182              :   }
     183            0 :   return type;
     184              : }
     185              : 
     186              : #define DEFAULT_TENSOR_DEBUG_META_FLAGS (TDBG_META_DISABLED)
     187              : 
     188              : /**
     189              :  * @brief Flag to print minimized log.
     190              :  */
     191              : #define DEFAULT_SILENT TRUE
     192              : 
     193              : #define gst_tensor_debug_parent_class parent_class
     194          864 : G_DEFINE_TYPE (GstTensorDebug, gst_tensor_debug, GST_TYPE_BASE_TRANSFORM);
     195              : 
     196              : /* gobject vmethods */
     197              : static void gst_tensor_debug_set_property (GObject * object,
     198              :     guint prop_id, const GValue * value, GParamSpec * pspec);
     199              : static void gst_tensor_debug_get_property (GObject * object,
     200              :     guint prop_id, GValue * value, GParamSpec * pspec);
     201              : static void gst_tensor_debug_finalize (GObject * object);
     202              : 
     203              : /* gstbasetransform vmethods */
     204              : static GstFlowReturn gst_tensor_debug_transform_ip (GstBaseTransform * trans,
     205              :     GstBuffer * buffer);
     206              : static GstCaps *gst_tensor_debug_fixate_caps (GstBaseTransform * trans,
     207              :     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
     208              : static gboolean gst_tensor_debug_set_caps (GstBaseTransform * trans,
     209              :     GstCaps * incaps, GstCaps * outcaps);
     210              : 
     211              : /**
     212              :  * @brief Initialize the tensor_debug's class.
     213              :  */
     214              : static void
     215            0 : gst_tensor_debug_class_init (GstTensorDebugClass * klass)
     216              : {
     217              :   GObjectClass *object_class;
     218              :   GstElementClass *element_class;
     219              :   GstBaseTransformClass *trans_class;
     220              : 
     221            0 :   GST_DEBUG_CATEGORY_INIT (gst_tensor_debug_debug, "tensor_debug", 0,
     222              :       "Element to provide debug information of other/tensors streams. If this is enabled, the pipeline performance and overhead may be deteriorated significantly.");
     223              : 
     224            0 :   trans_class = (GstBaseTransformClass *) klass;
     225            0 :   object_class = (GObjectClass *) klass;
     226            0 :   element_class = (GstElementClass *) klass;
     227              : 
     228              :   /* GObjectClass vmethods */
     229            0 :   object_class->set_property = gst_tensor_debug_set_property;
     230            0 :   object_class->get_property = gst_tensor_debug_get_property;
     231            0 :   object_class->finalize = gst_tensor_debug_finalize;
     232              : 
     233              :   /**
     234              :    * GstTensorDebug::silent:
     235              :    *
     236              :    * The flag to enable/disable debugging messages.
     237              :    */
     238            0 :   g_object_class_install_property (object_class, PROP_SILENT,
     239              :       g_param_spec_boolean ("silent", "silent", "Produce verbose output",
     240              :           DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     241              : 
     242              :   /**
     243              :    * GstTensorDebug::output:
     244              :    *
     245              :    * The combination of enums configuring output methods.
     246              :    * @todo check the behavior of name and nick (output methods vs output)
     247              :    */
     248            0 :   g_object_class_install_property (object_class, PROP_OUTPUT,
     249              :       g_param_spec_flags ("output-method", "output",
     250              :           "Output methods for debug/profile contents. Different methods can be enabled simultaneously.",
     251              :           TENSOR_DEBUG_TYPE_OUTPUT_FLAGS, DEFAULT_TENSOR_DEBUG_OUTPUT_FLAGS,
     252              :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     253              : 
     254              :   /**
     255              :    * GstTensorDebug::cap:
     256              :    *
     257              :    * The logging preference of the stream capability (GSTCAP).
     258              :    */
     259            0 :   g_object_class_install_property (object_class, PROP_CAP,
     260              :       g_param_spec_enum ("capability", "cap",
     261              :           "The logging preference for stream capability (GSTCAP)",
     262              :           TENSOR_DEBUG_TYPE_CAPS, DEFAULT_TENSOR_DEBUG_CAP,
     263              :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     264              : 
     265              :   /**
     266              :    * GstTensorDebug::meta:
     267              :    *
     268              :    * The logging preference of in-stream metadata (GSTMETA).
     269              :    */
     270            0 :   g_object_class_install_property (object_class, PROP_META,
     271              :       g_param_spec_flags ("metadata", "meta",
     272              :           "The logging preference for stream metadata (GstMeta)",
     273              :           TENSOR_DEBUG_TYPE_META_FLAGS, DEFAULT_TENSOR_DEBUG_META_FLAGS,
     274              :           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
     275              : 
     276              : 
     277              :   /* set pad template */
     278            0 :   gst_element_class_add_pad_template (element_class,
     279              :       gst_static_pad_template_get (&src_factory));
     280            0 :   gst_element_class_add_pad_template (element_class,
     281              :       gst_static_pad_template_get (&sink_factory));
     282              : 
     283            0 :   gst_element_class_set_static_metadata (element_class,
     284              :       "TensorDebug",
     285              :       "Filter/Tensor",
     286              :       "Help debug or profile a tensor stream by logging the desired details of other/tensors. Users may log the details to console, files, or memory buffers.",
     287              :       "MyungJoo Ham <myungjoo.ham@samsung.com>");
     288              : 
     289              :   /* GstBaseTransform vmethods */
     290            0 :   trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_tensor_debug_transform_ip);
     291              : 
     292            0 :   trans_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_tensor_debug_fixate_caps);
     293            0 :   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_tensor_debug_set_caps);
     294              : 
     295              :   /* GstBaseTransform Property */
     296            0 :   trans_class->passthrough_on_same_caps = TRUE;
     297              :       /** This won't modify the contents! */
     298            0 :   trans_class->transform_ip_on_passthrough = TRUE;
     299              :       /** call transform_ip although it's passthrough */
     300              : 
     301              :   /**
     302              :    * Note.
     303              :    * Without transform_caps and with passthrough_on_same_caps = TRUE,
     304              :    * This element is not allowed to touch the contents, but can inspect
     305              :    * the contents with transform_ip by setting transform_ip_on_passthrough.
     306              :    */
     307            0 : }
     308              : 
     309              : /**
     310              :  * @brief Initialize tensor_debug element.
     311              :  */
     312              : static void
     313            0 : gst_tensor_debug_init (GstTensorDebug * self)
     314              : {
     315              :   /** init properties */
     316            0 :   self->silent = DEFAULT_SILENT;
     317            0 :   self->output_mode = DEFAULT_TENSOR_DEBUG_OUTPUT_FLAGS;
     318            0 :   self->cap_mode = DEFAULT_TENSOR_DEBUG_CAP;
     319            0 :   self->meta_mode = DEFAULT_TENSOR_DEBUG_META_FLAGS;
     320              : 
     321            0 : }
     322              : 
     323              : /**
     324              :  * @brief Function to finalize instance.
     325              :  */
     326              : static void
     327            0 : gst_tensor_debug_finalize (GObject * object)
     328              : {
     329            0 :   G_OBJECT_CLASS (parent_class)->finalize (object);
     330            0 : }
     331              : 
     332              : /**
     333              :  * @brief Setter for tensor_debug properties.
     334              :  */
     335              : static void
     336            0 : gst_tensor_debug_set_property (GObject * object, guint prop_id,
     337              :     const GValue * value, GParamSpec * pspec)
     338              : {
     339            0 :   GstTensorDebug *self = GST_TENSOR_DEBUG (object);
     340              : 
     341            0 :   switch (prop_id) {
     342            0 :     case PROP_SILENT:
     343            0 :       self->silent = g_value_get_boolean (value);
     344            0 :       silent_debug (self, "Set silent = %d", self->silent);
     345            0 :       break;
     346            0 :     case PROP_OUTPUT:
     347            0 :       self->output_mode = g_value_get_flags (value);
     348            0 :       silent_debug (self, "Set output = %x", self->output_mode);
     349            0 :       break;
     350            0 :     case PROP_CAP:
     351            0 :       self->cap_mode = g_value_get_enum (value);
     352            0 :       silent_debug (self, "Set cap = %x", self->cap_mode);
     353            0 :       break;
     354            0 :     case PROP_META:
     355            0 :       self->meta_mode = g_value_get_flags (value);
     356            0 :       silent_debug (self, "Set meta = %x", self->meta_mode);
     357            0 :       break;
     358            0 :     default:
     359            0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     360            0 :       break;
     361              :   }
     362            0 : }
     363              : 
     364              : /**
     365              :  * @brief Getter for tensor_debug properties.
     366              :  */
     367              : static void
     368            0 : gst_tensor_debug_get_property (GObject * object, guint prop_id,
     369              :     GValue * value, GParamSpec * pspec)
     370              : {
     371            0 :   GstTensorDebug *self = GST_TENSOR_DEBUG (object);
     372              : 
     373            0 :   switch (prop_id) {
     374            0 :     case PROP_SILENT:
     375            0 :       g_value_set_boolean (value, self->silent);
     376            0 :       break;
     377            0 :     case PROP_OUTPUT:
     378            0 :       g_value_set_flags (value, self->output_mode);
     379            0 :       break;
     380            0 :     case PROP_CAP:
     381            0 :       g_value_set_enum (value, self->cap_mode);
     382            0 :       break;
     383            0 :     case PROP_META:
     384            0 :       g_value_set_flags (value, self->meta_mode);
     385            0 :       break;
     386            0 :     default:
     387            0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     388            0 :       break;
     389              :   }
     390            0 : }
     391              : 
     392              : /**
     393              :  * @brief The core function that provides debug output based
     394              :  *        on the contents.
     395              :  */
     396              : static void
     397            0 : _gst_tensor_debug_output (GstTensorDebug * self, GstBuffer * buffer)
     398              : {
     399              :   UNUSED (self);
     400              :   UNUSED (buffer);
     401              :   /** @todo NYI: do the debug task */
     402            0 : }
     403              : 
     404              : /**
     405              :  * @brief in-place transform
     406              :  */
     407              : static GstFlowReturn
     408            0 : gst_tensor_debug_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
     409              : {
     410            0 :   GstTensorDebug *self = GST_TENSOR_DEBUG (trans);
     411              : 
     412            0 :   _gst_tensor_debug_output (self, buffer);
     413              : 
     414            0 :   return GST_FLOW_OK;
     415              : }
     416              : 
     417              : /**
     418              :  * @brief fixate caps. required vmethod of GstBaseTransform.
     419              :  */
     420              : static GstCaps *
     421            0 : gst_tensor_debug_fixate_caps (GstBaseTransform * trans,
     422              :     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
     423              : {
     424              :   UNUSED (trans);
     425              :   UNUSED (direction);
     426              :   UNUSED (caps);
     427              : 
     428            0 :   return gst_caps_fixate (othercaps);
     429              : }
     430              : 
     431              : /**
     432              :  * @brief set caps. required vmethod of GstBaseTransform.
     433              :  */
     434              : static gboolean
     435            0 : gst_tensor_debug_set_caps (GstBaseTransform * trans,
     436              :     GstCaps * in_caps, GstCaps * out_caps)
     437              : {
     438              :   UNUSED (trans);
     439              : 
     440            0 :   return gst_caps_can_intersect (in_caps, out_caps);
     441              : }
        

Generated by: LCOV version 2.0-1