- clang format + naming improved
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#if defined(TARGET_WIN)
|
||||
# include <WinSock2.h>
|
||||
# include <Windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) || defined(TARGET_OSX)
|
||||
# include <arpa/inet.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "HL_Rtp.h"
|
||||
@@ -28,30 +28,30 @@
|
||||
#define LOG_SUBSYSTEM "network"
|
||||
|
||||
static constexpr size_t MAX_RTP_PACKET_SIZE = 65535;
|
||||
static const char RTPDUMP_SHEBANG[] = "#!rtpplay1.0";
|
||||
static const char RTPDUMP_SHEBANG[] = "#!rtpplay1.0";
|
||||
|
||||
// RTP fixed header (little-endian bit-field layout)
|
||||
struct RtpHeader
|
||||
{
|
||||
unsigned char cc:4; /* CSRC count */
|
||||
unsigned char x:1; /* header extension flag */
|
||||
unsigned char p:1; /* padding flag */
|
||||
unsigned char version:2; /* protocol version */
|
||||
unsigned char pt:7; /* payload type */
|
||||
unsigned char m:1; /* marker bit */
|
||||
unsigned char cc : 4; /* CSRC count */
|
||||
unsigned char x : 1; /* header extension flag */
|
||||
unsigned char p : 1; /* padding flag */
|
||||
unsigned char version : 2; /* protocol version */
|
||||
unsigned char pt : 7; /* payload type */
|
||||
unsigned char m : 1; /* marker bit */
|
||||
unsigned short seq; /* sequence number */
|
||||
unsigned int ts; /* timestamp */
|
||||
unsigned int ssrc; /* synchronization source */
|
||||
unsigned int ts; /* timestamp */
|
||||
unsigned int ssrc; /* synchronization source */
|
||||
};
|
||||
|
||||
struct RtcpHeader
|
||||
{
|
||||
unsigned char rc:5; /* reception report count */
|
||||
unsigned char p:1; /* padding flag */
|
||||
unsigned char version:2; /* protocol version */
|
||||
unsigned char pt; /* payload type */
|
||||
uint16_t len; /* length */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
unsigned char rc : 5; /* reception report count */
|
||||
unsigned char p : 1; /* padding flag */
|
||||
unsigned char version : 2; /* protocol version */
|
||||
unsigned char pt; /* payload type */
|
||||
uint16_t len; /* length */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
};
|
||||
|
||||
// --- IPv4 address helpers ---
|
||||
@@ -59,10 +59,8 @@ struct RtcpHeader
|
||||
static std::string ipToString(uint32_t ip)
|
||||
{
|
||||
// ip in host byte order → dotted-decimal
|
||||
return std::to_string((ip >> 24) & 0xFF) + "." +
|
||||
std::to_string((ip >> 16) & 0xFF) + "." +
|
||||
std::to_string((ip >> 8) & 0xFF) + "." +
|
||||
std::to_string( ip & 0xFF);
|
||||
return std::to_string((ip >> 24) & 0xFF) + "." + std::to_string((ip >> 16) & 0xFF) + "." +
|
||||
std::to_string((ip >> 8) & 0xFF) + "." + std::to_string(ip & 0xFF);
|
||||
}
|
||||
|
||||
static uint32_t stringToIp(const std::string& s)
|
||||
@@ -87,7 +85,7 @@ bool RtpHelper::isRtp(const void* buffer, size_t length)
|
||||
return false;
|
||||
|
||||
unsigned char pt = h->pt;
|
||||
bool rtp = (pt >= 96 && pt <= 127) || (pt < 35);
|
||||
bool rtp = (pt >= 96 && pt <= 127) || (pt < 35);
|
||||
return rtp;
|
||||
}
|
||||
|
||||
@@ -130,7 +128,7 @@ int RtpHelper::findPtype(const void* buffer, size_t length)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RtpHelper::findPacketNo(const void *buffer, size_t length)
|
||||
int RtpHelper::findPacketNo(const void* buffer, size_t length)
|
||||
{
|
||||
if (isRtp(buffer, length))
|
||||
return ntohs(reinterpret_cast<const RtpHeader*>(buffer)->seq);
|
||||
@@ -144,15 +142,16 @@ int RtpHelper::findPayloadLength(const void* buffer, size_t length)
|
||||
return -1;
|
||||
|
||||
const RtpHeader* h = reinterpret_cast<const RtpHeader*>(buffer);
|
||||
const uint8_t* p = static_cast<const uint8_t*>(buffer);
|
||||
const uint8_t* p = static_cast<const uint8_t*>(buffer);
|
||||
|
||||
// Fixed header (12 bytes) + CSRC list (4 * CC bytes)
|
||||
size_t offset = 12 + 4u * h->cc;
|
||||
size_t offset = 12 + 4u * h->cc;
|
||||
if (offset > length)
|
||||
return -1;
|
||||
|
||||
// Header extension
|
||||
if (h->x) {
|
||||
if (h->x)
|
||||
{
|
||||
if (offset + 4 > length)
|
||||
return -1;
|
||||
uint16_t extWords = (static_cast<uint16_t>(p[offset + 2]) << 8) | p[offset + 3];
|
||||
@@ -164,7 +163,8 @@ int RtpHelper::findPayloadLength(const void* buffer, size_t length)
|
||||
size_t payloadLen = length - offset;
|
||||
|
||||
// Padding
|
||||
if (h->p && payloadLen > 0) {
|
||||
if (h->p && payloadLen > 0)
|
||||
{
|
||||
uint8_t padBytes = p[length - 1];
|
||||
if (padBytes > payloadLen)
|
||||
return -1;
|
||||
@@ -186,29 +186,29 @@ std::shared_ptr<jrtplib::RTPPacket> RtpDump::parseRtpData(const uint8_t* data, s
|
||||
if (!data || len < 12 || !RtpHelper::isRtp(data, len))
|
||||
return nullptr;
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
// Both are heap-allocated; RTPRawPacket takes ownership and deletes them
|
||||
jrtplib::RTPIPAddress senderAddress = {jrtplib::RTPIPv4Address(uint32_t(0), uint16_t(0))};
|
||||
uint8_t* dataCopy = new uint8_t[len];
|
||||
uint8_t* dataCopy = new uint8_t[len];
|
||||
std::memcpy(dataCopy, data, len);
|
||||
|
||||
jrtplib::RTPRawPacket raw(dataCopy, len, senderAddress, jrtplib::RTPTime(0), true);
|
||||
auto packet = std::make_shared<jrtplib::RTPPacket>(raw);
|
||||
auto packet = std::make_shared<jrtplib::RTPPacket>(raw);
|
||||
|
||||
if (packet->GetCreationError() != 0)
|
||||
return nullptr;
|
||||
|
||||
return packet;
|
||||
} catch (const std::exception& e) {
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
ICELogInfo(<< "Failed to parse RTP packet: " << e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RtpDump::RtpDump(const char* filename)
|
||||
: mFilename(filename ? filename : "")
|
||||
{
|
||||
}
|
||||
RtpDump::RtpDump(const char* filename) : mFilename(filename ? filename : "") {}
|
||||
|
||||
RtpDump::~RtpDump() = default;
|
||||
|
||||
@@ -237,14 +237,19 @@ void RtpDump::load()
|
||||
|
||||
// Parse source address from the text line
|
||||
size_t spacePos = textLine.find(' ');
|
||||
if (spacePos != std::string::npos) {
|
||||
if (spacePos != std::string::npos)
|
||||
{
|
||||
std::string addrPart = textLine.substr(spacePos + 1);
|
||||
size_t slashPos = addrPart.find('/');
|
||||
if (slashPos != std::string::npos) {
|
||||
size_t slashPos = addrPart.find('/');
|
||||
if (slashPos != std::string::npos)
|
||||
{
|
||||
mSourceIp = stringToIp(addrPart.substr(0, slashPos));
|
||||
try {
|
||||
try
|
||||
{
|
||||
mSourcePort = static_cast<uint16_t>(std::stoi(addrPart.substr(slashPos + 1)));
|
||||
} catch (...) {
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
mSourcePort = 0;
|
||||
}
|
||||
}
|
||||
@@ -260,14 +265,14 @@ void RtpDump::load()
|
||||
input.read(reinterpret_cast<char*>(&buf32), 4);
|
||||
mStartUsec = ntohl(buf32);
|
||||
|
||||
input.read(reinterpret_cast<char*>(&buf32), 4); // source IP (already NBO in file)
|
||||
input.read(reinterpret_cast<char*>(&buf32), 4); // source IP (already NBO in file)
|
||||
// The binary header stores IP in network byte order; convert to host
|
||||
mSourceIp = ntohl(buf32);
|
||||
|
||||
input.read(reinterpret_cast<char*>(&buf16), 2);
|
||||
mSourcePort = ntohs(buf16);
|
||||
|
||||
input.read(reinterpret_cast<char*>(&buf16), 2); // padding — discard
|
||||
input.read(reinterpret_cast<char*>(&buf16), 2); // padding — discard
|
||||
|
||||
if (!input.good())
|
||||
throw std::runtime_error("Failed to read rtpdump binary header");
|
||||
@@ -275,21 +280,25 @@ void RtpDump::load()
|
||||
// --- 3. Packet records ---
|
||||
size_t packetCount = 0;
|
||||
|
||||
while (input.good() && input.peek() != EOF) {
|
||||
while (input.good() && input.peek() != EOF)
|
||||
{
|
||||
// Packet header: length(2) + plen(2) + offset(4) = 8 bytes
|
||||
uint16_t recLength, plen;
|
||||
uint32_t offsetMs;
|
||||
|
||||
input.read(reinterpret_cast<char*>(&recLength), 2);
|
||||
if (input.gcount() != 2) break;
|
||||
if (input.gcount() != 2)
|
||||
break;
|
||||
recLength = ntohs(recLength);
|
||||
|
||||
input.read(reinterpret_cast<char*>(&plen), 2);
|
||||
if (input.gcount() != 2) break;
|
||||
if (input.gcount() != 2)
|
||||
break;
|
||||
plen = ntohs(plen);
|
||||
|
||||
input.read(reinterpret_cast<char*>(&offsetMs), 4);
|
||||
if (input.gcount() != 4) break;
|
||||
if (input.gcount() != 4)
|
||||
break;
|
||||
offsetMs = ntohl(offsetMs);
|
||||
|
||||
// All-zeros record signals end of file in some implementations
|
||||
@@ -365,9 +374,10 @@ void RtpDump::add(const void* buffer, size_t len)
|
||||
return;
|
||||
|
||||
uint32_t offsetMs = 0;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
if (!mRecording) {
|
||||
if (!mRecording)
|
||||
{
|
||||
mRecording = true;
|
||||
mRecordStart = now;
|
||||
|
||||
@@ -376,9 +386,11 @@ void RtpDump::add(const void* buffer, size_t len)
|
||||
auto epoch = wallNow.time_since_epoch();
|
||||
auto sec = std::chrono::duration_cast<std::chrono::seconds>(epoch);
|
||||
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(epoch - sec);
|
||||
mStartSec = static_cast<uint32_t>(sec.count());
|
||||
mStartSec = static_cast<uint32_t>(sec.count());
|
||||
mStartUsec = static_cast<uint32_t>(usec.count());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - mRecordStart);
|
||||
offsetMs = static_cast<uint32_t>(elapsed.count());
|
||||
}
|
||||
@@ -396,8 +408,7 @@ void RtpDump::add(const void* buffer, size_t len, uint32_t offsetMs)
|
||||
throw std::runtime_error("Packet too large: " + std::to_string(len));
|
||||
|
||||
RtpData entry;
|
||||
entry.mRawData.assign(static_cast<const uint8_t*>(buffer),
|
||||
static_cast<const uint8_t*>(buffer) + len);
|
||||
entry.mRawData.assign(static_cast<const uint8_t*>(buffer), static_cast<const uint8_t*>(buffer) + len);
|
||||
entry.mOffsetMs = offsetMs;
|
||||
entry.mPacket = parseRtpData(entry.mRawData.data(), entry.mRawData.size());
|
||||
|
||||
@@ -414,9 +425,8 @@ void RtpDump::flush()
|
||||
throw std::runtime_error("Failed to open file for writing: " + mFilename);
|
||||
|
||||
// --- 1. Text header ---
|
||||
std::string textLine = std::string(RTPDUMP_SHEBANG) + " " +
|
||||
ipToString(mSourceIp) + "/" +
|
||||
std::to_string(mSourcePort) + "\n";
|
||||
std::string textLine =
|
||||
std::string(RTPDUMP_SHEBANG) + " " + ipToString(mSourceIp) + "/" + std::to_string(mSourcePort) + "\n";
|
||||
output.write(textLine.data(), static_cast<std::streamsize>(textLine.size()));
|
||||
|
||||
// --- 2. Binary file header (16 bytes) ---
|
||||
@@ -435,13 +445,14 @@ void RtpDump::flush()
|
||||
buf16 = htons(mSourcePort);
|
||||
output.write(reinterpret_cast<const char*>(&buf16), 2);
|
||||
|
||||
buf16 = 0; // padding
|
||||
buf16 = 0; // padding
|
||||
output.write(reinterpret_cast<const char*>(&buf16), 2);
|
||||
|
||||
// --- 3. Packet records ---
|
||||
size_t written = 0;
|
||||
|
||||
for (const auto& pkt : mPacketList) {
|
||||
for (const auto& pkt : mPacketList)
|
||||
{
|
||||
if (pkt.mRawData.empty())
|
||||
continue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user