NVIDIA DeepStream SDK API Reference

9.2 Release
9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
43 #ifndef __DEEPSTREAM_MULTIMODEL_APP_H__
44 #define __DEEPSTREAM_MULTIMODEL_APP_H__
45 
46 #include <gst/gst.h>
47 #include <glib.h>
48 
49 #include "nvdsmeta_schema.h" /* InferenceProvenanceMeta (public schema struct). The
50  * NVDS_CUSTOM_MSG_INFERENCE_PROVENANCE meta-type enum
51  * lives in nvdsmeta.h (pulled in via gstnvdsmeta.h) --
52  * a consumer needs BOTH headers. */
53 #include "gstnvmodelmux_perf.h" /* ModelMuxPerf / ModelMuxPerfCounter perf-metrics module */
54 
55 G_BEGIN_DECLS
56 
57 #define MM_MAX_STREAMS_DEFAULT 16
58 #define MM_MAX_BATCH 1024 /* hard cap on batch-size (sizes every internal mux) */
59 #define MM_MAX_MODELS 32
60 #define MM_DEFAULT_REST_PORT 9000
61 #define MM_DEFAULT_REST_IP "0.0.0.0"
62 
63 /* Model versions are POSITIVE INTEGERS ("1", "2", ...), matching Triton's model-repository
64  * convention (numbered version dirs; highest = latest). The first version is "1"; model/load
65  * auto-increments to max+1. A model is identified by (name, version), joined into a canonical
66  * instance KEY "name@version" used as the pool / limbo-map hash key, so multiple versions of
67  * one name coexist as distinct ModelBins. */
68 #define MM_MODEL_VERSION_DEFAULT "1"
69 #define MM_MODEL_KEY_SEP '@'
70 
71 /* Canonical batched-mux geometry. Applied to the nvmultiurisrcbin input mux and
72  * mirrored by the per-model + combined muxes, so all batches share resolution.
73  * (Decided at runtime; not user config.) */
74 /* GIE position of a stage. Values match nvinfer's process-mode (1 = primary/full
75  * frame, 2 = secondary/objects); shared so the element, the control plane and the
76  * secondary chain all test the same constants. */
77 #define MM_PROCESS_MODE_PGIE 1
78 #define MM_PROCESS_MODE_SGIE 2
79 
80 /* Offset added to a SHADOW lane's gie id. A model's configured gie-unique-id names its
81  * PRIMARY lane (that is the id a downstream secondary targets); the A/B twin must still
82  * be distinguishable in the object meta, so it takes id + this. Matches the Shadow
83  * pool's historical base of 100, so ids look the same as they always did. */
84 #define MM_SHADOW_GIE_OFFSET 100
85 
86 #define MM_MUX_WIDTH 1920
87 #define MM_MUX_HEIGHT 1080
88 #define MM_MUX_PUSH_TIMEOUT 33333
89 
90 /* ================================================================== */
91 /* Pipeline-wide routing revision */
92 /* */
93 /* routing_revision is the CAS token a controller sends back as */
94 /* if_revision, so there may only ever be ONE of it per pipeline: a */
95 /* per-stage counter would let a route applied at the secondary leave */
96 /* the primary's number untouched, and a controller holding that stale */
97 /* number would win a compare-and-swap it should have lost. */
98 /* */
99 /* Every nvmodelmux stage therefore points at the SAME counter. The */
100 /* stages find each other through a GstContext -- GStreamer's own */
101 /* mechanism for sharing one live object between element instances in */
102 /* a pipeline (the same way GstGLDisplay is shared): the first stage */
103 /* to reach READY posts need-context, gets no answer, creates the */
104 /* counter and posts have-context; the pipeline caches that context */
105 /* and hands it to every other stage, whose need-context is then */
106 /* answered synchronously from the cache. No shared globals, no */
107 /* assumption about which stage comes up first, and a stage in a */
108 /* pipeline of its own simply owns the counter alone. */
109 /* ================================================================== */
110 
112 #define MODELMUX_CONTEXT_TYPE_ROUTING "nvidia.deepstream.modelmux.routing"
113 
114 #define MODELMUX_CONTEXT_FIELD_REV "revision"
115 
119 typedef struct _ModelMuxRevShared ModelMuxRevShared;
120 
121 #define MODELMUX_TYPE_REV_SHARED (modelmux_rev_shared_get_type ())
122 GType modelmux_rev_shared_get_type (void);
132 
136 typedef enum
137 {
142 } ModelType;
143 
144 /* ================================================================== */
145 /* Backend registry */
146 /* */
147 /* Every per-backend fact lives in ONE table (modelmux_backends[] in */
148 /* gstnvmodelmux_config.c) and is reached through modelmux_backend(). */
149 /* Call sites ask a NAMED question -- "does this backend take a raw */
150 /* .engine?" -- instead of testing the enum, so adding a backend is a */
151 /* new row rather than a hunt for every `== MODEL_INFERSERVER` branch. */
152 /* */
153 /* The enum is deliberately NOT a capability: nvinferserver refuses an */
154 /* engine because Triton owns its checkpoints, and a vision encoder */
155 /* will refuse one for entirely different reasons. Two backends can */
156 /* share an answer without sharing a reason, and a table records the */
157 /* answer where a conditional records the coincidence. */
158 /* ================================================================== */
159 
163 #define MM_BACKEND_AT_PGIE (1u << 0)
164 #define MM_BACKEND_AT_SGIE (1u << 1)
165 
168 typedef struct
169 {
171  const gchar *element;
174  const gchar *const *markers;
176  guint positions;
179  gboolean engine_file;
183  gboolean version_artifact;
185  gboolean inplace_reload;
188  gboolean owns_placement;
191  gboolean multi_gpu_scale;
195  gboolean gpu_ids_list;
196 
199  const gchar *config_prop;
203  const gchar *config_group;
207  const gchar *engine_prop;
211  gboolean gie_id;
216  const gchar *cfg_section;
218  const gchar *gpu_key;
220 
227 gboolean modelmux_config_apply_properties (GstElement * element,
228  const gchar * config_file,
229  const gchar * group);
230 
236 gboolean modelmux_backend_at_position (ModelType type, gint process_mode);
237 
239 typedef struct
240 {
241  gchar *name;
242  gchar *config_file;
243  gchar *engine_file;
244  gchar *version;
245  guint max_streams;
246  ModelType type;
248 
253 typedef struct
254 {
255  gchar *name;
256  gchar *version;
257  gchar *engine;
258  gchar *config;
259  gint gpu;
260  gint gie;
265  guint batch;
273 
277 typedef struct
278 {
279  gchar *sensor_id;
280  gchar *primary;
281  gchar *primary_version;
282  gchar *shadow;
283  gchar *shadow_version;
285 
286 typedef struct
287 {
289  guint batch_size;
290 
291  /* defaults / behaviour */
292  guint per_model_max_streams;
293  gboolean unified_batch;
294  gint process_mode;
302  gboolean gie_ids_from_config;
303  gboolean enable;
305  gboolean shard_compact;
309  gboolean compact_idle_models_across_pools;
318  gboolean model_sharding;
325  /* [muxer]: nvstreammux settings shared by BOTH the per-model inference muxers (one per model
326  * bin, batching that model's streams before nvinfer) AND the single outer combined mux
327  * (ib->out_mux, merging all model bins' outputs downstream). width/height/live-source are
328  * common to all muxers; only the flush cadence differs (per-model regroups an already-batched
329  * upstream -> 10ms; combined aggregates across parallel inference -> ~33ms). The per-model
330  * BATCH size is per_model_max_streams above; the combined-mux batch is auto-derived
331  * (out_slots = unified ? per-model batch x2 : x1) and is NOT settable. */
332  guint mux_width;
333  guint mux_height;
334  gboolean mux_live_source;
335  guint model_mux_push_timeout;
336  guint combined_mux_push_timeout;
341  gboolean attach_perf_metric;
342  guint perf_metric_interval_sec;
350  gboolean copy_primary_buffer;
351  gboolean copy_shadow_buffer;
352  guint copy_buffer_pool_size;
363  gboolean lane_leaky;
364 
373  guint gpu;
374 
377  gint placement_policy;
378 
388  gboolean auto_gpu_scale;
389 
398  guint num_models;
402  ModelVersionArtifact versions[MM_MAX_MODELS * 4];
403  guint num_versions;
415  GMutex versions_lock;
416  gchar *default_primary;
417  gchar *default_primary_version;
418  gchar *default_shadow;
419  gchar *default_shadow_version;
420  gint default_primary_gpu;
424  gint default_shadow_gpu;
425 
429  guint num_bindings;
431 
432 /* A/B provenance user-meta: InferenceProvenanceMeta is now PUBLIC, defined in
433  * nvdsmeta_schema.h (tagged NVDS_CUSTOM_MSG_INFERENCE_PROVENANCE), so downstream
434  * DS components can parse it without this private header. It is attached as
435  * NvDsUserMeta on EACH frame before the combined display mux (ModelBin nvinfer
436  * src for inferred frames, passthrough queue src for no-infer frames), and lets
437  * nvmodelmux restore source_id after the combined mux rewrites it to a display
438  * slot index. Flat struct => the copy func is a single memcpy that survives the
439  * combined nvstreammux. */
440 
445 typedef enum
446 {
451 } ModelStatus;
452 
453 /* --------------------------------------------------------------------------------------- */
454 /* ModelBin: one logical model NAME for one ROLE. */
455 /* */
456 /* ghost sink_<idx> -> nvstreammux -> nvinfer -> nvstreamdemux -> ghost src_<idx> */
457 /* */
458 /* Multiple streams share a single ModelBin (true batched inference). A recycled */
459 /* index pool keeps mux/demux pad ids bounded (sink_0..sink_{max-1}). */
460 /* */
461 /* Lifecycle (role-agnostic): created at NULL (NOT_READY) -> loaded async to */
462 /* READY (engine warmed) -> SERVING when streams attach -> back to READY when the */
463 /* last stream leaves. The bin is only destroyed by an explicit unload. */
464 /* --------------------------------------------------------------------------------------- */
465 typedef struct
466 {
467  gchar *name;
468  gchar *role;
469  ModelType type;
473  gboolean perf_on;
474  ModelMuxPerf *perf;
475 
476  gchar *config_file;
477  guint unique_id;
478  guint max_streams;
479 
482  guint mux_width;
483  guint mux_height;
484  guint mux_push_timeout;
485  gint process_mode;
486  gboolean mux_live_source;
487  gint mux_gpu;
491  GstElement *bin;
492  GstElement *mux;
493  GstElement *conv_in;
500  GstElement *infer;
501  GstElement *conv_out;
505  GstElement *demux;
506  GstPad *zero_stream_drop_pad;
507  gulong zero_stream_drop_probe;
509  GQueue *free_idx;
510  GHashTable *idx_to_stream;
511  gint *slot_stream;
517  guint num_streams;
518  gboolean served;
523  gint status;
524  GThread *load_thread;
525  const GHashTable *stream_names;
526  gpointer pool;
528  gchar *engine;
530  gchar *version;
532  gchar *key;
536  guint inst;
539  gint gpu;
543  gboolean conv_cross;
548  gint conv_gpu;
549  gint cfg_gpu;
553  gboolean pinned;
557  gpointer next_shard;
561  GMutex prov_lock;
565  gchar *ota_old_version;
568  gchar *ota_old_engine;
569  gchar *ota_old_config;
574  gchar *ota_old_key;
581  gchar *ota_new_key;
582  gpointer ota_ib;
585  gboolean ota_await;
586  gpointer ota_group;
591  gboolean ota_ok;
593  gboolean ota_compensating;
597  GPtrArray *retired;
603 } ModelBin;
604 
625 typedef struct
626 {
627  gchar *name;
628  gchar *version;
629  gint gpu;
631  gchar *key;
633  ModelBin *bin;
638 
644 typedef struct
645 {
646  gchar *role;
647  guint base_uid;
648  guint next_uid;
649  guint max_streams;
650  GstElement *parent_pipeline;
651  GstElement *container;
652  GHashTable *models;
658  const ModelMuxConfig *config;
663  const GHashTable *stream_names;
664  DefaultModelRef default_ref;
668  gpointer owner;
669 } ModelPool;
670 
681 typedef enum
682 {
686 
696 #define MM_GPU_ANY (-1)
697 
698 /* ------------------------------------------------------------------ */
699 /* Per-stream ROUTING TABLE */
700 /* */
701 /* ModelMuxStreamEntry + ModelMuxRoleAttach are the bin's record of */
702 /* WHAT IT HAS WIRED UP for every attached stream, so a later detach / */
703 /* model-routing / promote / compaction can find and unplug exactly the */
704 /* pads and elements that belong to that stream -- and nothing else. */
705 /* */
706 /* ModelMuxBin.stream_wiring (hash: source_id -> ModelMuxStreamEntry*) */
707 /* | */
708 /* +-> StreamEntry { column, demux_src, tee, */
709 /* prim: RoleAttach -- lane to the PRIMARY model */
710 /* shad: RoleAttach -- lane to the SHADOW model (or off) } */
711 /* */
712 /* ONE StreamEntry per attached stream; each embeds TWO RoleAttach */
713 /* records inline (not allocated), one per role. A RoleAttach is the */
714 /* wiring of ONE physical lane: */
715 /* */
716 /* tee --> [conv] --> in_q --> ModelBin --> out_q --> out_mux */
717 /* */
718 /* i.e. WHICH model this role is routed to plus every element/pad the */
719 /* lane occupies (tee src pad, queues, optional copy converter, the */
720 /* combined-mux sink pad). Rerouting a role swaps only that lane's */
721 /* model hookup; the queues, the other role and all other streams keep */
722 /* running. model/status and the MM_DEBUG routing dump are walks over */
723 /* this table. */
724 /* */
725 /* Lifetime: created by modelmux_bin_attach_stream, freed by */
726 /* modelmux_stream_teardown on detach. All mutation happens on the main loop */
727 /* under ib->lock. */
728 /* ------------------------------------------------------------------ */
729 
733 typedef struct
734 {
735  gboolean active;
736  gboolean busy;
737  gchar *model;
738  ModelPool *role;
739  GstElement *conv;
742  GstElement *in_q;
743  GstElement *out_q;
744  GstPad *tee_src;
745  GstPad *out_mux_sink;
746  gint out_idx;
747  GstPad *tap_pad;
748  gulong tap_probe_id;
749  GstPad *verify_head_pad;
750  gulong verify_head_probe_id;
751  GstPad *verify_queue_pad;
752  gulong verify_queue_probe_id;
753  gpointer verify_ctx;
754  gboolean passthru;
758  gchar *pending_model;
762  gint req_gpu;
767  gboolean via_default;
778 
783 typedef struct
784 {
785  guint stream_id;
786  gint column;
789  guint branch_serial;
791  GstPad *demux_src;
792  GstPad *branch_tap_pad;
793  gulong branch_tap_probe_id;
794  GstElement *tee;
795  ModelMuxRoleAttach prim;
796  ModelMuxRoleAttach shad;
797  gpointer promote_ctx;
808 
809 /* -------------------------------------------------------------------- */
810 /* Frame accounting (MM_DEBUG only): per-(source,role) drop detection. */
811 /* */
812 /* Counts the SAME source frame at three points along its path so a */
813 /* drop can be both DETECTED and LOCALIZED: */
814 /* in -- entered the bin (in_demux probe) */
815 /* inferred -- passed the role's nvinfer (provenance probe) */
816 /* delivered-- left the combined mux (out-mux probe) */
817 /* gap = in - delivered: steady = in-flight latency (OK); GROWING = a */
818 /* real drop; <0 = make-before-break swap overlap. Counters are bumped */
819 /* LOCK-FREE (g_atomic) on streaming threads; the *_base fields are set */
820 /* on the main loop at role-attach / dump. Indexed by source_id (flat). */
821 /* ------------------------------------------------------------------ */
822 #define MM_ACCT_MAX 256
823 #define MM_ROLE_PRIMARY 0
824 #define MM_ROLE_SHADOW 1
825 #define MM_ROLE_SLOTS 2
826 
827 typedef struct
828 {
829  gint in_base;
830  gint infer_base;
831  gint out_base;
832  gint infer;
833  gint out;
834  gint last_out_fn;
835  gint warm;
836  gint floor;
837  gint over;
839  gint last_src_fn;
843 
844 typedef struct
845 {
846  gint in_count;
847  gint last_in_fn;
849 } ModelMuxAcct;
850 
870 typedef struct
871 {
872  guint *src;
873  guint n;
874  gchar *primary;
882  gchar *shadow;
883  gboolean clear_shadow;
884  gint p_gpu;
885  gint s_gpu;
886  gboolean p_via_default;
887  gboolean s_via_default;
889 
890 /* --------------------------------------------------------------------------- */
891 /* ModelMuxBin: the reusable inference subgraph. */
892 /* */
893 /* GhostPad sink (batched) -> nvstreamdemux -> per-stream tee */
894 /* -> { Primary ModelPool, Shadow ModelPool } */
895 /* role outputs -> combined nvstreammux -> GhostPad src (one batched output) */
896 /* */
897 /* The bin accepts ONE batched src (from nvmultiurisrcbin) on its sink GhostPad*/
898 /* and decouples it internally, so the bin's pad is its first/entry element. */
899 /* */
900 /* --------------------------------------------------------------------------- */
901 typedef struct
902 {
903  GstElement *bin;
904  GstElement *parent_pipeline;
906  const ModelMuxConfig *config;
907  guint max_streams;
908  gboolean unified;
910  gint active_streams;
914  GHashTable *stream_names;
929  GHashTable *stream_cam_ids;
930  GHashTable *stream_wiring;
931  GPtrArray *retired_names;
932  GHashTable *streams_pending;
934  GHashTable *streams_cancelled;
937  GMutex lock;
938  GMutex free_lock;
942  gboolean log_enabled;
943  guint debug_interval;
945  GstPad *sink_ghost;
946  GstElement *in_demux;
947  GstElement *out_mux;
948  GstPad *src_ghost;
950  GQueue *col_free_idx;
952  ModelPool *primary_pool;
953  ModelPool *shadow_pool;
954 
955  /* Type-less model/load: a model loaded via the API has NO primary/shadow type.
956  * It is warmed into this "limbo" map (role Unknown) inside the shared container,
957  * and PROMOTED into primary/shadow on first use (stream-add or model/update) --
958  * pure bookkeeping, zero-drop. Stays here (READY) until explicit model/unload. */
959  GHashTable *limbo_models;
962  guint next_limbo_gie;
964  gchar *name_slot[MM_ACCT_MAX];
973  GList *pending_frees;
976  GList *pending_sources;
978  guint compact_poll_id;
979  guint dump_source_id;
980  guint perf_timer_id;
981  guint64 routing_revision;
986  ModelMuxRevShared *rev_shared;
990  GPtrArray *pending_routes;
994  /* OTA rename-rollback hook (control layer): invoked on the MAIN loop by
995  * modelmux_ota_rename_rollback_main AFTER a failed update's identity rename was
996  * rolled back, with NO bin locks held at the call moment -- from_key = the
997  * rejected update's key (rolled back FROM), to_key = the restored serving
998  * key. Lets the owner re-sync its own key-addressed state. */
999  void (*ota_rollback_cb) (gpointer owner, const gchar * from_key,
1000  const gchar * to_key);
1001  gpointer ota_rollback_owner;
1002  gint shutting_down;
1003  gboolean ever_attached;
1008  gint frame_count;
1014  ModelMuxAcct acct[MM_ACCT_MAX];
1015  /* attach-perf-metric: per-source THROUGHPUT (frames/sec leaving the bin) for
1016  * PASSTHROUGH streams -- which run no nvinfer, so they have no ModelMuxPerf bin
1017  * counter. Bin-lifetime (indexed by source_id, like acct[]) so the recording
1018  * probe never dangles. Single writer per source (one passthrough lane), so the
1019  * lock-free ModelMuxPerfCounter record is safe; ticked under ib->lock by the perf
1020  * timer; read by the perf table + model/status. No inference latency exists on
1021  * this path, so only the rate is meaningful. */
1022  ModelMuxPerfCounter thru_perf[MM_ACCT_MAX];
1023 } ModelMuxBin;
1024 
1025 /* ------------------------------------------------------------------ */
1026 /* API */
1027 /* ------------------------------------------------------------------ */
1028 
1029 /* modelmux_config_parse takes the GObject element (GstNvModelMux) and is declared in
1030  * gstnvmodelmux.h -- it reconciles the parsed file with self->is_prop_set. */
1031 void modelmux_config_clear (ModelMuxConfig * config);
1032 /* Canonical model-instance key. model_key joins (name, version) into a freshly
1033  * allocated "name@version" (version defaults to MM_MODEL_VERSION_DEFAULT when NULL/empty);
1034  * used as the pool/limbo hash key so versions of one name coexist. model_key_split
1035  * splits a key back into bare name + version (both newly allocated; pass NULL to skip). */
1036 gchar *model_key (const gchar * name, const gchar * version);
1037 void model_key_split (const gchar * key, gchar ** name_out, gchar ** version_out);
1038 /* TRUE iff `v` is a valid model version: a positive integer with no leading zero
1039  * ("1","2",...,"42"). Rejects NULL/empty, "0", "01", "1", "1.0", negatives, non-digits.
1040  * (Triton model-repository convention -- versions are numbered dirs.) */
1041 gboolean modelmux_version_is_int (const gchar * v);
1042 const ModelCatalogEntry *modelmux_config_find_model (const ModelMuxConfig * config, const gchar * name);
1043 /* Auto-detect the inference backend from a model's config-file (nvinferserver protobuf
1044  * 'infer_config {' vs nvinfer INI '[property]'); defaults to nvinfer. modelmux_infer_plugin_str
1045  * returns the gst element name ("nvinfer" / "nvinferserver") for logs + element creation. */
1046 ModelType modelmux_detect_model_type (const gchar * config_file);
1047 const gchar *modelmux_infer_plugin_str (ModelType type);
1048 /* Derive a per-(name,version) config with this load's ARTIFACT + PLACEMENT applied:
1049  * `engine` (optional) swapped into the engine key and/or `gpu` (optional, -1 = keep the
1050  * config's device) written into the gpu key. Handles BOTH backends:
1051  * nvinfer : model-engine-file + gpu-id under [property] (INI) / property: (YAML)
1052  * nvinferserver : gpu_ids: [N] inside infer_config (protobuf text or YAML). A raw
1053  * .engine does not map to Triton (its model repository owns the
1054  * checkpoints) -> warned + skipped; the gpu placement still applies.
1055  * Returns the derived config path (caller g_free), or NULL when nothing could be derived
1056  * (caller uses the base config as-is). The derived filename is tagged with BOTH
1057  * `model_name` and `version` (e.g. trafficcamnet_1_config_infer_primary.txt). */
1058 gchar *modelmux_config_derive (const gchar * base_cfg, const gchar * engine, gint gpu,
1059  gint gie,
1060  const gchar * model_name, const gchar * version);
1061 /* Record/refresh the per-version artifact + placement of a runtime model/load or
1062  * model/update, so later lazy warms, in-place updates and gpu-addressed routing resolve
1063  * this version's engine/config/device. gpu=-1 keeps any previously recorded placement. */
1064 /* batch: 0 = leave the version's batch as-is (unset on a fresh entry). */
1065 void modelmux_config_register_version (ModelMuxConfig * config, const gchar * name,
1066  const gchar * version, const gchar * engine,
1067  const gchar * config_file, gint gpu, guint batch);
1068 /* Placement of a loaded (name, version): the gpu recorded at load/update time, or -1
1069  * when the version runs on its config's device (gpu 0 unless the config overrides). */
1070 /* Per-version batch (0 = unset; resolve name-level/catalog then global). Locked scan. */
1071 guint modelmux_config_version_batch (const ModelMuxConfig * config, const gchar * name,
1072  const gchar * version);
1073 /* The per-VERSION gie-unique-id a [model-<name>-<version>] block declares (-1 = none). */
1074 gint modelmux_config_version_gie (const ModelMuxConfig * config, const gchar * name,
1075  const gchar * version);
1076 gint modelmux_config_version_gpu (const ModelMuxConfig * config, const gchar * name,
1077  const gchar * version);
1078 /* TRUE when @name already has a version other than @version on record. The catalog base
1079  * config can back only ONE version; a sibling turns a bare load into two version numbers
1080  * resolving to one model. Locked scan. */
1081 gboolean modelmux_config_has_other_version (const ModelMuxConfig * config,
1082  const gchar * name, const gchar * version);
1083 /* Resolve the EFFECTIVE config path for a (name, version) from its per-version artifact
1084  * ([model-<name>-<version>] block): a custom config and/or an engine swapped into it.
1085  * Returns a newly-allocated config path (caller g_free) when an override applies, or NULL
1086  * when the version has no override (caller uses the catalog base config as-is).
1087  * *derive_failed (optional) is set TRUE when the version DOES carry an explicit engine/gpu
1088  * override but deriving it FAILED -- the caller must then refuse to instantiate rather than
1089  * fall back to the base config (which would run the wrong artifact/device). */
1090 gchar *modelmux_config_resolve_version_cfg (const ModelMuxConfig * config, const gchar * name,
1091  const gchar * version,
1092  gboolean * derive_failed);
1093 /* Device a model CONFIG FILE pins its inference to: nvinfer keyfile "gpu-id=N" or
1094  * nvinferserver pbtxt "gpu_ids: [N]". -1 = no key present (backend defaults to 0). */
1095 gint modelmux_config_file_gpu (const gchar * config_file);
1096 gint modelmux_config_file_process_mode (const gchar * config_file);
1097 /* The gie-unique-id a model's infer config declares (-1 = absent). A stage adopts it
1098  * as the model's gie id so `operate-on-gie-id` stays config-knowable, exactly as with
1099  * a plain nvinfer; the SHADOW lane adds MM_SHADOW_GIE_OFFSET so an A/B pair stays
1100  * distinguishable in the object meta. */
1101 gint modelmux_config_file_gie_id (const gchar * config_file);
1102 /* The gie-unique-id a SECONDARY operates ON (nvinfer `operate-on-gie-id`); -1 = absent,
1103  * nvinfer's default meaning every GIE. This is the model's INPUT filter, so it is also
1104  * the only correct answer to which stage's objects it actually classified -- the
1105  * MM_OVERLAY line uses it to label only the tiles the model really ran on. */
1106 gint modelmux_config_file_operate_on_gie (const gchar * config_file);
1107 /* modelmux_gpu_stats (whole-device NVML stats) lives in gstnvmodelmux_perf.h -- the
1108  * module header its definition includes, so the prototype is visible there
1109  * (tmake builds with -Werror=missing-prototypes). Included above. */
1110 /* Register a model at runtime (idempotent) so a stream can use a shadow/primary
1111  * that was not the configured default. Returns the (existing or new) entry. */
1112 const ModelCatalogEntry *modelmux_config_register_model (ModelMuxConfig * config, const gchar * name,
1113  const gchar * config_file,
1114  const gchar * engine_file,
1115  const gchar * version,
1116  guint max_streams);
1117 /* Update an ALREADY-registered model's artifacts in place (OTA): overwrites
1118  * config_file/engine_file/version when a non-NULL/non-empty value is supplied (others
1119  * left as-is). Returns the entry, or NULL if the name is not registered. */
1120 const ModelCatalogEntry *modelmux_config_update_model (ModelMuxConfig * config, const gchar * name,
1121  const gchar * config_file,
1122  const gchar * engine_file,
1123  const gchar * version);
1124 /* Resolve a stream's (primary, shadow) refs: config-time per-sensor binding
1125  * (matched by camera id) wins; any role it leaves unset falls back to that
1126  * role's RUNTIME default ref (the pool-embedded designation). Bindings are
1127  * static config; defaults are runtime state -- two sources, one resolution. */
1128 void modelmux_config_resolve_models (const ModelMuxConfig * config,
1129  const DefaultModelRef * def_primary,
1130  const DefaultModelRef * def_shadow,
1131  const gchar * camera_id,
1132  const gchar ** primary, const gchar ** shadow,
1133  const gchar ** primary_version,
1134  const gchar ** shadow_version,
1135  gboolean * primary_is_default,
1136  gboolean * shadow_is_default);
1137 
1138 /* ModelBin */
1139 ModelBin *model_bin_new (const gchar * name, const gchar * role,
1140  const gchar * config_file, const gchar * engine_file,
1141  const gchar * version, guint unique_id, guint max_streams,
1142  const ModelMuxConfig * config,
1143  GstElement * parent_pipeline, GstElement * container,
1144  const GHashTable * stream_names, guint inst);
1145 GstPad *model_bin_attach (ModelBin * model_bin, guint stream_id);
1146 gboolean model_bin_detach (ModelBin * model_bin, guint stream_id);
1147 gboolean model_bin_has_capacity (ModelBin * model_bin);
1148 guint model_bin_num_streams (ModelBin * model_bin);
1149 /* Warm the engine in the background so the bin reaches READY (idempotent). */
1150 void model_bin_load (ModelBin * model_bin);
1151 ModelStatus model_bin_status (ModelBin * model_bin);
1152 const gchar *model_status_str (ModelStatus s);
1153 /* Borrowed model version identity used by provenance, diagnostics and status.
1154  * The returned pointer is owned by the model bin and remains valid for readers. */
1155 G_GNUC_INTERNAL const gchar *model_version_str (ModelBin * model_bin);
1156 /* Backend-aware engine/identity string captured from a warmed model bin.
1157  * Returns a newly-allocated string; caller frees. */
1158 G_GNUC_INTERNAL gchar *get_infer_engine_str (ModelBin * model_bin);
1159 void model_bin_free (ModelBin * model_bin);
1160 
1161 /* ModelPool */
1162 ModelPool *model_pool_new (const gchar * role, guint base_uid, guint max_streams,
1163  GstElement * parent_pipeline, GstElement * container,
1164  const ModelMuxConfig * config, const GHashTable * stream_names);
1165 GstPad *model_pool_attach (ModelPool * rb, guint stream_id,
1166  const gchar * model_name, gint gpu, GstPad * in_pad,
1167  guint branch_serial,
1168  GstElement ** in_q_out, GstElement ** out_q_out,
1169  GstElement ** conv_out, gboolean * cap_overflow,
1170  ModelBin ** attached_bin_out);
1171 gboolean model_pool_detach (ModelPool * rb, guint stream_id, const gchar * model_name);
1172 /* Pre-create + warm a model in this pool so it is ready before streams arrive. */
1173 /* batch: explicit per-instance cap (0 = resolve: version registry -> catalog -> global). */
1174 gboolean model_pool_load_model (ModelPool * rb, const gchar * model_name,
1175  const gchar * cfg_override, guint batch);
1176 /* Explicit teardown of an IDLE (READY, 0-stream) model. Returns FALSE if it is
1177  * still serving streams. ModelBins are otherwise never destroyed on detach. */
1178 gboolean model_pool_unload_model (ModelPool * rb, const gchar * model_name);
1179 void model_pool_free (ModelPool * rb);
1180 /* Internal read-only helper for status/perf reporting. Caller must already hold
1181  * the owning ModelMuxBin lock while traversing pool membership. */
1182 G_GNUC_INTERNAL ModelBin *modelmux_perf_find_bin_for_source (ModelPool * pool,
1183  guint source_id);
1184 G_GNUC_INTERNAL void modelmux_role_set (ModelBin * model_bin, const gchar * role);
1185 G_GNUC_INTERNAL const gchar *modelmux_role_get (ModelBin * model_bin);
1186 G_GNUC_INTERNAL const gchar *modelmux_resolve_role (ModelBin * model_bin, guint source_id);
1187 G_GNUC_INTERNAL gint modelmux_role_idx (const gchar * role);
1188 G_GNUC_INTERNAL void modelmux_fmt_route_cell (gchar * buf, gsize n,
1189  const ModelMuxRoleAttach * ra);
1190 G_GNUC_INTERNAL gboolean modelmux_debug_enabled (void);
1191 G_GNUC_INTERNAL void modelmux_debug_configure (ModelMuxBin * ib);
1192 G_GNUC_INTERNAL void modelmux_schedule_dump (ModelMuxBin * ib,
1193  guint delay_seconds);
1194 
1195 /* ---- SECONDARY stage: linear chain -- ModelMuxSgieBin (gstnvmodelmux_sgie.c) ----
1196  * At process-mode=2 one model serves ALL streams on the already-batched buffer, so the
1197  * stage needs no demux/mux and no per-stream lanes -- only
1198  * sink -> queue -> [xfer-in] -> infer -> [xfer-out] -> src.
1199  * Built instead of the ModelMuxBin when the stage is a secondary. */
1200 typedef struct _ModelMuxSgieBin ModelMuxSgieBin;
1201 
1202 ModelMuxSgieBin *modelmux_sgie_new (GstElement * parent, const gchar * name,
1203  const ModelMuxConfig * config);
1204 void modelmux_sgie_free (ModelMuxSgieBin * sgie_bin);
1205 GstPad *modelmux_sgie_get_sink (ModelMuxSgieBin * sgie_bin);
1206 GstPad *modelmux_sgie_get_src (ModelMuxSgieBin * sgie_bin);
1207 /* the serving model's identity + element, for logging and model/status */
1208 GstElement *modelmux_sgie_get_infer (ModelMuxSgieBin * sgie_bin);
1209 const gchar *modelmux_sgie_model_name (ModelMuxSgieBin * sgie_bin);
1210 const gchar *modelmux_sgie_model_version (ModelMuxSgieBin * sgie_bin);
1211 /* GET plane, answered by the stage that hosts the model. Same v1 shape as the
1212  * primary's, tagged with process_mode so the host can merge per-stage responses. */
1213 gchar *modelmux_sgie_status_json (ModelMuxSgieBin * sgie_bin,
1214  const gchar * f_model, const gchar * f_version);
1215 gchar *modelmux_sgie_route_json (ModelMuxSgieBin * sgie_bin);
1216 /* Point this stage at the pipeline-wide routing counter (takes a ref). The
1217  * secondary has no routing table of its own, but a route APPLIED here still
1218  * invalidates every controller's if_revision, so it bumps the same number the
1219  * primary does -- see MODELMUX_CONTEXT_TYPE_ROUTING. */
1221  ModelMuxRevShared * rev);
1222 /* Bump it after a route this stage ACCEPTED (applied now, or parked on a warming
1223  * model -- the declarative intent is recorded either way, exactly as a queued
1224  * promotion counts at the primary). No-op when no counter is attached. */
1226 /* Which line this stage owns in the MM_OVERLAY stack. The primary draws at the top and
1227  * each secondary gets its own line under it, so a pipeline with several secondaries
1228  * shows one name per stage instead of them fighting over one label. Assigned at
1229  * READY->PAUSED, when every stage's catalog is parsed and the set of stages is known. */
1230 void modelmux_sgie_set_overlay_slot (ModelMuxSgieBin * sgie_bin, guint slot);
1231 /* Display facts for the MM_DEBUG models_table (see gstnvmodelmux_debug.c), one
1232  * resident model per @idx. Returns FALSE once @idx is past the last one, so the
1233  * caller walks with `for (i = 0; modelmux_sgie_get_info (bin, i, ...); i++)` and
1234  * never reaches into the struct itself. */
1235 gboolean modelmux_sgie_get_info (ModelMuxSgieBin * sgie_bin, guint idx,
1236  const gchar ** name, const gchar ** version,
1237  const gchar ** backend, guint * gie, gint * gpu,
1238  guint * streams, const gchar ** state,
1239  gboolean * serving, gchar ** engine);
1240 /* model/update: in-place OTA on the stage's one inference element (nvinfer only).
1241  * Fills the verdict (@http/@err_code/@reason/@hint -- all static strings) whether it
1242  * triggers or refuses; returns TRUE only when the swap was handed to nvinfer, which
1243  * confirms it asynchronously. */
1244 gboolean modelmux_sgie_update (ModelMuxSgieBin * sgie_bin, const gchar * name,
1245  const gchar * from_version, const gchar * version,
1246  const gchar * config_file, const gchar * engine_file,
1247  gint * http, const gchar ** err_code,
1248  const gchar ** reason, const gchar ** hint);
1249 /* model/load: build + warm ANOTHER version of a model this stage's catalog declares,
1250  * resident but NOT inferring -- "available, not active". It costs VRAM and changes no
1251  * output until an all-streams model/routing makes it the serving one. Same verdict
1252  * contract as _update; TRUE means accepted (202) and warming on its own thread. */
1253 gboolean modelmux_sgie_load (ModelMuxSgieBin * sgie_bin, const gchar * name,
1254  const gchar * version, const gchar * config_file,
1255  const gchar * engine_file, gint * http,
1256  const gchar ** err_code, const gchar ** reason,
1257  const gchar ** hint);
1258 /* model/routing: make an already-resident model the SERVING one -- an all-streams
1259  * rebind, instant because the displaced model stays loaded and warm, and reversed by
1260  * the identical call naming the other version. A target still warming PARKS the route
1261  * (the current model keeps serving until it is ready) rather than being refused.
1262  * Payload shape -- streams:"all", no shadow, no camera list -- is the caller's to
1263  * check; this decides on residency. Same verdict contract as _load. */
1264 gboolean modelmux_sgie_route (ModelMuxSgieBin * sgie_bin, const gchar * name,
1265  const gchar * version, gint * http,
1266  const gchar ** err_code, const gchar ** reason,
1267  const gchar ** hint);
1268 /* model/unload: release a RESIDENT model and its engine. Refuses exactly one thing --
1269  * the model that is SERVING, because a secondary cannot run without one; reroute to
1270  * another resident model first. An omitted @version is accepted only while the name has
1271  * a single version here. Same verdict contract as _load. */
1272 gboolean modelmux_sgie_unload (ModelMuxSgieBin * sgie_bin, const gchar * name,
1273  const gchar * version, gint * http,
1274  const gchar ** err_code, const gchar ** reason,
1275  const gchar ** hint);
1276 
1277 /* Per-tile debug overlay (env MM_OVERLAY=1), shared by BOTH stages so one env var
1278  * governs the whole picture: the primary draws its provenance line at the top of each
1279  * tile, the secondary stacks the model it is serving just under it. Debug only.
1280  *
1281  * The two meta types are forward-declared rather than pulled in with nvdsmeta.h: this
1282  * header is included by every translation unit, and only the two overlay callers need
1283  * the full definitions (they include nvdsmeta.h themselves). */
1284 struct _NvDsBatchMeta;
1285 struct _NvDsFrameMeta;
1286 gboolean modelmux_overlay_enabled (void);
1287 void modelmux_draw_label (struct _NvDsBatchMeta * bmeta,
1288  struct _NvDsFrameMeta * fm,
1289  guint x_offset, guint y_offset, const gchar * text,
1290  const gchar * role);
1291 
1292 /* ModelMuxBin */
1293 ModelMuxBin *modelmux_bin_new (GstElement * pipeline, const gchar * name,
1294  guint max_streams, const ModelMuxConfig * config);
1295 GstPad *modelmux_bin_get_sink (ModelMuxBin * ib);
1296 /* p_gpu/s_gpu: requested instance placement per role (MM_GPU_ANY = no constraint).
1297  * p_via_default/s_via_default: TRUE when that role's model came from the DEFAULT
1298  * fallback (see ModelMuxRoleAttach.via_default). */
1299 /* name = DISPLAY name (overlay, model/status) -- may be the camera_id when the
1300  * host supplied only one identifier.
1301  * cam_id = the ROUTABLE camera_id from stream/add, or NULL when none was given.
1302  * Kept apart from `name` because only this one is accepted by
1303  * POST /api/v1/model/routing (see ModelMuxBin.stream_cam_ids). */
1304 gboolean modelmux_bin_attach_stream (ModelMuxBin * ib, guint stream_id,
1305  const gchar * name, const gchar * cam_id,
1306  const gchar * primary, const gchar * shadow,
1307  gint p_gpu, gint s_gpu,
1308  gboolean p_via_default, gboolean s_via_default);
1309 gboolean modelmux_bin_detach_stream (ModelMuxBin * ib, guint stream_id);
1310 /* Update the ROUTING TABLE for one stream: re-point its primary and/or shadow to
1311  * new model(s). Re-wires only the role(s) whose model changed, under a single
1312  * pad-block, leaving the unchanged role running. (Atomic per-stream model swap.)
1313  * p_gpu/s_gpu constrain WHICH instance serves each role (MM_GPU_ANY = any). */
1314 gboolean modelmux_bin_update_routing (ModelMuxBin * ib, guint stream_id,
1315  const gchar * primary, const gchar * shadow,
1316  gint p_gpu, gint s_gpu,
1317  gboolean p_via_default, gboolean s_via_default);
1318 GstPad *modelmux_bin_get_src (ModelMuxBin * ib);
1319 /* number of streams currently attached (0 => the bin/sources have drained). */
1321 /* Pre-load the configured default primary (+ shadow if set) so they are READY
1322  * before any stream is added (zero attach-time downtime). */
1323 /* Preload the configured default primary (+ shadow) so they are READY before any
1324  * stream attaches. wait=TRUE blocks until each default is WARMED and returns FALSE
1325  * if any FAILED to warm (caller fails the state change); wait=FALSE kicks the async
1326  * warm and returns TRUE immediately (legacy behaviour). */
1327 gboolean modelmux_bin_load_defaults (ModelMuxBin * ib);
1328 /* TYPE-LESS model/load: warm the named model into the limbo map (role Unknown) so
1329  * it is READY but unassigned. Its primary/shadow type is decided LATER, on first
1330  * use (stream-add or model/update), which PROMOTES it into the matching pool. The
1331  * model must already be in the config registry (name/config-file). Idempotent.
1332  * `gpu` >= 0 PINS the bin to that device BEFORE the warm starts (conv-in placed
1333  * on the final device from the first buffer); -1 = the config's device. */
1334 ModelStatus modelmux_bin_load_model (ModelMuxBin * ib, const gchar * key,
1335  const gchar * cfg_override, gint gpu,
1336  guint batch);
1337 /* model/load with gpus[]: materialize ONE shard per listed GPU for (name,version) --
1338  * the base shard from cfgs[0]/gpus[0] plus n-1 PINNED sibling shards, each with its own
1339  * per-GPU derived config (cfgs[i]; NULL => the base config), all sharing one gie-id and
1340  * warming in the background like the base. n<=1 degrades to modelmux_bin_load_model
1341  * (identical single-instance path). ALL-OR-NOTHING: if any sibling shard fails to
1342  * materialize, every instance this call created (base included) is rolled back and
1343  * MODEL_FAILED is returned -- a partial group is never silently deployed. Otherwise
1344  * returns the base shard's status. */
1346  const gchar * key,
1347  const gchar * const cfgs[],
1348  const gint gpus[], guint n,
1349  guint batch);
1350 /* TRUE iff `key` has a LIVE shard whose effective placement is `gpu` (a shard's own
1351  * recorded gpu, falling back to the version registry, then device 0). FALSE when the
1352  * model is not live -- callers fall back to the config registry. */
1353 gboolean modelmux_bin_model_on_gpu (ModelMuxBin * ib, const gchar * key,
1354  gint gpu);
1355 /* Collect the DISTINCT effective gpus of `key`'s live shard chain into `out` (capacity
1356  * `cap`); returns the count (0 = not live). Used for engine-coverage validation and
1357  * teaching error messages. */
1358 guint modelmux_bin_model_gpus (ModelMuxBin * ib, const gchar * key,
1359  gint * out, guint cap);
1360 /* LIVE instance's batch/stream cap for `key` (base shard's max_streams; 0 = not live).
1361  * Load/update admission uses it: a loaded version's batch is immutable. */
1362 guint modelmux_bin_model_batch (ModelMuxBin * ib, const gchar * key);
1363 /* model/load with set_default_primary/shadow: create + warm the model DIRECTLY into the
1364  * role's pool (bypassing limbo), like a config-time default preload. cfg_override = the
1365  * per-version/engine-derived config (NULL => catalog base). Returns the model status. */
1366 ModelStatus modelmux_bin_load_into_pool (ModelMuxBin * ib, gboolean shadow,
1367  const gchar * key, const gchar * cfg_override);
1368 /* Re-designate the RUNTIME default for a role to (name, version[, gpu]). "Default" is derived
1369  * everywhere from the role pool's DefaultModelRef (routing fallback, unload protection, dump,
1370  * dedup), so this
1371  * single swap makes every subsystem follow; the prior default auto-demotes. `gpu` >= 0 persists
1372  * a placement pin for default-resolved streams; gpu < 0 keeps the existing pin when the NAME is
1373  * unchanged (OTA version rename) and resets it to MM_GPU_ANY on an identity change (a pin
1374  * belongs to the identity it was set for). Locks internally (callers must NOT hold ib->lock). */
1375 void modelmux_bin_set_default (ModelMuxBin * ib, gboolean shadow,
1376  const gchar * name, const gchar * version,
1377  gint gpu);
1378 /* CLEAR a role's runtime default designation ("no default for this role"): the
1379  * counterpart of modelmux_bin_set_default, and what default{"shadow": null} needs.
1380  * Drops only the IDENTITY -- the model it named keeps serving its attached streams
1381  * and is reclaimed by the normal idle paths once they leave. Idempotent (clearing
1382  * an absent default is a no-op). Streams whose lane RESOLVED from this default are
1383  * not touched here: sweeping them is the caller's decision, exactly as it is for a
1384  * default switch. Locks internally; callers must NOT hold ib->lock. */
1385 void modelmux_bin_clear_default (ModelMuxBin * ib, gboolean shadow);
1386 /* Apply a sensor id / display name to an ALREADY-ATTACHED stream (late bind).
1387  * Either field may be NULL to leave it unchanged; a stream that has gone is a no-op. */
1388 void modelmux_bin_set_stream_identity (ModelMuxBin * ib, guint stream_id,
1389  const gchar * name, const gchar * cam_id);
1390 /* Read-only access to a role's runtime default designation (the pool-embedded
1391  * ref) for the element-side control plane (route guards, resolution). Returned
1392  * pointer is owned by the pool; main-loop readers are same-thread with all
1393  * writers, streaming-thread readers must hold ib->lock. */
1394 const DefaultModelRef *modelmux_bin_get_default (ModelMuxBin * ib, gboolean shadow);
1395 /* LOCKED "is this the configured default?" predicate, for callers that are NOT on
1396  * the main loop -- the REST control plane answers model/unload synchronously on the
1397  * civetweb thread. The DefaultModelRef strings are replaced+freed by the default
1398  * writers under ib->lock, so dereferencing the borrowed ref from
1399  * modelmux_bin_get_default() off the main loop races a writer freeing the old
1400  * key/name. This compares UNDER ib->lock and returns only a boolean, so no borrowed
1401  * pointer escapes to the caller.
1402  * version != NULL/"" -> exact (name, version) IDENTITY match ("name@version")
1403  * version == NULL/"" -> bare NAME match (ANY version of the name is a default)
1404  * Locks internally: callers must NOT already hold ib->lock. */
1405 gboolean modelmux_bin_is_configured_default (ModelMuxBin * ib, const gchar * name,
1406  const gchar * version);
1407 /* Collect source-ids of streams currently routed to `key` in the given role (incl. a
1408  * passthrough stream awaiting promotion to it). Fills `out` (capacity `cap`), returns count.
1409  * Used to reroute streams off a demoted old default onto the new one. */
1410 guint modelmux_bin_streams_on_model (ModelMuxBin * ib, gboolean shadow,
1411  const gchar * key, guint * out, guint cap,
1412  gboolean default_only);
1413 /* In-place OTA checkpoint reload: hot-swap the engine (and/or config) on the
1414  * already-loaded model `name` across ALL its shards -- same bin, same gie, no reroute.
1415  * `engine` set -> nvinfer "model-engine-file" (engine-only swap); else `config` -> full
1416  * "config-file-path" reload. `version` updates provenance/status. Returns TRUE if the
1417  * model was found and the reload was triggered; FALSE if `name` has no live bin. */
1418 gboolean modelmux_bin_reload_model (ModelMuxBin * ib, const gchar * name,
1419  const gchar * config, const gchar * engine,
1420  const gchar * version);
1421 /* Multi-GPU in-place reload: like modelmux_bin_reload_model, but each shard is
1422  * swapped to the engine matching ITS effective gpu ({gpus[i] -> engines[i]}, n pairs).
1423  * ALL-OR-NOTHING admission under one lock hold: if any shard's gpu has no engine in
1424  * the map, NOTHING is swapped and FALSE is returned (caller reports GPU_ENGINE_MISSING). */
1426  const gchar * name, const gint gpus[],
1427  const gchar * const engines[], guint n,
1428  const gchar * version);
1429 /* TRUE if `name` has a LIVE bin (limbo or either pool). Distinguishes a first-load
1430  * (create) from an OTA reload / update-on-missing. */
1431 gboolean modelmux_bin_model_loaded (ModelMuxBin * ib, const gchar * name);
1432 /* TRUE while any live bin of bare model `name` has an OTA update awaiting nvinfer's
1433  * confirm (model/load admission gate: keeps the update's freed OLD key reservable
1434  * for a failed confirm's rename-back). */
1435 gboolean modelmux_bin_update_in_flight (ModelMuxBin * ib, const gchar * name);
1436 /* Ensure the named model exists + is warming in the given role's pool (idempotent
1437  * get-or-create + background load). Promotes a limbo model into the role if needed.
1438  * Used by model/update; NOT called on stream-add. */
1440  gboolean shadow, const gchar * name);
1441 /* QUERY ONLY (no create, no load): current status of an ALREADY-loaded model in
1442  * the role's pool. Returns MODEL_WARMING/READY/SERVING, or -1 if the model
1443  * is absent (never loaded). Used by stream-add routing so a requested-but-not-
1444  * loaded model is NOT auto-loaded -- routing falls back to the default instead. */
1446  gboolean shadow, const gchar * name);
1447 /* Explicit unload of a model in the given role's pool (model-unload API). Refuses
1448  * if the model is still SERVING; destroys the bin if READY. Returns TRUE
1449  * on success. */
1450 /* JSON status dump; schema is always {"models":[...],"streams":[...]}. Filters are
1451  * INDEPENDENT -- each narrows its own array: f_model -> models[] = that model; f_stream/
1452  * f_sid (>=0) -> streams[] = that stream; both -> one model + one stream; none -> full.
1453  * An array whose filter is absent while the other's is present comes back []. g_free it. */
1454 gchar *modelmux_bin_status_json (ModelMuxBin * ib, const gchar * f_model,
1455  const gchar * f_version, const gchar * f_stream,
1456  gint f_sid);
1457 /* Build the ROUTING-PLANE snapshot for GET /api/v1/model/routing: routes[] +
1458  * default{} + routing_revision, with streams GROUPED by identical routing state.
1459  * f_camera = optional strict point lookup on camera_id. NULL (and only NULL) is
1460  * the full snapshot; any non-NULL value -- INCLUDING "" -- is a PRESENT filter,
1461  * so an empty or unresolvable id yields an empty routes[] rather than the whole
1462  * fleet. Takes ib->lock itself.
1463  * Returns a newly allocated JSON string; caller frees with g_free. */
1464 gchar *modelmux_bin_route_json (ModelMuxBin * ib, const gchar * f_camera);
1465 /* Bump the routing revision (under ib->lock): call after every APPLIED routing
1466  * change -- scoped reroute, default switch, in-place update trigger. */
1468 /* Point this bin at the pipeline-wide counter (takes a ref, drops any previous).
1469  * Called by the element once the routing GstContext is negotiated; until then the
1470  * bin falls back to its own field, so the value is never garbage. */
1472 /* Current routing revision: the shared counter when one is attached, this bin's
1473  * own otherwise. Takes ib->lock. */
1475 /* REPLACE the mirrored list of accepted-but-deferred routes (under ib->lock),
1476  * taking ownership of `notes` and freeing whatever was there. notes==NULL clears
1477  * it. Wholesale replacement on purpose -- the control layer republishes its whole
1478  * queue after every change, so there is no per-entry sync to get wrong. */
1479 void modelmux_bin_set_pending_routes (ModelMuxBin * ib, GPtrArray * notes);
1480 /* Free a ModelMuxPendingRouteNote (GDestroyNotify for the array above). */
1481 void modelmux_pending_route_note_free (gpointer note);
1482 /* Sink-ghost query probe that answers /api/v1/model/status custom queries. */
1483 G_GNUC_INTERNAL GstPadProbeReturn modelmux_status_query_probe (GstPad * pad,
1484  GstPadProbeInfo * info,
1485  gpointer udata);
1486 /* Sink-ghost query probe that answers the SYNCHRONOUS control-admission query
1487  * (model/unload today): decides admission on the spot and writes back the
1488  * verdict + reason. udata is the ModelMuxBin (self = parent_pipeline). */
1489 G_GNUC_INTERNAL GstPadProbeReturn modelmux_control_query_probe (GstPad * pad,
1490  GstPadProbeInfo * info,
1491  gpointer udata);
1492 /* Post a model-plane COMPLETION event (model-loaded / -unloaded / -updated /
1493  * streams-routed) on the pipeline bus so apps react like they do for stream-add.
1494  * `src` is any element in the pipeline; the message routes up to the app bus. */
1495 G_GNUC_INTERNAL void modelmux_post_model_event (GstElement * src,
1496  const gchar * event, const gchar * name, const gchar * version,
1497  gint gpu, gboolean ok, const gchar * detail);
1498 /* Control-plane only: friendly source (camera) name for a source id, or NULL. */
1499 G_GNUC_INTERNAL const gchar * modelmux_bin_source_name (ModelMuxBin * ib, guint sid);
1500 /* Read-only: is (name@version)=`key` loaded (limbo/primary/shadow), and how many
1501  * streams is it serving across its shard chain? TRUE if present (*streams set).
1502  * *streams_csv (optional, owned) = the serving stream sensor names ("cam-1,cam-3").
1503  * Lets model/unload report a precise serving-vs-not-loaded reason up front. */
1504 gboolean modelmux_bin_key_serving (ModelMuxBin * ib, const gchar * key,
1505  guint * streams, gchar ** streams_csv);
1506 /* Bare `name`: comma-separated sensor names of every stream serving ANY loaded
1507  * version of the name (owned; "" if none). For the name-only unload reason. */
1508 gchar * modelmux_bin_name_serving_streams (ModelMuxBin * ib, const gchar * name);
1509 /* Scoped reroute -- n source ids, or n==0 => all active streams.
1510  * p_gpu/s_gpu: per-role placement constraint (MM_GPU_ANY = any). */
1511 guint modelmux_bin_update_routing_scoped (ModelMuxBin * ib, const guint * src_ids,
1512  guint n, const gchar * primary, const gchar * shadow,
1513  gint p_gpu, gint s_gpu,
1514  gboolean p_via_default, gboolean s_via_default);
1515 /* Promote a stream's no-infer PASSTHROUGH primary to a now-WARMED model (deferred attach):
1516  * tears down the passthrough branch and attaches the model branch in its place. Called by
1517  * the control-plane poller once the model warms. No-op if the stream is gone / not passthru.
1518  * p_gpu/s_gpu: per-role placement constraint (MM_GPU_ANY = any). */
1519 void modelmux_bin_promote_passthru (ModelMuxBin * ib, guint stream_id,
1520  const gchar * model, const gchar * shadow, gint p_gpu, gint s_gpu,
1521  gboolean p_via_default, gboolean s_via_default);
1522 /* Tag a passthrough stream with the model it is awaiting (deferred promotion), so the routing
1523  * table shows "<model> (passthru)" instead of "-". No-op if the stream isn't passthrough.
1524  * `gpu` records the requested placement the eventual promote must honour (MM_GPU_ANY = any). */
1525 void modelmux_bin_set_pending_model (ModelMuxBin * ib, guint stream_id,
1526  const gchar * model, gint gpu, gboolean via_default);
1527 /* Clear an ABANDONED pending tag (deferred promote's target failed/unloaded): the
1528  * stream reverts to a plain passthrough (no intended model, no placement, no origin). */
1529 void modelmux_bin_clear_pending_model (ModelMuxBin * ib, guint stream_id);
1530 /* List the streams (within the src_ids scope; n==0 => all active streams) whose PRIMARY is a
1531  * no-infer PASSTHROUGH branch. *out is allocated to the scope size (caller g_free's);
1532  * returns the count -- sized dynamically so a route-all can never silently truncate. Used by
1533  * model/routing: a passthrough stream can't be rerouted through the normal role machinery
1534  * (no model lane to swap) -- it must go through the deferred-PROMOTE path instead. */
1536  const guint * src_ids, guint n, guint ** out);
1537 /* Every wired stream's source_id (caller g_free's *out); returns the count.
1538  * Materialises a whole-pipeline scope into the fleet it means right now. */
1539 guint modelmux_bin_active_stream_ids (ModelMuxBin * ib, guint ** out);
1540 /* IN-PLACE move: a promote (primary=<current shadow>, shadow="none") or a
1541  * clean swap (primary=<old shadow>, shadow=<old primary>) whose scope FULLY COVERS the
1542  * bins involved is done by re-labeling the existing bins (role+pool+records) instead of
1543  * building new ones -- no new bin, no engine reload, gie-id preserved, zero frame drop
1544  * (the bins' pads are never touched). Returns TRUE if handled in place; FALSE if not
1545  * eligible (caller falls back to the generic create+warm reroute). */
1546 gboolean modelmux_bin_try_inplace (ModelMuxBin * ib, const guint * src_ids,
1547  guint n, const gchar * primary, const gchar * shadow);
1548 /* TYPE-LESS model/unload: free the model by name wherever it lives -- the limbo
1549  * map OR either pool -- when idle. No primary/shadow type needed. */
1550 gboolean modelmux_bin_unload_model (ModelMuxBin * ib, const gchar * key);
1551 /* Result of a gpu-scoped model/unload (modelmux_bin_unload_model_gpus). */
1552 typedef enum
1553 {
1554  MM_UNLOAD_GPU_REMOVED = 0, /* the requested per-gpu instance(s) were removed */
1555  MM_UNLOAD_GPU_ALL, /* the set covered every gpu -> whole version gone */
1556  MM_UNLOAD_GPU_ABSENT, /* (name@version) is not loaded */
1557  MM_UNLOAD_GPU_NO_MATCH, /* loaded, but no instance sits on any listed gpu */
1558  MM_UNLOAD_GPU_SERVING /* a targeted instance is serving/mid-load: refused */
1560 /* GPU-scoped model/unload: drain ONLY the instance(s) of `key` (name@version)
1561  * that sit on a gpu in gpus[0..n_gpus) -- the version's other per-gpu instances
1562  * keep serving. Idle-only per targeted instance (a SERVING/mid-load target
1563  * refuses the WHOLE op, changing nothing). If the set covers every gpu of the
1564  * version it degrades to a full unload (MM_UNLOAD_GPU_ALL). On SERVING refusal,
1565  * *serving_gpu / *serving_streams report the first offending instance so the
1566  * caller can emit a clear "still inferring" error. */
1568  const gchar * key, const gint * gpus, guint n_gpus,
1569  gint * serving_gpu, guint * serving_streams, gchar ** serving_csv);
1570 /* Unload EVERY non-serving version of `name` (bare): serving versions are left intact.
1571  * Returns the count unloaded; *present (optional) = how many "name@*" versions exist
1572  * (lets the caller tell "all serving" from "not loaded"). Used when no version given. */
1573 guint modelmux_bin_unload_versions (ModelMuxBin * ib, const gchar * name,
1574  guint * present);
1575 void modelmux_bin_free (ModelMuxBin * ib);
1576 
1577 G_END_DECLS
1578 
1579 #endif /* __DEEPSTREAM_MULTIMODEL_APP_H__ */
model_bin_new
ModelBin * model_bin_new(const gchar *name, const gchar *role, const gchar *config_file, const gchar *engine_file, const gchar *version, guint unique_id, guint max_streams, const ModelMuxConfig *config, GstElement *parent_pipeline, GstElement *container, const GHashTable *stream_names, guint inst)
modelmux_control_query_probe
G_GNUC_INTERNAL GstPadProbeReturn modelmux_control_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer udata)
modelmux_bin_source_name
const G_GNUC_INTERNAL gchar * modelmux_bin_source_name(ModelMuxBin *ib, guint sid)
modelmux_bin_model_gpus
guint modelmux_bin_model_gpus(ModelMuxBin *ib, const gchar *key, gint *out, guint cap)
modelmux_config_file_gie_id
gint modelmux_config_file_gie_id(const gchar *config_file)
ModelPool
ModelPool: the live INVENTORY of one role's (Primary or Shadow) instantiated models,...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:644
modelmux_bin_load_model
ModelStatus modelmux_bin_load_model(ModelMuxBin *ib, const gchar *key, const gchar *cfg_override, gint gpu, guint batch)
ModelCatalogEntry
A model definition from the [model-*] config groups.
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:239
modelmux_config_resolve_models
void modelmux_config_resolve_models(const ModelMuxConfig *config, const DefaultModelRef *def_primary, const DefaultModelRef *def_shadow, const gchar *camera_id, const gchar **primary, const gchar **shadow, const gchar **primary_version, const gchar **shadow_version, gboolean *primary_is_default, gboolean *shadow_is_default)
modelmux_bin_new
ModelMuxBin * modelmux_bin_new(GstElement *pipeline, const gchar *name, guint max_streams, const ModelMuxConfig *config)
StreamModelBinding
A config-time per-sensor model binding, parsed from a [stream-model-<sensor_id>] group.
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:277
modelmux_bin_key_serving
gboolean modelmux_bin_key_serving(ModelMuxBin *ib, const gchar *key, guint *streams, gchar **streams_csv)
modelmux_bin_clear_default
void modelmux_bin_clear_default(ModelMuxBin *ib, gboolean shadow)
modelmux_version_is_int
gboolean modelmux_version_is_int(const gchar *v)
ModelMuxRoleAttach
One role branch (Primary or Shadow) attached for a stream: the model this role is currently routed to...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:733
modelmux_sgie_get_infer
GstElement * modelmux_sgie_get_infer(ModelMuxSgieBin *sgie_bin)
modelmux_bin_unload_model
gboolean modelmux_bin_unload_model(ModelMuxBin *ib, const gchar *key)
modelmux_sgie_route
gboolean modelmux_sgie_route(ModelMuxSgieBin *sgie_bin, const gchar *name, const gchar *version, gint *http, const gchar **err_code, const gchar **reason, const gchar **hint)
MM_MAX_STREAMS_DEFAULT
#define MM_MAX_STREAMS_DEFAULT
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:57
MM_UNLOAD_GPU_REMOVED
@ MM_UNLOAD_GPU_REMOVED
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1554
ModelMuxAcctRole
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:827
modelmux_fmt_route_cell
G_GNUC_INTERNAL void modelmux_fmt_route_cell(gchar *buf, gsize n, const ModelMuxRoleAttach *ra)
ModelBackendInfo
One row of the backend registry.
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:168
modelmux_sgie_model_version
const gchar * modelmux_sgie_model_version(ModelMuxSgieBin *sgie_bin)
modelmux_sgie_get_sink
GstPad * modelmux_sgie_get_sink(ModelMuxSgieBin *sgie_bin)
modelmux_backend_at_position
gboolean modelmux_backend_at_position(ModelType type, gint process_mode)
TRUE iff @type may run at @process_mode (MM_PROCESS_MODE_PGIE / _SGIE).
modelmux_perf_find_bin_for_source
G_GNUC_INTERNAL ModelBin * modelmux_perf_find_bin_for_source(ModelPool *pool, guint source_id)
model_pool_unload_model
gboolean model_pool_unload_model(ModelPool *rb, const gchar *model_name)
modelmux_bin_try_inplace
gboolean modelmux_bin_try_inplace(ModelMuxBin *ib, const guint *src_ids, guint n, const gchar *primary, const gchar *shadow)
modelmux_bin_set_rev_shared
void modelmux_bin_set_rev_shared(ModelMuxBin *ib, ModelMuxRevShared *rev)
modelmux_bin_routing_revision
guint64 modelmux_bin_routing_revision(ModelMuxBin *ib)
modelmux_config_register_model
const ModelCatalogEntry * modelmux_config_register_model(ModelMuxConfig *config, const gchar *name, const gchar *config_file, const gchar *engine_file, const gchar *version, guint max_streams)
ModelStatus
ModelStatus
ModelBin lifecycle (applies to EVERY ModelBin, any role).
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:445
ModelMuxUnloadGpuResult
ModelMuxUnloadGpuResult
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1552
modelmux_rev_shared_get
guint64 modelmux_rev_shared_get(ModelMuxRevShared *rev)
Current value; 0 for a NULL @rev, which is the same answer a stage that has not negotiated the contex...
model_pool_load_model
gboolean model_pool_load_model(ModelPool *rb, const gchar *model_name, const gchar *cfg_override, guint batch)
modelmux_sgie_update
gboolean modelmux_sgie_update(ModelMuxSgieBin *sgie_bin, const gchar *name, const gchar *from_version, const gchar *version, const gchar *config_file, const gchar *engine_file, gint *http, const gchar **err_code, const gchar **reason, const gchar **hint)
get_infer_engine_str
G_GNUC_INTERNAL gchar * get_infer_engine_str(ModelBin *model_bin)
modelmux_sgie_set_rev_shared
void modelmux_sgie_set_rev_shared(ModelMuxSgieBin *sgie_bin, ModelMuxRevShared *rev)
MM_UNLOAD_GPU_ALL
@ MM_UNLOAD_GPU_ALL
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1555
model_status_str
const gchar * model_status_str(ModelStatus s)
modelmux_bin_update_in_flight
gboolean modelmux_bin_update_in_flight(ModelMuxBin *ib, const gchar *name)
model_bin_status
ModelStatus model_bin_status(ModelBin *model_bin)
modelmux_bin_route_json
gchar * modelmux_bin_route_json(ModelMuxBin *ib, const gchar *f_camera)
modelmux_sgie_get_info
gboolean modelmux_sgie_get_info(ModelMuxSgieBin *sgie_bin, guint idx, const gchar **name, const gchar **version, const gchar **backend, guint *gie, gint *gpu, guint *streams, const gchar **state, gboolean *serving, gchar **engine)
ModelMuxSgieBin
struct _ModelMuxSgieBin ModelMuxSgieBin
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1200
modelmux_bin_passthru_streams
guint modelmux_bin_passthru_streams(ModelMuxBin *ib, const guint *src_ids, guint n, guint **out)
MM_ROLE_SLOTS
#define MM_ROLE_SLOTS
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:825
modelmux_sgie_status_json
gchar * modelmux_sgie_status_json(ModelMuxSgieBin *sgie_bin, const gchar *f_model, const gchar *f_version)
MM_MAX_MODELS
#define MM_MAX_MODELS
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:59
modelmux_sgie_new
ModelMuxSgieBin * modelmux_sgie_new(GstElement *parent, const gchar *name, const ModelMuxConfig *config)
modelmux_resolve_role
const G_GNUC_INTERNAL gchar * modelmux_resolve_role(ModelBin *model_bin, guint source_id)
modelmux_bin_get_default
const DefaultModelRef * modelmux_bin_get_default(ModelMuxBin *ib, gboolean shadow)
modelmux_schedule_dump
G_GNUC_INTERNAL void modelmux_schedule_dump(ModelMuxBin *ib, guint delay_seconds)
modelmux_sgie_get_src
GstPad * modelmux_sgie_get_src(ModelMuxSgieBin *sgie_bin)
version
int version
Definition: sources/libs/nvll_batch_jpeg_encode/oss/jpeglib.h:908
modelmux_bin_status_json
gchar * modelmux_bin_status_json(ModelMuxBin *ib, const gchar *f_model, const gchar *f_version, const gchar *f_stream, gint f_sid)
half_float::floor
half floor(half arg)
Nearest integer not greater than half value.
Definition: includes/half.hpp:4096
modelmux_bin_bump_routing_revision
void modelmux_bin_bump_routing_revision(ModelMuxBin *ib)
modelmux_pending_route_note_free
void modelmux_pending_route_note_free(gpointer note)
model_pool_new
ModelPool * model_pool_new(const gchar *role, guint base_uid, guint max_streams, GstElement *parent_pipeline, GstElement *container, const ModelMuxConfig *config, const GHashTable *stream_names)
_MmPerf
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_perf.h:77
modelmux_bin_attach_stream
gboolean modelmux_bin_attach_stream(ModelMuxBin *ib, guint stream_id, const gchar *name, const gchar *cam_id, const gchar *primary, const gchar *shadow, gint p_gpu, gint s_gpu, gboolean p_via_default, gboolean s_via_default)
model_bin_num_streams
guint model_bin_num_streams(ModelBin *model_bin)
modelmux_bin_clear_pending_model
void modelmux_bin_clear_pending_model(ModelMuxBin *ib, guint stream_id)
modelmux_config_version_batch
guint modelmux_config_version_batch(const ModelMuxConfig *config, const gchar *name, const gchar *version)
modelmux_config_clear
void modelmux_config_clear(ModelMuxConfig *config)
ModelMuxAcct
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:844
modelmux_sgie_unload
gboolean modelmux_sgie_unload(ModelMuxSgieBin *sgie_bin, const gchar *name, const gchar *version, gint *http, const gchar **err_code, const gchar **reason, const gchar **hint)
modelmux_bin_model_loaded
gboolean modelmux_bin_model_loaded(ModelMuxBin *ib, const gchar *name)
modelmux_detect_model_type
ModelType modelmux_detect_model_type(const gchar *config_file)
model_pool_detach
gboolean model_pool_detach(ModelPool *rb, guint stream_id, const gchar *model_name)
MODEL_VISION_ENCODER
@ MODEL_VISION_ENCODER
nvinferserver (Triton backend)
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:140
MODEL_FAILED
@ MODEL_FAILED
engine loaded, >=1 stream attached
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:450
modelmux_bin_prepare_model
ModelStatus modelmux_bin_prepare_model(ModelMuxBin *ib, gboolean shadow, const gchar *name)
ModelMuxPendingRouteNote
One ACCEPTED-but-not-yet-applied model/routing, mirrored down from the control layer so the status vi...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:870
ModelType
ModelType
Inference backend element used inside a ModelBin.
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:136
modelmux_bin_set_default
void modelmux_bin_set_default(ModelMuxBin *ib, gboolean shadow, const gchar *name, const gchar *version, gint gpu)
model_key_split
void model_key_split(const gchar *key, gchar **name_out, gchar **version_out)
modelmux_config_version_gie
gint modelmux_config_version_gie(const ModelMuxConfig *config, const gchar *name, const gchar *version)
modelmux_role_set
G_GNUC_INTERNAL void modelmux_role_set(ModelBin *model_bin, const gchar *role)
ModelBin
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:465
MODEL_BACKEND_N
@ MODEL_BACKEND_N
nvdsvisionencoder (object embeddings)
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:141
modelmux_debug_configure
G_GNUC_INTERNAL void modelmux_debug_configure(ModelMuxBin *ib)
modelmux_infer_plugin_str
const gchar * modelmux_infer_plugin_str(ModelType type)
_NvDsBatchMeta
Holds information about a formed batch containing frames from different sources.
Definition: includes/nvdsmeta.h:264
MODEL_SERVING
@ MODEL_SERVING
engine loaded, idle (0 streams); ready to take streams
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:449
modelmux_role_idx
G_GNUC_INTERNAL gint modelmux_role_idx(const gchar *role)
modelmux_config_register_version
void modelmux_config_register_version(ModelMuxConfig *config, const gchar *name, const gchar *version, const gchar *engine, const gchar *config_file, gint gpu, guint batch)
modelmux_bin_set_stream_identity
void modelmux_bin_set_stream_identity(ModelMuxBin *ib, guint stream_id, const gchar *name, const gchar *cam_id)
modelmux_sgie_bump_routing_revision
void modelmux_sgie_bump_routing_revision(ModelMuxSgieBin *sgie_bin)
modelmux_config_version_gpu
gint modelmux_config_version_gpu(const ModelMuxConfig *config, const gchar *name, const gchar *version)
modelmux_bin_get_sink
GstPad * modelmux_bin_get_sink(ModelMuxBin *ib)
modelmux_config_resolve_version_cfg
gchar * modelmux_config_resolve_version_cfg(const ModelMuxConfig *config, const gchar *name, const gchar *version, gboolean *derive_failed)
ModelMuxConfig
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:286
MODEL_WARMING
@ MODEL_WARMING
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:447
modelmux_role_get
const G_GNUC_INTERNAL gchar * modelmux_role_get(ModelBin *model_bin)
gstnvmodelmux_perf.h
modelmux_config_derive
gchar * modelmux_config_derive(const gchar *base_cfg, const gchar *engine, gint gpu, gint gie, const gchar *model_name, const gchar *version)
modelmux_bin_load_defaults
gboolean modelmux_bin_load_defaults(ModelMuxBin *ib)
modelmux_bin_set_pending_routes
void modelmux_bin_set_pending_routes(ModelMuxBin *ib, GPtrArray *notes)
modelmux_bin_set_pending_model
void modelmux_bin_set_pending_model(ModelMuxBin *ib, guint stream_id, const gchar *model, gint gpu, gboolean via_default)
modelmux_bin_promote_passthru
void modelmux_bin_promote_passthru(ModelMuxBin *ib, guint stream_id, const gchar *model, const gchar *shadow, gint p_gpu, gint s_gpu, gboolean p_via_default, gboolean s_via_default)
modelmux_bin_free
void modelmux_bin_free(ModelMuxBin *ib)
modelmux_sgie_set_overlay_slot
void modelmux_sgie_set_overlay_slot(ModelMuxSgieBin *sgie_bin, guint slot)
modelmux_config_has_other_version
gboolean modelmux_config_has_other_version(const ModelMuxConfig *config, const gchar *name, const gchar *version)
modelmux_bin_active_stream_ids
guint modelmux_bin_active_stream_ids(ModelMuxBin *ib, guint **out)
modelmux_bin_load_into_pool
ModelStatus modelmux_bin_load_into_pool(ModelMuxBin *ib, gboolean shadow, const gchar *key, const gchar *cfg_override)
model_pool_free
void model_pool_free(ModelPool *rb)
modelmux_debug_enabled
G_GNUC_INTERNAL gboolean modelmux_debug_enabled(void)
modelmux_config_find_model
const ModelCatalogEntry * modelmux_config_find_model(const ModelMuxConfig *config, const gchar *name)
modelmux_config_file_process_mode
gint modelmux_config_file_process_mode(const gchar *config_file)
modelmux_bin_model_status
gint modelmux_bin_model_status(ModelMuxBin *ib, gboolean shadow, const gchar *name)
modelmux_bin_reload_model_multi
gboolean modelmux_bin_reload_model_multi(ModelMuxBin *ib, const gchar *name, const gint gpus[], const gchar *const engines[], guint n, const gchar *version)
modelmux_sgie_free
void modelmux_sgie_free(ModelMuxSgieBin *sgie_bin)
modelmux_bin_model_on_gpu
gboolean modelmux_bin_model_on_gpu(ModelMuxBin *ib, const gchar *key, gint gpu)
modelmux_bin_get_src
GstPad * modelmux_bin_get_src(ModelMuxBin *ib)
ModelStatus
ModelStatus
ModelBin lifecycle (applies to EVERY ModelBin, any role).
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:445
modelmux_config_file_gpu
gint modelmux_config_file_gpu(const gchar *config_file)
MODEL_INFERSERVER
@ MODEL_INFERSERVER
nvinfer (TensorRT; default)
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:139
MODEL_WARMED
@ MODEL_WARMED
engine still building/loading; cannot attach yet
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:448
modelmux_config_apply_properties
gboolean modelmux_config_apply_properties(GstElement *element, const gchar *config_file, const gchar *group)
Apply every key of @group in @config_file to @element as the property of the same name,...
modelmux_bin_streams_on_model
guint modelmux_bin_streams_on_model(ModelMuxBin *ib, gboolean shadow, const gchar *key, guint *out, guint cap, gboolean default_only)
model_pool_attach
GstPad * model_pool_attach(ModelPool *rb, guint stream_id, const gchar *model_name, gint gpu, GstPad *in_pad, guint branch_serial, GstElement **in_q_out, GstElement **out_q_out, GstElement **conv_out, gboolean *cap_overflow, ModelBin **attached_bin_out)
modelmux_bin_model_batch
guint modelmux_bin_model_batch(ModelMuxBin *ib, const gchar *key)
modelmux_bin_update_routing_scoped
guint modelmux_bin_update_routing_scoped(ModelMuxBin *ib, const guint *src_ids, guint n, const gchar *primary, const gchar *shadow, gint p_gpu, gint s_gpu, gboolean p_via_default, gboolean s_via_default)
modelmux_config_file_operate_on_gie
gint modelmux_config_file_operate_on_gie(const gchar *config_file)
modelmux_bin_unload_versions
guint modelmux_bin_unload_versions(ModelMuxBin *ib, const gchar *name, guint *present)
model_bin_has_capacity
gboolean model_bin_has_capacity(ModelBin *model_bin)
model_key
gchar * model_key(const gchar *name, const gchar *version)
modelmux_bin_detach_stream
gboolean modelmux_bin_detach_stream(ModelMuxBin *ib, guint stream_id)
ModelVersionArtifact
A per-version artifact override from a [model-<name>-<version>] config group: the engine/checkpoint a...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:253
modelmux_bin_is_configured_default
gboolean modelmux_bin_is_configured_default(ModelMuxBin *ib, const gchar *name, const gchar *version)
modelmux_post_model_event
G_GNUC_INTERNAL void modelmux_post_model_event(GstElement *src, const gchar *event, const gchar *name, const gchar *version, gint gpu, gboolean ok, const gchar *detail)
modelmux_rev_shared_ref
ModelMuxRevShared * modelmux_rev_shared_ref(ModelMuxRevShared *rev)
modelmux_sgie_load
gboolean modelmux_sgie_load(ModelMuxSgieBin *sgie_bin, const gchar *name, const gchar *version, const gchar *config_file, const gchar *engine_file, gint *http, const gchar **err_code, const gchar **reason, const gchar **hint)
modelmux_status_query_probe
G_GNUC_INTERNAL GstPadProbeReturn modelmux_status_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer udata)
model_bin_detach
gboolean model_bin_detach(ModelBin *model_bin, guint stream_id)
MM_UNLOAD_GPU_ABSENT
@ MM_UNLOAD_GPU_ABSENT
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1556
modelmux_rev_shared_new
ModelMuxRevShared * modelmux_rev_shared_new(void)
A new counter at revision 0, refcount 1.
PACK_PLACEMENT
@ PACK_PLACEMENT
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:683
modelmux_bin_update_routing
gboolean modelmux_bin_update_routing(ModelMuxBin *ib, guint stream_id, const gchar *primary, const gchar *shadow, gint p_gpu, gint s_gpu, gboolean p_via_default, gboolean s_via_default)
modelmux_sgie_route_json
gchar * modelmux_sgie_route_json(ModelMuxSgieBin *sgie_bin)
model_version_str
const G_GNUC_INTERNAL gchar * model_version_str(ModelBin *model_bin)
modelmux_backend
const ModelBackendInfo * modelmux_backend(ModelType type)
The registry row for @type.
SPREAD_PLACEMENT
@ SPREAD_PLACEMENT
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:684
modelmux_bin_num_streams
guint modelmux_bin_num_streams(ModelMuxBin *ib)
_NvDsFrameMeta
Holds metadata for a frame in a batch.
Definition: includes/nvdsmeta.h:308
modelmux_bin_reload_model
gboolean modelmux_bin_reload_model(ModelMuxBin *ib, const gchar *name, const gchar *config, const gchar *engine, const gchar *version)
MM_ACCT_MAX
#define MM_ACCT_MAX
max source_id tracked (flat, lock-free)
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:822
ModelType
ModelType
Inference backend element used inside a ModelBin.
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:136
modelmux_bin_unload_model_gpus
ModelMuxUnloadGpuResult modelmux_bin_unload_model_gpus(ModelMuxBin *ib, const gchar *key, const gint *gpus, guint n_gpus, gint *serving_gpu, guint *serving_streams, gchar **serving_csv)
MM_UNLOAD_GPU_SERVING
@ MM_UNLOAD_GPU_SERVING
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1558
ModelMuxRevShared
struct _ModelMuxRevShared ModelMuxRevShared
The counter itself: refcounted (each stage holds one ref) and self-locking, so it can be read while a...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:119
modelmux_config_update_model
const ModelCatalogEntry * modelmux_config_update_model(ModelMuxConfig *config, const gchar *name, const gchar *config_file, const gchar *engine_file, const gchar *version)
ModelPlacementPolicy
ModelPlacementPolicy
Stream placement policy across a multi-GPU instance group ([multimodel] placement-policy) – applies o...
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:681
MODEL_INFER
@ MODEL_INFER
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:138
ModelMuxUnloadGpuResult
ModelMuxUnloadGpuResult
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1552
MM_UNLOAD_GPU_NO_MATCH
@ MM_UNLOAD_GPU_NO_MATCH
Definition: 9.2/sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:1557
modelmux_overlay_enabled
gboolean modelmux_overlay_enabled(void)
ModelMuxBin
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:901
modelmux_rev_shared_get_type
GType modelmux_rev_shared_get_type(void)
modelmux_bin_name_serving_streams
gchar * modelmux_bin_name_serving_streams(ModelMuxBin *ib, const gchar *name)
modelmux_rev_shared_unref
void modelmux_rev_shared_unref(ModelMuxRevShared *rev)
modelmux_draw_label
void modelmux_draw_label(struct _NvDsBatchMeta *bmeta, struct _NvDsFrameMeta *fm, guint x_offset, guint y_offset, const gchar *text, const gchar *role)
ModelMuxPerfCounter
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_perf.h:58
model_bin_free
void model_bin_free(ModelBin *model_bin)
DefaultModelRef
DefaultModelRef: a role's RUNTIME default model DESIGNATION – embedded in that role's ModelPool ("thi...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:625
ModelMuxStreamEntry
Per-stream bookkeeping inside the ModelMuxBin: ONE record per attached stream (the routing-table row)...
Definition: sources/gst-plugins/gst-nvmodelmux/gstnvmodelmux_priv.h:783
model_bin_load
void model_bin_load(ModelBin *model_bin)
model_bin_attach
GstPad * model_bin_attach(ModelBin *model_bin, guint stream_id)
modelmux_rev_shared_bump
guint64 modelmux_rev_shared_bump(ModelMuxRevShared *rev)
Increment and return the new value.
modelmux_sgie_model_name
const gchar * modelmux_sgie_model_name(ModelMuxSgieBin *sgie_bin)
modelmux_bin_load_model_instances
ModelStatus modelmux_bin_load_model_instances(ModelMuxBin *ib, const gchar *key, const gchar *const cfgs[], const gint gpus[], guint n, guint batch)