vstreamermediamtx_web_logos

VStreamerMediaMtx C++ library

v1.1.4

Table of contents

Overview

The VStreamerMediaMtx C++ library provides RTSP, WebRTC, SRT (optional, not tested in version 1.1.1), RTPM (optional, not tested in version 1.1.1) and HLS (optional, not tested in version 1.1.1) video streaming without audio. The library inherits interface from VStreamer. The library depends on: OpenCV (version >= 4.5) library (running GStreamer pipeline and video scaling, linked, Apache 2.0 license), GStreamer (video encoding and streaming to mediamtx, run as external process by OpenCV, not included in code), mediamtx (provides video server, run as external process, not included in code, MIT license), VCodec (not used, defines video codec interface, source code included, Apache 2.0 license), VOverlay (defines video overlay interface, source code included, Apache 2.0 license), FormatConverterOpenCv (provides methods to convert pixel formats, source code included), ConfigReader (provides functions to read / write JSON files, source code included) and ChildProcess (provides functions to run child process, source code included). The library supports changing RTSP parameters such as: RTSP server port, IP, stream name, user name, password etc. The library works frame-by-frame and accepts video frames in formats: RGB24, BGR24, YUYV, UYVY, GRAY, YUV24, NV12, NV21, YU12 and YV12. Principle of operation: when user sends frame (call sendFrame(…) function) the library copies video frame to internal buffer. After initialization the library runs internal thread. Internal thread is taking new frame according to FPS (set by user in parameters). After taking new frame the library does frame scaling (according to scaling mode if input frame size different from video stream size) and put overlay information (if overlay engine is initialized by user). After preparing frame the library runs (once) GStreamer pipeline and sends video frame to it. GStreamer pipeline includes video encoder (software or hardware, set by user). GStreamer pipeline streams data to external process mediamtx (user should run it in advance or using auto run provided by the library) which provides video server service for clients. All instances of the library should use the same RTSP port, user name and password, RTSP multicast IP and port. The version 1.1.1 of the library support H264, H265 and JPEG video encoding on CPU, Intel GPU and Nvidia Jetson platforms using GStreamer. Bellow the working principle:

vstreamermediamtx

Key features:

  1. All instances of VStreamerMediaMtx class use the same RTSP server port, user name, password, multicast port and multicast IP. If user change one of this parameters in one instance the all other VStreamerMediaMtx instances in user application will be restarted automatically with new parameters. The mediamtx process provides RTSP server on the same port for all streams (Difference only in stream name). For example: rtsp://127.0.0.1:7031/Camera1Stream1 (first instance of VStreamerMediaMtx), rtsp://127.0.0.1:7031/Camera1Stream2 (second instance of VStreamerMediaMtx) etc.
  2. RTSP server port, user name, password, multicast IP and multicast port are configurable in mediamtx configuration file (mediamtx.yml). To change RTSP server port, user name, password, multicast IP or multicast port user must stop mediamtx process, change mediamtx.yml file and run mediamtx process again. The library provides automatic mediamtx configuration if user provides path to mediamtx executable file.
  3. The VStreamerMediaMtx supports video overlay (user must initialize VOverlay object if overlay required).
  4. VCodec interface not used. The library compatible with Linux operating systems only. The video server compatible with all popular RTSP clients: ffmpeg, gstreamer, VLC, Milestone etc.
  5. IMPORTANT: the library uses GStreamer pipeline for video encoding. The library can use software encoders or hardware encoders. Type of codec set by user in parameters. Version 1.1.1 of the library supports following GStreamer software codecs (on CPU): x264enc for H264 video encoding, x265enc for H265 video encoding and jpegenc for JPEG video encoding. The library supports following hardware codecs: vaapih264enc or nvv4l2h264enc for H264 video encoding and vaapih265enc or nvv4l2h265enc for H265 video encoding. For JPEG encoding it uses nvjpegenc in NVDIA JETSON platform or jpegenc software codec for all other platforms. For more details see Table 6.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 15.12.2024 - First version.
1.1.0 14.01.2025 - Add support of Nvidia Jetson platform.
- Add start/stop control for mediamtx.
1.1.1 28.01.2025 - Fix resolution settings and restart issue of mediamtx.
1.1.2 10.02.2025 - Add streamer params to overlay engine.
1.1.3 13.02.2025 - Add check for odd multicast port value.
1.1.4 18.02.2025 - Fix encoding params table in documentation.

Library files

The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt --------------------- Main CMake file of the library.
3rdparty --------------------------- Folder with third-party libraries.
    CMakeLists.txt ----------------- CMake file for to include third-party libraries.
    FormatConverterOpenCv ---------- Folder with FormatConverterOpenCv library source code.
    VStreamer ---------------------- Folder with VStreamer library source code.
    ChildProcess ------------------- Folder with ChildProcess library source code.
