LCOV - code coverage report
Current view: top level - nnstreamer-2.4.2/gst/nnstreamer - ml_agent.c (source / functions) Coverage Total Hit
Test: nnstreamer 2.4.2-0 nnstreamer/nnstreamer#58eaa3c6edb7484955a5d8c32f47a60ba9501210 Lines: 74.6 % 59 44
Test Date: 2025-04-18 05:37:26 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /* SPDX-License-Identifier: LGPL-2.1-only */
       2              : /**
       3              :  * Copyright (C) 2023 Wook Song <wook16.song@samsung.com>
       4              :  * Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
       5              :  *
       6              :  *
       7              :  * @file    ml_agent.c
       8              :  * @date    23 Jun 2023
       9              :  * @brief   Internal helpers to make a bridge between NNS filters and the ML Agent service
      10              :  * @see     http://github.com/nnstreamer/nnstreamer
      11              :  * @author  wook16.song <wook16.song@samsung.com>
      12              :  * @bug     No known bugs except for NYI items
      13              :  */
      14              : 
      15              : #include <json-glib/json-glib.h>
      16              : #include <nnstreamer_log.h>
      17              : #include <mlops-agent-interface.h>
      18              : 
      19              : #include "ml_agent.h"
      20              : 
      21              : const gchar URI_SCHEME[] = "mlagent";
      22              : const gchar URI_KEYWORD_MODEL[] = "model";
      23              : const gchar JSON_KEY_MODEL_PATH[] = "path";
      24              : 
      25              : /**
      26              :  * @brief Get a path of the model file from a given GValue
      27              :  * @param[in] val A pointer to a GValue holding a G_TYPE_STRING value
      28              :  * @return A newly allocated c-string representing the model file path, if the given GValue contains a valid URI
      29              :  * Otherwise, it simply returns a duplicated (strdup'ed) c-string that the val contains.
      30              :  * @note The caller should free the return c-string after using it.
      31              :  */
      32              : gchar *
      33          297 : mlagent_get_model_path_from (const GValue * val)
      34              : {
      35          297 :   g_autofree gchar *scheme = NULL;
      36          297 :   g_autofree gchar *uri = g_value_dup_string (val);
      37          297 :   GError *err = NULL;
      38              :   gchar *uri_hier_part;
      39              :   gchar **parts;
      40              : 
      41          297 :   if (!uri)
      42            0 :     return NULL;
      43              : 
      44              :   /** Common checker for the given URI */
      45          297 :   scheme = g_uri_parse_scheme (uri);
      46          297 :   if (!scheme || g_strcmp0 (URI_SCHEME, scheme)) {
      47          288 :     return g_steal_pointer (&uri);
      48              :   }
      49              : 
      50            9 :   uri_hier_part = g_strstr_len (uri, -1, ":");
      51            9 :   if (!uri_hier_part)
      52            0 :     return NULL;
      53              : 
      54           36 :   while (*uri_hier_part == ':' || *uri_hier_part == '/') {
      55           27 :     uri_hier_part++;
      56              :   }
      57              : 
      58              :   /**
      59              :    * @note Only for the following URI formats to get the file path of
      60              :    *       the matching models are currently supported.
      61              :    *       mlagent://model/name or mlagent://model/name/version
      62              :    *
      63              :    *       It is required to be revised to support more scenarios
      64              :    *       that exploit the ML Agent.
      65              :    */
      66            9 :   parts = g_strsplit_set (uri_hier_part, "/", 0);
      67              :   {
      68              :     enum MODEL_PART_CONSTANTS
      69              :     {
      70              :       MODEL_PART_IDX_NAME = 1,
      71              :       MODEL_PART_IDX_VERSION = 2,
      72              :       MODEL_VERSION_MIN = 1,
      73              :       MODEL_VERSION_MAX = 255,
      74              :     };
      75            9 :     const size_t NUM_PARTS_MODEL = 3;
      76              :     size_t num_parts;
      77              : 
      78            9 :     num_parts = g_strv_length (parts);
      79            9 :     if (num_parts == 0) {
      80            0 :       goto fallback;
      81              :     }
      82              : 
      83            9 :     if (!g_strcmp0 (parts[0], URI_KEYWORD_MODEL)) {
      84              :       /** Convert the given URI for a model to the file path */
      85            9 :       g_autofree gchar *name = g_strdup (parts[MODEL_PART_IDX_NAME]);
      86            9 :       g_autofree gchar *stringified_json = NULL;
      87            9 :       g_autoptr (JsonParser) json_parser = NULL;
      88              :       gint rcode;
      89              : 
      90            9 :       if (num_parts < NUM_PARTS_MODEL - 1) {
      91            0 :         goto fallback;
      92              :       }
      93              : 
      94              :       /**
      95              :        * @todo The specification of the data layout filled in the third
      96              :        *       argument (i.e., stringified_json) by the callee is not fully decided.
      97              :        */
      98            9 :       if (num_parts == NUM_PARTS_MODEL - 1) {
      99            4 :         rcode = ml_agent_model_get_activated (name, &stringified_json);
     100              :       } else {
     101            5 :         guint version = strtoul (parts[MODEL_PART_IDX_VERSION], NULL, 10);
     102            5 :         rcode = ml_agent_model_get (name, version, &stringified_json);
     103              :       }
     104              : 
     105            9 :       if (rcode != 0) {
     106            1 :         nns_loge
     107              :             ("Failed to get the stringified JSON using the given URI(%s)", uri);
     108            1 :         goto fallback;
     109              :       }
     110              : 
     111            8 :       json_parser = json_parser_new ();
     112              :       /** @todo Parse stringified_json to get the model's path */
     113            8 :       if (!json_parser_load_from_data (json_parser, stringified_json, -1, &err)) {
     114            0 :         nns_loge ("Failed to parse the stringified JSON while "
     115              :             "get the model's path: %s",
     116              :             (err ? err->message : "unknown reason"));
     117            0 :         goto fallback;
     118              :       }
     119            8 :       g_clear_error (&err);
     120              : 
     121              :       {
     122            8 :         const gchar *path = NULL;
     123              :         JsonNode *jroot;
     124              :         JsonObject *jobj;
     125              : 
     126            8 :         jroot = json_parser_get_root (json_parser);
     127            8 :         if (jroot == NULL) {
     128            0 :           nns_loge ("Failed to get JSON root node while get the model's path");
     129            0 :           goto fallback;
     130              :         }
     131              : 
     132            8 :         jobj = json_node_get_object (jroot);
     133            8 :         if (jobj == NULL) {
     134            0 :           nns_loge
     135              :               ("Failed to get JSON object from the root node while get the model's path");
     136            0 :           goto fallback;
     137              :         }
     138              : 
     139            8 :         if (!json_object_has_member (jobj, JSON_KEY_MODEL_PATH)) {
     140            0 :           nns_loge
     141              :               ("Failed to get the model's path from the given URI: "
     142              :               "There is no key named, %s, in the JSON object",
     143              :               JSON_KEY_MODEL_PATH);
     144            0 :           goto fallback;
     145              :         }
     146              : 
     147            8 :         path = json_object_get_string_member (jobj, JSON_KEY_MODEL_PATH);
     148            8 :         if (path == NULL || !g_strcmp0 (path, "")) {
     149            0 :           nns_loge
     150              :               ("Failed to get the model's path from the given URI: "
     151              :               "Invalid value for the key, %s", JSON_KEY_MODEL_PATH);
     152            0 :           goto fallback;
     153              :         }
     154              : 
     155            8 :         g_strfreev (parts);
     156            8 :         return g_strdup (path);
     157              :       }
     158              :     }
     159              :   }
     160              : 
     161            0 : fallback:
     162            1 :   g_clear_error (&err);
     163            1 :   g_strfreev (parts);
     164              : 
     165            2 :   return g_strdup (uri);
     166              : }
        

Generated by: LCOV version 2.0-1