Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ sudo make install

Configure options may vary according to your specific system.

If the DeepStream development headers and libraries are available, the
`perf` element also reports `ds-fps` for batched buffers. The default
SDK path is `/opt/nvidia/deepstream/deepstream`; use `deepstream-dir`
with Meson, or `--with-deepstream-dir` with Autotools for nonstandard
installs.

## Usage

Just link in the `perf` element wherever you want to take the
Expand Down
39 changes: 39 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,45 @@ PKG_CHECK_MODULES(GST, [
])
])

dnl optional DeepStream support for batched frame-rate reporting
AC_ARG_WITH([deepstream-dir],
[AS_HELP_STRING([--with-deepstream-dir=DIR],
[root directory of DeepStream installation])],
[DEEPSTREAM_PREFIX="$withval"],
[DEEPSTREAM_PREFIX="/opt/nvidia/deepstream/deepstream"])

DEEPSTREAM_CFLAGS=""
DEEPSTREAM_LIBS=""
have_deepstream=no

deepstream_save_CPPFLAGS="$CPPFLAGS"
deepstream_save_LDFLAGS="$LDFLAGS"
deepstream_save_LIBS="$LIBS"

CPPFLAGS="$CPPFLAGS $GST_CFLAGS -I$DEEPSTREAM_PREFIX/sources/includes"
LDFLAGS="$LDFLAGS -L$DEEPSTREAM_PREFIX/lib"

AC_CHECK_HEADERS([nvdsmeta.h], [
AC_CHECK_LIB([nvds_meta], [nvds_acquire_meta_lock], [
AC_CHECK_LIB([nvdsgst_meta], [gst_buffer_get_nvds_batch_meta], [
DEEPSTREAM_CFLAGS="-I$DEEPSTREAM_PREFIX/sources/includes"
DEEPSTREAM_LIBS="-L$DEEPSTREAM_PREFIX/lib -lnvdsgst_meta -lnvds_meta"
have_deepstream=yes
], [], [-lnvds_meta])
])
])

CPPFLAGS="$deepstream_save_CPPFLAGS"
LDFLAGS="$deepstream_save_LDFLAGS"
LIBS="$deepstream_save_LIBS"

AS_IF([test "x$have_deepstream" = "xyes"], [
AC_DEFINE([HAVE_DEEPSTREAM], [1], [Define if DeepStream support is available])
])

AC_SUBST(DEEPSTREAM_CFLAGS)
AC_SUBST(DEEPSTREAM_LIBS)

dnl check for host OS
AC_CANONICAL_HOST

Expand Down
7 changes: 7 additions & 0 deletions examples/perf-info-example.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ print_perf_info (GstMessage * message)
gdouble mean_bps = 0.0;
gdouble fps = 0.0;
gdouble mean_fps = 0.0;
gdouble ds_fps = 0.0;
gint cpu = 0;
gboolean has_cpu = FALSE;
gboolean has_ds_fps = FALSE;

gst_message_parse_info_details (message, &details);
if (details == NULL) {
Expand All @@ -58,12 +60,17 @@ print_perf_info (GstMessage * message)
}

has_cpu = gst_structure_get_int (details, "cpu", &cpu);
has_ds_fps = gst_structure_get_double (details, "ds-fps", &ds_fps);

g_print ("%s: timestamp=%" GST_TIME_FORMAT
" bps=%.3f mean_bps=%.3f fps=%.3f mean_fps=%.3f",
GST_MESSAGE_SRC_NAME (message), GST_TIME_ARGS (timestamp), bps,
mean_bps, fps, mean_fps);

if (has_ds_fps) {
g_print (" ds-fps=%.3f", ds_fps);
}

if (has_cpu) {
g_print (" cpu=%d", cpu);
}
Expand Down
31 changes: 31 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,37 @@ endforeach
# Create an empty configuration object to set config.h information
cdata = configuration_data()

deepstream_dir = get_option('deepstream-dir')
deepstream_libdir = join_paths(deepstream_dir, 'lib')