src -------------------------------- Folder with library source code.
    CMakeLists.txt ----------------- CMake file of the library.
    VStreamerMediaMtx.cpp ---------- C++ implementation file.
    VStreamerMediaMtx.h ------------ Main library header file.
    VStreamerMediaMtxVersion.h ----- Header file with library version.
    VStreamerMediaMtxVersion.h.in -- CMake service file to generate version file.
example ---------------------------- Folder for example application files.
    CMakeLists.txt ----------------- CMake file of example application.
    main.cpp ----------------------- Source C++ file of example application.
test ------------------------------- Folder for test application files.
    CMakeLists.txt ----------------- CMake file of test application.
    main.cpp ----------------------- Source C++ file of test application.

VStreamerMediaMtx class description

VStreamerMediaMtx class declaration

VStreamerMediaMtx class declared in VStreamerMediaMtx.h file. Class declaration:

namespace cr
{
namespace video
{
/// Video streamer based on GStreamer and OpenCv.
class VStreamerMediaMtx : public cr::video::VStreamer
{
public:

    /// Get string of current library version.
    static std::string getVersion();

    /// Class constructor.
    VStreamerMediaMtx();

    /// Class destructor.
    ~VStreamerMediaMtx();

    /// Init video streamer by set of parameters.
    bool initVStreamer(cr::video::VStreamerParams &params,
                       cr::video::VCodec *codec = nullptr,
                       cr::video::VOverlay *overlay = nullptr) override;

    /// Get init status.
    bool isVStreamerInit() override;

    /// Close video streamer.
    void closeVStreamer() override;

    /// Send frame to video streamer.
    bool sendFrame(cr::video::Frame& frame) override;

    /// Set video streamer parameter.
    bool setParam(cr::video::VStreamerParam id, float value) override;

    /// Set video streamer parameter.
    bool setParam(cr::video::VStreamerParam id, std::string value) override;

    /// Get all video streamer parameters.
    void getParams(cr::video::VStreamerParams& params) override;

    /// Execute action command.
    bool executeCommand(cr::video::VStreamerCommand id) override;

    /// Set media mtx path.
    static void setMediaMtxPath(std::string path);

};
}
}

getVersion method

The getVersion() method return string of current class version. Method declaration:

static std::string getVersion();

Method can be used without VStreamerMediaMtx class instance:

cout << "VStreamerMediaMtx version: " << VStreamerMediaMtx::getVersion();

Console output:

VStreamerMediaMtx version: 1.1.2

initVStreamer method

The initVStreamer(…) method initializes video server. If server already initialized the method will reinitialize server. If video server parameters changed user does not need to call initVStreamer(…) method to reinitialize server (use setParam(…) method). Method declaration:

bool initVStreamer(cr::video::VStreamerParams &params,
                   cr::video::VCodec *codec = nullptr,
                   cr::video::VOverlay *overlay = nullptr) override;
Parameter Value
params VStreamerParams object which includes all parameters for initialization.
codec Not used. VCodec object pointer.
overlay VOverlay object pointer for video overlay function.

Returns: TRUE if initialization is done or FALSE if not.

isVStreamerInit method

The isVStreamerInit() method returns video streamer initialization status. Method declaration:

bool isVStreamerInit() override;

Returns: TRUE if the video streamer initialized or FALSE if not.

setParam (string parameter) method

The setParam(…) method sets parameter with string value. Some of parameters require modification of mediamtx.yml file as well. If path that contains mediamtx and mediamtx.yml is set by using setMediaMtxPath method, library will handle all required modifications internally and restart mediamtx properly. If this path is not set, user is responsible of configuration of mediamtx.yml and restarting mediamtx. Following table shows parameters that require modification of mediamtx.yml file:

Table 2 - Parameters that require modification of mediamtx.yml file. | | | | | | |—|—|—|—|—| | User name | Password | Rtsp port | Multicast port | Multicast ip |

Method declaration:

bool setParam(cr::video::VStreamerParam id, std::string value) override;
Parameter Value
id Parameter ID according to VStreamerParam enum.
value Parameter value with string type.

Returns: TRUE if parameter is set or FALSE if not.

setParam (float parameter) method

The setParam(…) method to set parameter with float value. Some of parameters require modification of mediamtx.yml file as well. If path that contains mediamtx and mediamtx.yml is set by using setMediaMtxPath method, library will handle all required modifications internally and restart mediamtx properly. If this path is not set, user is responbile of configuration of mediamtx.yml and restarting mediamtx. For the list of the parameters that require this modification see the Table 2. Also see the Table 5 for more information about changing parameters and behavior of streams. Method declaration:

bool setParam(cr::video::VStreamerParam id, float value) override;
Parameter Value
id Parameter ID according to VStreamerParam enum.
value Parameter value with float type.

Returns: TRUE if parameter is set or FALSE if not.

getParams method

The getParams(…) method to get all parameters that are defined in form of VStreamerParams. Method declaration:

