mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Implementation for rtcp sender report
This commit is contained in:
20
src/rtcp/rtcp_header.cpp
Normal file
20
src/rtcp/rtcp_header.cpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#include "rtcp_header.h"
|
||||||
|
|
||||||
|
RtcpHeader::RtcpHeader()
|
||||||
|
: version_(0), padding_(0), count_or_format_(0), length_(0) {}
|
||||||
|
|
||||||
|
RtcpHeader::~RtcpHeader() {}
|
||||||
|
|
||||||
|
int RtcpHeader::Encode(uint8_t version, uint8_t padding,
|
||||||
|
uint8_t count_or_format, uint8_t payload_type,
|
||||||
|
uint16_t length, uint8_t* buffer) {
|
||||||
|
if (!buffer) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = (version << 6) | (padding << 5) | (count_or_format << 4);
|
||||||
|
buffer[1] = payload_type;
|
||||||
|
buffer[2] = length >> 8 & 0xFF;
|
||||||
|
buffer[3] = length & 0xFF;
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
58
src/rtcp/rtcp_header.h
Normal file
58
src/rtcp/rtcp_header.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef _RTCP_HEADER_H_
|
||||||
|
#define _RTCP_HEADER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// RTCP header
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |V=2|P| RC | PT=SR=200 | length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
#define DEFAULT_RTCP_VERSION 2
|
||||||
|
#define DEFAULT_RTCP_HEADER_SIZE 4
|
||||||
|
|
||||||
|
class RtcpHeader {
|
||||||
|
public:
|
||||||
|
typedef enum {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
SR = 200,
|
||||||
|
RR = 201,
|
||||||
|
SDES = 202,
|
||||||
|
BYE = 203,
|
||||||
|
APP = 204
|
||||||
|
} PAYLOAD_TYPE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RtcpHeader();
|
||||||
|
~RtcpHeader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetVerion(uint8_t version) { version_ = version; }
|
||||||
|
void SetPadding(uint8_t padding) { padding_ = padding; }
|
||||||
|
void SetCountOrFormat(uint8_t count_or_format) {
|
||||||
|
count_or_format_ = count_or_format;
|
||||||
|
}
|
||||||
|
void SetPayloadType(uint8_t payload_type) { payload_type_ = payload_type; }
|
||||||
|
void SetLength(uint16_t length) { length_ = length; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint8_t Verion() const { return version_; }
|
||||||
|
uint8_t Padding() const { return padding_; }
|
||||||
|
uint8_t CountOrFormat() const { return count_or_format_; }
|
||||||
|
PAYLOAD_TYPE PayloadType() const { return PAYLOAD_TYPE(payload_type_); }
|
||||||
|
uint16_t Length() const { return length_; }
|
||||||
|
|
||||||
|
int Encode(uint8_t version, uint8_t padding, uint8_t count_or_format,
|
||||||
|
uint8_t payload_type, uint16_t length, uint8_t* buffer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t version_ : 2;
|
||||||
|
uint8_t padding_ : 1;
|
||||||
|
uint8_t count_or_format_ : 5;
|
||||||
|
uint8_t payload_type_ : 8;
|
||||||
|
uint16_t length_ : 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,74 +1,6 @@
|
|||||||
#ifndef _RTCP_PACKET_H_
|
#ifndef _RTCP_PACKET_H_
|
||||||
#define _RTCP_PACKET_H_
|
#define _RTCP_PACKET_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// SR
|
|
||||||
// 0 1 2 3
|
|
||||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// |V=2|P| RC | PT=SR=200 | length | header
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | SSRC of sender |
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | NTP timestamp, most significant word | sender
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info
|
|
||||||
// | NTP timestamp, least significant word |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | RTP timestamp |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | sender's packet count |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | sender's octet count |
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | SSRC_1 (SSRC of first source) | report
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
|
||||||
// | fraction lost | cumulative number of packets lost | 1
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | extended highest sequence number received |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | interarrival jitter |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | last SR (LSR) |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | delay since last SR (DLSR) |
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | SSRC_2 (SSRC of second source) | report
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
|
||||||
// : ... : 2
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | profile-specific extensions |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
|
|
||||||
// RR
|
|
||||||
// 0 1 2 3
|
|
||||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// |V=2|P| RC | PT=RR=201 | length | header
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | SSRC of packet sender |
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | SSRC_1 (SSRC of first source) | report
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
|
||||||
// | fraction lost | cumulative number of packets lost | 1
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | extended highest sequence number received |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | interarrival jitter |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | last SR (LSR) |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
// | delay since last SR (DLSR) |
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | SSRC_2 (SSRC of second source) | report
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
|
||||||
// : ... : 2
|
|
||||||
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
||||||
// | profile-specific extensions |
|
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
||||||
|
|
||||||
class RtcpPacket {
|
class RtcpPacket {
|
||||||
public:
|
public:
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -78,108 +10,7 @@ class RtcpPacket {
|
|||||||
SDES = 202,
|
SDES = 202,
|
||||||
BYE = 203,
|
BYE = 203,
|
||||||
APP = 204
|
APP = 204
|
||||||
} PAYLOAD_TYPE;
|
} RTCP_TYPE;
|
||||||
|
|
||||||
public:
|
|
||||||
RtcpPacket();
|
|
||||||
RtcpPacket(const uint8_t *buffer, size_t size);
|
|
||||||
RtcpPacket(const RtcpPacket &rtp_packet);
|
|
||||||
RtcpPacket(RtcpPacket &&rtp_packet);
|
|
||||||
RtcpPacket &operator=(const RtcpPacket &rtp_packet);
|
|
||||||
RtcpPacket &operator=(RtcpPacket &&rtp_packet);
|
|
||||||
|
|
||||||
~RtcpPacket();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Set Header
|
|
||||||
void SetVerion(uint8_t version) { version_ = version; }
|
|
||||||
void SetPadding(uint8_t padding) { padding_ = padding; }
|
|
||||||
void SetReceptionReportCount(uint8_t reception_report_count) {
|
|
||||||
reception_report_count_ = reception_report_count;
|
|
||||||
}
|
|
||||||
void SetPayloadType(PAYLOAD_TYPE payload_type) {
|
|
||||||
payload_type_ = payload_type;
|
|
||||||
}
|
|
||||||
void SetLength(uint16_t length) { length_ = length; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef struct {
|
|
||||||
uint8_t v : 2;
|
|
||||||
uint8_t p : 1;
|
|
||||||
uint8_t rc : 5;
|
|
||||||
uint8_t pt : 8;
|
|
||||||
uint16_t length : 16;
|
|
||||||
} RTCP_HEADER;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t ssrc_of_sender : 32;
|
|
||||||
uint64_t ntp_timestamp : 64;
|
|
||||||
uint32_t rtp_timestamp : 32;
|
|
||||||
uint32_t total_sent_count : 32;
|
|
||||||
uint32_t total_payload_sent_count : 32;
|
|
||||||
} SENDER_INFO;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t ssrc : 32;
|
|
||||||
uint8_t fraction_lost : 8;
|
|
||||||
uint32_t cumulative_packets_lost : 24;
|
|
||||||
uint32_t highest_sequence_number_received : 32;
|
|
||||||
uint32_t jitter : 32;
|
|
||||||
uint32_t lsr : 32;
|
|
||||||
uint32_t dlsr : 32;
|
|
||||||
} REPORT;
|
|
||||||
|
|
||||||
void SetRtcpHeader(RTCP_HEADER &rtcp_header) {
|
|
||||||
rtcp_header_.v = rtcp_header.v;
|
|
||||||
rtcp_header_.p = rtcp_header.p;
|
|
||||||
rtcp_header_.rc = rtcp_header.rc;
|
|
||||||
rtcp_header_.pt = rtcp_header.pt;
|
|
||||||
rtcp_header_.length = rtcp_header.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSenderInfo(SENDER_INFO &sender_info) {
|
|
||||||
sender_info_.ssrc_of_sender = sender_info.ssrc_of_sender;
|
|
||||||
sender_info_.ntp_timestamp = sender_info.ntp_timestamp;
|
|
||||||
sender_info_.rtp_timestamp = sender_info.rtp_timestamp;
|
|
||||||
sender_info_.total_sent_count = sender_info.total_sent_count;
|
|
||||||
sender_info_.total_payload_sent_count =
|
|
||||||
sender_info.total_payload_sent_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetReport(REPORT &report) {
|
|
||||||
report_.ssrc = report.ssrc;
|
|
||||||
report_.fraction_lost = report.fraction_lost;
|
|
||||||
report_.cumulative_packets_lost = report.cumulative_packets_lost;
|
|
||||||
report_.highest_sequence_number_received =
|
|
||||||
report.highest_sequence_number_received;
|
|
||||||
report_.jitter = report.jitter;
|
|
||||||
report_.lsr = report.lsr;
|
|
||||||
report_.dlsr = report.dlsr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
const uint8_t *Encode(uint8_t *payload, size_t payload_size);
|
|
||||||
size_t Decode(uint8_t *payload);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Get Header
|
|
||||||
const uint8_t Verion() { return version_; }
|
|
||||||
const uint8_t Padding() { return padding_; }
|
|
||||||
const uint8_t ReceptionReportCount() { return reception_report_count_; }
|
|
||||||
const PAYLOAD_TYPE PayloadType() { return PAYLOAD_TYPE(payload_type_); }
|
|
||||||
const uint16_t Length() { return length_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Header
|
|
||||||
uint8_t version_ = 0;
|
|
||||||
uint8_t padding_ = false;
|
|
||||||
uint8_t reception_report_count_ = 0;
|
|
||||||
uint8_t payload_type_ = 0;
|
|
||||||
uint16_t length_ = 0;
|
|
||||||
|
|
||||||
RTCP_HEADER rtcp_header_;
|
|
||||||
SENDER_INFO sender_info_;
|
|
||||||
REPORT report_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
5
src/rtcp/rtcp_receiver_report.cpp
Normal file
5
src/rtcp/rtcp_receiver_report.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "rtcp_receiver_report.h"
|
||||||
|
|
||||||
|
RtcpReceiverReport::RtcpReceiverReport() {}
|
||||||
|
|
||||||
|
RtcpReceiverReport::~RtcpReceiverReport() {}
|
||||||
52
src/rtcp/rtcp_receiver_report.h
Normal file
52
src/rtcp/rtcp_receiver_report.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#ifndef _RTCP_RECEIVER_REPORT_H_
|
||||||
|
#define _RTCP_RECEIVER_REPORT_H_
|
||||||
|
|
||||||
|
// RR
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |V=2|P| RC | PT=SR=200 | length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | SSRC of packet sender |
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | SSRC_1 (SSRC of first source) | report
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||||
|
// | fraction lost | cumulative number of packets lost | 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | extended highest sequence number received |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | interarrival jitter |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | last SR (LSR) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | delay since last SR (DLSR) |
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | SSRC_2 (SSRC of second source) | report
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||||
|
// : ... : 2
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | profile-specific extensions |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "rtcp_header.h"
|
||||||
|
#include "rtcp_report_block.h"
|
||||||
|
|
||||||
|
#define DEFAULT_SR_SIZE 32
|
||||||
|
|
||||||
|
class RtcpReceiverReport {
|
||||||
|
public:
|
||||||
|
RtcpReceiverReport();
|
||||||
|
~RtcpReceiverReport();
|
||||||
|
|
||||||
|
public:
|
||||||
|
const uint8_t *Encode(uint8_t *payload, size_t payload_size);
|
||||||
|
size_t Decode(uint8_t *payload);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RtcpHeader rtcp_header_;
|
||||||
|
std::vector<RtcpReportBlock> reports_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
5
src/rtcp/rtcp_report_block.cpp
Normal file
5
src/rtcp/rtcp_report_block.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "rtcp_report_block.h"
|
||||||
|
|
||||||
|
RtcpReportBlock::RtcpReportBlock() {}
|
||||||
|
|
||||||
|
RtcpReportBlock::~RtcpReportBlock() {}
|
||||||
53
src/rtcp/rtcp_report_block.h
Normal file
53
src/rtcp/rtcp_report_block.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef _RTCP_REPORT_BLOCK_H_
|
||||||
|
#define _RTCP_REPORT_BLOCK_H_
|
||||||
|
|
||||||
|
// Report block 1
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | SSRC_1 (SSRC of first source) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | fraction lost | cumulative number of packets lost |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | extended highest sequence number received |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | interarrival jitter |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | last SR (LSR) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | delay since last SR (DLSR) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class RtcpReportBlock {
|
||||||
|
public:
|
||||||
|
RtcpReportBlock();
|
||||||
|
~RtcpReportBlock();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef struct {
|
||||||
|
uint32_t source_ssrc : 32;
|
||||||
|
uint8_t fraction_lost : 8;
|
||||||
|
uint32_t cumulative_lost : 24;
|
||||||
|
uint32_t extended_high_seq_num : 32;
|
||||||
|
uint32_t jitter : 32;
|
||||||
|
uint32_t lsr : 32;
|
||||||
|
uint32_t dlsr : 32;
|
||||||
|
} REPORT;
|
||||||
|
|
||||||
|
void SetReport(REPORT &report) {
|
||||||
|
report_.source_ssrc = report.source_ssrc;
|
||||||
|
report_.fraction_lost = report.fraction_lost;
|
||||||
|
report_.cumulative_lost = report.cumulative_lost;
|
||||||
|
report_.extended_high_seq_num = report.extended_high_seq_num;
|
||||||
|
report_.jitter = report.jitter;
|
||||||
|
report_.lsr = report.lsr;
|
||||||
|
report_.dlsr = report.dlsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
REPORT report_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
52
src/rtcp/rtcp_sender_report.cpp
Normal file
52
src/rtcp/rtcp_sender_report.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "rtcp_sender_report.h"
|
||||||
|
|
||||||
|
RtcpSenderReport::RtcpSenderReport() {
|
||||||
|
buffer_ = new uint8_t[DEFAULT_SR_SIZE];
|
||||||
|
size_ = DEFAULT_SR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtcpSenderReport::~RtcpSenderReport() {
|
||||||
|
if (buffer_) {
|
||||||
|
delete buffer_;
|
||||||
|
buffer_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *RtcpSenderReport::Encode() {
|
||||||
|
int pos =
|
||||||
|
rtcp_header_.Encode(DEFAULT_RTCP_VERSION, 0, DEFAULT_SR_BLOCK_NUM,
|
||||||
|
RtcpPacket::RTCP_TYPE::SR, DEFAULT_SR_SIZE, buffer_);
|
||||||
|
|
||||||
|
buffer_[pos] = sender_info_.sender_ssrc >> 24 & 0xFF;
|
||||||
|
buffer_[pos + 1] = sender_info_.sender_ssrc >> 16 & 0xFF;
|
||||||
|
buffer_[pos + 2] = sender_info_.sender_ssrc >> 8 & 0xFF;
|
||||||
|
buffer_[pos + 3] = sender_info_.sender_ssrc & 0xFF;
|
||||||
|
|
||||||
|
buffer_[pos + 4] = sender_info_.ntp_ts >> 56 & 0xFF;
|
||||||
|
buffer_[pos + 5] = sender_info_.ntp_ts >> 48 & 0xFF;
|
||||||
|
buffer_[pos + 6] = sender_info_.ntp_ts >> 40 & 0xFF;
|
||||||
|
buffer_[pos + 7] = sender_info_.ntp_ts >> 32 & 0xFF;
|
||||||
|
buffer_[pos + 8] = sender_info_.ntp_ts >> 24 & 0xFF;
|
||||||
|
buffer_[pos + 9] = sender_info_.ntp_ts >> 16 & 0xFF;
|
||||||
|
buffer_[pos + 10] = sender_info_.ntp_ts >> 8 & 0xFF;
|
||||||
|
buffer_[pos + 11] = sender_info_.ntp_ts & 0xFF;
|
||||||
|
|
||||||
|
buffer_[pos + 12] = sender_info_.rtp_ts >> 24 & 0xFF;
|
||||||
|
buffer_[pos + 13] = sender_info_.rtp_ts >> 16 & 0xFF;
|
||||||
|
buffer_[pos + 14] = sender_info_.rtp_ts >> 8 & 0xFF;
|
||||||
|
buffer_[pos + 15] = sender_info_.rtp_ts & 0xFF;
|
||||||
|
|
||||||
|
buffer_[pos + 16] = sender_info_.sender_packet_count >> 24 & 0xFF;
|
||||||
|
buffer_[pos + 17] = sender_info_.sender_packet_count >> 16 & 0xFF;
|
||||||
|
buffer_[pos + 18] = sender_info_.sender_packet_count >> 8 & 0xFF;
|
||||||
|
buffer_[pos + 19] = sender_info_.sender_packet_count & 0xFF;
|
||||||
|
|
||||||
|
buffer_[pos + 20] = sender_info_.sender_octet_count >> 24 & 0xFF;
|
||||||
|
buffer_[pos + 21] = sender_info_.sender_octet_count >> 16 & 0xFF;
|
||||||
|
buffer_[pos + 22] = sender_info_.sender_octet_count >> 8 & 0xFF;
|
||||||
|
buffer_[pos + 23] = sender_info_.sender_octet_count & 0xFF;
|
||||||
|
|
||||||
|
return buffer_;
|
||||||
|
}
|
||||||
88
src/rtcp/rtcp_sender_report.h
Normal file
88
src/rtcp/rtcp_sender_report.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#ifndef _RTCP_SENDER_REPORT_H_
|
||||||
|
#define _RTCP_SENDER_REPORT_H_
|
||||||
|
|
||||||
|
// SR
|
||||||
|
// 0 1 2 3
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |V=2|P| RC | PT=SR=200 | length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | SSRC of sender |
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | NTP timestamp, most significant word | sender
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info
|
||||||
|
// | NTP timestamp, least significant word |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | RTP timestamp |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | sender's packet count |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | sender's octet count |
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | SSRC_1 (SSRC of first source) | report
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||||
|
// | fraction lost | cumulative number of packets lost | 1
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | extended highest sequence number received |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | interarrival jitter |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | last SR (LSR) |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// | delay since last SR (DLSR) |
|
||||||
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||||
|
// | SSRC_2 (SSRC of second source) | report
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
|
||||||
|
// : ... : 2
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "rtcp_header.h"
|
||||||
|
#include "rtcp_packet.h"
|
||||||
|
#include "rtcp_report_block.h"
|
||||||
|
|
||||||
|
#define DEFAULT_SR_BLOCK_NUM 1
|
||||||
|
#define DEFAULT_SR_SIZE 52
|
||||||
|
|
||||||
|
class RtcpSenderReport {
|
||||||
|
public:
|
||||||
|
RtcpSenderReport();
|
||||||
|
~RtcpSenderReport();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef struct {
|
||||||
|
uint32_t sender_ssrc : 32;
|
||||||
|
uint64_t ntp_ts : 64;
|
||||||
|
uint32_t rtp_ts : 32;
|
||||||
|
uint32_t sender_packet_count : 32;
|
||||||
|
uint32_t sender_octet_count : 32;
|
||||||
|
} SENDER_INFO;
|
||||||
|
|
||||||
|
void SetSenderInfo(SENDER_INFO &sender_info) {
|
||||||
|
sender_info_.sender_ssrc = sender_info.sender_ssrc;
|
||||||
|
sender_info_.ntp_ts = sender_info.ntp_ts;
|
||||||
|
sender_info_.rtp_ts = sender_info.rtp_ts;
|
||||||
|
sender_info_.sender_packet_count = sender_info.sender_packet_count;
|
||||||
|
sender_info_.sender_octet_count = sender_info.sender_octet_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
const uint8_t *Encode();
|
||||||
|
size_t Decode();
|
||||||
|
|
||||||
|
// Entire RTP buffer
|
||||||
|
const uint8_t *Buffer() const { return buffer_; }
|
||||||
|
size_t Size() const { return size_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RtcpHeader rtcp_header_;
|
||||||
|
SENDER_INFO sender_info_;
|
||||||
|
std::vector<RtcpReportBlock> reports_;
|
||||||
|
|
||||||
|
// Entire RTCP buffer
|
||||||
|
uint8_t *buffer_ = nullptr;
|
||||||
|
size_t size_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -141,30 +141,30 @@ class RtpPacket {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Get Header
|
// Get Header
|
||||||
const uint32_t Verion() { return version_; }
|
uint32_t Verion() const { return version_; }
|
||||||
const bool HasPadding() { return has_padding_; }
|
bool HasPadding() const { return has_padding_; }
|
||||||
const bool HasExtension() { return has_extension_; }
|
bool HasExtension() const { return has_extension_; }
|
||||||
const bool Marker() { return marker_; }
|
bool Marker() const { return marker_; }
|
||||||
const PAYLOAD_TYPE PayloadType() { return PAYLOAD_TYPE(payload_type_); }
|
PAYLOAD_TYPE PayloadType() const { return PAYLOAD_TYPE(payload_type_); }
|
||||||
const uint16_t SequenceNumber() { return sequence_number_; }
|
uint16_t SequenceNumber() const { return sequence_number_; }
|
||||||
const uint32_t Timestamp() { return timestamp_; }
|
uint32_t Timestamp() const { return timestamp_; }
|
||||||
const uint32_t Ssrc() { return ssrc_; }
|
uint32_t Ssrc() const { return ssrc_; }
|
||||||
const std::vector<uint32_t> Csrcs() { return csrcs_; };
|
std::vector<uint32_t> Csrcs() const { return csrcs_; };
|
||||||
const uint16_t ExtensionProfile() { return extension_profile_; }
|
uint16_t ExtensionProfile() const { return extension_profile_; }
|
||||||
const uint8_t *ExtensionData() { return extension_data_; }
|
const uint8_t *ExtensionData() const { return extension_data_; }
|
||||||
|
|
||||||
// Payload
|
// Payload
|
||||||
const uint8_t *Payload() { return payload_; };
|
const uint8_t *Payload() const { return payload_; };
|
||||||
const size_t PayloadSize() { return payload_size_; }
|
size_t PayloadSize() const { return payload_size_; }
|
||||||
|
|
||||||
// Entire RTP buffer
|
// Entire RTP buffer
|
||||||
const uint8_t *Buffer() { return buffer_; }
|
const uint8_t *Buffer() const { return buffer_; }
|
||||||
const size_t Size() { return size_; }
|
size_t Size() const { return size_; }
|
||||||
|
|
||||||
// NAL
|
// NAL
|
||||||
const NAL_UNIT_TYPE NalUnitType() { return nal_unit_type_; }
|
NAL_UNIT_TYPE NalUnitType() const { return nal_unit_type_; }
|
||||||
const bool FuAStart() { return fu_header_.start; }
|
bool FuAStart() const { return fu_header_.start; }
|
||||||
const bool FuAEnd() { return fu_header_.end; }
|
bool FuAEnd() const { return fu_header_.end; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void TryToDecodeH264RtpPacket(uint8_t *buffer);
|
inline void TryToDecodeH264RtpPacket(uint8_t *buffer);
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ RtpVideoReceiver::RtpVideoReceiver() {}
|
|||||||
RtpVideoReceiver::~RtpVideoReceiver() {}
|
RtpVideoReceiver::~RtpVideoReceiver() {}
|
||||||
|
|
||||||
void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||||
|
if (rtp_packet.PayloadType() == 200) {
|
||||||
|
LOG_ERROR("!!!!!!!!!!!!!!!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
if (!rtp_video_receive_statistics_) {
|
if (!rtp_video_receive_statistics_) {
|
||||||
rtp_video_receive_statistics_ =
|
rtp_video_receive_statistics_ =
|
||||||
std::make_unique<RtpVideoReceiveStatistics>();
|
std::make_unique<RtpVideoReceiveStatistics>();
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#define RTCP_INTERVAL 1000
|
||||||
|
|
||||||
RtpVideoSender::RtpVideoSender() {}
|
RtpVideoSender::RtpVideoSender() {}
|
||||||
|
|
||||||
RtpVideoSender::~RtpVideoSender() { rtp_video_send_statistics_->Stop(); }
|
RtpVideoSender::~RtpVideoSender() { rtp_video_send_statistics_->Stop(); }
|
||||||
@@ -19,6 +21,88 @@ void RtpVideoSender::Enqueue(std::vector<RtpPacket>& rtp_packets) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtpVideoSender::SetUdpSender(
|
||||||
|
std::function<int(const char*, size_t)> udp_sender) {
|
||||||
|
udp_sender_ = udp_sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
||||||
|
if (!udp_sender_) {
|
||||||
|
LOG_ERROR("udp_sender_ is nullptr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (0 != udp_sender_((const char*)rtp_packet.Buffer(), rtp_packet.Size())) {
|
||||||
|
LOG_ERROR("Send rtp packet failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_send_bytes_ += rtp_packet.Size();
|
||||||
|
total_rtp_packets_sent_++;
|
||||||
|
total_rtp_payload_sent_ += rtp_packet.PayloadSize();
|
||||||
|
|
||||||
|
if (CheckIsTimeSendRtcpPacket()) {
|
||||||
|
RtcpSenderReport rtcp_sr;
|
||||||
|
RtcpSenderReport::SENDER_INFO sender_info;
|
||||||
|
|
||||||
|
auto duration = std::chrono::system_clock::now().time_since_epoch();
|
||||||
|
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
|
||||||
|
uint32_t seconds_u32 = static_cast<uint32_t>(
|
||||||
|
std::chrono::duration_cast<std::chrono::seconds>(duration).count());
|
||||||
|
|
||||||
|
uint32_t fraction_u32 = static_cast<uint32_t>(
|
||||||
|
std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds)
|
||||||
|
.count());
|
||||||
|
|
||||||
|
sender_info.sender_ssrc = 0x00;
|
||||||
|
sender_info.ntp_ts = (uint64_t)seconds_u32 << 32 | (uint64_t)fraction_u32;
|
||||||
|
sender_info.rtp_ts =
|
||||||
|
std::chrono::high_resolution_clock::now().time_since_epoch().count() *
|
||||||
|
1000000;
|
||||||
|
sender_info.sender_packet_count = total_rtp_packets_sent_;
|
||||||
|
sender_info.sender_octet_count = total_rtp_payload_sent_;
|
||||||
|
|
||||||
|
rtcp_sr.SetSenderInfo(sender_info);
|
||||||
|
|
||||||
|
rtcp_sr.Encode();
|
||||||
|
|
||||||
|
SendRtcpSR(rtcp_sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RtpVideoSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) {
|
||||||
|
if (!udp_sender_) {
|
||||||
|
LOG_ERROR("udp_sender_ is nullptr");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (udp_sender_((const char*)rtcp_sr.Buffer(), rtcp_sr.Size())) {
|
||||||
|
LOG_ERROR("Send SR failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR("Send SR");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtpVideoSender::CheckIsTimeSendRtcpPacket() {
|
||||||
|
auto now_ts =
|
||||||
|
std::chrono::high_resolution_clock::now().time_since_epoch().count() *
|
||||||
|
1000000;
|
||||||
|
|
||||||
|
if (now_ts - last_send_rtcp_packet_ts_ >= RTCP_INTERVAL) {
|
||||||
|
last_send_rtcp_packet_ts_ = now_ts;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool RtpVideoSender::Process() {
|
bool RtpVideoSender::Process() {
|
||||||
last_send_bytes_ = 0;
|
last_send_bytes_ = 0;
|
||||||
|
|
||||||
@@ -26,10 +110,7 @@ bool RtpVideoSender::Process() {
|
|||||||
if (!rtp_packe_queue_.isEmpty()) {
|
if (!rtp_packe_queue_.isEmpty()) {
|
||||||
RtpPacket rtp_packet;
|
RtpPacket rtp_packet;
|
||||||
rtp_packe_queue_.pop(rtp_packet);
|
rtp_packe_queue_.pop(rtp_packet);
|
||||||
if (rtp_packet_send_func_) {
|
SendRtpPacket(rtp_packet);
|
||||||
rtp_packet_send_func_(rtp_packet);
|
|
||||||
last_send_bytes_ += rtp_packet.Size();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtp_video_send_statistics_) {
|
if (rtp_video_send_statistics_) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "rtcp_packet.h"
|
||||||
|
#include "rtcp_sender_report.h"
|
||||||
#include "rtp_packet.h"
|
#include "rtp_packet.h"
|
||||||
#include "rtp_video_send_statistics.h"
|
#include "rtp_video_send_statistics.h"
|
||||||
#include "thread_base.h"
|
#include "thread_base.h"
|
||||||
@@ -17,21 +19,28 @@ class RtpVideoSender : public ThreadBase {
|
|||||||
void Enqueue(std::vector<RtpPacket> &rtp_packets);
|
void Enqueue(std::vector<RtpPacket> &rtp_packets);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SetRtpPacketSendFunc(
|
void SetUdpSender(
|
||||||
std::function<void(RtpPacket &)> rtp_packet_send_func) {
|
std::function<int(const char *, size_t)> rtp_packet_send_func);
|
||||||
rtp_packet_send_func_ = rtp_packet_send_func;
|
|
||||||
}
|
private:
|
||||||
|
int SendRtpPacket(RtpPacket &rtp_packet);
|
||||||
|
int SendRtcpSR(RtcpSenderReport &rtcp_sr);
|
||||||
|
|
||||||
|
bool CheckIsTimeSendRtcpPacket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Process() override;
|
bool Process() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(RtpPacket &)> rtp_packet_send_func_ = nullptr;
|
std::function<int(const char *, size_t)> udp_sender_ = nullptr;
|
||||||
RingBuffer<RtpPacket> rtp_packe_queue_;
|
RingBuffer<RtpPacket> rtp_packe_queue_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<RtpVideoSendStatistics> rtp_video_send_statistics_ = nullptr;
|
std::unique_ptr<RtpVideoSendStatistics> rtp_video_send_statistics_ = nullptr;
|
||||||
uint32_t last_send_bytes_ = 0;
|
uint32_t last_send_bytes_ = 0;
|
||||||
|
uint32_t last_send_rtcp_packet_ts_ = 0;
|
||||||
|
uint32_t total_rtp_packets_sent_ = 0;
|
||||||
|
uint32_t total_rtp_payload_sent_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -60,11 +60,13 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) {
|
|||||||
rtp_video_receiver_->Start();
|
rtp_video_receiver_->Start();
|
||||||
|
|
||||||
rtp_video_sender_ = std::make_unique<RtpVideoSender>();
|
rtp_video_sender_ = std::make_unique<RtpVideoSender>();
|
||||||
rtp_video_sender_->SetRtpPacketSendFunc([this](
|
rtp_video_sender_->SetUdpSender([this](const char *data, size_t size) -> int {
|
||||||
RtpPacket &rtp_packet) -> void {
|
if (!ice_agent_) {
|
||||||
if (ice_agent_) {
|
LOG_ERROR("ice_agent_ is nullptr");
|
||||||
ice_agent_->Send((const char *)rtp_packet.Buffer(), rtp_packet.Size());
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ice_agent_->Send(data, size);
|
||||||
});
|
});
|
||||||
|
|
||||||
rtp_video_sender_->Start();
|
rtp_video_sender_->Start();
|
||||||
|
|||||||
10
xmake.lua
10
xmake.lua
@@ -59,9 +59,15 @@ target("frame")
|
|||||||
add_files("src/frame/*.cpp")
|
add_files("src/frame/*.cpp")
|
||||||
add_includedirs("src/frame", {public = true})
|
add_includedirs("src/frame", {public = true})
|
||||||
|
|
||||||
|
target("rtcp")
|
||||||
|
set_kind("static")
|
||||||
|
add_deps("log")
|
||||||
|
add_files("src/rtcp/*.cpp")
|
||||||
|
add_includedirs("src/rtcp", {public = true})
|
||||||
|
|
||||||
target("rtp")
|
target("rtp")
|
||||||
set_kind("static")
|
set_kind("static")
|
||||||
add_deps("log", "frame", "ringbuffer", "thread")
|
add_deps("log", "frame", "ringbuffer", "thread", "rtcp")
|
||||||
add_files("src/rtp/*.cpp")
|
add_files("src/rtp/*.cpp")
|
||||||
add_includedirs("src/rtp", {public = true})
|
add_includedirs("src/rtp", {public = true})
|
||||||
|
|
||||||
@@ -101,7 +107,7 @@ target("qos")
|
|||||||
|
|
||||||
target("transmission")
|
target("transmission")
|
||||||
set_kind("static")
|
set_kind("static")
|
||||||
add_deps("log", "ws", "ice", "qos", "rtp")
|
add_deps("log", "ws", "ice", "qos", "rtp", "rtcp")
|
||||||
add_files("src/transmission/*.cpp")
|
add_files("src/transmission/*.cpp")
|
||||||
add_packages("asio", "nlohmann_json")
|
add_packages("asio", "nlohmann_json")
|
||||||
add_includedirs("src/ws", "src/ice", "src/qos", {public = true})
|
add_includedirs("src/ws", "src/ice", "src/qos", {public = true})
|
||||||
|
|||||||
Reference in New Issue
Block a user