LCOV - code coverage report
Current view: top level - nnstreamer-2.4.2/ext/nnstreamer/extra - nnstreamer_protobuf.cc (source / functions) Coverage Total Hit
Test: nnstreamer 2.4.2-0 nnstreamer/nnstreamer#eca68b8d050408568af95d831a8eef62aaee7784 Lines: 83.5 % 85 71
Test Date: 2025-03-14 05:36:58 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /* SPDX-License-Identifier: LGPL-2.1-only */
       2              : /**
       3              :  * GStreamer / NNStreamer subplugin "protobuf" to support tensor converter and
       4              :  * decoder
       5              :  * Copyright (C) 2020 Gichan Jang <gichan2.jang@samsung.com>
       6              :  */
       7              : /**
       8              :  * @file        nnstreamer_protobuf.cc
       9              :  * @date        16 June 2020
      10              :  * @brief       Protobuf util function for nnstreamer
      11              :  * @see         https://github.com/nnstreamer/nnstreamer
      12              :  * @author      Gichan Jang <gichan2.jang@samsung.com>
      13              :  * @bug         No known bugs except for NYI items
      14              :  *
      15              :  */
      16              : /**
      17              :  * Install protobuf
      18              :  * We assume that you use Ubuntu linux distribution.
      19              :  * You may simply download binary packages from PPA
      20              :  *
      21              :  * $ sudo apt-add-repository ppa:nnstreamer
      22              :  * $ sudo apt update
      23              :  * $ sudo apt install libprotobuf-dev libprotobuf-lite17 libprotobuf17
      24              :  * protobuf-compiler17
      25              :  */
      26              : 
      27              : #include <nnstreamer_log.h>
      28              : #include <nnstreamer_plugin_api.h>
      29              : #include <nnstreamer_util.h>
      30              : #include "nnstreamer.pb.h" /* Generated by `protoc` */
      31              : #include "nnstreamer_protobuf.h"
      32              : 
      33              : /** @brief tensordec-plugin's GstTensorDecoderDef callback */
      34              : GstFlowReturn
      35           84 : gst_tensor_decoder_protobuf (const GstTensorsConfig *config,
      36              :     const GstTensorMemory *input, GstBuffer *outbuf)
      37              : {
      38              :   GstMapInfo out_info;
      39              :   GstMemory *out_mem;
      40              :   size_t size, outbuf_size;
      41           84 :   nnstreamer::protobuf::Tensors tensors;
      42           84 :   nnstreamer::protobuf::Tensors::frame_rate *fr = NULL;
      43              :   guint num_tensors;
      44              :   gboolean is_flexible;
      45              :   GstTensorMetaInfo meta;
      46              :   GstTensorInfo *_info;
      47              : 
      48           84 :   if (!config || !input || !outbuf) {
      49            3 :     ml_loge ("NULL parameter is passed to tensor_decoder::protobuf");
      50            3 :     return GST_FLOW_ERROR;
      51              :   }
      52              : 
      53           81 :   is_flexible = gst_tensors_config_is_flexible (config);
      54              : 
      55           81 :   num_tensors = config->info.num_tensors;
      56           81 :   if (num_tensors <= 0 || num_tensors > NNS_TENSOR_SIZE_LIMIT) {
      57            0 :     ml_loge ("The number of input tenosrs "
      58              :              "exceeds more than NNS_TENSOR_SIZE_LIMIT, %s",
      59              :         NNS_TENSOR_SIZE_LIMIT_STR);
      60            0 :     return GST_FLOW_ERROR;
      61              :   }
      62           81 :   tensors.set_num_tensor (num_tensors);
      63              : 
      64           81 :   fr = tensors.mutable_fr ();
      65           81 :   if (!fr) {
      66            0 :     nns_loge ("Failed to get pointer of tensors / tensordec-protobuf");
      67            0 :     return GST_FLOW_ERROR;
      68              :   }
      69              : 
      70           81 :   fr->set_rate_n (config->rate_n);
      71           81 :   fr->set_rate_d (config->rate_d);
      72              : 
      73           81 :   tensors.set_format (
      74           81 :       (nnstreamer::protobuf::Tensors::Tensor_format) config->info.format);
      75              : 
      76          187 :   for (unsigned int i = 0; i < num_tensors; ++i) {
      77          106 :     nnstreamer::protobuf::Tensor *tensor = tensors.add_tensor ();
      78              : 
      79          106 :     _info = gst_tensors_info_get_nth_info ((GstTensorsInfo *) &config->info, i);
      80              : 
      81          106 :     if (is_flexible) {
      82            9 :       gst_tensor_meta_info_parse_header (&meta, input[i].data);
      83            9 :       gst_tensor_meta_info_convert (&meta, _info);
      84              :     }
      85              : 
      86          106 :     tensor->set_name (_info->name ? _info->name : "");
      87          106 :     tensor->set_type ((nnstreamer::protobuf::Tensor::Tensor_type) _info->type);
      88              : 
      89         1802 :     for (int j = 0; j < NNS_TENSOR_RANK_LIMIT; ++j) {
      90         1696 :       tensor->add_dimension (_info->dimension[j]);
      91              :     }
      92              : 
      93          106 :     tensor->set_data (input[i].data, (int) input[i].size);
      94              :   }
      95              : 
      96           81 :   size = tensors.ByteSizeLong ();
      97           81 :   outbuf_size = gst_buffer_get_size (outbuf);
      98              : 
      99           81 :   if (outbuf_size == 0) {
     100           81 :     out_mem = gst_allocator_alloc (NULL, size, NULL);
     101              :   } else {
     102            0 :     if (outbuf_size < size) {
     103            0 :       gst_buffer_set_size (outbuf, size);
     104              :     }
     105            0 :     out_mem = gst_buffer_get_all_memory (outbuf);
     106              :   }
     107              : 
     108           81 :   if (!gst_memory_map (out_mem, &out_info, GST_MAP_WRITE)) {
     109            0 :     nns_loge ("Cannot map output memory / tensordec-protobuf");
     110            0 :     gst_memory_unref (out_mem);
     111            0 :     return GST_FLOW_ERROR;
     112              :   }
     113              : 
     114           81 :   tensors.SerializeToArray (out_info.data, size);
     115              : 
     116           81 :   gst_memory_unmap (out_mem, &out_info);
     117              : 
     118           81 :   if (outbuf_size == 0)
     119           81 :     gst_buffer_append_memory (outbuf, out_mem);
     120              :   else
     121            0 :     gst_buffer_replace_all_memory (outbuf, out_mem);
     122              : 
     123           81 :   return GST_FLOW_OK;
     124           84 : }
     125              : 
     126              : /** @brief tensor converter plugin's NNStreamerExternalConverter callback */
     127              : GstBuffer *
     128           83 : gst_tensor_converter_protobuf (GstBuffer *in_buf, GstTensorsConfig *config, void *priv_data)
     129              : {
     130           83 :   nnstreamer::protobuf::Tensors tensors;
     131           83 :   nnstreamer::protobuf::Tensors::frame_rate *fr = NULL;
     132              :   GstTensorInfo *_info;
     133              :   GstMemory *in_mem, *out_mem;
     134              :   GstMapInfo in_info;
     135              :   GstBuffer *out_buf;
     136              :   gsize mem_size;
     137              :   gpointer mem_data;
     138              :   UNUSED (priv_data);
     139              : 
     140           83 :   if (!in_buf || !config) {
     141            2 :     ml_loge ("NULL parameter is passed to tensor_converter::protobuf");
     142            2 :     return NULL;
     143              :   }
     144              : 
     145           81 :   in_mem = gst_buffer_get_all_memory (in_buf);
     146           81 :   if (!gst_memory_map (in_mem, &in_info, GST_MAP_READ)) {
     147            0 :     nns_loge ("Cannot map input memory / tensor_converter_protobuf");
     148            0 :     gst_memory_unref (in_mem);
     149            0 :     return NULL;
     150              :   }
     151              : 
     152           81 :   tensors.ParseFromArray (in_info.data, in_info.size);
     153              : 
     154           81 :   config->info.num_tensors = tensors.num_tensor ();
     155           81 :   config->info.format = (tensor_format) tensors.format ();
     156           81 :   fr = tensors.mutable_fr ();
     157           81 :   config->rate_n = fr->rate_n ();
     158           81 :   config->rate_d = fr->rate_d ();
     159           81 :   out_buf = gst_buffer_new ();
     160              : 
     161          187 :   for (guint i = 0; i < config->info.num_tensors; i++) {
     162          106 :     const nnstreamer::protobuf::Tensor *tensor = &tensors.tensor (i);
     163          106 :     std::string _name = tensor->name ();
     164          106 :     const gchar *name = _name.c_str ();
     165              : 
     166          106 :     _info = gst_tensors_info_get_nth_info (&config->info, i);
     167              : 
     168          107 :     _info->name = (name && strlen (name) > 0) ? g_strdup (name) : NULL;
     169          106 :     _info->type = (tensor_type) tensor->type ();
     170         1802 :     for (guint j = 0; j < NNS_TENSOR_RANK_LIMIT; j++) {
     171         1696 :       _info->dimension[j] = tensor->dimension (j);
     172              :     }
     173          106 :     mem_size = tensor->data ().length ();
     174          106 :     mem_data = _g_memdup (tensor->data ().c_str (), mem_size);
     175              : 
     176          106 :     out_mem = gst_memory_new_wrapped (
     177              :         (GstMemoryFlags) 0, mem_data, mem_size, 0, mem_size, mem_data, g_free);
     178              : 
     179          106 :     gst_tensor_buffer_append_memory (out_buf, out_mem, _info);
     180              :   }
     181              : 
     182              :   /** copy timestamps */
     183           81 :   gst_buffer_copy_into (
     184              :       out_buf, in_buf, (GstBufferCopyFlags) GST_BUFFER_COPY_METADATA, 0, -1);
     185           81 :   gst_memory_unmap (in_mem, &in_info);
     186           81 :   gst_memory_unref (in_mem);
     187              : 
     188           81 :   return out_buf;
     189           83 : }
        

Generated by: LCOV version 2.0-1