Examples

Complete code examples for MediaX video streaming.

Uncompressed Video

Simple Transmitter

#include <iostream>
#include <vector>
#include <cstring>
#include "rtp/rtp.h"
#include "uncompressed/rtp_uncompressed_payloader.h"
#include "sap/sap_announcer.h"

int main() {
    // Configure stream
    mediax::rtp::StreamInformation stream_info;
    stream_info.session_name = "test-pattern";
    stream_info.hostname = "239.192.1.1";
    stream_info.port = 5004;
    stream_info.width = 640;
    stream_info.height = 480;
    stream_info.framerate = 30;
    stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceRgb24;

    // Start SAP announcer
    mediax::sap::SapAnnouncer announcer;
    announcer.AddSapAnnouncement(stream_info);
    announcer.Start();

    // Create payloader
    mediax::rtp::uncompressed::RtpUncompressedPayloader payloader;
    payloader.SetStreamInfo(stream_info);

    if (!payloader.Open()) {
        std::cerr << "Failed to open payloader" << std::endl;
        return 1;
    }

    // Generate and transmit color bars
    std::vector<uint8_t> buffer(640 * 480 * 3);

    for (int frame = 0; frame < 300; ++frame) {
        // Create color bars
        for (int y = 0; y < 480; ++y) {
            for (int x = 0; x < 640; ++x) {
                int idx = (y * 640 + x) * 3;
                int bar = x / 80;  // 8 bars

                switch (bar % 8) {
                    case 0: buffer[idx] = 255; buffer[idx+1] = 255; buffer[idx+2] = 255; break; // White
                    case 1: buffer[idx] = 255; buffer[idx+1] = 255; buffer[idx+2] = 0; break;   // Yellow
                    case 2: buffer[idx] = 0; buffer[idx+1] = 255; buffer[idx+2] = 255; break;   // Cyan
                    case 3: buffer[idx] = 0; buffer[idx+1] = 255; buffer[idx+2] = 0; break;     // Green
                    case 4: buffer[idx] = 255; buffer[idx+1] = 0; buffer[idx+2] = 255; break;   // Magenta
                    case 5: buffer[idx] = 255; buffer[idx+1] = 0; buffer[idx+2] = 0; break;     // Red
                    case 6: buffer[idx] = 0; buffer[idx+1] = 0; buffer[idx+2] = 255; break;     // Blue
                    case 7: buffer[idx] = 0; buffer[idx+1] = 0; buffer[idx+2] = 0; break;       // Black
                }
            }
        }

        payloader.Transmit(buffer.data(), true);
        std::cout << "Sent frame " << frame << std::endl;
    }

    // Cleanup
    payloader.Close();
    announcer.Stop();
    announcer.DeleteAllSapAnnouncements();

    return 0;
}

Simple Receiver

#include <iostream>
#include <vector>
#include "rtp/rtp.h"
#include "uncompressed/rtp_uncompressed_depayloader.h"
#include "sap/sap_listener.h"

int main() {
    // Discover streams via SAP
    mediax::sap::SapListener listener;
    listener.Start();

    std::cout << "Listening for streams..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(3));

    auto& streams = listener.GetSapAnnouncements();

    if (streams.empty()) {
        std::cerr << "No streams found" << std::endl;
        listener.Stop();
        return 1;
    }

    // Use first discovered stream
    auto stream_info = streams.begin()->second;
    std::cout << "Connecting to: " << stream_info.session_name << std::endl;

    listener.Stop();

    // Create depayloader
    mediax::rtp::uncompressed::RtpUncompressedDepayloader depayloader;
    depayloader.SetStreamInfo(stream_info);

    if (!depayloader.Open()) {
        std::cerr << "Failed to open depayloader" << std::endl;
        return 1;
    }

    depayloader.Start();

    // Receive frames
    size_t buffer_size = stream_info.width * stream_info.height * 3;
    std::vector<uint8_t> buffer(buffer_size);

    for (int i = 0; i < 100; ++i) {
        if (depayloader.Receive(buffer.data(), 1000)) {
            std::cout << "Received frame " << i << std::endl;
        } else {
            std::cout << "Timeout waiting for frame" << std::endl;
        }
    }

    // Cleanup
    depayloader.Stop();
    depayloader.Close();

    return 0;
}

H.264 Compressed Video

H.264 Transmitter

#include <iostream>
#include <vector>
#include "rtp/rtp.h"
#include "h264/gst/vaapi/rtp_h264_payloader.h"
#include "sap/sap_announcer.h"

int main() {
    mediax::rtp::StreamInformation stream_info;
    stream_info.session_name = "h264-test";
    stream_info.hostname = "239.192.1.1";
    stream_info.port = 5004;
    stream_info.width = 1920;
    stream_info.height = 1080;
    stream_info.framerate = 30;
    stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceH264Part10;

    mediax::sap::SapAnnouncer announcer;
    announcer.AddSapAnnouncement(stream_info);
    announcer.Start();

    mediax::rtp::h264::gst::vaapi::RtpH264GstVaapiPayloader payloader;
    payloader.SetStreamInfo(stream_info);
    payloader.Open();

    // Send RGB frames - hardware encoder compresses to H.264
    std::vector<uint8_t> buffer(1920 * 1080 * 3);

    for (int frame = 0; frame < 300; ++frame) {
        // Fill with gradient
        for (int y = 0; y < 1080; ++y) {
            for (int x = 0; x < 1920; ++x) {
                int idx = (y * 1920 + x) * 3;
                buffer[idx] = (x + frame) % 256;     // R
                buffer[idx+1] = (y + frame) % 256;   // G
                buffer[idx+2] = (frame) % 256;       // B
            }
        }

        payloader.Transmit(buffer.data(), true);
    }

    payloader.Close();
    announcer.Stop();
    announcer.DeleteAllSapAnnouncements();

    return 0;
}