void getParams(cr::video::VStreamerParams& params) override;
Parameter Value
params Reference to VStreamerParams object to store all video server parameters.

executeCommand method

The executeCommand(…) method to execute command. Method declaration:

bool executeCommand(cr::video::VStreamerCommand id) override;
Parameter Value
id Command ID according to VStreamerCommand enum.

Returns: TRUE if command is executed or FALSE if not.

setMediaMtxPath method

The setMediaMtxPath(…) is a static method to set path to mediamtx executable. By default this path is not set and library will assume that mediamtx is running already. Also if this path is not set user is responsible of configuration of mediamtx.yml file if any parameter is changed. For example, user can call setParam to change the port for streams meanwhile mediamtx.yml file should be also modified. So if this path is not set, user should handle modification of mediamtx.yml and restart mediamtx executable (see Run mediamtx section for an example), if it is set, library will run mediamtx as additional process and handle all required modification internally. Also if path is set, library will kill all running instances of mediamtx if there is any running. Method declaration:

static void setMediaMtxPath(std::string path);
Parameter Value
path Path that contains mediamtx executable and mediamtx.yml configuration file. For example if mediamtx and mediamtx.yml are located in home folder if user called pi, path should be set as “/home/pi”.

sendFrame method

The sendFrame(…) method sends video frame to video server for streaming. The method copies frame data to internal buffer. Method declaration:

bool sendFrame(cr::video::Frame& frame) override;
Parameter Value
frame Frame object. The method accepts video frames in formats: RGB24, BGR24, YUYV, UYVY, GRAY, YUV24, NV12, NV21, YU12 and YV12

Returns: TRUE if frame is sent or FALSE if not.

closeVStreamer method

The closeVStreamer() method to close video server if it is open. Method declaration:

void closeVStreamer() override;

decodeAndExecuteCommand method of VStreamer interface

The decodeAndExecuteCommand(…) method decodes and executes command encoded by encodeSetParamCommand(…) and encodeCommand(…) methods on video streamer side. It is a virtual method which means if implementation does not define it, default definition from VStreamer class will be used. Each implementation of the video streamer must provide thread-safe setParam(…) and executeCommand(…) method calls to make default definition of decodeAndExecuteCommand(…) thread-safe. This means that the decodeAndExecuteCommand(…) method can be safely called from any thread. Method declaration:

virtual bool decodeAndExecuteCommand(uint8_t* data, int size);
Parameter Description
data Pointer to input command.
size Size of command.

Returns: TRUE if command decoded (SET_PARAM or COMMAND) and executed (action command or set param command).

encodeSetParamCommand method of VStreamer interface

The encodeSetParamCommand(…) static method to encode command to change any parameter in remote video streamer. To control video streamer remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VStreamer class contains static methods for encoding the control command. The VStreamer class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) designed to encode SET_PARAM command. Method has two overlays: one for numeric parameters and one for string parameters. Method declaration:

static void encodeSetParamCommand(uint8_t* data, int& size, VStreamerParam id, std::string value);

static void encodeSetParamCommand(uint8_t *data, int &size,  VStreamerParam id, float value);
Parameter Description
data Pointer to data buffer for output command. Must have size >= 11.
size Size of encoded data. Will be minimum 11 bytes.
id Parameter ID according to VStreamerParam enum.
value Numeral video streamer parameter value. Only for non string parameters. For string parameters (see VStreamerParam enum) this parameters may have any values.
value String parameter value (see VStreamerParam enum).

encodeSetParamCommand(…) is static method and used without VStreamer class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Random parameter value.
float outValue = (float)(rand() % 20);
// Encode command.
VStreamer::encodeSetParamCommand(data, size, VStreamerParam::CUSTOM1, outValue);

encodeCommand method of VStreamer interface

The encodeCommand(…) static method to encode command for remote video streamer. To control a video streamer remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VStreamer class contains static methods for encoding the control command. The VStreamer class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) designed to encode COMMAND (action command). Method declaration:

static void encodeCommand(uint8_t* data, int& size, VStreamerCommand id);
Parameter Description
data Pointer to data buffer for output command. Must have size >= 7 bytes.
size Size of encoded data. Will be 7 bytes.
id Command ID according to VStreamerCommand enum.

encodeCommand(…) is static method and used without VStreamer class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Encode command.
VStreamer::encodeCommand(data, size, VStreamerCommand::RESTART);

decodeCommand method of VStreamer interface

The decodeCommand(…) static method to decode command on video streamer side (edge device). Method declaration:

static int decodeCommand(uint8_t* data, int size, VStreamerParam& paramId,
                         VStreamerCommand& commandId, float& value,
                         std::string& strValue);
