Streaming to gstreamer from home made app

I copied the following code from ChatGPT which packs H265 frames in RTP packets and sends them to a receiver computer that is supposed to decode them with any app, but when i run gstreamer on the receiving desktop, it gives an “invalid RTP payload” message and does not open the video

if i stream from gstreamer it works fine

any ideas on why this happens?

#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <chrono>
#include <thread>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

// RTP header structure
struct RTPHeader {
    uint8_t version;
    uint8_t padding;
    uint8_t extension;
    uint8_t csrcCount;
    uint8_t marker;
    uint8_t payloadType;
    uint16_t sequenceNumber;
    uint32_t timestamp;
    uint32_t ssrc;
};

// Function to send RTP packets
void sendRtpPackets(const vector<uint8_t>& encodedData, int socket, const sockaddr_in& destAddress, uint16_t destPort) {
    constexpr size_t RTP_HEADER_SIZE = 12;
    constexpr size_t MAX_PAYLOAD_SIZE = 1400;
    
    size_t dataSize = encodedData.size();
    size_t numPackets = (dataSize + MAX_PAYLOAD_SIZE - 1) / MAX_PAYLOAD_SIZE;

    RTPHeader rtpHeader;
    memset(&rtpHeader, 0, sizeof(RTPHeader));
    rtpHeader.version = 2;
    rtpHeader.sequenceNumber = htons(0);
    rtpHeader.ssrc = htonl(12345);  // Set your own SSRC value

    for (size_t i = 0; i < numPackets; ++i) {
        size_t payloadSize = min(MAX_PAYLOAD_SIZE, dataSize - i * MAX_PAYLOAD_SIZE);
        size_t packetSize = RTP_HEADER_SIZE + payloadSize;
        vector<uint8_t> rtpPacket(packetSize);

        rtpHeader.sequenceNumber = htons(i);

        memcpy(&rtpPacket[0], &rtpHeader, sizeof(RTPHeader));
        memcpy(&rtpPacket[RTP_HEADER_SIZE], &encodedData[i * MAX_PAYLOAD_SIZE], payloadSize);

        ssize_t bytesSent = sendto(socket, rtpPacket.data(), packetSize, 0,
                                   (struct sockaddr*)&destAddress, sizeof(destAddress));

        if (bytesSent < 0) {
            cerr << "Failed to send RTP packet." << endl;
            return;
        }

        // Delay between packets to control the sending rate
        this_thread::sleep_for(chrono::milliseconds(10));
    }
}

int main() {
    // Load encoded H.265 data from file
    ifstream file("encoded_data.h265", ios::binary | ios::ate);
    if (!file) {
        cerr << "Failed to open encoded data file." << endl;
        return 1;
    }

    streamsize fileSize = file.tellg();
    file.seekg(0, ios::beg);

    vector<uint8_t> encodedData(fileSize);
    if (!file.read(reinterpret_cast<char*>(encodedData.data()), fileSize)) {
        cerr << "Failed to read encoded data from file." << endl;
        return 1;
    }

    // Initialize UDP socket
    int socketDescriptor = socket(AF_INET, SOCK_DGRAM, 0);
    if (socketDescriptor < 0) {
        cerr << "Failed to create UDP socket." << endl;
        return 1;
    }

    // Set destination address and port
    sockaddr_in destAddress{};
    destAddress.sin_family = AF_INET;
    destAddress.sin_port = htons(12345);  // Set destination port
    if (inet_aton("192.168.0.100", &destAddress.sin_addr) == 0) {
        cerr << "Invalid destination address." << endl;
        return 1;
    }

    // Send RTP packets
    sendRtpPackets(encodedData, socketDescriptor, destAddress, 12345);

    // Close the socket
    close(socketDescriptor);

    return 0;
}

Hi,
This would need other users to check and share experience.

For running RTSP through gstreamer, you can refer to Jetson Nano FAQ

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.