When you are creating or debugging an Analytics Plugin, you need a video source. Using a regular video camera is not recommended because the video will not be reproducible. So, we recommend using one of the mechanisms which allow you to use existing video files as a source for a virtual camera:
A command-line tool which, being run on a computer in the same network as Nx Witness Server (or, the same computer), creates a discoverable virtual camera which streams the given video file(s).
Image Library Plugin
A Server Plugin, provided with the Nx Witness Server distribution, that creates a virtual camera which streams the given set of static images as a video stream.
Testcamera is a command-line tool that creates a discoverable virtual IP camera which streams the given video file(s). Here, we mostly describe its features useful for debugging Analytics Plugins. More details can be obtained from Testcamera. Also, details about using testcamera can be learned from its command-line help:
This tool is distributed together with Nx Witness Server for all platforms, and can be found among other executables in the installed Server directory, next to the Server executable, as testcamera (on Linux), or testcamera.exe (on Windows).
Additionally, testcamera comes with the VMS Benchmark package which is available for Linux and Windows. This helps to run testcamera from a PC where a VMS Server isn’t installed.
The tool executable depends on many libraries that come with Nx Witness Server. The easiest way to use it on another computer is to install Nx Witness Server, or unpack the VMS Benchmark package.
Alternatively, it can be copied together with the libraries — on Linux, this means all the .so* files in the lib directory in the Server installation directory; and on Windows, this means all the .dll files in the bin directory in the Server installation directory.
Note: The libraries must reside in a directory with the same relative path to the executable file, as they do in the installed Server.
Testcamera can be run in many different ways: it can be instructed to create one virtual camera streaming a single file or a number of files sequentially in a loop; or to create a number of virtual cameras each streaming the same of different video files. Here, we give examples of the most useful scenarios.
The basic scenario is creating a virtual camera that provides both Primary (high-quality) and Secondary (low-quality) video streams, streaming the same video file in a loop for each stream (each at its own FPS, see below):
If you want the Secondary stream use a different file, add the argument secondary-files=:
.../testcamera files=video_for_primary.ts secondary-files=video_for_secondary.ts
In all scenarios, if the secondary-files= argument is not specified, the Secondary stream will be present and will use the same files as the Primary stream. If the Secondary stream is not needed, it can be suppressed by specifying --no-secondary option:
.../testcamera files=video_for_primary.ts --no-secondary
Frame rate and timestamps (PTS)
When Testcamera is streaming video, there are two distinct aspects related to the frame rate: a physical interval at which the frames are sent via the network, and the values of the timestamps sent together with the frames (if timestamps are sent at all).
The physical interval at which Testcamera sends the frames is fixed and doesn’t depend on the video file contents (including timestamps in it) — the default is 10 FPS, which can be changed via --fps* command-line options.
Testcamera, by default, doesn’t send the frame timestamps; Nx Witness Server assigns the timestamps using the current time at the moment of receiving the frame. This doesn’t yield reproducible results; so, we recommend using the --pts command-line option to instruct Testcamera to send a timestamp with each frame.
Unless other --*pts* options are specified, Testcamera will simply take Presentation Time Stamp (PTS) stored for each frame in the file and send it with the frame.
But, since most video files have their timestamps starting with 0 and Testcamera streams video files in a loop, this will lead to the Server interpreting the incoming video as attributed to Jan 01, 1970 (Unix Epoch start); and when the file loops, the video appears on the timeline as replacing the previous iteration.
To work around this inconvenience of looping on the timeline, you can request a "PTS unlooping” via --unloop-pts option. Testcamera will produce a monotonous PTS sequence: for the next iteration, the PTS of the first frame will be equal to the PTS of the last frame of the previous iteration plus the inter-frame delta — this delta is determined as the difference between the last and the next-to-last frames.
As for the zero point of the timeline, --shift-pts-* options allow you to perform a "PTS Shifting": the first frame will have the PTS defined by these options, which effectively shifts the timeline of the frames to the desired period in time.
The most useful shifting mode is defined by --shift-pts-*-period-us=<period> options. The value of shifting will be determined by Testcamera to serve two purposes:
- Make the frames appear on the timeline close to the current time.
- Allow the PTS of each frame that appears in the video file (can be treated as a frame id), to be deduced from the PTS produced by Testcamera for this frame (so, received by the Analytics Plugin).
- It can be deduced by simply taking the remainder of the division of the received PTS by the file period (see below).
This mode helps to identify each frame of the video in Testcamera logs, Analytics Logs (see Analytics Logs), and the logs of the Analytics Plugin; regardless of the iteration of the file playback by Testcamera.
A file period is the human-perceived duration of the video: the difference of its first and last PTS plus the gap between its iterations.
For an equally-distanced frame file, this will be number_of_frames / FPS. This number can be easily obtained from the Testcamera log (produced on the standard output) when running the video file for the first time; just search for the word period.
For most cases, the recommended way to stream video files for testing Analytics Plugins would be to specify the FPS corresponding to the difference of the timestamps in the video file; and to use PTS unlooping and shifting to a moment close to the current time.
For example, for a 30-FPS file with the length of 10 seconds (300 frames in total), the command may look like:
.../testcamera files=video_for_primary.ts --no-secondary --fps=30
--pts --unloop-pts --shift-pts-primary-period-us=10000000
Logs and experimental options
The regular log of Testcamera activity, including loading video files into memory and negotiating with the Servers, is produced on the standard output (stdout). Certain information, like error messages and information about used .ini files, is produced on the standard error output (stderr).
Certain aspects of Testcamera can be customized via the options in test_camera.ini. For details of what the .ini files are and where they are located, see IniConfig.
To create this file, filled with default values and documentation for its options, just create an empty .ini file with the proper location and name, and restart Testcamera. After editing the values in this file, restart Testcamera again to make it read the new values.
Note: The same test_camera.ini is used by Nx Witness Server — many of the options in this file, like the customized Discovery Message, must be set to the same values in Testcamera and Nx Witness Server, to enable them to work together.
If Testcamera is run on the same PC as the Server, and under the same user (e.g. both manually started from the console), they will likely share the same physical file because their .ini file directories will coincide.
A dedicated frame log can be requested via the --frame-log=<filename> option. This log has a line for each video frame sent to a Server, containing detailed data of the frame: its PTS in the video file and its PTS that’s being sent to the Server (can be different due to PTS shifting and unlooping), etc.
This log is useful for tracking each frame as it passes from Testcamera to Nx Witness Server and then to the Plugin, and is reflected in the Analytics Logs (see Analytics Logs).
Normally, the camera becomes discoverable by all Servers in the same network. If you want to limit it to a particular Server, e.g. running on the same developer workstation as Testcamera, the best option is to instruct Testcamera to broadcast its presence only within the PC:
.../testcamera --local-interface=127.0.0.1 files=my_video.ts
Alternatively, Testcamera can be made discoverable by a Server only in a dedicated IP subnetwork — e.g. when using a second network adapter for a dedicated network containing the Server PC and the Testcamera PC.
As an example, if the dedicated subnetwork is 192.168.* and its network adapter on the Testcamera PC is 192.168.0.100, then Testcamera can be instructed to broadcast its presence only in this network:
.../testcamera --local-interface=192.168.0.100 files=my_video.ts
We do not recommend running Testcamera in an office network without the restrictions shown above. Otherwise, all VMS Servers in the office will discover this Testcamera and eventually pull video stream(s) from it, producing unnecessary load and complicating your debugging.
Another way to make the particular Testcamera instance discoverable only by the particular Server is to use a custom Discovery Port:
- Specify the --discovery-port=<port> option using a value other than the default 4984.
- Add this Testcamera to the Server manually:
- In the main menu of Nx Witness Desktop (top-left menu icon), select Add Devices…
- Specify the Testcamera host address, and the custom Discovery Port value in the Port field, then click Search
- When the Testcamera appears on the list, click Add All Devices.
Image Library Plugin
Besides Testcamera, there is another way to create a virtual camera that will playback the specified static images — using Image Library Plugin.
Image Library Plugin is included as a binary in the Nx Witness Server distribution and is located in the plugins_optional directory. To activate it, specify its name in vms_server_plugins.ini:
The source code of Image Library Plugin is included with Video Source SDK as a sample Plugin. We recommend consulting its source code for details about how it works. Also, you can extend this Plugin with the required features, building it from the source.
To build it, unpack the Video Source SDK zip, and run the script build_samples.sh for Linux or Cygwin, or build_samples.bat for Windows. See details about building SDK samples in Building your Plugin.
To install the built Plugin, put its dynamic library to the plugins_optional directory, replacing the original image_library_plugin.dll (on Windows) or libimage_library_plugin.so (on Linux). For details, see Loading Plugins.
If you need to introduce some settings for the modified Plugin, we recommend introducing a dedicated image_library_plugin.ini file, writing the code based on the IniConfig mechanism; the same way it’s done in Stub Analytics Plugin.
To use Image Library Plugin, you need to add its virtual camera to the Server manually:
- In the main menu of Nx Witness Desktop (top-left menu icon), select Add Devices.
- In the Address field, specify the absolute path to a directory containing JPEG images.
- Click Search and wait until the camera appears in the table.
- Click Add All Devices.
The virtual camera will then appear in the Resource Tree, and will play back the images sequentially.
The order of the images can be arbitrary, but you may find it easy to modify the Image Library Plugin source code to sort the files to your needs: in dir_contents_manager.cpp, change the implementation of the function
The frame rate is 1 FPS, which is hard-coded in camera_manager.cpp:
static const int FRAME_DURATION_USEC = 1*1000*1000;