nvds_meta_dep = cc.find_library('nvds_meta',
dirs: [deepstream_libdir],
required: false)
nvdsgst_meta_dep = cc.find_library('nvdsgst_meta',
dirs: [deepstream_libdir],
required: false)

if nvds_meta_dep.found() and nvdsgst_meta_dep.found()
deepstream_include_dir = join_paths(deepstream_dir, 'sources/includes')
deepstream_incdir = include_directories(deepstream_include_dir)

if cc.has_header('gstnvdsmeta.h',
dependencies : gst_dep,
include_directories : deepstream_incdir)
Comment on lines +92 to +94

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass GStreamer headers into the DeepStream header check

In a normal Meson installation, gstnvdsmeta.h includes GStreamer headers from a pkg-config-provided directory such as /usr/include/gstreamer-1.0, but this compiler check receives only the DeepStream include directory. Although gst_dep was resolved earlier, Meson does not apply dependency flags to unrelated compiler checks automatically, so this test fails and silently leaves HAVE_DEEPSTREAM unset even when the full SDK is installed. Pass the GStreamer dependency to has_header, or probe the less-dependent nvdsmeta.h as the Autotools path does.

Useful? React with 👍 / 👎.

deepstream_dep = declare_dependency(
dependencies: [nvds_meta_dep, nvdsgst_meta_dep],
include_directories: deepstream_incdir,
)
cdata.set('HAVE_DEEPSTREAM', 1)
else
deepstream_dep = declare_dependency()
endif
else
deepstream_dep = declare_dependency()
endif

plugin_deps += deepstream_dep

# Plugin information
origin_url='http://www.ridgerun.com/'
plugin_url='https://github.com/RidgeRun/gst-perf'
Expand Down
3 changes: 3 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ option('package-name', type : 'string', yield : true,
description : 'Package name to use in plugins')
option('package-origin', type : 'string', value : 'Unknown package origin', yield : true,
description : 'Package origin URL to use in plugins')
option('deepstream-dir', type : 'string',
value : '/opt/nvidia/deepstream/deepstream',
description : 'DeepStream SDK installation directory')
5 changes: 2 additions & 3 deletions plugins/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ plugin_LTLIBRARIES = libgstperf.la
libgstperf_la_SOURCES = gstperf.c gstperf.h

# compiler and linker flags used to compile this plugin, set in configure.ac
libgstperf_la_CFLAGS = $(GST_CFLAGS)
libgstperf_la_LIBADD = $(GST_LIBS)
libgstperf_la_CFLAGS = $(GST_CFLAGS) $(DEEPSTREAM_CFLAGS)
libgstperf_la_LIBADD = $(GST_LIBS) $(DEEPSTREAM_LIBS)
libgstperf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)

50 changes: 47 additions & 3 deletions plugins/gstperf.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
*
* Perf plugin can be used to capture pipeline performance data. Each
* second perf plugin sends frames per second and bits per second data
* using gst_element_post_message.
* using gst_element_post_message. When DeepStream batch metadata is
* available at build time, it also reports the batched frame rate as
* ds-fps.
*/

#ifdef HAVE_CONFIG_H
Expand All @@ -40,6 +42,10 @@
#include <stdio.h>
#include <string.h>

#ifdef HAVE_DEEPSTREAM
#include <gstnvdsmeta.h>
#endif

/* pad templates */
static GstStaticPadTemplate gst_perf_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
Expand Down Expand Up @@ -90,6 +96,7 @@ struct _GstPerf
gdouble fps;
guint32 frame_count;
guint64 frame_count_total;
guint32 ds_frame_count;

gdouble bps;
gdouble mean_bps;
Expand Down Expand Up @@ -193,7 +200,11 @@ gst_perf_class_init (GstPerfClass * klass)