Parameter Description
data Pointer to input command.
size Size of command. Should be minimum 11 bytes for SET_PARAM and 7 bytes for COMMAND.
paramId Parameter ID according to VStreamerParam enum. After decoding SET_PARAM command the method will return parameter ID.
commandId Command ID according to VStreamerCommand enum. After decoding COMMAND the method will return command ID.
value Numeral video streamer parameter value. Only for non string parameters. For string parameters (see VStreamerParam enum) this parameters may have any values.
strValue String parameter value (see VStreamerParam enum).

Returns: 0 - in case decoding COMMAND, 1 - in case decoding SET_PARAM command or -1 in case errors.

Data structures

VStreamer.h file defines IDs for parameters (VStreamerParam enum) and IDs for commands (VStreamerCommand enum).

VStreamerCommand enum

Enum declaration:

enum class VStreamerCommand
{
    /// Restart.
    RESTART = 1,
    /// Enable. Equal to MODE param.
    ON,
    /// Disable. Equal to MODE params.
    OFF
};

Table 3 - Video stream commands description.

Command Description
RESTART Restarts streamer with last VStreamerParams.
ON Enables streamer if it is disabled.
OFF Disables streamer if it is enabled.

VStreamerParam enum

Enum declaration:

namespace cr
{
namespace rtsp
{
enum class VStreamerParam
{
    /// Mode: 0 - disabled, 1 - enabled.
    MODE = 1,
    /// Video stream width from 8 to 8192.
    WIDTH,
    /// Video stream height from 8 to 8192.
    HEIGHT,
    /// Streamer IP.
    IP,
    /// Streamer port.
    PORT,
    /// Streamer multicast IP.
    MULTICAST_IP,
    /// Streamer multicast port.
    MULTICAST_PORT,
    /// Streamer user (for rtsp streaming): "" - no user.
    USER,
    /// Streamer password (for rtsp streaming): "" - no password.
    PASSWORD,
    /// Streamer suffix(for rtsp streaming, stream name).
    SUFFIX,
    /// Minimum bitrate for variable bitrate mode, kbps.
    MIN_BITRATE_KBPS,
    /// Maximum bitrate for variable bitrate mode, kbps.
    MAX_BITRATE_KBPS,
    /// Current bitrate, kbps.
    BITRATE_KBPS,
    /// Bitrate mode: 0 - constant bitrate, 1 - variable bitrate.
    BITRATE_MODE,
    /// FPS.
    FPS,
    /// GOP size for H264 and H265 codecs.
    GOP,
    /// H264 profile: 0 - baseline, 1 - main, 2 - high.
    H264_PROFILE,
    /// JPEG quality from 1 to 100% for JPEG codec.
    JPEG_QUALITY,
    /// Codec type: "H264", "HEVC" or "JPEG".
    CODEC,
    /// Scaling mode: 0 - fit, 1 - cut.
    FIT_MODE,
    /// Cycle time, mksec. Calculated by RTSP server.
    CYCLE_TIME_MKSEC,
    /// Overlay mode: false - off, true - on.
    OVERLAY_MODE,
    /// Type of the streamer
    TYPE,
    /// Custom parameter 1.
    CUSTOM1,
    /// Custom parameter 2.
    CUSTOM2,
    /// Custom parameter 3. 
    CUSTOM3
};
}
}

Table 4 - Video streamer params description.

Parameter Description
MODE Enable / disable streamer: 0 - disable, 1 - enabled.
WIDTH Frame width. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter.
HEIGHT Frame height. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter.
IP RTSP server IP.
PORT RTSP server port. If port has been changed the mediamtx process must be stopped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
MULTICAST_IP RTSP server multicast IP. Multicast RTSP streaming is enabled by default in mediamtx. If multicast IP has been changed the mediamtx process must be stopped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
MULTICAST_PORT RTSP server multicast port. Multicast RTSP streaming is enabled by default in mediamtx. If multicast port has been changed the mediamtx process must be stopped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
USER User name for auth. If user name has been changed the mediamtx process must be stopped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
PASSWORD Password for auth. If password has been changed the mediamtx process must be stopped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
SUFFIX Stream name for RTSP server.
MIN_BITRATE_KBPS Not supported by VStreamerMediaMtx library.
MAX_BITRATE_KBPS Not supported by VStreamerMediaMtx library.
BITRATE_KBPS Bitrate for H264 and H265 codecs, kbps.
BITRATE_MODE Not supported by VStreamerMediaMtx library.
FPS Streamer’s FPS and also encoding FPS. Regardless of the input video frame rate, the streamer will provide the specified FPS.
GOP H264 or H265 codec GOP size.
H264_PROFILE H264 encoding profile: 0 - baseline, 1 - main, 2 - high.
JPEG_QUALITY JPEG encoding quality from 1 to 100.
CODEC Codec type: H264, H255 or JPEG.
FIT_MODE Scaling mode: 0 - fit, 1 - crop.
OVERLAY_MODE Overlay enable / disable: 0 - disable, 1 - enable.
CYCLE_TIME_MKSEC Read only Cycle timeout, microseconds.
TYPE Not supported by VStreamerMediaMtx library.
CUSTOM1 Codec type for hardware and software codec selection. See the table 7 for details.
CUSTOM2 Not supported by VStreamerMediaMtx library.
CUSTOM3 Not supported by VStreamerMediaMtx library.

