"git@developer.sourcefind.cn:jerrrrry/infinicore.git" did not exist on "a19efb54f4a07116956bb927fd74a6e8be929807"
Commit 77e9fc8c authored by das-qa's avatar das-qa
Browse files

Add deepstream-test3 deepstream-test4 and deepstream_mqtt_test

parent 633cf47f
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
APP:= deepstream-test4-app
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=7.1
LIB_INSTALL_DIR?=/opt/deepstream/lib/
APP_INSTALL_DIR?=/opt/deepstream/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
C_SRCS:= $(wildcard *.c)
CPP_SRCS:= $(wildcard *.cpp)
INCS:= $(wildcard *.h)
PKGS:= gstreamer-1.0
OBJS:= $(CPP_SRCS:.cpp=.o) $(C_SRCS:.c=.o)
CFLAGS+= -I/opt/deepstream/include/ \
-I /opt/dtk/cuda/cuda-12/targets/x86_64-linux/include
CFLAGS+= $(shell pkg-config --cflags $(PKGS))
LIBS:= $(shell pkg-config --libs $(PKGS))
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lrt \
-I /opt/dtk/cuda/cuda-12/targets/x86_64-linux/lib -lcudart -lnvds_yml_parser \
-lnvbufsurface_sugon -lnvdsgst_helper \
-lcuda -lyaml-cpp -Wl,-rpath,$(LIB_INSTALL_DIR)
all: $(APP)
%.o: %.cpp $(INCS) Makefile
$(CXX) -c -o $@ $(CFLAGS) $<
%.o: %.c $(INCS) Makefile
$(CC) -c -o $@ $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CXX) -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
*****************************************************************************
* SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*****************************************************************************
*****************************************************************************
deepstream-test4-app
README
*****************************************************************************
===============================================================================
1. Prerequisites:
===============================================================================
Please follow instructions in the apps/sample_apps/deepstream-app/README on how
to install the prerequisites for Deepstream SDK, the DeepStream SDK itself and
the apps.
You must have the following development packages installed
GStreamer-1.0
GStreamer-1.0 Base Plugins
GStreamer-1.0 gstrtspserver
X11 client-side library
To install these packages, execute the following command:
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
libgstrtspserver-1.0-dev libx11-dev
This example can be configured to use either the nvinfer or the nvinferserver
element for inference.
If nvinferserver is selected, the Triton Inference Server is used for inference
processing. In this case, the example needs to be run inside the
DeepStream-Triton docker container. Please refer
samples/configs/deepstream-app-triton/README for the steps to download the
container image and setup model repository.
#Deepstream msgbroker supports sending messages to Azure(mqtt) IOThub, kafka, AMQP broker(rabbitmq) and Redis
Dependencies
------------
Azure Iot:
----------
Refer to the README files available under
/opt/nvidia/deepstream/deepstream/sources/libs/azure_protocol_adaptor
for detailed documentation on prerequisites and usages of Azure protocol
adaptor with the message broker plugin for sending messages to cloud.
Kafka:
------
Refer to the README file available under
/opt/nvidia/deepstream/deepstream/sources/libs/kafka_protocol_adaptor
for detailed documentation on prerequisites and usages of kafka protocol
adaptor with the message broker plugin for sending messages to cloud.
AMQP (rabbitmq):
----------------
Install rabbitmq-c library
--------------------------
Refer to the README file available under
/opt/nvidia/deepstream/deepstream/sources/libs/amqp_protocol_adaptor
for detailed documentation on prerequisites and usages of rabbitmq based
amqp protocol adaptor with the message broker plugin for sending messages to cloud.
Redis:
------
Refer to the README file available under
/opt/nvidia/deepstream/deepstream/sources/libs/redis_protocol_adaptor
for detailed documentation on prerequisites and usages of redis protocol
adaptor with the message broker plugin for sending messages to cloud.
SETUP:
1.Use --proto-lib or -p command line option to set the path of adaptor library.
Adaptor library can be found at /opt/nvidia/deepstream/deepstream/lib
kafka lib - libnvds_kafka_proto.so
azure device client - libnvds_azure_proto.so
AMQP lib - libnvds_amqp_proto.so
Redis lib - libnvds_redis_proto.so
2.Use --conn-str command line option as required to set connection to backend server.
For Azure - Full Azure connection string
For Kafka - Connection string of format: host;port
For Amqp - Connection string of format: host;port;username;password
For Redis - Connection string of format: host;port
Provide connection string under quotes. e.g. --conn-str="host;port;topic;password"
3.Use --topic or -t command line option to provide message topic
4.Use --schema or -s command line option to select the message schema (optional).
Json payload to send to cloud can be generated using different message schemas.
schema = 0; Full message schema with separate payload per object (Default)
schema = 1; Minimal message with multiple objects in single payload.
schema = 2; Protobuf encoded message with multiple objects in single payload.
Refer user guide to get more details about message schema.
5.Use --no-display to disable display.
6.Use --msg2p-meta to choose the metadata type to create payload (optional).
0=Event Msg meta(default), Create NVDS_EVENT_MSG_META type of meta and attach to buffer
1=nvdsmeta, Use the fields within NvDsFrameMeta/NvDsObjectMeta to populate payload
7.Use --frame-interval to specify frame interval to generate message payload
default value=30; Message payloads generated every 30 frames
8.Use --cfg-file or -c command line option to set adaptor configuration file.
This is optional if connection string has all relevent information.
For kafka: use /opt/nvidia/deepstream/deepstream/sources/libs/kafka_protocol_adaptor/cfg_kafka.txt as reference.
This file is used to define the parition key field to be used while sending messages to the
kafka broker. Refer Kafka Protocol Adaptor section in the DeepStream Plugin Manual for
more details about using this config option. The partition-key setting within the cfg_kafka.txt
should be set based on the schema type selected using the --schema option. Set this to
"sensor.id" in case of Full message schema, and to "sensorId" in case of Minimal message schema
For Azure, use /opt/nvidia/deepstream/deepstream/sources/libs/azure_protocol_adaptor/device_client/cfg_azure.txt as reference.
It has the following section:
[message-broker]
#connection_str = HostName=<my-hub>.azure-devices.net;DeviceId=<device_id>;SharedAccessKey=<my-policy-key>
#custom_msg_properties = <key>=<value>;
#share-connection=1
Azure device connection string:
-------------------------------
You can provide the connection_str within cfg_azure.txt of format:
connection_str = HostName=<my-hub>.azure-devices.net;DeviceId=<device_id>;SharedAccessKey=<my-policy-key>
OR
you can pass in full connection string with --conn-str option
For AMQP, use /opt/nvidia/deepstream/deepstream/sources/libs/amqp_protocol_adaptor/cfg_amqp.txt as reference.
It has the following default options:
[message-broker]
password = guest
hostname = localhost
username = guest
port = 5672
exchange = amq.topic
topic = topicname
#share-connection=1
AMQP connection string:
----------------------
Provide hostname, port, username, password details in the cfg_amqp.txt
OR
you can pass in full connection string with --conn-str option in format: "hostname;port;username;password"
For Redis, use /opt/nvidia/deepstream/deepstream/sources/libs/redis_protocol_adaptor/cfg_redis.txt as reference.
It has the following default options:
[message-broker]
hostname=localhost
port=6379
consumergroup=mygroup
consumername=myname
streamsize=10000
share-connection = 1
Redis connection string:
----------------------
Provide hostname, port details in the cfg_redis.txt
OR
you can pass in full connection string with --conn-str option in format: "hostname;port"
NOTE:
- DO NOT delete the line [message-broker] in cfg file. Its the section identifier used for parsing
- Share connection
----------------
#share-connection=1
Uncomment the field share-connection in cfg_*.txt and set its value to 1
if you need to generate a connection signature. This signature is a unique string
which is generated by parsing all the connection related params used for making a connection.
Uncommenting this field signifies that the connection created can be shared
with other components within the same process.
7. Enable logging:
Go through the README to setup & enable logs for the messaging libraries(kafka, azure, amqp)
$ cat ../../../tools/nvds_logger/README
===============================================================================
2. Purpose:
===============================================================================
This sample builds on top of the deepstream-test1 sample to demonstrate to use
"nvmsgconv" and "nvmsgbroker" plugins in the pipeline. Create NVDS_EVENT_MSG_META
type of meta and attach to buffer. NVDS_EVENT_MSG_META is used for different types
of objects e.g. vehicle, person etc.
===============================================================================
3. To compile:
===============================================================================
$ Set CUDA_VER in the MakeFile as per platform.
For both Jetson & x86, CUDA_VER=12.6
$ sudo make (sudo not required in case of docker containers)
NOTE: To compile the sources, run make with "sudo" or root permission.
===============================================================================
4. Usage:
===============================================================================
Two ways to run the application:
1.Run with command line arguments as shown below. In this method, user needs to modify the source
code of deepstream-test4-app to configure pipeline properties.
$ ./deepstream-test4-app -i <H264 filename> -p <Proto adaptor library> --conn-str=<Connection string> --topic=<topicname> -s <0/1>
2.Run with the yml file. In this method, user needs to update the yml file to configure
pipeline properties.
$ ./deepstream-test4-app <yml file>
e.g. $ ./deepstream-test4-app dstest4_config.yml
The GIE configuration group in the YAML configuration file of the application
can be used to set the inference plugin type (nvinfer or nvinferserver) and
corresponding plugin configuration file.
3.Send the image by the broker based on Kafka
1) Change the parameters of msgconv filed in the dstest4_config.yml
2) Run with the yml file
$ ./deepstream-test4-app <yml file>
e.g. $ ./deepstream-test4-app dstest4_config.yml
3) The format of the image message
Image message fields are separated by ";".
Specific Format: "image;image_format;image_widthximage_height;time;encoded_data;"
For Example: "image;jpg;640x480;2023-07-31T10:20:13;xxxxxxxxxxx;"
4) How to decode the data encoded by base64 for consumer
C/C++ snippet code
-----------------
#include <glib.h>
gsize size = 0;
guchar *decoded_data = g_base64_decode (encoded_data, &size);
-----------------
Python snippet code
-----------------
import base64
decoded_data = base64.b64decode(encoded_data)
-----------------
NOTE: More details about the message adapters can be found at README inside DS_PACKAGE_DIR/sources/libs/*_protocol_adaptor
Update the msgbroker properties, "proto-lib", "conn-str" and "topic" accordingly in the dstest4_config.yml before running
the application.
Azure Iotedge runtime integration of deepstream-test4-app:
----------------------------------------------------------
# Refer to sections within DS_PACKAGE_DIR/sources/libs/azure_protocol_adaptor/module_client/README to:
1. Create azure IotHub
2. Register a new Azure IoT Edge device from the Azure portal
3. Setup and install Azure Iot Edge on your machine
4. Install dependencies
5. Specify connection string
6. Use cfg file (optional)
7. Install & setup nvidia-docker
8. Deploy a iotedge module
9. Start the edge runtime
# On Azure iothub deployment page, use the information below as an example to use deepstream-test4-app using
* sample video stream (sample_720p.h264)
* send messages with minimal schema
* with display disabled
* Message topic = mytopic
(Note: Message topic cant be empty)
NOTE: Sign up & create a Nvidia GPU Cloud account to be to pull containers : https://ngc.nvidia.com/
Once you sign in goto Dashboard->Configuration->Get API key (to get your nvcr.io Authentication details)
Deployment of a Module:
-----------------------
On the Azure portal, Click on the Iot edge device you have created and click Set Modules:
Container Registry Settings:
Name: NGC
Address: nvcr.io
User Name: $oauthtoken
Password: <password (or API key) from your NGC account>
Deployment modules:
Add new module:
- Name: ds
- Image URI:
For x86 dockers:
docker pull nvcr.io/nvidia/deepstream:<tag>-devel
docker pull nvcr.io/nvidia/deepstream:<tag>-samples
docker pull nvcr.io/nvidia/deepstream:<tag>-iot
docker pull nvcr.io/nvidia/deepstream:<tag>-base
docker pull nvcr.io/nvidia/deepstream:<tag>-triton
For Jetson dockers:
docker pull nvcr.io/nvidia/deepstream-l4t:<tag>-samples
docker pull nvcr.io/nvidia/deepstream-l4t:<tag>-iot
docker pull nvcr.io/nvidia/deepstream-l4t:<tag>-base
- container Create options:
{
"HostConfig": {
"Runtime": "nvidia",
},
"WorkingDir": "/opt/nvidia/deepstream/deepstream/sources/apps/sample_apps/deepstream-test4",
"ENTRYPOINT":
[
"/opt/nvidia/deepstream/deepstream/bin/deepstream-test4-app",
"-i", "/opt/nvidia/deepstream/deepstream/ samples/streams/sample_720p.h264",
"-p",
"/opt/nvidia/deepstream/deepstream/lib/libnvds_azure_edge_proto.so",
"--no-display",
"-s",
"1",
"--topic",
"mytopic"
]
}
- specify route options for the module:
option 1) Default route where every message from every module is sent upstream
{
"routes": {
"route": "FROM /messages/* INTO $upstream"
}
}
option 2) you can mention specific routes where messages sent upstream based on topic name
ex: in the sample test programs, topic name "mytopic" is used for the module name ds
{
"routes": {
"route": "FROM /messages/modules/ds/outputs/mytopic INTO $upstream",
}
}
#Start the edge runtime and verify if modules are running:
---------------------------------------------------------
#Restart the iotedge on your system
sudo systemctl restart iotedge
#Give it a few seconds
#check edge runtime status
systemctl status iotedge
#List the modules running
sudo iotedge list
#check output from the modules
sudo iotedge logs ds
This document shall describe about the sample deepstream-test4 application.
This sample builds on top of the deepstream-test1 sample to demonstrate how to:
* Use "nvmsgconv" and "nvmsgbroker" plugins in the pipeline.
* Create NVDS_EVENT_MSG_META type of meta and attach to buffer.
* Use NVDS_EVENT_MSG_META for different types of objects e.g. vehicle, person etc.
* Provide copy / free functions if meta data is extended through "extMsg" field.
* Use "msg_custom_meta" to send images.
"nvmsgconv" plugin uses NVDS_EVENT_MSG_META type of metadata from the buffer
and generates the "DeepStream Schema" payload in Json format. Static properties
of schema are read from configuration file in the form of key-value pair.
Check dstest4_msgconv_config.txt for reference. Generated payload is attached
as NVDS_META_PAYLOAD type metadata to the buffer.
"nvmsgbroker" plugin extracts NVDS_META_PAYLOAD type of metadata from the buffer
and sends that payload to the server using APIs in nvmsgbroker C library.
Generating custom metadata for different type of objects:
In addition to common fields provided in NvDsEventMsgMeta structure, user can
also create custom objects and attach to buffer as NVDS_EVENT_MSG_META metadata.
To do that NvDsEventMsgMeta provides "extMsg" and "extMsgSize" fields. User can
create custom structure, fill that structure and assign the pointer of that
structure as "extMsg" and set the "extMsgSize" accordingly.
If custom object contains fields that can't be simply mem copied then user should
also provide function to copy and free those objects.
Refer generate_event_msg_meta() to know how to use "extMsg" and "extMsgSize"
fields for custom objects and how to provide copy/free function and attach that
object to buffer as metadata.
NOTE: This app by default sends message for first object of every 30th frame.
Default option uses NVDS_EVENT_MSG_META type (--msg2p-meta 0 or -m 0)
To change the frequency of messages, modify the following line in source code accordingly.
if (is_first_object && !(frame_number % frame_interval)) should be changed to:
if (!(frame_number % frame_interval)) //To get all objects of a single frame
If NvDsMeta type is used (--msg2p-meta 1 or -m 1),
every frame_interval, payload is generated and all objects in a frame are part of payload.
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*/
#include <gst/gst.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <cuda_runtime_api.h>
#include <sys/timeb.h>
#include "gstnvdsmeta.h"
#include "nvdsmeta_schema.h"
#include "nvds_yml_parser.h"
#include "nvbufsurface.h"
// #include "nvds_obj_encode.h"
#include <sys/stat.h>
#include <stdio.h>
#include "deepstream_test4_yml_parse.h"
//#define ENABLE_DUMP_FILE
#ifdef ENABLE_DUMP_FILE
FILE *fp;
char fileObjNameString[1024];
#endif
//#define MEASURE_ENCODE_TIME
#ifdef MEASURE_ENCODE_TIME
#include <sys/time.h>
#define START_PROFILE \
{ \
struct timeval t1, t2; \
double elapsedTime = 0; \
gettimeofday(&t1, NULL);
#define STOP_PROFILE(X) \
gettimeofday(&t2, NULL); \
elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; \
elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; \
printf("%s ElaspedTime=%f ms\n", X, elapsedTime); \
}
#else
#define START_PROFILE
#define STOP_PROFILE(X)
#endif
#define MAX_DISPLAY_LEN 64
#define MAX_TIME_STAMP_LEN 32
#define PGIE_CLASS_ID_VEHICLE 0
#define PGIE_CLASS_ID_PERSON 2
#define PGIE_CONFIG_FILE "dstest4_pgie_config.txt"
#define MSCONV_CONFIG_FILE "dstest4_msgconv_config.txt"
/* The muxer output resolution must be set if the input streams will be of
* different resolution. The muxer will scale all the input frames to this
* resolution. */
#define MUXER_OUTPUT_WIDTH 1920
#define MUXER_OUTPUT_HEIGHT 1080
/* Muxer batch formation timeout, for e.g. 40 millisec. Should ideally be set
* based on the fastest source's framerate. */
#define MUXER_BATCH_TIMEOUT_USEC 40000
#define IS_YAML(file) (g_str_has_suffix (file, ".yml") || g_str_has_suffix (file, ".yaml"))
/* Check for parsing error. */
#define RETURN_ON_PARSER_ERROR(parse_expr) \
if (NVDS_YAML_PARSER_SUCCESS != parse_expr) { \
g_printerr("Error in parsing configuration file.\n"); \
return -1; \
}
static gchar *cfg_file = NULL;
static gchar *input_file = NULL;
static gchar *topic = NULL;
static gchar *conn_str = NULL;
static gchar *proto_lib = NULL;
static gint schema_type = 0;
static gint msg2p_meta = 0;
static gint frame_interval = 30;
static gboolean display_off = FALSE;
gint frame_number = 0;
gchar pgie_classes_str[4][32] = { "Vehicle", "TwoWheeler", "Person",
"Roadsign"
};
GOptionEntry entries[] = {
{"cfg-file", 'c', 0, G_OPTION_ARG_FILENAME, &cfg_file,
"Set the adaptor config file. Optional if connection string has relevant details.",
NULL},
{"input-file", 'i', 0, G_OPTION_ARG_FILENAME, &input_file,
"Set the input H264 file", NULL},
{"topic", 't', 0, G_OPTION_ARG_STRING, &topic,
"Name of message topic. Optional if it is part of connection string or config file.",
NULL},
{"conn-str", 0, 0, G_OPTION_ARG_STRING, &conn_str,
"Connection string of backend server. Optional if it is part of config file.",
NULL},
{"proto-lib", 'p', 0, G_OPTION_ARG_STRING, &proto_lib,
"Absolute path of adaptor library", NULL},
{"schema", 's', 0, G_OPTION_ARG_INT, &schema_type,
"Type of message schema (0=Full, 1=minimal, 2=protobuf), default=0", NULL},
{"msg2p-meta", 0, 0, G_OPTION_ARG_INT, &msg2p_meta,
"msg2payload generation metadata type (0=Event Msg meta, 1=nvds meta), default=0",
NULL},
{"frame-interval", 0, 0, G_OPTION_ARG_INT, &frame_interval,
"Frame interval at which payload is generated , default=30", NULL},
{"no-display", 0, 0, G_OPTION_ARG_NONE, &display_off, "Disable display",
NULL},
{NULL}
};
static void
generate_ts_rfc3339 (char *buf, int buf_size)
{
time_t tloc;
struct tm tm_log;
struct timespec ts;
char strmsec[6]; //.nnnZ\0
clock_gettime (CLOCK_REALTIME, &ts);
memcpy (&tloc, (void *) (&ts.tv_sec), sizeof (time_t));
gmtime_r (&tloc, &tm_log);
strftime (buf, buf_size, "%Y-%m-%dT%H:%M:%S", &tm_log);
int ms = ts.tv_nsec / 1000000;
g_snprintf (strmsec, sizeof (strmsec), ".%.3dZ", ms);
strncat (buf, strmsec, buf_size);
}
static gpointer
meta_copy_func (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsEventMsgMeta *srcMeta = (NvDsEventMsgMeta *) user_meta->user_meta_data;
NvDsEventMsgMeta *dstMeta = NULL;
dstMeta = (NvDsEventMsgMeta *) g_memdup2 (srcMeta, sizeof (NvDsEventMsgMeta));
if (srcMeta->ts)
dstMeta->ts = g_strdup (srcMeta->ts);
if (srcMeta->sensorStr)
dstMeta->sensorStr = g_strdup (srcMeta->sensorStr);
if (srcMeta->objSignature.size > 0) {
dstMeta->objSignature.signature = (gdouble *) g_memdup2 (srcMeta->objSignature.signature,
srcMeta->objSignature.size);
dstMeta->objSignature.size = srcMeta->objSignature.size;
}
if (srcMeta->objectId) {
dstMeta->objectId = g_strdup (srcMeta->objectId);
}
if (srcMeta->extMsgSize > 0) {
if (srcMeta->objType == NVDS_OBJECT_TYPE_VEHICLE) {
NvDsVehicleObject *srcObj = (NvDsVehicleObject *) srcMeta->extMsg;
NvDsVehicleObject *obj =
(NvDsVehicleObject *) g_malloc0 (sizeof (NvDsVehicleObject));
if (srcObj->type)
obj->type = g_strdup (srcObj->type);
if (srcObj->make)
obj->make = g_strdup (srcObj->make);
if (srcObj->model)
obj->model = g_strdup (srcObj->model);
if (srcObj->color)
obj->color = g_strdup (srcObj->color);
if (srcObj->license)
obj->license = g_strdup (srcObj->license);
if (srcObj->region)
obj->region = g_strdup (srcObj->region);
dstMeta->extMsg = obj;
dstMeta->extMsgSize = sizeof (NvDsVehicleObject);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_PERSON) {
NvDsPersonObject *srcObj = (NvDsPersonObject *) srcMeta->extMsg;
NvDsPersonObject *obj =
(NvDsPersonObject *) g_malloc0 (sizeof (NvDsPersonObject));
obj->age = srcObj->age;
if (srcObj->gender)
obj->gender = g_strdup (srcObj->gender);
if (srcObj->cap)
obj->cap = g_strdup (srcObj->cap);
if (srcObj->hair)
obj->hair = g_strdup (srcObj->hair);
if (srcObj->apparel)
obj->apparel = g_strdup (srcObj->apparel);
dstMeta->extMsg = obj;
dstMeta->extMsgSize = sizeof (NvDsPersonObject);
}
}
return dstMeta;
}
static void
meta_free_func (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsEventMsgMeta *srcMeta = (NvDsEventMsgMeta *) user_meta->user_meta_data;
g_free (srcMeta->ts);
g_free (srcMeta->sensorStr);
if (srcMeta->objSignature.size > 0) {
g_free (srcMeta->objSignature.signature);
srcMeta->objSignature.size = 0;
}
if (srcMeta->objectId) {
g_free (srcMeta->objectId);
}
if (srcMeta->extMsgSize > 0) {
if (srcMeta->objType == NVDS_OBJECT_TYPE_VEHICLE) {
NvDsVehicleObject *obj = (NvDsVehicleObject *) srcMeta->extMsg;
if (obj->type)
g_free (obj->type);
if (obj->color)
g_free (obj->color);
if (obj->make)
g_free (obj->make);
if (obj->model)
g_free (obj->model);
if (obj->license)
g_free (obj->license);
if (obj->region)
g_free (obj->region);
} else if (srcMeta->objType == NVDS_OBJECT_TYPE_PERSON) {
NvDsPersonObject *obj = (NvDsPersonObject *) srcMeta->extMsg;
if (obj->gender)
g_free (obj->gender);
if (obj->cap)
g_free (obj->cap);
if (obj->hair)
g_free (obj->hair);
if (obj->apparel)
g_free (obj->apparel);
}
g_free (srcMeta->extMsg);
srcMeta->extMsgSize = 0;
}
g_free (user_meta->user_meta_data);
user_meta->user_meta_data = NULL;
}
static void
generate_vehicle_meta (gpointer data)
{
NvDsVehicleObject *obj = (NvDsVehicleObject *) data;
obj->type = g_strdup ("sedan");
obj->color = g_strdup ("blue");
obj->make = g_strdup ("Bugatti");
obj->model = g_strdup ("M");
obj->license = g_strdup ("XX1234");
obj->region = g_strdup ("CA");
}
static gpointer
meta_copy_func_custom (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsCustomMsgInfo *srcMeta = (NvDsCustomMsgInfo *) user_meta->user_meta_data;
NvDsCustomMsgInfo *dstMeta = NULL;
dstMeta = (NvDsCustomMsgInfo *) g_memdup2 (srcMeta, sizeof (NvDsCustomMsgInfo));
if (srcMeta->message)
dstMeta->message = (gpointer) g_strdup ((const char*)srcMeta->message);
dstMeta->size = srcMeta->size;
return dstMeta;
}
static void
meta_free_func_custom (gpointer data, gpointer user_data)
{
NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
NvDsCustomMsgInfo *srcMeta = (NvDsCustomMsgInfo *) user_meta->user_meta_data;
if (srcMeta->message)
g_free (srcMeta->message);
srcMeta->size = 0;
g_free (user_meta->user_meta_data);
}
static void
generate_person_meta (gpointer data)
{
NvDsPersonObject *obj = (NvDsPersonObject *) data;
obj->age = 45;
obj->cap = g_strdup ("none");
obj->hair = g_strdup ("black");
obj->gender = g_strdup ("male");
obj->apparel = g_strdup ("formal");
}
static void
generate_event_msg_meta (gpointer data, gint class_id,
NvDsObjectMeta * obj_params)
{
NvDsEventMsgMeta *meta = (NvDsEventMsgMeta *) data;
meta->sensorId = 0;
meta->placeId = 0;
meta->moduleId = 0;
meta->sensorStr = g_strdup ("sensor-0");
meta->ts = (gchar *) g_malloc0 (MAX_TIME_STAMP_LEN + 1);
meta->objectId = (gchar *) g_malloc0 (MAX_LABEL_SIZE);
strncpy (meta->objectId, obj_params->obj_label, MAX_LABEL_SIZE);
generate_ts_rfc3339 (meta->ts, MAX_TIME_STAMP_LEN);
/*
* This demonstrates how to attach custom objects.
* Any custom object as per requirement can be generated and attached
* like NvDsVehicleObject / NvDsPersonObject. Then that object should
* be handled in payload generator library (nvmsgconv.cpp) accordingly.
*/
if (class_id == PGIE_CLASS_ID_VEHICLE) {
meta->type = NVDS_EVENT_MOVING;
meta->objType = NVDS_OBJECT_TYPE_VEHICLE;
meta->objClassId = PGIE_CLASS_ID_VEHICLE;
NvDsVehicleObject *obj =
(NvDsVehicleObject *) g_malloc0 (sizeof (NvDsVehicleObject));
generate_vehicle_meta (obj);
meta->extMsg = obj;
meta->extMsgSize = sizeof (NvDsVehicleObject);
} else if (class_id == PGIE_CLASS_ID_PERSON) {
meta->type = NVDS_EVENT_ENTRY;
meta->objType = NVDS_OBJECT_TYPE_PERSON;
meta->objClassId = PGIE_CLASS_ID_PERSON;
NvDsPersonObject *obj =
(NvDsPersonObject *) g_malloc0 (sizeof (NvDsPersonObject));
generate_person_meta (obj);
meta->extMsg = obj;
meta->extMsgSize = sizeof (NvDsPersonObject);
}
}
/* osd_sink_pad_buffer_probe will extract metadata received on OSD sink pad
* and update params for drawing rectangle, object information etc. */
static GstPadProbeReturn
osd_sink_pad_buffer_metadata_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer u_data)
{
GstBuffer *buf = (GstBuffer *) info->data;
NvDsFrameMeta *frame_meta = NULL;
NvOSD_TextParams *txt_params = NULL;
guint vehicle_count = 0;
guint person_count = 0;
gboolean is_first_object = TRUE;
NvDsMetaList *l_frame, *l_obj;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
if (!batch_meta) {
// No batch meta attached.
return GST_PAD_PROBE_OK;
}
for (l_frame = batch_meta->frame_meta_list; l_frame; l_frame = l_frame->next) {
frame_meta = (NvDsFrameMeta *) l_frame->data;
if (frame_meta == NULL) {
// Ignore Null frame meta.
continue;
}
is_first_object = TRUE;
for (l_obj = frame_meta->obj_meta_list; l_obj; l_obj = l_obj->next) {
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *) l_obj->data;
if (obj_meta == NULL) {
// Ignore Null object.
continue;
}
txt_params = &(obj_meta->text_params);
if (txt_params->display_text)
g_free (txt_params->display_text);
txt_params->display_text = (char *)g_malloc0 (MAX_DISPLAY_LEN);
g_snprintf (txt_params->display_text, MAX_DISPLAY_LEN, "%s ",
pgie_classes_str[obj_meta->class_id]);
if (obj_meta->class_id == PGIE_CLASS_ID_VEHICLE)
vehicle_count++;
if (obj_meta->class_id == PGIE_CLASS_ID_PERSON)
person_count++;
/* Now set the offsets where the string should appear */
txt_params->x_offset = obj_meta->rect_params.left;
txt_params->y_offset = obj_meta->rect_params.top - 25;
/* Font , font-color and font-size */
txt_params->font_params.font_name = (char *) "Serif";
txt_params->font_params.font_size = 10;
txt_params->font_params.font_color.red = 1.0;
txt_params->font_params.font_color.green = 1.0;
txt_params->font_params.font_color.blue = 1.0;
txt_params->font_params.font_color.alpha = 1.0;
/* Text background color */
txt_params->set_bg_clr = 1;
txt_params->text_bg_clr.red = 0.0;
txt_params->text_bg_clr.green = 0.0;
txt_params->text_bg_clr.blue = 0.0;
txt_params->text_bg_clr.alpha = 1.0;
/*
* Ideally NVDS_EVENT_MSG_META should be attached to buffer by the
* component implementing detection / recognition logic.
* Here it demonstrates how to use / attach that meta data.
*/
if (is_first_object && !(frame_number % frame_interval)) {
/* Frequency of messages to be send will be based on use case.
* Here message is being sent for first object every frame_interval(default=30).
*/
NvDsEventMsgMeta *msg_meta =
(NvDsEventMsgMeta *) g_malloc0 (sizeof (NvDsEventMsgMeta));
msg_meta->bbox.top = obj_meta->rect_params.top;
msg_meta->bbox.left = obj_meta->rect_params.left;
msg_meta->bbox.width = obj_meta->rect_params.width;
msg_meta->bbox.height = obj_meta->rect_params.height;
msg_meta->frameId = frame_number;
msg_meta->trackingId = obj_meta->object_id;
msg_meta->confidence = obj_meta->confidence;
generate_event_msg_meta (msg_meta, obj_meta->class_id, obj_meta);
NvDsUserMeta *user_event_meta =
nvds_acquire_user_meta_from_pool (batch_meta);
if (user_event_meta) {
user_event_meta->user_meta_data = (void *) msg_meta;
user_event_meta->base_meta.meta_type = NVDS_EVENT_MSG_META;
user_event_meta->base_meta.copy_func =
(NvDsMetaCopyFunc) meta_copy_func;
user_event_meta->base_meta.release_func =
(NvDsMetaReleaseFunc) meta_free_func;
nvds_add_user_meta_to_frame (frame_meta, user_event_meta);
} else {
g_print ("Error in attaching event meta to buffer\n");
}
is_first_object = FALSE;
}
}
}
g_print ("Frame Number = %d "
"Vehicle Count = %d Person Count = %d\n",
frame_number, vehicle_count, person_count);
frame_number++;
return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
osd_sink_pad_buffer_image_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer u_data)
{
GstBuffer *buf = (GstBuffer *) info->data;
NvDsFrameMeta *frame_meta = NULL;
gboolean is_first_object = TRUE;
NvDsMetaList *l_frame, *l_obj;
gchar *encoded_data;
gchar *message_data;
gchar *width, *height;
gchar *ts = (gchar *) g_malloc0 (MAX_TIME_STAMP_LEN + 1);
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
if (!batch_meta) {
// No batch meta attached.
g_free(ts);
return GST_PAD_PROBE_OK;
}
for (l_frame = batch_meta->frame_meta_list; l_frame; l_frame = l_frame->next) {
frame_meta = (NvDsFrameMeta *) l_frame->data;
if (frame_meta == NULL) {
// Ignore Null frame meta.
continue;
}
is_first_object = TRUE;
for (l_obj = frame_meta->obj_meta_list; l_obj; l_obj = l_obj->next) {
NvDsObjectMeta *obj_meta = (NvDsObjectMeta *) l_obj->data;
if (obj_meta == NULL) {
// Ignore Null object.
continue;
}
if (is_first_object && !(frame_number % frame_interval)) {
/* Frequency of images to be send will be based on use case.
* Here images is being sent for first object every frame_interval(default=30).
*/
NvDsUserMetaList *usrMetaList = obj_meta->obj_user_meta_list;
while (usrMetaList != NULL) {
NvDsUserMeta *user_event_meta_custom =
nvds_acquire_user_meta_from_pool (batch_meta);
NvDsCustomMsgInfo *msg_custom_meta =
(NvDsCustomMsgInfo *) g_malloc0 (sizeof (NvDsCustomMsgInfo));
NvDsUserMeta *usrMetaData = (NvDsUserMeta *) usrMetaList->data;
if (usrMetaData->base_meta.meta_type == NVDS_CROP_IMAGE_META) {
// NvDsObjEncOutParams *enc_jpeg_image =
// (NvDsObjEncOutParams *) usrMetaData->user_meta_data;
// START_PROFILE;
// encoded_data = g_base64_encode(enc_jpeg_image->outBuffer, enc_jpeg_image->outLen);
generate_ts_rfc3339 (ts, MAX_TIME_STAMP_LEN);
width = g_strdup_printf("%f", obj_meta->detector_bbox_info.org_bbox_coords.width);
height = g_strdup_printf("%f", obj_meta->detector_bbox_info.org_bbox_coords.height);
/* Image message fields are separated by ";".
* Specific Format: "image;image_format;image_widthximage_height;time;encoded data;"
* For Example: "image;jpg;640x480;2023-07-31T10:20:13;xxxxxxxxxxx"
*/
message_data = g_strconcat("image;jpg;", width, "x", height, ";", ts, ";", encoded_data, ";", NULL);
STOP_PROFILE("Base64 Encode Time ");
msg_custom_meta->size = strlen(message_data);
msg_custom_meta->message = g_strdup(message_data);
if (user_event_meta_custom) {
user_event_meta_custom->user_meta_data = (void *) msg_custom_meta;
user_event_meta_custom->base_meta.meta_type = NVDS_CUSTOM_MSG_BLOB;
user_event_meta_custom->base_meta.copy_func =
(NvDsMetaCopyFunc) meta_copy_func_custom;
user_event_meta_custom->base_meta.release_func =
(NvDsMetaReleaseFunc) meta_free_func_custom;
nvds_add_user_meta_to_frame (frame_meta, user_event_meta_custom);
} else {
g_print ("Error in attaching event meta custom to buffer\n");
}
#ifdef ENABLE_DUMP_FILE
gsize size = 0;
snprintf (fileObjNameString, 1024, "%s_%d_%d_%s.jpg",
ts, frame_number, frame_meta->batch_id, obj_meta->obj_label);
guchar *decoded_data = g_base64_decode (encoded_data, &size);
fp = fopen(fileObjNameString, "wb");
if(fp) {
fwrite(decoded_data, size, 1, fp);
fclose(fp);
} else {
g_printerr ("Could not open file!\n");
}
g_free(decoded_data);
#endif
g_free(encoded_data);
g_free(message_data);
g_free(width);
g_free(height);
usrMetaList = NULL;
} else {
usrMetaList = usrMetaList->next;
}
}
is_first_object = FALSE;
}
}
}
g_free(ts);
frame_number++;
return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
pgie_src_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer ctx)
{
GstBuffer *buf = (GstBuffer *) info->data;
GstMapInfo inmap = GST_MAP_INFO_INIT;
if (!gst_buffer_map (buf, &inmap, GST_MAP_READ)) {
GST_ERROR ("input buffer mapinfo failed");
return GST_PAD_PROBE_DROP;
}
NvBufSurface *ip_surf = (NvBufSurface *) inmap.data;
gst_buffer_unmap (buf, &inmap);
NvDsObjectMeta *obj_meta = NULL;
NvDsMetaList *l_frame = NULL;
NvDsMetaList *l_obj = NULL;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
l_frame = l_frame->next) {
guint num_rects = 0;
NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
for (l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next) {
obj_meta = (NvDsObjectMeta *) (l_obj->data);
if (obj_meta->class_id == PGIE_CLASS_ID_VEHICLE) {
num_rects++;
}
if (obj_meta->class_id == PGIE_CLASS_ID_PERSON) {
num_rects++;
}
/* Conditions that user needs to set to encode the detected objects of
* interest. Here, by default all the detected objects are encoded.
* For demonstration, we will encode the first object in the frame. */
// if ((obj_meta->class_id == PGIE_CLASS_ID_PERSON
// || obj_meta->class_id == PGIE_CLASS_ID_VEHICLE)
// && num_rects == 1) {
// NvDsObjEncUsrArgs objData = { 0 };
// /* To be set by user */
// objData.saveImg = FALSE;
// objData.attachUsrMeta = TRUE;
// /* Set if Image scaling Required */
// objData.scaleImg = FALSE;
// objData.scaledWidth = 0;
// objData.scaledHeight = 0;
// /* Preset */
// objData.objNum = num_rects;
// /* Quality */
// objData.quality = 80;
// /*Main Function Call */
// // nvds_obj_enc_process ((NvDsObjEncCtxHandle)ctx, &objData, ip_surf, obj_meta, frame_meta);
// }
}
}
// nvds_obj_enc_finish ((NvDsObjEncCtxHandle)ctx);
return GST_PAD_PROBE_OK;
}
static gboolean
bus_call (GstBus * bus, GstMessage * msg, gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR:{
gchar *debug = NULL;
GError *error = NULL;
gst_message_parse_error (msg, &error, &debug);
g_printerr ("ERROR from element %s: %s\n",
GST_OBJECT_NAME (msg->src), error->message);
if (debug)
g_printerr ("Error details: %s\n", debug);
g_free (debug);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
int
main (int argc, char *argv[])
{
GMainLoop *loop = NULL;
GstElement *pipeline = NULL, *source = NULL, *h264parser = NULL,
*decoder = NULL, *sink = NULL, *pgie = NULL,
*nvosd = NULL, *nvstreammux;
GstElement *msgconv = NULL, *msgbroker = NULL, *tee = NULL;
GstElement *queue1 = NULL, *queue2 = NULL;
GstBus *bus = NULL;
guint bus_watch_id;
GstPad *osd_sink_pad = NULL;
GstPad *tee_render_pad = NULL;
GstPad *tee_msg_pad = NULL;
GstPad *sink_pad = NULL;
GstPad *src_pad = NULL;
GstPad *pgie_src_pad = NULL;
GOptionContext *ctx = NULL;
GOptionGroup *group = NULL;
GError *error = NULL;
NvDsGieType pgie_type = NVDS_GIE_PLUGIN_INFER_SERVER;
int current_device = -1;
cudaGetDevice (&current_device);
struct cudaDeviceProp prop;
cudaGetDeviceProperties (&prop, current_device);
ctx = g_option_context_new ("Nvidia DeepStream Test4");
group = g_option_group_new ("test4", NULL, NULL, NULL, NULL);
g_option_group_add_entries (group, entries);
g_option_context_set_main_group (ctx, group);
g_option_context_add_group (ctx, gst_init_get_option_group ());
if (!g_option_context_parse (ctx, &argc, &argv, &error)) {
g_option_context_free (ctx);
g_printerr ("%s", error->message);
return -1;
}
g_option_context_free (ctx);
if (!proto_lib || !input_file) {
if (argc > 1 && !IS_YAML (argv[1])) {
g_printerr ("missing arguments\n");
g_printerr ("Usage: %s <yml file>\n", argv[0]);
g_printerr
("Usage: %s -i <H264 filename> -p <Proto adaptor library> --conn-str=<Connection string>\n",
argv[0]);
return -1;
} else if (!argv[1]) {
g_printerr ("missing arguments\n");
g_printerr ("Usage: %s <yml file>\n", argv[0]);
g_printerr
("Usage: %s -i <H264 filename> -p <Proto adaptor library> --conn-str=<Connection string>\n",
argv[0]);
return -1;
}
}
loop = g_main_loop_new (NULL, FALSE);
/* Parse inference plugin type */
if (argc > 1 && IS_YAML(argv[1])) {
RETURN_ON_PARSER_ERROR(nvds_parse_gie_type(&pgie_type, argv[1],
"primary-gie"));
}
/* Create gstreamer elements */
/* Create Pipeline element that will form a connection of other elements */
pipeline = gst_pipeline_new ("dstest4-pipeline");
/* Source element for reading from the file */
source = gst_element_factory_make ("filesrc", "file-source");
/* Since the data format in the input file is elementary h264 stream,
* we need a h264parser */
h264parser = gst_element_factory_make ("h264parse", "h264-parser");
/* Use nvdec_h264 for hardware accelerated decode on GPU */
decoder = gst_element_factory_make ("mach264dec", "mach264dec-decoder");
nvstreammux = gst_element_factory_make ("nvstreammux", "nvstreammux");
/* Use nvinfer or nvinferserver to run inferencing on decoder's output,
* behaviour of inferencing is set through config file */
if (pgie_type == NVDS_GIE_PLUGIN_INFER_SERVER) {
pgie = gst_element_factory_make ("nvinferserver", "primary-nvinference-engine");
} else {
pgie = gst_element_factory_make ("nvinfer", "primary-nvinference-engine");
}
/* Create OSD to draw on the converted RGBA buffer */
nvosd = gst_element_factory_make ("nvdsosd", "nv-onscreendisplay");
/* Create msg converter to generate payload from buffer metadata */
msgconv = gst_element_factory_make ("nvmsgconv", "nvmsg-converter");
/* Create msg broker to send payload to server */
msgbroker = gst_element_factory_make ("nvmsgbroker", "nvmsg-broker");
/* Create tee to render buffer and send message simultaneously */
tee = gst_element_factory_make ("tee", "nvsink-tee");
/* Create queues */
queue1 = gst_element_factory_make ("queue", "nvtee-que1");
queue2 = gst_element_factory_make ("queue", "nvtee-que2");
/* Finally render the osd output */
sink = gst_element_factory_make ("fakesink", "nvvideo-renderer");
if (!pipeline || !source || !h264parser || !decoder || !nvstreammux || !pgie
|| !nvosd || !msgconv || !msgbroker || !tee
|| !queue1 || !queue2 || !sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
if (argc > 1 && IS_YAML (argv[1])) {
RETURN_ON_PARSER_ERROR(nvds_parse_file_source(source, argv[1], "source"));
RETURN_ON_PARSER_ERROR(nvds_parse_streammux(nvstreammux, argv[1], "streammux"));
RETURN_ON_PARSER_ERROR(nvds_parse_gie(pgie, argv[1], "primary-gie"));
g_object_set (G_OBJECT (msgconv), "config", "dstest4_msgconv_config.yml",
NULL);
RETURN_ON_PARSER_ERROR(nvds_parse_msgconv (msgconv, argv[1], "msgconv"));
RETURN_ON_PARSER_ERROR(nvds_parse_msgbroker(msgbroker, argv[1], "msgbroker"));
RETURN_ON_PARSER_ERROR(nvds_parse_fake_sink (sink, argv[1], "sink"));
msg2p_meta = ds_test4_parse_meta_type(argv[1], "msgconv");
g_print("msg2p_meta = %d\n", msg2p_meta);
} else {
/* we set the input filename to the source element */
g_object_set (G_OBJECT (source), "location", input_file, NULL);
g_object_set (G_OBJECT (nvstreammux), "batch-size", 1, NULL);
g_object_set (G_OBJECT (nvstreammux), "width", MUXER_OUTPUT_WIDTH, "height",
MUXER_OUTPUT_HEIGHT,
"batched-push-timeout", MUXER_BATCH_TIMEOUT_USEC, NULL);
/* Set all the necessary properties of the nvinfer element,
* the necessary ones are : */
g_object_set (G_OBJECT (pgie), "config-file-path", PGIE_CONFIG_FILE, NULL);
g_object_set (G_OBJECT (msgconv), "config", MSCONV_CONFIG_FILE, NULL);
g_object_set (G_OBJECT (msgconv), "payload-type", schema_type, NULL);
g_object_set (G_OBJECT (msgconv), "msg2p-newapi", msg2p_meta, NULL);
g_object_set (G_OBJECT (msgconv), "frame-interval", frame_interval, NULL);
g_object_set (G_OBJECT (msgbroker), "proto-lib", proto_lib,
"conn-str", conn_str, "sync", FALSE, NULL);
if (topic) {
g_object_set (G_OBJECT (msgbroker), "topic", topic, NULL);
}
if (cfg_file) {
g_object_set (G_OBJECT (msgbroker), "config", cfg_file, NULL);
}
g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
}
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* Set up the pipeline */
/* we add all elements into the pipeline */
gst_bin_add_many (GST_BIN (pipeline),
source, h264parser, decoder, nvstreammux, pgie,
nvosd, tee, queue1, queue2, msgconv, msgbroker, sink, NULL);
/* we link the elements together */
/* file-source -> h264-parser -> nvh264-decoder -> nvstreammux ->
* pgie -> nvvidconv -> nvosd -> tee -> video-renderer
* |
* |-> msgconv -> msgbroker */
sink_pad = gst_element_request_pad_simple (nvstreammux, "sink_0");
if (!sink_pad) {
g_printerr ("Streammux request sink pad failed. Exiting.\n");
return -1;
}
src_pad = gst_element_get_static_pad (decoder, "src");
if (!src_pad) {
g_printerr ("Decoder request src pad failed. Exiting.\n");
return -1;
}
if (gst_pad_link (src_pad, sink_pad) != GST_PAD_LINK_OK) {
g_printerr ("Failed to link decoder to stream muxer. Exiting.\n");
return -1;
}
gst_object_unref (sink_pad);
gst_object_unref (src_pad);
if (!gst_element_link_many (source, h264parser, decoder, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
if (!gst_element_link_many (nvstreammux, pgie, nvosd, tee, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
if (!gst_element_link_many (queue1, msgconv, msgbroker, NULL)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
if (!gst_element_link (queue2, sink)) {
g_printerr ("Elements could not be linked. Exiting.\n");
return -1;
}
sink_pad = gst_element_get_static_pad (queue1, "sink");
tee_msg_pad = gst_element_request_pad_simple (tee, "src_%u");
tee_render_pad = gst_element_request_pad_simple (tee, "src_%u");
if (!tee_msg_pad || !tee_render_pad) {
g_printerr ("Unable to get request pads\n");
return -1;
}
if (gst_pad_link (tee_msg_pad, sink_pad) != GST_PAD_LINK_OK) {
g_printerr ("Unable to link tee and message converter\n");
gst_object_unref (sink_pad);
return -1;
}
gst_object_unref (sink_pad);
sink_pad = gst_element_get_static_pad (queue2, "sink");
if (gst_pad_link (tee_render_pad, sink_pad) != GST_PAD_LINK_OK) {
g_printerr ("Unable to link tee and render\n");
gst_object_unref (sink_pad);
return -1;
}
gst_object_unref (sink_pad);
pgie_src_pad = gst_element_get_static_pad (pgie, "src");
/* Create Context for Object Encoding.
* Takes GPU ID as a parameter. Passed by user through commandline.
* Initialized as 0. */
// NvDsObjEncCtxHandle obj_ctx_handle = nvds_obj_enc_create_context (0);
// if (!obj_ctx_handle) {
// g_print ("Unable to create context\n");
// return -1;
// }
if (!pgie_src_pad)
g_print ("Unable to get src pad\n");
else
gst_pad_add_probe (pgie_src_pad, GST_PAD_PROBE_TYPE_BUFFER,
pgie_src_pad_buffer_probe, NULL, NULL);
gst_object_unref (pgie_src_pad);
/* Lets add probe to get informed of the meta data generated, we add probe to
* the sink pad of the osd element, since by that time, the buffer would have
* had got all the metadata. */
osd_sink_pad = gst_element_get_static_pad (nvosd, "sink");
if (!osd_sink_pad)
g_print ("Unable to get sink pad\n");
else {
if (msg2p_meta == 0) { //generate payload using eventMsgMeta
gst_pad_add_probe (osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_sink_pad_buffer_metadata_probe, NULL, NULL);
} else { //generate payload using NVDS_CUSTOM_MSG_BLOB
gst_pad_add_probe (osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_sink_pad_buffer_image_probe, NULL, NULL);
}
}
gst_object_unref (osd_sink_pad);
/* Set the pipeline to "playing" state */
if (argc > 1 && IS_YAML (argv[1])) {
g_print ("Using file: %s\n", argv[1]);
} else {
g_print ("Now playing: %s\n", input_file);
}
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait till pipeline encounters an error or EOS */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
// nvds_obj_enc_destroy_context (obj_ctx_handle);
g_free (cfg_file);
g_free (input_file);
g_free (topic);
g_free (conn_str);
g_free (proto_lib);
/* Release the request pads from the tee, and unref them */
gst_element_release_request_pad (tee, tee_msg_pad);
gst_element_release_request_pad (tee, tee_render_pad);
gst_object_unref (tee_msg_pad);
gst_object_unref (tee_render_pad);
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
return 0;
}
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*/
#include "deepstream_test4_yml_parse.h"
#include <yaml-cpp/yaml.h>
#include <string>
#include <iostream>
guint ds_test4_parse_meta_type(gchar *cfg_file_path, const char* group)
{
std::string paramKey = "";
auto docs = YAML::LoadAllFromFile(cfg_file_path);
int total_docs = docs.size();
guint val = 0;
for (int i =0; i < total_docs;i++)
{
if (docs[i][group]) {
if (docs[i][group]["msg2p-newapi"]) {
val= docs[i][group]["msg2p-newapi"].as<guint>();
return val;
}
}
}
return 0;
}
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*/
#ifndef _DS_TEST4_YAML_PARSER_H_
#define _DS_TEST4_YAML_PARSER_H_
#include <gst/gst.h>
G_BEGIN_DECLS
guint ds_test4_parse_meta_type(gchar *cfg_file_path, const char* group);
G_END_DECLS
#endif
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
source:
location: ../../../streams/cr7_1920x1080.h264
streammux:
batch-size: 1
batched-push-timeout: 40000
width: 1920
height: 1080
msgconv:
#If you want to send images, please set the "payload-type: 1" and "msg2p-newapi: 1"
payload-type: 1
msg2p-newapi: 1
frame-interval: 30
msgbroker:
proto-lib: /opt/deepstream/lib/libnvds_mqtt_proto.so
conn-str: 127.0.0.1;1883
topic: /server/fromArm
sync: 0
sink:
sync: 1
# Inference using nvinferserver:
primary-gie:
plugin-type: 1
config-file-path: yolov5_nvinferserver_config.txt
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2018-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
[sensor0]
enable=1
type=Camera
id=CAMERA_ID
location=45.293701447;-75.8303914499;48.1557479338
description="Entrance of Garage Right Lane"
coordinate=5.2;10.1;11.2
[place0]
enable=1
id=1
type=garage
name=XYZ
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=walsh
place-sub-field2=lane1
place-sub-field3=P2
[place1]
enable=1
id=1
type=garage
name=XYZ
location=28.47;47.46;1.53
coordinate=1.0;2.0;3.0
place-sub-field1="C-76-2"
place-sub-field2="LEV/EV/CP/ADA"
place-sub-field3=P2
[analytics0]
enable=1
id=XYZ
description="Vehicle Detection and License Plate Recognition"
source=OpenALR
version=1.0
\ No newline at end of file
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
sensor0:
enable: 1
type: Camera
id: CAMERA_ID
location: 45.293701447;-75.8303914499;48.1557479338
description: "Entrance of Garage Right Lane"
coordinate: 5.2;10.1;11.2
place0:
enable: 1
id: 1
type: garage
name: XYZ
location: 30.32;-40.55;100.0
coordinate: 1.0;2.0;3.0
place-sub-field1: walsh
place-sub-field2: lane1
place-sub-field3: P2
place1:
enable: 1
id: 1
type: garage
name: XYZ
location: 28.47;47.46;1.53
coordinate: 1.0;2.0;3.0
place-sub-field1: "C-76-2"
place-sub-field2: "LEV/EV/CP/ADA"
place-sub-field3: P2
analytics0:
enable: 1
id: XYZ
description: "Vehicle Detection and License Plate Recognition"
source: OpenALR
version: 1.0
\ No newline at end of file
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
infer_config {
unique_id: 1
gpu_ids: [0]
max_batch_size: 30
backend {
inputs: [ {
name: "input_1:0"
}]
outputs: [
{name: "output_cov/Sigmoid:0"},
{name: "output_bbox/BiasAdd:0"}
]
triton {
model_name: "Primary_Detector"
version: -1
model_repo {
root: "../../../../samples/triton_model_repo"
strict_model_config: true
}
}
}
preprocess {
network_format: MEDIA_FORMAT_NONE
tensor_order: TENSOR_ORDER_LINEAR
tensor_name: "input_1:0"
maintain_aspect_ratio: 0
frame_scaling_hw: FRAME_SCALING_HW_DEFAULT
frame_scaling_filter: 1
normalize {
scale_factor: 0.00392156862745098
channel_offsets: [0, 0, 0]
}
}
postprocess {
labelfile_path: "../../../../samples/models/Primary_Detector/labels.txt"
detection {
num_detected_classes: 4
per_class_params {
key: 0
value { pre_threshold: 0.4 }
}
nms {
confidence_threshold:0.2
topk:20
iou_threshold:0.5
}
}
}
extra {
copy_input_to_host_buffers: false
output_buffer_pool_size: 2
}
}
input_control {
process_mode: PROCESS_MODE_FULL_FRAME
operate_on_gie_id: -1
interval: 0
}
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
infer_config {
unique_id: 1
gpu_ids: [0]
max_batch_size: 1
backend {
inputs: [ {
name: "images"
}]
outputs: [
{name: "output0"}
]
triton {
model_name: "YOLOV5_FP16"
version: 1
model_repo {
root: "../../../sugon_samples/triton_model_repo"
strict_model_config: true
backend_dir: "/opt/deepstream/third_party/backends"
log_level: 1
}
}
}
preprocess {
network_format: IMAGE_FORMAT_RGB
tensor_order: TENSOR_ORDER_LINEAR
maintain_aspect_ratio: 0
frame_scaling_hw: FRAME_SCALING_HW_DEFAULT
frame_scaling_filter: 1
normalize {
scale_factor: 0.00392157
channel_offsets: [0, 0, 0]
}
}
postprocess {
labelfile_path: "../../../sugon_samples/labels/YOLOV5/labels.txt"
detection {
num_detected_classes: 80
per_class_params {
key: 0
value { pre_threshold: 0.4 }
}
nms {
confidence_threshold:0.2
topk:20
iou_threshold:0.5
}
custom_parse_bbox_func: "parseYolov5OutputBoundingBoxFP32"
}
}
extra {
copy_input_to_host_buffers: false
output_buffer_pool_size: 2
}
custom_lib {
path: "/opt/deepstream/lib/libnvdsinferserver__customparser_sugon.so"
}
}
input_control {
process_mode: PROCESS_MODE_FULL_FRAME
operate_on_gie_id: -1
interval: 0
}
*****************************************************************************
* SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
*
* NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
* property and proprietary rights in and to this material, related
* documentation and any modifications thereto. Any use, reproduction,
* disclosure or distribution of this material and related documentation
* without an express license agreement from NVIDIA CORPORATION or
* its affiliates is strictly prohibited.
*****************************************************************************
*****************************************************************************
deepstream-test1-app
README
*****************************************************************************
===============================================================================
1. Prerequisites:
===============================================================================
Please follow instructions in the apps/sample_apps/deepstream-app/README on how
to install the prerequisites for Deepstream SDK, the DeepStream SDK itself and the
apps.
You must have the following development packages installed
GStreamer-1.0
GStreamer-1.0 Base Plugins
GStreamer-1.0 gstrtspserver
X11 client-side library
To install these packages, execute the following command:
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
libgstrtspserver-1.0-dev libx11-dev
This example can be configured to use either the nvinfer or the nvinferserver
element for inference.
If nvinferserver is selected, the Triton Inference Server is used for inference
processing. In this case, the example needs to be run inside the
DeepStream-Triton docker container. Please refer
samples/configs/deepstream-app-triton/README for the steps to download the
container image and setup model repository.
===============================================================================
2. Purpose:
===============================================================================
This document shall describe about the sample deepstream-test1 application.
It is meant for demonstration of how to use the various DeepStream SDK
elements in the pipeline and extract meaningful insights from a video stream.
===============================================================================
3. To compile:
===============================================================================
$ Set CUDA_VER in the MakeFile as per platform.
For both Jetson & x86, CUDA_VER=12.6
$ sudo make (sudo not required in case of docker containers)
===============================================================================
4. Usage:
===============================================================================
terminal 1:
mosquitto -c mosquitto.conf
terminal 2:
mosquitto_sub -v -h 127.0.0.1 -t /server/fromArm
terminal 3:
/usr/bin/gst-launch-1.0 filesrc location=/workspace/shared_docker/video/cr7_1920x1080.h264 ! h264parse ! mach264dec! queue name=q1 ! mux.sink_0 nvstreammux name=mux batch-size=1 ! queue name=q2 ! nvinferserver config-file-path=./yolov5_nvinferserver_config.txt ! nvmsgconv config=./dstest4_msgconv_config.txt payload-type=1 msg2p-newapi=1 ! nvmsgbroker proto-lib=/opt/deepstream/lib/libnvds_mqtt_proto.so conn-str="127.0.0.1;1883" topic="/server/fromArm" sync=0
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2018-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
[sensor0]
enable=1
type=Camera
id=CAMERA_ID
location=45.293701447;-75.8303914499;48.1557479338
description="Entrance of Garage Right Lane"
coordinate=5.2;10.1;11.2
[place0]
enable=1
id=1
type=garage
name=XYZ
location=30.32;-40.55;100.0
coordinate=1.0;2.0;3.0
place-sub-field1=walsh
place-sub-field2=lane1
place-sub-field3=P2
[place1]
enable=1
id=1
type=garage
name=XYZ
location=28.47;47.46;1.53
coordinate=1.0;2.0;3.0
place-sub-field1="C-76-2"
place-sub-field2="LEV/EV/CP/ADA"
place-sub-field3=P2
[analytics0]
enable=1
id=XYZ
description="Vehicle Detection and License Plate Recognition"
source=OpenALR
version=1.0
\ No newline at end of file
# 设置 Mosquitto 服务器监听所有网络接口(通过 0.0.0.0 指定)上的 1883 端口.
listener 1883 127.0.0.1
# 设置运行 Mosquitto 服务时使用的用户为 root。
# 这通常不是一个安全的做法,因为通常推荐使用一个权限较低的专用用户账户来运行服务以减少潜在的安全风险。
user root
# 允许匿名用户连接到 MQTT 服务器。这意味着客户端无需提供用户名和密码即可连接并发布、订阅消息。
allow_anonymous true
# 指定 Mosquitto 服务运行时生成的进程 ID 文件位置。
#pid_file /var/run/mosquitto.pid
# 开启持久化模式,意味着在服务器重启后,一些会话状态和保留消息等信息会被保存下来
#persistence true
# 设置持久化数据存储的位置,在本例中是 /tmp 目录。
#persistence_location /tmp
# 指定日志输出方式为写入文件,并设定日志文件的路径为 /tmp/mosquitto.log。
#log_dest file /tmp/mosquitto.log
# 指定包含其他配置文件的目录,当 Mosquitto 启动时,会加载此目录下的所有 .conf 结尾的文件作为附加配置。
#include_dir /mnt/mosquitto/etc/mosquitto/conf.d/
#max_inflight_messages 1024
#max_queued_messages 5120
#message_size_limit 2048000
#set_tcp_nodelay true
################################################################################
# SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
################################################################################
infer_config {
unique_id: 1
gpu_ids: [0]
max_batch_size: 1
backend {
inputs: [ {
name: "images"
}]
outputs: [
{name: "output0"}
]
triton {
model_name: "YOLOV5_FP16"
version: 1
model_repo {
root: "../../../sugon_samples/triton_model_repo"
strict_model_config: true
backend_dir: "/opt/deepstream/third_party/backends"
log_level: 1
}
}
}
preprocess {
network_format: IMAGE_FORMAT_RGB
tensor_order: TENSOR_ORDER_LINEAR
maintain_aspect_ratio: 0
frame_scaling_hw: FRAME_SCALING_HW_DEFAULT
frame_scaling_filter: 1
normalize {
scale_factor: 0.00392157
channel_offsets: [0, 0, 0]
}
}
postprocess {
labelfile_path: "../../../sugon_samples/labels/YOLOV5/labels.txt"
detection {
num_detected_classes: 80
per_class_params {
key: 0
value { pre_threshold: 0.4 }
}
nms {
confidence_threshold:0.2
topk:20
iou_threshold:0.5
}
custom_parse_bbox_func: "parseYolov5OutputBoundingBoxFP32"
}
}
extra {
copy_input_to_host_buffers: false
output_buffer_pool_size: 2
}
custom_lib {
path: "/opt/deepstream/lib/libnvdsinferserver__customparser_sugon.so"
}
}
input_control {
process_mode: PROCESS_MODE_FULL_FRAME
operate_on_gie_id: -1
interval: 0
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment