streamreceiver_web_logo

StreamReceiver C++ application

v1.1.0

Table of contents

Overview

StreamReceiver is a C++ application that receives frames from a video stream and shows those frames in a window with statistics. The application receives RTSP streams (RTP over UDP unicast, UDP multicast, TCP interleaved or an HTTP tunnel) and RTSPS streams (RTSP over TLS, with RTP inside the TLS connection, plain UDP, SRTP or an HTTPS tunnel). It also receives SDP-less RTP and SRTP push streams, which a sender sends without RTSP signaling, and raw MPEG-TS datagrams. The application passes a source string to the VSourceStream library, which receives and decodes the stream, and shows the frames that the library delivers with the SimpleUI library, which uses X11 (libx11-dev, libxext-dev packages) on Linux. The repository does not contain these libraries: see How to run the application.

StreamReceiver is general-purpose software: it is not tied to any sector or application, and the developer of a program decides what the program does with it.

Versions

Table 1 - Application versions.

Version Release date What’s new
1.0.0 13.10.2026 - First version.
1.1.0 23.10.2026 - Without arguments the application prints the usage (quick start, source string formats, examples and options) and asks for the source string. The option -h or –help prints the usage.
- After a failed initialization the application points to the ERROR line of the VSourceStream library. In the console mode the source string can be entered again (at most 5 attempts).
- A frame is shown without the telemetry text if the telemetry is not available.
- Exit code: 0 after a stop by the user, 1 after an error or a lost stream (a failed initialization returned 255).
- Git submodules removed: the repository contains no sub-repositories and no 3rdparty folder. A stand alone build takes the libraries from the folders next to the repository.
- Comments and structure of main.cpp cleaned up, README corrected.

Application files

The repository structure is shown below:

CMakeLists.txt ----------------- Main CMake file of the application.
src ---------------------------- Folder with application source code.
    CMakeLists.txt ------------- CMake file of the application.
    main.cpp ------------------- Source C++ file of the application.
    StreamReceiverVersion.h ---- Header file with application version.
    StreamReceiverVersion.h.in - File for CMake to generate version header.
static ------------------------- Folder with images of this documentation.
    streamreceiver_web_logo.png  Logo.

How to run the application