All parameters can be updated in VStreamerMediaMtx via overloaded setParam methods that accept float or string values. However, the behavior of VStreamerMediaMtx depends on the parameter being updated. Some parameters are common across all instances, so updating these parameters will restart all instances. Others are unique to each instance and will only restart the current instance, while some parameters are unique to each instance and can be updated without restarting the instance. The following table shows the groups of parameters based on their update behavior:

Table 5 - Parameter Groups

Update Behavior Parameters
All instances will be restarted automatically RTSP port, username, password, multicast IP, multicast port
Only the current instance will be restarted width, height, fps, GOP, H264 profile, JPEG quality, codec, bitrate, suffix, custom1 (selection of hardware/software codec type)
Update without restart overlay mode, fit mode, mode

If restart of related instance is required, all clients should also reconnect the related stream.

VStreamerParams class description

VStreamerParams class declaration

VStreamerParams class used for video stream initialization (initVStreamer(…) method) or to get all actual params (getParams(…) method). Also VStreamerParams provides structure to write/read params from JSON files (JSON_READABLE macro, see ConfigReader class description) and provide methods to encode and decode params. Class declaration:

namespace cr
{
namespace rtsp
{
class VStreamerParams
{
public:
    /// Streamer mode: false - Off, true - On.
    bool enable{true};
    /// Video stream width from 8 to 8192.
    int width{1280};
    /// Video stream height from 8 to 8192.
    int height{720};
    /// Streamer IP.
    std::string ip{"127.0.0.1"};
    /// Streamer port.
    int port{8554};
    /// Streamer multicast IP.
    std::string multicastIp{"224.1.0.1"};
    /// Streamer multicast port.
    unsigned int multicastPort{18000};
    /// Streamer user (for rtsp streaming): "" - no user.
    std::string user{""};
    /// Streamer password (for rtsp streaming): "" - no password.
    std::string password{""};
    /// Streamer suffix (for rtsp streaming) (stream name).
    std::string suffix{"live"};
    /// Minimum bitrate for variable bitrate mode, kbps.
    int minBitrateKbps{1000};
    /// Maximum bitrate for variable bitrate mode, kbps.
    int maxBitrateKbps{5000};
    /// Current bitrate, kbps.
    int bitrateKbps{3000};
    /// Bitrate mode: 0 - constant bitrate, 1 - variable bitrate.
    int bitrateMode{0};
    /// FPS.
    float fps{30.0f};
    /// GOP size for H264 and H265 codecs.
    int gop{30};
    /// H264 profile: 0 - baseline, 1 - main, 2 - high.
    int h264Profile{0};
    /// JPEG quality from 1 to 100% for JPEG codec.
    int jpegQuality{80};
    /// Codec type: "H264", "HEVC" or "JPEG".
    std::string codec{"H264"};
    /// Scaling mode: 0 - fit, 1 - cut.
    int fitMode{0};
    /// Cycle time, mksec. Calculated by RTSP server.
    int cycleTimeMksec{0};
    /// Overlay mode: false - off, true - on.
    bool overlayMode{true};
    /// type of the streamer
    int type{0};
    /// Custom parameter 1.
    float custom1{0.0f};
    /// Custom parameter 2.
    float custom2{0.0f};
    /// Custom parameter 3.
    float custom3{0.0f};

    JSON_READABLE(VStreamerParams, enable, width, height, ip, port, multicastIp,
                  multicastPort, user, password, suffix, minBitrateKbps,
                  maxBitrateKbps, bitrateKbps, bitrateMode, fps, gop, h264Profile,
                  jpegQuality, codec, fitMode, overlayMode, type, custom1, custom2, custom3)

    /// operator =
    VStreamerParams& operator= (const VStreamerParams& src);

    /// Encode params.
    bool encode(uint8_t* data, int bufferSize, int& size,
                VStreamerParamsMask* mask = nullptr);

    /// Decode params.
    bool decode(uint8_t* data, int dataSize);
};
}
}

Table 6 - Video streamer params description. Some params maybe unsupported by particular video streamer class.