g_object_class_install_property (gobject_class, PROP_LAST_INFO,
g_param_spec_string ("last-info", "Last info",
#ifdef HAVE_DEEPSTREAM
"A string containing the performance information posted to the GStreamer bus (timestamp, bps, mean_bps, fps, mean_fps, ds-fps)",
#else
"A string containing the performance information posted to the GStreamer bus (timestamp, bps, mean_bps, fps, mean_fps)",
#endif
NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

gst_perf_signals[SIGNAL_ON_BITRATE] =
Expand Down Expand Up @@ -582,10 +593,23 @@ gst_perf_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GstPerf *perf = GST_PERF (trans);
GstClockTime time = gst_util_get_timestamp ();
GstClockTime diff = GST_CLOCK_DIFF (perf->prev_timestamp, time);
#ifdef HAVE_DEEPSTREAM
guint ds_frame_count = 0;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);

if (batch_meta != NULL) {
nvds_acquire_meta_lock (batch_meta);
ds_frame_count = batch_meta->num_frames_in_batch;
nvds_release_meta_lock (batch_meta);
}
#endif

if (!GST_CLOCK_TIME_IS_VALID (perf->prev_timestamp) ||
(GST_CLOCK_TIME_IS_VALID (time) && diff >= GST_SECOND)) {
gdouble time_factor, fps;
#ifdef HAVE_DEEPSTREAM
gdouble ds_fps;
#endif
guint idx;
gchar info[GST_PERF_MSG_MAX_SIZE];
gboolean print_cpu_load;
Expand All @@ -602,6 +626,10 @@ gst_perf_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
gst_perf_update_average (perf->frame_count_total, fps, perf->fps);
perf->frame_count_total++;

#ifdef HAVE_DEEPSTREAM
ds_fps = perf->ds_frame_count / time_factor;
#endif

g_mutex_lock (&perf->bps_mutex);
bps = perf->bps;
g_mutex_unlock (&perf->bps_mutex);
Expand All @@ -617,13 +645,23 @@ gst_perf_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GST_OBJECT_NAME (perf), GST_TIME_ARGS (time), bps, mean_bps,
fps, perf->fps);

#ifdef HAVE_DEEPSTREAM
if (idx < GST_PERF_MSG_MAX_SIZE) {
idx += g_snprintf (&info[idx], GST_PERF_MSG_MAX_SIZE - idx,
"; ds-fps: %0.03f", ds_fps);
}
#endif

details = gst_structure_new_empty ("perf");
gst_structure_set (details,
"timestamp", GST_TYPE_CLOCK_TIME, time,
"bps", G_TYPE_DOUBLE, bps,
"mean_bps", G_TYPE_DOUBLE, mean_bps,
"fps", G_TYPE_DOUBLE, fps,
"mean_fps", G_TYPE_DOUBLE, perf->fps,
#ifdef HAVE_DEEPSTREAM
"ds-fps", G_TYPE_DOUBLE, ds_fps,
#endif
NULL);

gst_perf_reset (perf);
Expand All @@ -636,8 +674,10 @@ gst_perf_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
if (print_cpu_load) {
guint32 cpu_load;
gst_perf_cpu_get_load (perf, &cpu_load);
idx = g_snprintf (&info[idx], GST_PERF_MSG_MAX_SIZE - idx,
"; cpu: %d; ", cpu_load);
if (idx < GST_PERF_MSG_MAX_SIZE) {
idx += g_snprintf (&info[idx], GST_PERF_MSG_MAX_SIZE - idx,
"; cpu: %d; ", cpu_load);
}
gst_structure_set (details, "cpu", G_TYPE_INT, (gint) cpu_load, NULL);
}

Expand All @@ -652,6 +692,9 @@ gst_perf_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
}

perf->frame_count++;
#ifdef HAVE_DEEPSTREAM
perf->ds_frame_count += ds_frame_count;
#endif
g_mutex_lock (&perf->byte_count_mutex);
perf->byte_count += gst_buffer_get_size (buf);
g_mutex_unlock (&perf->byte_count_mutex);
Expand Down Expand Up @@ -690,6 +733,7 @@ gst_perf_reset (GstPerf * perf)
g_return_if_fail (perf);

perf->frame_count = 0;
perf->ds_frame_count = 0;
}

static void
Expand Down