This guide elaborates on the means and techniques of debugging plugins in development for Nx Witness Server.
To develop a plugin, you will need to obtain and unpack the Nx Witness SDK archive, available alongside an Nx Witness distribution of a particular version. Inside you will find the readme.md (further referenced in this guide as the readme) — read it carefully, as it explains what the plugins are, and how to build the included plugin samples.
This guide assumes you can successfully build and run a plugin and are ready to start developing your own, presumably based on one of the provided samples — just copy the folder with the sample of your choice inside the samples folder, and change its name.
Throughout this guide, you will find:
- Information about SDK and Nx Witness features or mechanisms. Using them is mandatory if you need the functionality they provide.
- Description of helper tools included with the SDK source code (typically in subfolders named helpers). Such code is not mandatory to use — use it only when it suits your particular need, or copy and modify it.
- Advice on best practices.
This guide focuses on the infrastructure of plugin development including advice on what to write in the plugin code, and how to debug it. It is not intended to cover aspects of the SDK related to the VMS knowledge domain.
To learn about which Nx Witness features plugins may use or provide, study the documentation included with the SDK in Doxygen format (see docs/html/index.html), and study the provided plugin samples.
In this guide, we will be primarily working with the Metadata SDK, which will be further referred to as SDK. Currently, there are three different SDKs — Video Source SDK, Storage SDK, and Metadata SDK.
Each is needed to develop their respective type of plugin; see the readme in each SDK for details. The SDKs are based on the common concept of reference-countable objects (like COM technology), and, as a result, share a number of identical C++ files.
The Metadata SDK is the newest of the three and contains the most recent implementation of this concept. There are plans in the future to combine all three SDKs, effectively rebasing the domain-specific parts of Video Source SDK and Storage SDK onto the infrastructure included with the Metadata SDK and merging them.
The SDK package contains only text files, html pages, and C++ source code. The source code has the following structure:
- src/nx/sdk/ — The SDK Core (defining the API between Nx Witness Server and a Plugin), and its helper code. The subfolders nx/ and sdk/ are needed to reflect the C++ namespaces (this is a part of the Network Optix coding style).
- i_*.h — Headers that define SDK Core interfaces. They support the Plugin infrastructure and are not domain-specific (e.g. they don’t mention working with video).
- *.h (w/o i_ as prefix) — Headers for basic SDK Core features, like the concept of an interface — a header-only class with pure virtual functions and inherited objects managed by reference counting, like in COM technology — a smart pointer which manages the reference counting, and some utility classes.
- helpers/ — Classes and functions which can be helpful when writing a Plugin but are not mandatory. Most of them provide default implementations for certain interfaces but are extensible — simply inherit from a helper class, and override the functions that don’t suit your needs.
- analytics/ — The domain-specific part of the SDK intended for creating Analytics Plugins — which typically analyze video and supply metadata to Nx Witness Server. Contains interfaces, and the optional-to-use helper code — default extensible implementations of the interfaces.
- nx_kit/ — A standalone, self-contained helper library (see paragraph below). Using this library in your plugin is not mandatory, but the included plugin samples extensively rely on it, as does this guide.
- samples/ — plugin samples; each subfolder represents a plugin.
- unit_tests/ — unit tests covering the code in the src folder: the SDK core and certain helpers.
- docs/ — HTML documentation for all the C++ source code in the SDK package, including the plugin samples; generated by Doxygen.
- build_samples* — sample-building scripts for different platforms.
- readme.md — the main readme document for the SDK.
The support for some essential technologies is unfortunately still missing from the C++ standard library, including: JSON parsing/generation; reading .ini files; assertions that work in both Debug and Release builds; and convenient logging.
The SDK includes a small, pure C++ library called nx_kit which covers these topics. For details, see nx_kit/readme.md. This library is used only in helper code included with the SDK, but not in the core SDK components, and is optional. However, nx_kit is widely used in the provided samples, and many recommendations in this guide are based on it.
Since the SDK is an open-source package, you can use the SDK Core (which offers reference-countable objects) and its helper code to introduce plugins into some other C++ project.
Building your Plugin
The officially supported "entry point" method of building plugins is running a sample building script (build_samples.sh for Linux or Cygwin, or build_samples.bat for Windows) included with the SDK. Consult the readme and try it before using a different method(e.g. using an IDE).
Once you can run the sample building script successfully, we recommend switching to a more familiar method; the popular methods are:
- Using cmake from the command-line, in combination with a text editor like Notepad++, vim, emacs, or Visual Studio Code.
- Using an IDE, like Qt Creator, Visual Studio, or CLion.
To ease your transition to an IDE or your own method of building, explore the console output of the script – it shows each command essential to the build process. When in doubt, use the source code of the script to learn more. Then, try to build the sample of your choice, issuing the necessary commands manually — it will help to understand the details.
The SDK and its samples are cross-platform — can be built on Windows or Linux, including cross-compiling for ARM-based devices. Decide whether or not your plugin should also be cross-platform — you can use any platform for its development, but you will also need to test it on each platform.
Cross-platform plugins reach a wider user base, but at a cost; all the source code you write and the libraries you use must be cross-platform as well — so either have a specific version for each platform or be platform-agnostic.
If you are new to C++, we recommend using the C++ standard library for cross-platform plugins wherever possible. The SDK and its included samples use the language features up to C++14, and require no additional libraries, but the code you write can use any higher language standard.
C++17 and the upcoming C++20 offer many standard library features previously available only via third-party libraries; they include file system (walking through directories and files on disk), multi-threading support, and regular expressions. In addition to those libraries, you can use any other popular, cross-platform C++ library like Boost or Qt, if you are more familiar with them.
Article is closed for comments.