H.264 Receiver

#include <iostream>
#include <vector>
#include "rtp/rtp.h"
#include "h264/gst/vaapi/rtp_h264_depayloader.h"

int main() {
    mediax::rtp::StreamInformation stream_info;
    stream_info.hostname = "239.192.1.1";
    stream_info.port = 5004;
    stream_info.width = 1920;
    stream_info.height = 1080;
    stream_info.encoding = mediax::rtp::ColourspaceType::kColourspaceH264Part10;

    mediax::rtp::h264::gst::vaapi::RtpH264GstVaapiDepayloader depayloader;
    depayloader.SetStreamInfo(stream_info);
    depayloader.Open();
    depayloader.Start();

    // Receive decoded RGB frames
    std::vector<uint8_t> buffer(1920 * 1080 * 3);

    for (int i = 0; i < 100; ++i) {
        if (depayloader.Receive(buffer.data(), 1000)) {
            std::cout << "Received decoded frame " << i << std::endl;
        }
    }

    depayloader.Stop();
    depayloader.Close();

    return 0;
}

Python Examples

Transmitter with NumPy

#!/usr/bin/env python3
import sys
sys.path.append('/usr/local/lib/python3/dist-packages')
import mediax
import numpy as np
import time

# Configure stream
stream_info = mediax.rtp.StreamInformation()
stream_info.session_name = "numpy-stream"
stream_info.hostname = "239.192.1.1"
stream_info.port = 5004
stream_info.width = 640
stream_info.height = 480
stream_info.framerate = 30
stream_info.encoding = mediax.rtp.ColourspaceType_kColourspaceRgb24

# Start announcer
announcer = mediax.sap.SapAnnouncer()
announcer.AddSapAnnouncement(stream_info)
announcer.Start()

# Create payloader
payloader = mediax.rtp_uncompressed_payloader.RtpUncompressedPayloader()
payloader.SetStreamInfo(stream_info)
payloader.Open()

# Transmit moving gradient
for frame in range(300):
    # Create gradient pattern
    y_coords = np.arange(480).reshape(-1, 1)
    x_coords = np.arange(640).reshape(1, -1)

    r = ((x_coords + frame * 2) % 256).astype(np.uint8)
    g = ((y_coords + frame) % 256).astype(np.uint8)
    b = np.full((480, 640), frame % 256, dtype=np.uint8)

    rgb = np.stack([r * np.ones((480, 1), dtype=np.uint8),
                    g * np.ones((1, 640), dtype=np.uint8),
                    b], axis=-1).astype(np.uint8)

    payloader.Transmit(rgb.tobytes(), True)
    time.sleep(1/30)

# Cleanup
payloader.Close()
announcer.Stop()
announcer.DeleteAllSapAnnouncements()

Stream Discovery

#!/usr/bin/env python3
import sys
sys.path.append('/usr/local/lib/python3/dist-packages')
import mediax
import time

print("Discovering streams...")

listener = mediax.sap.SapListener()
listener.Start()

time.sleep(3)

streams = listener.GetSapAnnouncements()

if not streams:
    print("No streams found")
else:
    print(f"Found {len(streams)} stream(s):")
    for name, info in streams.items():
        print(f"\n  {name}")
        print(f"    Address: {info.hostname}:{info.port}")
        print(f"    Resolution: {info.width}x{info.height}")
        print(f"    Framerate: {info.framerate} fps")

listener.Stop()

OpenCV Integration

#!/usr/bin/env python3
import sys
sys.path.append('/usr/local/lib/python3/dist-packages')
import mediax
import numpy as np
import cv2

# Configure stream
stream_info = mediax.rtp.StreamInformation()
stream_info.hostname = "239.192.1.1"
stream_info.port = 5004
stream_info.width = 640
stream_info.height = 480
stream_info.encoding = mediax.rtp.ColourspaceType_kColourspaceRgb24

# Create depayloader
depayloader = mediax.rtp_uncompressed_depayloader.RtpUncompressedDepayloader()
depayloader.SetStreamInfo(stream_info)
depayloader.Open()
depayloader.Start()

buffer = bytearray(640 * 480 * 3)

while True:
    if depayloader.Receive(buffer, 100):
        # Convert to numpy and BGR for OpenCV
        frame = np.frombuffer(buffer, dtype=np.uint8).reshape((480, 640, 3))
        bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

        cv2.imshow('MediaX Stream', bgr)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

depayloader.Stop()
depayloader.Close()
cv2.destroyAllWindows()

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(mediax_examples)

find_package(mediax REQUIRED)

# Uncompressed examples
add_executable(transmitter transmitter.cpp)
target_link_libraries(transmitter PRIVATE mediax::mediax)

add_executable(receiver receiver.cpp)
target_link_libraries(receiver PRIVATE mediax::mediax)

# H.264 examples (requires GStreamer)
add_executable(h264_transmitter h264_transmitter.cpp)
target_link_libraries(h264_transmitter PRIVATE mediax::mediax)

add_executable(h264_receiver h264_receiver.cpp)
target_link_libraries(h264_receiver PRIVATE mediax::mediax)

Building Examples

mkdir build && cd build
cmake ..
make

# Run transmitter in one terminal
./transmitter

# Run receiver in another terminal
./receiver

Support