Parameter Description
enable Enable/disable streamer: false - disable, true - enabled.
width Frame width. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter.
height Frame height. Regardless of the resolution of the input video, the streamer will scale the images according to this parameter.
ip RTSP server IP.
port RTSP server port. If port has been changed the mediamtx process must be stepped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
multicastIp RTSP server multicast IP. Multicast RTSP streaming is enabled by default in mediamtx. If multicast IP has been changed the mediamtx process must be stepped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
multicastPort RTSP server multicast port. Multicast RTSP streaming is enabled by default in mediamtx. If multicast port has been changed the mediamtx process must be stepped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
user User name for auth. If user name has been changed the mediamtx process must be stepped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
password Password for auth. If password has been changed the mediamtx process must be stepped, mediamtx.yml changed and mediamtx restarted. If mediamtx path is set, library will handle this internally.
suffix Stream name for RTSP server.
minBitrateKbps Not supported by VStreamerMediaMtx library.
maxBitrateKbps Not supported by VStreamerMediaMtx library.
bitrateKbps Bitrate for H264 and H265 codecs, kbps.
bitrateMode Not supported by VStreamerMediaMtx library.
fps Streamer’s FPS and also encoding FPS. Regardless of the input video frame rate, the streamer will provide the specified FPS.
gop H264 or H265 codec GOP size.
h264Profile H264 encoding profile: 0 - baseline, 1 - main, 2 - high.
jpegQuality JPEG encoding quality from 1 to 100.
codec Codec type for encoding RAW frames: H264 or HEVC.
fitMode Scaling mode: 0 - fit, 1 - crop. in case RAW input video frames.
overlayMode Overlay enable / disable: false - disable, true - enable.
cycleTimeMksec Read only Cycle timeout, microseconds.
type Not supported by VStreamerMediaMtx library.
custom1 Codec type for hardware and software codec selection. See the table 7 for details.
custom2 Not supported by VStreamerMediaMtx library.
custom3 Not supported by VStreamerMediaMtx library.

Table 7 - Codec type selection.

CUSTOM1 H264 H265 JPEG
0 x264enc (software) x265enc (software) jpegenc (software)
1 vaapih264enc (hardware intel) vaapih265enc (hardware intel) jpegenc (software)
2 nvv4l2h264enc (hardware Jetson) nvv4l2h265enc (hardware Jetson) nvjpegenc (hardware Jetson)

Serialize video streamer params

VStreamerParams class provides method encode(…) to serialize video streamer params (fields of VStreamerParams class). Serialization of video streamer params necessary in case when you need to send video streamer params via communication channels. Method provides options to exclude particular parameters from serialization. To do this method inserts binary mask (4 bytes) where each bit represents particular parameter and decode(…) method recognizes it. Method declaration:

bool encode(uint8_t* data, int bufferSize, int& size, VStreamerParamsMask* mask = nullptr);
Parameter Value
data Pointer to data buffer.
size Size of encoded data.
bufferSize Data buffer size. If buffer size smaller than required, buffer will be filled with fewer parameters.
mask Parameters mask - pointer to VStreamerParamsMask structure. VStreamerParamsMask (declared in VStreamer.h file) determines flags for each field (parameter) declared in VStreamerParams class. If the user wants to exclude any parameters from serialization, he can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, he should set the corresponding flag in the VStreamerParams structure.

VStreamerParamsMask structure declaration:

struct VStreamerParamsMask
{
    bool enable{true};
    bool width{true};
    bool height{true};
    bool ip{true};
    bool port{true};
    bool multicastIp{true};
    bool multicastPort{true};
    bool user{true};
    bool password{true};
    bool suffix{true};
    bool minBitrateKbps{true};
    bool maxBitrateKbps{true};
    bool bitrateKbps{true};
    bool bitrateMode{true};
    bool fps{true};
    bool gop{true};
    bool h264Profile{true};
    bool jpegQuality{true};
    bool codec{true};
    bool fitMode{true};
    bool cycleTimeMksec{true};
    bool overlayMode{true};
    bool type{true};
    bool custom1{true};
    bool custom2{true};
    bool custom3{true};
};

Example without parameters mask:

// Prepare random params.
VStreamerParams in;
in.ip = "alsfghljb";
in.port = 0;

// Encode data.
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size);
cout << "Encoded data size: " << size << " bytes" << endl;

Example without parameters mask:

// Prepare random params.
VStreamerParams in;
in.ip = "alsfghljb";
in.port = 0;

// Prepare params mask.
VStreamerParamsMask mask;
mask.port = false; // Exclude port. Others by default.

// Encode data.
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size, &mask);
cout << "Encoded data size: " << size << " bytes" << endl;

Deserialize video stream params

VStreamerParams class provides method decode(…) to deserialize video streamer params (fields of VStreamerParams class). Deserialization of video streamer params necessary in case when you need to receive video streamer params via communication channels. Method automatically recognizes which parameters were serialized by encode(…) method. Method declaration:

bool decode(uint8_t* data, int dataSize);
Parameter Value
data Pointer to encode data buffer.
dataSize Size of data.

Returns: TRUE if data decoded (deserialized) or FALSE if not.

Example:

// Encode data.
VStreamerParams in;
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size);

cout << "Encoded data size: " << size << " bytes" << endl;

// Decode data.
VStreamerParams out;
if (!out.decode(data, size))
    cout << "Can't decode data" << endl;

