8. [DS 5.0GA_All_App] Enable Perf measurement(FPS) for deepstream sample apps
- If you are using deepstream-app, you can add
enable-perf-measurement=1
under Application Group in the config file - If you are using other deepstream sample apps such as deepstream-test2, you can apply following patch to enable it
diff --git a/sources/apps/sample_apps/deepstream-test2/deepstream_test2_app.c b/sources/apps/sample_apps/deepstream-test2/deepstream_test2_app.c
index a2231acf535b4826adb766ed28f3aa80294c7f82..e37d7504ed07c9db77e5d3cdac2c4943fd0d1010 100755
--- a/sources/apps/sample_apps/deepstream-test2/deepstream_test2_app.c
+++ b/sources/apps/sample_apps/deepstream-test2/deepstream_test2_app.c
@@ -28,6 +28,7 @@
#include <string.h>
#include "gstnvdsmeta.h"
+#include "deepstream_perf.h"
#define PGIE_CONFIG_FILE "dstest2_pgie_config.txt"
#define SGIE1_CONFIG_FILE "dstest2_sgie1_config.txt"
@@ -51,6 +52,29 @@
* based on the fastest source's framerate. */
#define MUXER_BATCH_TIMEOUT_USEC 40000
+#define MAX_STREAMS 64
+
+typedef struct
+{
+ /** identifies the stream ID */
+ guint32 stream_index;
+ gdouble fps[MAX_STREAMS];
+ gdouble fps_avg[MAX_STREAMS];
+ guint32 num_instances;
+ guint header_print_cnt;
+ GMutex fps_lock;
+ gpointer context;
+
+ /** Test specific info */
+ guint32 set_batch_size;
+}DemoPerfCtx;
+
+
+typedef struct {
+ GMutex *lock;
+ int num_sources;
+}LatencyCtx;
+
gint frame_number = 0;
/* These are the strings of the labels for the respective models */
gchar sgie1_classes_str[12][32] = { "black", "blue", "brown", "gold", "green",
@@ -80,6 +104,66 @@ guint sgie1_unique_id = 2;
guint sgie2_unique_id = 3;
guint sgie3_unique_id = 4;
+/**
+ * callback function to print the performance numbers of each stream.
+ */
+static void
+perf_cb (gpointer context, NvDsAppPerfStruct * str)
+{
+ DemoPerfCtx *thCtx = (DemoPerfCtx *) context;
+
+ g_mutex_lock(&thCtx->fps_lock);
+ /** str->num_instances is == num_sources */
+ guint32 numf = str->num_instances;
+ guint32 i;
+
+ for (i = 0; i < numf; i++) {
+ thCtx->fps[i] = str->fps[i];
+ thCtx->fps_avg[i] = str->fps_avg[i];
+ }
+ thCtx->context = thCtx;
+ g_print ("**PERF: ");
+ for (i = 0; i < numf; i++) {
+ g_print ("%.2f (%.2f)\t", thCtx->fps[i], thCtx->fps_avg[i]);
+ }
+ g_print ("\n");
+ g_mutex_unlock(&thCtx->fps_lock);
+}
+
+/**
+ * callback function to print the latency of each component in the pipeline.
+ */
+
+static GstPadProbeReturn
+latency_measurement_buf_prob(GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
+{
+ LatencyCtx *ctx = (LatencyCtx *) u_data;
+ static int batch_num = 0;
+ guint i = 0, num_sources_in_batch = 0;
+ if(nvds_enable_latency_measurement)
+ {
+ GstBuffer *buf = (GstBuffer *) info->data;
+ NvDsFrameLatencyInfo *latency_info = NULL;
+ g_mutex_lock (ctx->lock);
+ latency_info = (NvDsFrameLatencyInfo *)
+ calloc(1, ctx->num_sources * sizeof(NvDsFrameLatencyInfo));;
+ g_print("\n************BATCH-NUM = %d**************\n",batch_num);
+ num_sources_in_batch = nvds_measure_buffer_latency(buf, latency_info);
+
+ for(i = 0; i < num_sources_in_batch; i++)
+ {
+ g_print("Source id = %d Frame_num = %d Frame latency = %lf (ms) \n",
+ latency_info[i].source_id,
+ latency_info[i].frame_num,
+ latency_info[i].latency);
+ }
+ g_mutex_unlock (ctx->lock);
+ batch_num++;
+ }
+
+ return GST_PAD_PROBE_OK;
+}
+
/* This is the buffer probe function that we have registered on the sink pad
* of the OSD element. All the infer elements in the pipeline shall attach
* their metadata to the GstBuffer, here we will iterate & process the metadata
@@ -144,9 +228,9 @@ osd_sink_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
nvds_add_display_meta_to_frame(frame_meta, display_meta);
}
- g_print ("Frame Number = %d Number of objects = %d "
- "Vehicle Count = %d Person Count = %d\n",
- frame_number, num_rects, vehicle_count, person_count);
+ // g_print ("Frame Number = %d Number of objects = %d "
+ // "Vehicle Count = %d Person Count = %d\n",
+ // frame_number, num_rects, vehicle_count, person_count);
frame_number++;
return GST_PAD_PROBE_OK;
}
@@ -586,6 +670,30 @@ main (int argc, char *argv[])
gst_pad_add_probe (osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
osd_sink_pad_buffer_probe, NULL, NULL);
+ GstPad *sink_pad = gst_element_get_static_pad (nvvidconv1, "src");
+ if (!sink_pad)
+ g_print ("Unable to get sink pad\n");
+ else {
+ LatencyCtx *ctx = (LatencyCtx *)g_malloc0(sizeof(LatencyCtx));
+ ctx->lock = (GMutex *)g_malloc0(sizeof(GMutex));
+ ctx->num_sources = argc - 2;
+ gst_pad_add_probe (sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
+ latency_measurement_buf_prob, ctx, NULL);
+ }
+ gst_object_unref (sink_pad);
+
+ GstPad *tiler_pad = gst_element_get_static_pad (nvtiler, "sink");
+ if (!tiler_pad)
+ g_print ("Unable to get tiler_pad pad\n");
+ else {
+ NvDsAppPerfStructInt *str = (NvDsAppPerfStructInt *)g_malloc0(sizeof(NvDsAppPerfStructInt));
+ DemoPerfCtx *perf_ctx = (DemoPerfCtx *)g_malloc0(sizeof(DemoPerfCtx));
+ g_mutex_init(&perf_ctx->fps_lock);
+ str->context = perf_ctx;
+ enable_perf_measurement (str, tiler_pad, argc-2, 1, 0, perf_cb);
+ }
+ gst_object_unref (tiler_pad);
+
/* Set the pipeline to "playing" state */
g_print ("Now playing: %s\n", argv[1]);
gst_element_set_state (pipeline, GST_STATE_PLAYING);