rtp_pusher_web_logo

RtpPusher C++ library

v1.1.0

Table of contents

Overview

RtpPusher is a C++ library that provides H264 RTP packet sending to network. The library internally handles extracting NAL units and fragmenting them to UDP packets. The library depends on: Frame library (provides declaration of video frame object, source code included, Apache 2.0 license) and UdpSocket library (provides methods to works with UDP sockets). Also, example application depends on VSourceFile library to read H264 frames from the file (source code included). The library controls time interval between RTP packets to prevent network overload (the network bandwidth set by user). The library doesn’t have third-party dependencies to be installed in OS.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 15.07.2024 - First version.
1.1.0 12.12.2024 - Fix bugs for Windows OS.
- Update code structure.
- Update example.

Library files

The library supplied by source code only. The user would be 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 to include third-party libraries.
    Frame ------------------ Folder with Frame library source code.
    UdpSocket -------------- Folder with UdpSocket library source code.
src ------------------------ Folder with library source code.
    CMakeLists.txt --------- CMake file of the library.
    RtpPusher.h ------------ Main library header file.
    RtpPusher.cpp ---------- C++ implementation file.
    RtpPusherVersion.h ----- Header file with library version.
    RtpPusherVersion.h.in -- CMake service file to generate version header.
example -------------------- Folder with test application files.
    CMakeLists.txt --------- CMake file for example application.
    main.cpp --------------- Source C++ file of example application.
    3rdparty --------------- Folder with third-party libraries.
        CMakeLists.txt ----- CMake file to include third-party libraries.
        VSourceFile -------- Folder with VSourceFile library source code.

RtpPusher class description

RtpPusher class declaration

RtpPusher.h file contains RtpPusher class declaration:

namespace cr
{
namespace rtp
{
/// RTP pusher class.
class RtpPusher
{
public:

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

    /// Class constructor.
    RtpPusher();

    /// Class destructor.
    ~RtpPusher();

    /// Init video streamer by set of parameters.
    bool init(std::string ip,
              uint16_t port,
              int bandwidthKbps = 1000000,
              int maxPayloadSize = 1420);

    /// Get init status.
    bool isInit();

    /// Close video streamer.
    void close();

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

getVersion method

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

static std::string getVersion();

Method can be used without RtpPusher class instance. Example:

std::cout << "RtpPusher version: " << RtpPusher::getVersion() << std::endl;

Console output:

RtpPusher version: 1.1.0

init method

The init(…) method initializes RTP pusher. The method sets IP address, port of the destination, channel bandwidth (optionally) in Kbps and max RTP packet payload size (optionally). After initialization the library runs internal thread which is responsible for video streaming. Method declaration:

bool init(std::string ip, uint16_t port, int bandwidthKbps = 1000000, int maxPayloadSize = 1420);
Parameter Value
ip Destination ip.
port Destination UDP port.
bandwidthKbps Bandwidth of network in Kbps. Default value is 1000000 Kbps (1 Gbps). This parameters is used to calculate time gap between RTP packets.
maxPayloadSize Maximum RTP payload size, bytes. By default 1420. This parameter is used to adjust RTP packet size for different networks (make it lower to prevent filtering by routers).

Returns: TRUE if the RTP pusher initialized or FALSE if not.

isInit method

The isInit() method returns RTP pusher initialization status. Method declaration:

bool isInit();

Returns: TRUE if the RTP pusher initialized or FALSE if not.

close method

The close() method closes RTP pusher. The library will stop internal streaming thread. Method declaration:

void close();

sendFrame method

The sendFrame(…) method sends video frame. The method sends H264 frame to the destination IP and port by RTP packet.. The method is nonblocking which means that the method returns immediately after the frame is sent and internal thread handles the frame sending. The library copies frame data to the internal buffer and returns control. Method declaration:

bool sendFrame(cr::video::Frame &frame);
Parameter Description
frame Frame object with H264 data (H264 fourcc).

Returns: TRUE if the frame was sent or FALSE if not.

Build and connect to your project

Typical commands to build RtpPusher library:

cd RtpPusher
mkdir build
cd build
cmake ..
make

If you want to connect RtpPusher library to your CMake project as source code, you can do the following. For example, if your repository has structure:

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

Create folder 3rdparty and copy folder of RtpPusher repository there. New structure of your repository:

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

Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should be containing:

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_RTP_PUSHER                      ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_RTP_PUSHER)
    SET(${PARENT}_RTP_PUSHER                            ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_RTP_PUSHER_EXAMPLE                    OFF CACHE BOOL "" FORCE)
endif()

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

File 3rdparty/CMakeLists.txt adds folder RtpPusher to your project and excludes example from compiling (by default example excluded from compiling if RtpPusher included as sub-repository). The new structure of your repository will be:

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

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

add_subdirectory(3rdparty)

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

target_link_libraries(${PROJECT_NAME} RtpPusher)

Done!

Example

A simple application shows how to use the RtpPusher library. The example included VSourceFile library to read H264 files.

#include <iostream>
#include "VSourceFile.h"
#include "RtpPusher.h"

int main()
{
    // Init video source.
    cr::video::VSourceFile source;
    std::string initString = "test.h264";
    if (!source.openVSource(initString))
        return -1;
    
    std::cout << "Enter IP address: ";
    std::string ip = "127.0.0.1";
    std::cin >> ip;

    std::cout << "Enter port number: ";
    int port = 7032;
    std::cin >> port;

    // Init streamer.
    cr::rtp::RtpPusher rtpPusher;
    if (!rtpPusher.init(ip, port))
        return -1;

    // Main loop.
    cr::video::Frame sourceFrame;
    while (true)
    {
        // Get H264 frame from video source. We wait new frame for 1 sec.
        if (!source.getFrame(sourceFrame, 1000))
            continue;

        // Send frame.
        if (!rtpPusher.sendFrame(sourceFrame))
            continue;

        std::cout << "Frame : " << sourceFrame.frameId << std::endl;

        // Wait to simulate realistic scenario (30 FPS).
        std::this_thread::sleep_for(std::chrono::milliseconds(33));
    }
    return 1;
}

How to play RTP stream

To play RTP stream with ffmpeg or VLC user has to create SDP file (example of test.h264 which is located in static folder):

v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
a=tool:libavformat 58.29.100
m=video 7032 RTP/AVP 96
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0KAH5WoFAFum4CAgIE=,aM4wpIA=; profile-level-id=42C01E
a=control:streamid=0

Play stream with ffplay:

ffplay -protocol_whitelist file,udp,rtp -i test.sdp

To play RTP stream in VLC open test.sdp in VLC.