Read params from JSON file and write to JSON file

VStreamer library depends on ConfigReader library which provides method to read params from JSON file and to write params to JSON file. Example of writing and reading params to JSON file:

// Write params to file.
VStreamerParams in;
cr::utils::ConfigReader inConfig;
inConfig.set(in, "vStreamerParams");
inConfig.writeToFile("TestVStreamerParams.json");

// Read params from file.
cr::utils::ConfigReader outConfig;
if(!outConfig.readFromFile("TestVStreamerParams.json"))
{
    cout << "Can't open config file" << endl;
    return false;
}

TestVStreamerParams.json will look like:

{
    "vStreamerParams": {
        "bitrateKbps": 207,
        "bitrateMode": 206,
        "codec": "eydiucnksa",
        "custom1": 249.0,
        "custom2": 150.0,
        "custom3": 252.0,
        "enable": false,
        "fitMode": 39,
        "fps": 35.0,
        "gop": 1,
        "h264Profile": 61,
        "height": 61,
        "ip": "afhjaskdm",
        "jpegQuality": 80,
        "maxBitrateKbps": 89,
        "minBitrateKbps": 180,
        "multicastIp": "afhjaskdmasd",
        "multicastPort": 180,
        "overlayMode": true,
        "password": "adafsodjf",
        "port": 226,
        "suffix": "asdasdasd",
        "type": 167,
        "user": "afhidsjfnm",
        "width": 50
    }
}

Simple example

The application bellow shows VStreamerMediaMtx usage. The application create VStreamerMediaMtx object and initialize it. After the application generates artificial video frames and feeds VStreamerMediaMtx video streamer.

#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>
#include "VStreamerMediaMtx.h"

int main(int argc, char **argv)
{
    std::cout << "------------------------------------------" << std::endl;
    std::cout << "VStreamerMediaMtx v" << cr::video::VStreamerMediaMtx::getVersion() << " example" << std::endl;
    std::cout << "------------------------------------------" << std::endl;


    // Set suffix (stream name).
    std::string suffix = "live";
    std::cout << "Set suffix: ";
    std::cin >> suffix;

    // Set RTSP server port.
    int port = 8554;
    std::cout << "Set RTSP server port: ";
    std::cin >> port;

    // Set mediamtx path
    cr::video::VStreamerMediaMtx::setMediaMtxPath("/home/ahmet/Projects/");

    // Init video streamer params.
    cr::video::VStreamerParams params;
    params.enable = true;
    params.width = 640;
    params.height = 480;
    params.fps = 30.0f;
    params.bitrateKbps = 7000;
    params.gop = 30;
    params.port = port;
    params.codec = "H264";
    params.h264Profile = 1;
    params.jpegQuality = 58;
    params.custom1 = 0.0f;  // 0 - Software, 1 - Intel hardware, 2 - Jetson hardware


    cr::video::VStreamerMediaMtx streamer;
    if (!streamer.initVStreamer(params))
    {
        std::cout << "Video streamer init failed" << std::endl;
        return -1;
    }

    // Create frame.
    cr::video::Frame frame =
    cr::video::Frame(params.width, params.height, cr::video::Fourcc::YUV24);

    // Moving object parameters.
    int objectX = 200;
    int objectY = 200;
    int objectVx = 1;
    int objectVy = 1;
    int border = 100;
    int objectSize = 50;
    uint8_t color = 0;

    // Main loop.
    while (true)
    {

        // Move object.
        objectX += objectVx;
        objectY += objectVy;
        if (objectX < border || objectX > params.width - border - objectSize)
            objectVx = -objectVx;
        if (objectY < border || objectY > params.height - border - objectSize)
            objectVy = -objectVy;
    
        // Draw object.
        memset(frame.data, color++, frame.size);
        cv::Mat image(params.height, params.width, CV_8UC3, frame.data);
        cv::rectangle(image, cv::Rect(objectX, objectY, objectSize, objectSize),
                      cv::Scalar(0, 0, 255), -1);        

        // Add frame to streamer.
        if (!streamer.sendFrame(frame))
        {
            std::cout << "Send frame failed" << std::endl;
            break;
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(30));
    }

    return 0;
}

Test application

VStreamerMediamtx/test folder contains test application which demonstrates VStreamerMediaMtx library usage with multiple instances. The application creates two VStreamerMediaMtx objects and initializes them. The application generates artificial video frames and feeds VStreamerMediaMtx video streamers. Also application allows user to change parameters of streamers from terminal. Output of the application will be like:

------------------------------------------
VStreamerMediaMtx v1.1.2 test
------------------------------------------
Set number of instances: 2
Set path to MediaMTX: /home/pi
Set RTSP port: 7031
Stream 0: rtsp://127.0.0.1:7031/live0
Stream 1: rtsp://127.0.0.1:7031/live1
----------------------------------
Enter stream number (0-1): 0

