LCOV - code coverage report
Current view: top level - nnstreamer-2.4.2/ext/nnstreamer/tensor_decoder - tensordec-flexbuf.cc (source / functions) Coverage Total Hit
Test: nnstreamer 2.4.2-0 nnstreamer/nnstreamer#eca68b8d050408568af95d831a8eef62aaee7784 Lines: 86.8 % 68 59
Test Date: 2025-03-13 05:38:21 Functions: 88.9 % 9 8

            Line data    Source code
       1              : /* SPDX-License-Identifier: LGPL-2.1-only */
       2              : /**
       3              :  * GStreamer / NNStreamer tensor_decoder subplugin, "Flexbuffer"
       4              :  * Copyright (C) 2021 Gichan Jang <gichan2.jang@samsung.com>
       5              :  */
       6              : /**
       7              :  * @file        tensordec-flexbuf.cc
       8              :  * @date        12 Mar 2021
       9              :  * @brief       NNStreamer tensor-decoder subplugin, "flexbuffer",
      10              :  *              which converts tensor or tensors to flexbuffer byte stream.
      11              :  *
      12              :  * @see         https://github.com/nnstreamer/nnstreamer
      13              :  * @author      Gichan Jang <gichan2.jang@samsung.com>
      14              :  * @bug         No known bugs except for NYI items
      15              :  *
      16              :  */
      17              : /**
      18              :  * SECTION:tensor_decoder::flexbuf
      19              :  * @see https://google.github.io/flatbuffers/flexbuffers.html
      20              :  *
      21              :  * tensor_decoder::flexbuf converts tensors stream to flexbuffers.
      22              :  *
      23              :  * Binary format of the flexbuffers for tensors (default in nnstreamer).
      24              :  * Each data is represented in `KEY : TYPE | <VALUE>` form.
      25              :  *
      26              :  * Map {
      27              :  *   "num_tensors" : UInt32 | <The number of tensors>
      28              :  *   "rate_n" : Int32 | <Framerate numerator>
      29              :  *   "rate_d" : Int32 | <Framerate denominator>
      30              :  *   "tensor_#": Vector | { String | <tensor name>,
      31              :  *                          Int32 | <data type>,
      32              :  *                          Vector | <tensor dimension>,
      33              :  *                          Blob | <tensor data>
      34              :  *                         }
      35              :  * }
      36              :  *
      37              :  * If you want to convert tensors to your own binary format of the flexbuffers,
      38              :  * You can use custom mode of the tensor decoder.
      39              :  * This is an example of a callback type custom mode.
      40              :  * @code
      41              :  * // Define custom callback function
      42              :  * int tensor_decoder_custom_cb (const GstTensorMemory *input,
      43              :  *   const GstTensorsConfig *config, void *data, GstBuffer *out_buf) {
      44              :  *   // Write a code to convert tensors to flexbuffers.
      45              :  * }
      46              :  *
      47              :  * ...
      48              :  * // Register custom callback function
      49              :  * nnstreamer_decoder_custom_register ("tdec", tensor_converter_custom_cb, NULL);
      50              :  * ...
      51              :  * // Use the custom tensor converter in a pipeline.
      52              :  * // E.g., Pipeline of " ... (tensors) ! tensor_decoder mode=custom-code option1=tdec ! (flexbuffers)... "
      53              :  * ...
      54              :  * // After everything is done.
      55              :  * nnstreamer_decoder_custom_unregister ("tdec");
      56              :  * @endcode
      57              :  */
      58              : 
      59              : #include <flatbuffers/flexbuffers.h>
      60              : #include <glib.h>
      61              : #include <nnstreamer_log.h>
      62              : #include <nnstreamer_plugin_api.h>
      63              : #include <nnstreamer_plugin_api_decoder.h>
      64              : #include <nnstreamer_util.h>
      65              : #include "../extra/nnstreamer_flatbuf.h"
      66              : #include "tensordecutil.h"
      67              : 
      68              : #ifdef __cplusplus
      69              : extern "C" {
      70              : #endif /* __cplusplus */
      71              : void init_flxd (void) __attribute__ ((constructor));
      72              : void fini_flxd (void) __attribute__ ((destructor));
      73              : #ifdef __cplusplus
      74              : }
      75              : #endif /* __cplusplus */
      76              : 
      77              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
      78              : static int
      79           28 : flxd_init (void **pdata)
      80              : {
      81           28 :   *pdata = NULL;
      82           28 :   return TRUE;
      83              : }
      84              : 
      85              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
      86              : static void
      87           28 : flxd_exit (void **pdata)
      88              : {
      89              :   UNUSED (pdata);
      90           28 :   return;
      91              : }
      92              : 
      93              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
      94              : static int
      95            0 : flxd_setOption (void **pdata, int opNum, const char *param)
      96              : {
      97              :   UNUSED (pdata);
      98              :   UNUSED (opNum);
      99              :   UNUSED (param);
     100            0 :   return TRUE;
     101              : }
     102              : 
     103              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
     104              : static GstCaps *
     105          195 : flxd_getOutCaps (void **pdata, const GstTensorsConfig *config)
     106              : {
     107              :   GstCaps *caps;
     108              :   UNUSED (pdata);
     109              : 
     110          195 :   caps = gst_caps_from_string (GST_FLEXBUF_CAP_DEFAULT);
     111          195 :   setFramerateFromConfig (caps, config);
     112          195 :   return caps;
     113              : }
     114              : 
     115              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
     116              : static GstFlowReturn
     117           56 : flxd_decode (void **pdata, const GstTensorsConfig *config,
     118              :     const GstTensorMemory *input, GstBuffer *outbuf)
     119              : {
     120              :   GstMapInfo out_info;
     121              :   GstMemory *out_mem;
     122              :   guint i, num_tensors;
     123              :   gboolean need_alloc;
     124              :   size_t flex_size;
     125           56 :   flexbuffers::Builder fbb;
     126              :   gboolean is_flexible;
     127              :   GstTensorMetaInfo meta;
     128              :   GstTensorInfo *_info;
     129              : 
     130              :   UNUSED (pdata);
     131              : 
     132           56 :   if (!config || !input || !outbuf) {
     133            3 :     ml_loge ("NULL parameter is passed to tensor_decoder::flexbuf");
     134            3 :     return GST_FLOW_ERROR;
     135              :   }
     136              : 
     137           53 :   is_flexible = gst_tensors_config_is_flexible (config);
     138              : 
     139           53 :   num_tensors = config->info.num_tensors;
     140           53 :   fbb.Map ([&] () {
     141           53 :     fbb.UInt ("num_tensors", num_tensors);
     142           53 :     fbb.Int ("rate_n", config->rate_n);
     143           53 :     fbb.Int ("rate_d", config->rate_d);
     144           53 :     fbb.Int ("format", config->info.format);
     145          152 :     for (i = 0; i < num_tensors; i++) {
     146           99 :       gchar *tensor_key = g_strdup_printf ("tensor_%d", i);
     147           99 :       gchar *tensor_name = NULL;
     148              : 
     149           99 :       _info = gst_tensors_info_get_nth_info ((GstTensorsInfo *) &config->info, i);
     150              : 
     151           99 :       if (is_flexible) {
     152            9 :         gst_tensor_meta_info_parse_header (&meta, input[i].data);
     153            9 :         gst_tensor_meta_info_convert (&meta, _info);
     154              :       }
     155              : 
     156           99 :       if (_info->name == NULL) {
     157           98 :         tensor_name = g_strdup ("");
     158              :       } else {
     159            2 :         tensor_name = g_strdup (_info->name);
     160              :       }
     161           99 :       tensor_type type = _info->type;
     162              : 
     163           99 :       fbb.Vector (tensor_key, [&] () {
     164           99 :         fbb += tensor_name;
     165           99 :         fbb += type;
     166           99 :         fbb.Vector (_info->dimension, NNS_TENSOR_RANK_LIMIT);
     167           99 :         fbb.Blob (input[i].data, input[i].size);
     168           99 :       });
     169           99 :       g_free (tensor_key);
     170           99 :       g_free (tensor_name);
     171              :     }
     172           53 :   });
     173           53 :   fbb.Finish ();
     174           53 :   flex_size = fbb.GetSize ();
     175              : 
     176           53 :   need_alloc = (gst_buffer_get_size (outbuf) == 0);
     177              : 
     178           53 :   if (need_alloc) {
     179           53 :     out_mem = gst_allocator_alloc (NULL, flex_size, NULL);
     180              :   } else {
     181            0 :     if (gst_buffer_get_size (outbuf) < flex_size) {
     182            0 :       gst_buffer_set_size (outbuf, flex_size);
     183              :     }
     184            0 :     out_mem = gst_buffer_get_all_memory (outbuf);
     185              :   }
     186              : 
     187           53 :   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
     188            0 :     gst_memory_unref (out_mem);
     189            0 :     nns_loge ("Cannot map gst memory (tensor decoder flexbuf)\n");
     190            0 :     return GST_FLOW_ERROR;
     191              :   }
     192              : 
     193           53 :   memcpy (out_info.data, fbb.GetBuffer ().data (), flex_size);
     194              : 
     195           53 :   gst_memory_unmap (out_mem, &out_info);
     196              : 
     197           53 :   if (need_alloc)
     198           53 :     gst_buffer_append_memory (outbuf, out_mem);
     199              :   else
     200            0 :     gst_buffer_replace_all_memory (outbuf, out_mem);
     201              : 
     202           53 :   return GST_FLOW_OK;
     203           56 : }
     204              : 
     205              : static gchar decoder_subplugin_flexbuf[] = "flexbuf";
     206              : 
     207              : /** @brief flexbuffer tensordec-plugin GstTensorDecoderDef instance */
     208              : static GstTensorDecoderDef flexBuf = { .modename = decoder_subplugin_flexbuf,
     209              :   .init = flxd_init,
     210              :   .exit = flxd_exit,
     211              :   .setOption = flxd_setOption,
     212              :   .getOutCaps = flxd_getOutCaps,
     213              :   .decode = flxd_decode,
     214              :   .getTransformSize = NULL };
     215              : 
     216              : #ifdef __cplusplus
     217              : extern "C" {
     218              : #endif /* __cplusplus */
     219              : 
     220              : /** @brief Initialize this object for tensordec-plugin */
     221              : void
     222           52 : init_flxd (void)
     223              : {
     224           52 :   nnstreamer_decoder_probe (&flexBuf);
     225           52 : }
     226              : 
     227              : /** @brief Destruct this object for tensordec-plugin */
     228              : void
     229           52 : fini_flxd (void)
     230              : {
     231           52 :   nnstreamer_decoder_exit (flexBuf.modename);
     232           52 : }
     233              : #ifdef __cplusplus
     234              : }
     235              : #endif /* __cplusplus */
        

Generated by: LCOV version 2.0-1