Requirements:

  • Operating system: Linux or Windows.
  • Tools: CMake 3.13 or newer and a C++17 compiler: GCC or Clang on Linux, MSVC on Windows.
  • Linux: the X11 development packages of the SimpleUI window (Debian / Ubuntu: sudo apt install libx11-dev libxext-dev).
  • OpenSSL (optional): the OpenSSL 3.0 or newer development package (Debian / Ubuntu: sudo apt install libssl-dev). With OpenSSL the VSourceStream library supports TLS (rtsps:// sources), and CMake prints “VSourceStream: OpenSSL (TLS enabled)". Without OpenSSL CMake prints "VSourceStream: OpenSSL not found (TLS disabled)", and an rtsps:// source can't connect.

The repository does not contain sub-repositories. The libraries that the application depends on must be cloned into the same folder as StreamReceiver: SimpleUI, VSourceStream and the libraries of VSourceStream (Frame, ConfigReader, VSource, CryptoProvider, VCodec, VDecoderH264, VDecoderH265, VDecoderJPEG and FormatConverter). The folder structure must be:

<work folder>
    StreamReceiver
    Frame
    ConfigReader
    VSource
    CryptoProvider
    VCodec
    VDecoderH264
    VDecoderH265
    VDecoderJPEG
    FormatConverter
    VSourceStream
    SimpleUI

Typical commands to build the StreamReceiver application (use the URLs of the repositories provided to you):

git clone <StreamReceiver repository URL>
git clone <Frame repository URL>
git clone <ConfigReader repository URL>
git clone <VSource repository URL>
git clone <CryptoProvider repository URL>
git clone <VCodec repository URL>
git clone <VDecoderH264 repository URL>
git clone <VDecoderH265 repository URL>
git clone <VDecoderJPEG repository URL>
git clone <FormatConverter repository URL>
git clone <VSourceStream repository URL>
git clone <SimpleUI repository URL>
cd StreamReceiver
mkdir build
cd build
cmake ..
make

On Windows use cmake --build . --config Release instead of make; the application is then build\bin\Release\StreamReceiver.exe. The main CMakeLists.txt file of the application adds the folders ../Frame, ../ConfigReader, ../VSource, ../CryptoProvider, ../VCodec, ../VDecoderH264, ../VDecoderH265, ../VDecoderJPEG, ../FormatConverter, ../VSourceStream and ../SimpleUI (in this order) before the application itself. If a folder does not exist CMake stops with an error. The build type defaults to Release. The application has no other CMake options.

In the RapidPixel SDK the application is built from the root of the SDK (the libraries are taken from the SDK, the folders next to the application are not needed). The executable file is placed in the build/bin folder (build\bin\Release on Windows):

cd /path/to/RapidPixelSdk
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --target StreamReceiver

Run the application without arguments. It prints the usage: a quick start, the formats of the source string with examples and the list of the options. Then it asks for the source string. Enter it, for example:

cd build/bin
./StreamReceiver
Enter the source string (empty line to exit): rtsp://<IP>:<port>/StreamN -tcp

Or give the source string as arguments, for example:

cd build/bin
./StreamReceiver rtsp://<IP>:<port>/StreamN -tcp

The option -h or –help prints the usage and exits.

When the source is open, the application shows the frames in a window. The statistics of the last frame are drawn at the top left corner of the frame:

  • Frame ID, Key frame and Timestamp (90 kHz) of the frame;
  • Capture time (us) and Receive time (us): the time when the sender captured the frame (unknown if the sender does not give it) and the time when the application received it;
  • Latency (ms): receive time minus capture time (unknown without the capture time). It is exact only if the clocks of the sender and of the receiver are synchronized and the sender gives the real capture time of each frame. A sender that does not stamp the real capture time (for example a test source) gives a wrong value, also a negative one;
  • Lost frames, Lost packets and Packet loss (10 s);
  • Metadata units: the number of metadata units (KLV, ONVIF®) of the frame with the type, the stream, the exactness and the size of each unit.

Press ESC or close the window to stop the application. The exit code is 0 after a stop by the user. The exit code is 1 if the source string is empty or can’t be opened, or if no frame arrives for 30 s.

Supported sources

The URL scheme of the source string selects the source. Table 2 lists what each scheme receives.

Table 2 - Supported sources.

Scheme Transport Container Codecs Metadata Notes
rtsp:// UDP unicast (default; adaptive UDP / TCP, see Adaptive transport)
TCP interleaved (-tcp)
UDP multicast (-multicast)
RTSP over HTTP tunnel (-http)
RTP
MPEG-TS in RTP
H.264, H.265, JPEG
H.264, H.265 in MPEG-TS
KLV track (SMPTE336M, RFC 6597)
ONVIF® metadata track (VND.ONVIF.METADATA)
KLV in MPEG-TS
Default port 554. Digest authentication (SHA-256, MD5). RTCP NACK / RTX and PLI / FIR when the server offers them.
rtsps:// TCP interleaved inside TLS (default)
UDP unicast / multicast (-udp / -multicast)
SRTP over UDP or TCP (-srtp)
RTSP over HTTPS tunnel (-http)
RTP / SRTP
MPEG-TS in RTP
as rtsp:// as rtsp:// Default port 322. TLS 1.2 / 1.3 with peer verification (needs a build with OpenSSL). Digest and Basic authentication. SRTP keys from the SDP (SDES a=crypto).
rtp:// UDP unicast or multicast group (push, no SDP) RTP
MPEG-TS in RTP
raw MPEG-TS
H.264, H.265 (detected by content)
JPEG (payload type 26)
H.264, H.265 in MPEG-TS
KLV / ONVIF® on its own SSRC on the same port
KLV in MPEG-TS
RTCP on port + 1; RTCP on the RTP port (rtcp-mux) is recognized too.
udp:// UDP unicast or multicast group raw MPEG-TS
RTP accepted too
as rtp:// as rtp:// Receives exactly like rtp://, reports protocol “UDP”.
srtp:// UDP unicast or multicast group (push, no SDP) SRTP
MPEG-TS in SRTP
as rtp:// as rtp:// Pre-shared master key (-srtpkey). Every packet is authenticated; raw MPEG-TS is refused.

The application (the VSourceStream library) does not support:

  • HLS and WebRTC (MServer serves them to browsers);
  • SRT: an srt:// URL fails with “SRT is not supported” (MServer does not serve SRT either);
  • IPv6: IPv6 literals are refused, and host names are resolved to IPv4 addresses only;
  • audio: audio tracks and audio PIDs are ignored;
  • the H.264 interleaved packetization mode (packetization-mode=2);
  • multi-layer H.265, SVC and MVC;
  • MPEG-TS video other than H.264 and H.265;
  • SRTP keyed by MIKEY or DTLS-SRTP: the SRTP keys come only from the SDP (a=crypto) or from -srtpkey;
  • frames wider or taller than 8192 pixels, or with more than 8192 x 4352 pixels (H.264 / H.265 level 6.2).

Reception is tested by the test application of the VSourceStream library with MServer, its reference server. The “matrix” and “live” groups of the test application cover every delivery mode of MServer that is not HLS or WebRTC (RTSP over UDP, TCP, multicast and the HTTP tunnel; RTSPS interleaved, with plain UDP or multicast media, with SRTP over UDP or TCP, and through the HTTPS tunnel; the push leg in every container; H.264, H.265 and JPEG; KLV and ONVIF® metadata; digest authentication and the compliance profiles) and live changes to MServer while a client is connected. It is also tested with independent senders: ffmpeg 6.1.1 (RTP, MPEG-TS and MPEG-TS in RTP with libx264, libx265 and MJPEG), the GStreamer 1.24.2 payloaders and MPEG-TS muxer, and gst-rtsp-server 1.24.2 (RTSP over UDP, TCP and HTTP, RTSPS with its GnuTLS TLS stack, digest authentication).

Source string

The source string is given in the command line arguments of the application. The arguments are joined with spaces, so the string can be given as several arguments or as one argument in quotes. Without arguments, the application prints the usage and asks for the source string in the console (an empty line exits; after a failed initialization the string can be entered again, at most 5 attempts). The application passes the string to the openVSource(…) method of the VSourceStream library. Format:

<url> [option ...]

The URL comes first. The options follow, separated by spaces or tabs. The string can hold at most 4096 bytes and 32 tokens. Option names and URL schemes are case-insensitive. An option value is the next token, so a value can’t contain spaces.

Initialization fails on an unknown option, a missing value, a value out of range, a repeated option or a refused combination. An ERROR log line in the console then names the reason. With arguments the application exits with code 1, in the console mode it asks for the string again. A value is never clamped or ignored.

Table 3 - URL formats.

URL Description
rtsp://[user[:password]@]host[:port]/path[?query] RTSP. host is a host name (letters, digits, ‘-‘ and ‘.’; resolved to one IPv4 address) or an IPv4 literal. Default port 554. User and password are percent-decoded (%XX); each can have at most 128 bytes. The user name (from the URL after decoding, or from -user) must not contain control characters, ‘:’, ‘”’ or a backslash. The password must not contain control characters. In the user-info, ‘/’, ‘?’ and ‘#’ must be percent-encoded; the last ‘@’ ends the user-info. Path and query must use RFC 3986 characters. Fragments (‘#’) are refused. The URL can have at most 1024 bytes, not counting the user-info.
rtsps://[user[:password]@]host[:port]/path[?query] RTSP over TLS, same syntax. Default port 322.
rtp://<ipv4>:<port> SDP-less RTP or MPEG-TS reception (see SDP-less reception and auto-detection). ipv4 is a local address (0.0.0.0 = any address) or a multicast group in 224.0.0.0/4, which the application joins. Port 1 - 65534 (RTCP uses port + 1). User-info, path, query and host names are not allowed (a lone ‘/’ is tolerated).
udp://<ipv4>:<port> Raw MPEG-TS datagrams; RTP is accepted too. Same syntax as rtp://.
srtp://<ipv4>:<port> SDP-less SRTP with a pre-shared key. Same syntax as rtp://. -srtpkey is required.

Table 4 - Source string options.

Option Valid with Default Description
-tcp rtsp://, rtsps:// rtsps:// Transport preference: RTP interleaved in the RTSP connection (inside TLS for rtsps://).
-udp rtsp://, rtsps:// rtsp:// Transport preference: RTP over UDP unicast (SRTP over UDP with -srtp).
-multicast, -udpm rtsp://, rtsps:// - Transport preference: UDP multicast. The application sends DESCRIBE for the URL as given. SETUP asks for RTP/AVP;multicast, and the reply gives the group and the ports.
-http rtsp://, rtsps:// - RTSP over an HTTP tunnel (an HTTPS tunnel for rtsps://). The media is interleaved in the tunnel.
-autotransport rtsp://, rtsps:// on when no transport option is given Adaptive transport (see Adaptive transport): a switch UDP -> TCP on network loss, and a TCP latency guard. A transport option (-tcp, -udp, -multicast, -http) turns it off. Given together with -tcp or -udp, -autotransport keeps it on, and that option selects the initial transport.
-noautotransport rtsp://, rtsps:// - Turns the adaptive transport off. The firewall fallback UDP -> TCP still works.
-srtp rtsps:// - SRTP media (RTP/SAVP). The application sends DESCRIBE for the URL as given. If the SDP has no RTP/SAVP video with a usable a=crypto key, and the text after the first ‘?’ or ‘;’ contains neither “srtp” nor “savp” (case-sensitive, like MServer), the application sends DESCRIBE once more on the same connection. This time “?srtp” is appended to the URL (“&srtp” when the URL already has a query): this is MServer’s secure presentation.
-user NAME rtsp://, rtsps:// - User name, taken literally (not percent-decoded).
-password PASS rtsp://, rtsps:// - Password, taken literally. Requires -user.
-profile NAME all ONVIF Compliance mode: ONVIF, STRICT_FIPS, FIPS_ONVIF_BRIDGE or CRA_STRICT (case-insensitive). “NO” also selects ONVIF. Other names fail. See Security and compliance modes.
-cafile PATH rtsps:// system CA paths PEM CA bundle used for TLS peer verification. On Windows, OpenSSL has no system CA store by default (it does not read the Windows certificate store), so give -cafile or -fingerprint there.
-fingerprint FP rtsps:// - Pin the SHA-256 fingerprint of the server certificate: 32 hex pairs separated by ‘:’ (95 characters) or 64 hex digits, case-insensitive.
-noverify rtsps:// - Disables TLS peer verification. Allowed in the ONVIF profile only, and not together with -fingerprint or -cafile. The WARNING “TLS peer verification disabled (-noverify): the server is NOT authenticated” is logged once per initialization, not per reconnection.
-srtpkey BASE64 srtp:// required Master key followed by master salt, in strict standard base64 (RFC 4568 inline form), at most 128 characters. Decoded length: 30 bytes for the AES_CM_128 suites, 46 bytes for the AES_256_CM suites, 28 bytes for AEAD_AES_128_GCM, 44 bytes for AEAD_AES_256_GCM.
-srtpsuite NAME srtp:// AES_CM_128_HMAC_SHA1_80 SRTP suite (case-insensitive): AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_256_CM_HMAC_SHA1_80, AES_256_CM_HMAC_SHA1_32, AEAD_AES_128_GCM, AEAD_AES_256_GCM.
-iface IP rtp://, udp://, srtp://, rtsp:// and rtsps:// with -multicast system choice Unicast IPv4 address of the interface used for the multicast join (not 0.0.0.0, which names no interface).
-source IP rtp://, udp://, srtp:// any sender Accepts media only from this unicast IPv4 sender. A multicast group is then joined as source-specific multicast (SSM).
-timeout MS all 10000 Init / connect deadline, 100 - 60000 ms (see initVSource(…) for how long opening the source can block). Every reconnection attempt gets the same deadline.
-reconnect MS all (used by rtsp:// and rtsps://) 5000 No-media watchdog, 500 - 60000 ms: an RTSP session without video media for this time is reconnected (metadata packets alone do not keep it alive: a camera whose video stalled while its analytics stream goes on is reconnected).
-mindelay MS all 10 (3 with -nokeywait) Minimum reorder wait, 0 - 1000 ms (see Low latency design and adaptive jitter buffer). The default is 10 ms: the longer wait delays only the frames that are kept after a real loss. These are the next frame when the loss lies between two frames, the key frame after a skip (unless it is complete in the buffer) and the frames that -keywait lets through. In exchange, reordering of up to 10 ms (Wi-Fi, LTE, bonded links) does not cost the rest of a GOP (measured over 124 channel traces). With -nokeywait every frame behind a gap waits, so the default is 3 ms there.
-maxdelay MS all 200 Maximum reorder wait, 1 - 5000 ms. TCP transports always use 0.
-buffer N all CUSTOM_2 (32) Output buffer depth, 1 - 512 frames. Overrides VSourceParams::custom2.
-nokeywait all - After packet loss, the non-key frames are delivered anyway (decoding artifacts until the next key frame). The key-frame bypass of the reorder wait is then off, and the default minimum wait is 3 ms.
-keywait MS all 0 (unbounded) Bounded key frame wait, 0 - 60000 ms (0 = unbounded). After packet loss, non-key frames are skipped for at most MS. Then they are delivered again until the next key frame (decoding artifacts are possible). The key frame is requested with RTCP PLI / FIR when the server supports it. See Bounded key frame wait.
-nometadata all - No metadata tracks are set up, and no KLV / ONVIF® metadata is bound to frames: the telemetry has no metadata units. The ST 0604 SEI capture time of getTelemetry(…) is still parsed.
-seidata all - Also delivers the H.264 / H.265 SEI user_data_unregistered messages (x264 options, MISB ST 0604 time stamps, vendor data) as metadata units of type UNKNOWN. The SEI units of the frame’s own access unit are exact; they come after its exact KLV / ONVIF® units. An access unit that is not delivered (skipped before a key frame or after a loss, corrupt, without a picture, oversized, dropped by the output buffer or by -maxlatency) gives its SEI units to the next delivered frame. These units are not exact, and they count toward the carry bound (see Metadata binding): after a long skip they can push out older carried KLV / ONVIF® units. SEI NAL units above 64 KiB are not scanned. At most 16 user_data_unregistered messages (ST 0604 time stamps included) are taken per access unit. The SEI stays in the frame. Off by default: the telemetry then has KLV / ONVIF® units only. The ST 0604 capture time of getTelemetry(…) is parsed either way, within the same bounds.
-maxlatency MS all 0 (off) Output latency budget, 10 - 60000 ms (0 = off; 1 - 9 fail; see Output latency budget). When the oldest buffered frame is older than MS and a newer key frame is buffered, every frame before the newest buffered key frame is dropped. The drops are counted in CUSTOM_3, framesOverflow and framesLatencyDropped. The overflow policy does not change. So a consumer that stalled catches up at the next key frame instead of staying late. MS is also the budget of the TCP latency guard of the adaptive transport. Set it to at least a few frame intervals.
-priority N all inherited SCHED_FIFO priority 1 - 99 of the receive thread. Needs CAP_SYS_NICE or RLIMIT_RTPRIO. On Windows, any value gives THREAD_PRIORITY_TIME_CRITICAL (the highest priority below the realtime class). A failure gives one WARNING, and the source then works with the inherited policy. Without this option the receive thread inherits the policy and affinity of the thread that calls initVSource(…) (the main thread of the application). For the full effect, the thread that calls getFrame(…) must also run with a raised priority (in StreamReceiver it is the main thread, and the application does not change its priority). Measured under CPU contention: p99 4 - 10 ms -> 0.8 - 1.7 ms, only with both threads prioritized. See Receive thread, kernel timestamps and scheduling.
-cpu N all inherited Pins the receive thread to CPU 0 - 1023 (on Windows: 0 - 63, processor group 0). A failure gives one WARNING. Useful only on an otherwise idle CPU. See Receive thread, kernel timestamps and scheduling.

If both -mindelay and -maxdelay are given, min > max fails. A lone -mindelay above the default maximum (200 ms) raises the maximum to the same value. A lone -maxdelay below the default minimum (10 ms; 3 ms with -nokeywait) lowers the minimum to the same value. For example, -maxdelay 5 gives 5 - 5 ms, and -nokeywait -maxdelay 5 gives 3 - 5 ms.

Refused combinations (initialization fails):

  • more than one of -tcp, -udp, -multicast / -udpm and -http;
  • -tcp, -udp, -multicast, -http, -autotransport, -noautotransport, -srtp, -user, -password, -cafile, -fingerprint or -noverify with rtp://, udp:// or srtp://;
  • -autotransport together with -noautotransport, -multicast / -udpm or -http;
  • -keywait together with -nokeywait (also -keywait 0);
  • -seidata together with -nometadata;
  • -srtp with rtsp:// (the SRTP keys travel in the SDP, and only TLS protects the SDP);
  • -srtpkey or -srtpsuite without srtp://, srtp:// without -srtpkey, and a key whose decoded length does not match the suite;
  • -source with rtsp:// or rtsps://, and -iface with rtsp:// or rtsps:// without -multicast;
  • -noverify together with -fingerprint or -cafile;
  • credentials both in the URL user-info and in -user / -password, and -password without a user;
  • anything the compliance profile refuses, for example rtsp:// or -noverify in STRICT_FIPS and CRA_STRICT (see Security and compliance modes).

Examples:

rtsp://192.168.1.67:8900/Cam1 -tcp
rtsp://admin:<password>@192.168.1.67:554/live
rtsp://192.168.1.67:554/live -user admin -password <password> -udp -reconnect 3000
rtsp://192.168.1.67:554/live -multicast -iface 192.168.1.10
rtsp://192.168.1.67:554/live -http
rtsp://192.168.1.67:554/live -maxlatency 200 -priority 50 -cpu 3
rtsp://192.168.1.67:554/live -tcp -autotransport
rtsps://camera-1:322/live -cafile /etc/ssl/certs/ca-certificates.crt
rtsps://192.168.1.67:8555/live -srtp -udp -fingerprint <SHA-256 fingerprint of the server>
rtsps://camera-1:8555/live -profile CRA_STRICT -cafile /etc/ca.pem
rtp://0.0.0.0:8765
rtp://239.1.1.1:5004 -iface 192.168.1.10 -source 192.168.1.67
udp://0.0.0.0:5600 -keywait 2000 -seidata
srtp://0.0.0.0:5004 -srtpkey <base64 master key and salt> -srtpsuite AEAD_AES_128_GCM

Table of contents