after entering streamer number user will choose the operation:

-1 - Exit
0 - Set RTSP port
1 - Set resolution
2 - Set suffix
3 - Set bitrate
4 - Set user name and password
5 - Set fit mode
Choose option:

User can change parameters of streamers

Enter RTSP port: 7031

Build and connect to your project

The VStreamerMediaMtx library supports only Linux. Before compiling user must install GStreamer and OpenCV libraries. The library is working together with mediamtx which is external process (user must run it in advance before using VStreamerMediaMtx library). Commands to install necessary libraries in Linux (Ubuntu or Debian example):

sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
sudo apt install gstreamer1.0-rtsp
sudo apt-get install gstreamer1.0-vaapi
sudo apt-get install libopencv-dev

Typical commands to build VStreamerMediaMtx library:

cd VStreamerMediaMtx
mkdir build
cd build
cmake ..
make

If you want connect VStreamerMediaMtx library to your CMake project as source code you can make follow. For example, if your repository has structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create 3rdparty folder in your repository VStreamerMediaMtx repository folder there. New structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    VStreamerMediaMtx

Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:

cmake_minimum_required(VERSION 3.13)

################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)

################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)

################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_VSTREAMER_MEDIAMTX              ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VSTREAMER_MEDIAMTX)
    SET(${PARENT}_VSTREAMER_MEDIAMTX                    ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_VSTREAMER_MEDIAMTX_EXAMPLE            OFF CACHE BOOL "" FORCE)
endif()

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_VSTREAMER_MEDIAMTX)
    add_subdirectory(VStreamerMediaMtx)
endif()

File 3rdparty/CMakeLists.txt adds folder VStreamerMediaMtx to your project and excludes test application and examples from compiling (by default test application and examples excluded from compiling if VStreamerMediaMtx included as sub-repository). Your repository new structure will be:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    VStreamerMediaMtx

Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next you have to include VStreamerMediaMtx library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} VStreamerMediaMtx)

Done!

Run mediamtx

If mediamtx path is not set to library, user must handle modification of config file and restart of mediamtx manually. To use VStreamerMediaMtx library user must run mediamtx application. To run mediamtx from C++ code the ChildProcess library can be used. The mediamtx application uses mediamtx.yml config file. Parameters: RTSP port, multicast port, multicast IP, user name and password are using for all camera streams. If user’s application includes few VStreamerMediaMtx class instances this parameters must be changes for all instances. If user changes multicast port, multicast IP, user name or password the mediamtx processes mst be stopper, mediamtx.yml config file changed and mediamtx process launched again. C++ code example to change mediamtx.yml config file:

void modifyMediaMtxConfig(VStreamerParams& params)
{
    // Read MediaMtx config file.
    ifstream inputFile("/home/pi/mediamtx.yml");
    if (!inputFile.is_open())
    {
        g_logger.print(PrintColor::RED, PrintFlag::CONSOLE_AND_FILE) <<
        "[" << __LOGFILENAME__ << "][" << __LINE__ << "] ERROR: " <<
        "Can't read /home/pi/mediamtx.yml" << endl;
        return;
    }

    // Read file line by line.
    string line;
    string fileContent;
    bool userFound = false;
    bool passwordFound = false;
    while (getline(inputFile, line))
    {
        if (line.find("rtspAddress: :") != string::npos)
            line = "rtspAddress: :" + to_string(params.port);
        if (line.find("multicastIPRange:") != string::npos)
            line = "multicastIPRange: " + params.multicastIp + "/16";
        if (line.find("multicastRTPPort:") != string::npos)
            line = "multicastRTPPort: " + to_string(params.multicastPort);
        if (line.find("multicastRTCPPort:") != string::npos)
            line = "multicastRTCPPort: " + to_string(params.multicastPort + 1);
        if (line.find("- user:") != string::npos && !userFound)
        {
            if (params.user != "" && params.password != "")
                line = "- user: " + params.user;
            else
                line = "- user: any";
            userFound = true;
        }
        if (line.find("pass:") != string::npos && !passwordFound)
        {
            if (params.user != "" && params.password != "")
                line = "  pass: " + params.password;
            else
                line = "  pass: ";
            passwordFound = true;
        }
        fileContent += line + "\n";
    }
    inputFile.close();

    // Write new content to file.
    ofstream outputFile("/home/pi/mediamtx.yml");
    if (!outputFile.is_open())
    {
        g_logger.print(PrintColor::RED, PrintFlag::CONSOLE_AND_FILE) <<
        "[" << __LOGFILENAME__ << "][" << __LINE__ << "] ERROR: " <<
        "Can't open /home/pi/mediamtx.yml" << endl;
        return;
    }
    outputFile << fileContent;
    outputFile.close();
}

mediamtx application can be obtained from mediamtx releases. Follow instructins from mediamtx.


Table of contents