4. Examples

Minimal C++ publisher

The snippet below sends a single grayscale frame using RtmsSender. It binds to 0.0.0.0 (any local address) and multicasts to 239.0.0.1:5500 with timestamp-only extended info. Error handling is omitted for brevity.

#include <ifw/rtmslib_llnetio/rtmsSender.hpp>
#include <vector>

using namespace ifw::rtmslib;

int main() {
    const std::string src_ip = "0.0.0.0";      // bind locally
    const std::string dest_ip = "239.0.0.1";   // multicast or unicast
    const int dest_port = 5500;
    const int8_t bytes_per_pixel = 2;           // uint16 payload

    // Example 64x64 image
    const std::size_t width = 64;
    const std::size_t height = 64;
    const std::size_t raw_size = width * height * bytes_per_pixel;
    std::vector<uint8_t> payload(raw_size, 0xff);

    SenderConfig cfg;
    cfg.topic_id = 10;
    cfg.ext_info_mode = ExtendedInfoMode::TimestampOnly;

    RtmsSender sender(src_ip, dest_ip, dest_port, bytes_per_pixel, raw_size, cfg);

    // Timestamp-only extended info
    SampleExtInfo ext_info;
    ext_info.SetTimestamp(1699999999.0);

    return sender.SendSample(ext_info, payload);
}

Minimal C++ subscriber

Derive from RtmsReceiver and implement HandleSampleUser() to process each sample. The example below logs the sample id and copies statistics while honouring the extended info contract.

#include <ifw/rtmslib_llnetio/rtmsReceiver.hpp>
#include <iostream>

using namespace ifw::rtmslib;
using ifw::fnd::datatype::DataType;

class LoggingReceiver : public RtmsReceiver {
public:
    using RtmsReceiver::RtmsReceiver;

    void HandleSampleUser(SampleExtInfo& ext, std::vector<uint8_t>& payload) override {
        std::cout << "Received sample " << GetSampleId()
                  << " with " << payload.size() << " bytes" << std::endl;
        if (ext.GetExtInfoSize() > 0) {
            std::cout << "  timestamp: " << ext.GetTimestamp()
                      << " width: " << ext.GetWidth()
                      << " height: " << ext.GetHeight() << std::endl;
        }
    }
};

int main() {
    ReceiverConfig cfg;
    cfg.topic_id = 10;
    cfg.ext_info_mode = ExtendedInfoMode::TimestampOnly;

    LoggingReceiver receiver("239.0.0.1", "eth0", 5500, DataType::UINT16, cfg);

    // Block until one sample arrives or a timeout occurs.
    SampleExtInfo ext;
    std::vector<uint8_t> payload;
    receiver.ReceiveSample(ext, payload, std::chrono::seconds(5));
    receiver.StopReceiver();
}

Tips for integration

  • Keep sender and receiver ext_info_mode aligned; a mismatch will be detected and logged, and samples may be discarded.

  • packet_send_delay in SenderConfig can help avoid receiver overloads when using small MTUs or high frame rates.

  • ignore_connection_refused lets publishers start before any subscribers are listening; logs are throttled to avoid flooding.

  • Leverage SampleExtInfo to propagate geometry and datatype so subscribers can adapt to image size changes without restarts.