mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Add rtcp module
This commit is contained in:
0
src/rtcp/rtcp_packet.cpp
Normal file
0
src/rtcp/rtcp_packet.cpp
Normal file
185
src/rtcp/rtcp_packet.h
Normal file
185
src/rtcp/rtcp_packet.h
Normal file
@@ -0,0 +1,185 @@
|
||||
#ifndef _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 {
|
||||
public:
|
||||
typedef enum {
|
||||
UNKNOWN = 0,
|
||||
SR = 200,
|
||||
RR = 201,
|
||||
SDES = 202,
|
||||
BYE = 203,
|
||||
APP = 204
|
||||
} PAYLOAD_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
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define RTP_VERSION 1
|
||||
#define RTP_VERSION 2
|
||||
#define NALU 1
|
||||
#define FU_A 28
|
||||
#define FU_B 29
|
||||
|
||||
RtpCodec ::RtpCodec(PAYLOAD_TYPE payload_type)
|
||||
RtpCodec ::RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type)
|
||||
: version_(RTP_VERSION),
|
||||
has_padding_(false),
|
||||
has_extension_(false),
|
||||
@@ -41,7 +41,7 @@ void RtpCodec::Encode(uint8_t* buffer, size_t size,
|
||||
rtp_packet.SetHasPadding(has_padding_);
|
||||
rtp_packet.SetHasExtension(has_extension_);
|
||||
rtp_packet.SetMarker(1);
|
||||
rtp_packet.SetPayloadType(PAYLOAD_TYPE(payload_type_));
|
||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||
|
||||
timestamp_ =
|
||||
@@ -76,7 +76,7 @@ void RtpCodec::Encode(uint8_t* buffer, size_t size,
|
||||
rtp_packet.SetHasPadding(has_padding_);
|
||||
rtp_packet.SetHasExtension(has_extension_);
|
||||
rtp_packet.SetMarker(index == packet_num ? 1 : 0);
|
||||
rtp_packet.SetPayloadType(PAYLOAD_TYPE(payload_type_));
|
||||
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
|
||||
rtp_packet.SetSequenceNumber(sequence_number_++);
|
||||
|
||||
timestamp_ =
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
class RtpCodec {
|
||||
public:
|
||||
RtpCodec(PAYLOAD_TYPE payload_type);
|
||||
RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type);
|
||||
~RtpCodec();
|
||||
|
||||
public:
|
||||
|
||||
@@ -63,10 +63,12 @@
|
||||
|
||||
#define DEFAULT_MTU 1500
|
||||
#define MAX_NALU_LEN 1400
|
||||
typedef enum { H264 = 96, OPUS = 97, USER_DEFINED = 127 } PAYLOAD_TYPE;
|
||||
typedef enum { UNKNOWN = 0, NALU = 1, FU_A = 28, FU_B = 29 } NAL_UNIT_TYPE;
|
||||
|
||||
class RtpPacket {
|
||||
public:
|
||||
typedef enum { H264 = 96, OPUS = 97, USER_DEFINED = 127 } PAYLOAD_TYPE;
|
||||
typedef enum { UNKNOWN = 0, NALU = 1, FU_A = 28, FU_B = 29 } NAL_UNIT_TYPE;
|
||||
|
||||
public:
|
||||
RtpPacket();
|
||||
RtpPacket(const uint8_t *buffer, size_t size);
|
||||
@@ -104,16 +106,16 @@ class RtpPacket {
|
||||
|
||||
public:
|
||||
typedef struct {
|
||||
unsigned char forbidden_bit : 1;
|
||||
unsigned char nal_reference_idc : 2;
|
||||
unsigned char nal_unit_type : 5;
|
||||
uint8_t forbidden_bit : 1;
|
||||
uint8_t nal_reference_idc : 2;
|
||||
uint8_t nal_unit_type : 5;
|
||||
} FU_INDICATOR;
|
||||
|
||||
typedef struct {
|
||||
unsigned char start : 1;
|
||||
unsigned char end : 1;
|
||||
unsigned char remain_bit : 1;
|
||||
unsigned char nal_unit_type : 5;
|
||||
uint8_t start : 1;
|
||||
uint8_t end : 1;
|
||||
uint8_t remain_bit : 1;
|
||||
uint8_t nal_unit_type : 5;
|
||||
} FU_HEADER;
|
||||
|
||||
void SetFuIndicator(FU_INDICATOR fu_indicator) {
|
||||
@@ -143,7 +145,7 @@ class RtpPacket {
|
||||
const bool HasPadding() { return has_padding_; }
|
||||
const bool HasExtension() { return has_extension_; }
|
||||
const bool Marker() { return marker_; }
|
||||
const uint32_t PayloadType() { return payload_type_; }
|
||||
const PAYLOAD_TYPE PayloadType() { return PAYLOAD_TYPE(payload_type_); }
|
||||
const uint16_t SequenceNumber() { return sequence_number_; }
|
||||
const uint32_t Timestamp() { return timestamp_; }
|
||||
const uint32_t Ssrc() { return ssrc_; }
|
||||
|
||||
@@ -19,7 +19,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||
rtp_video_receive_statistics_->UpdateReceiveBytes(rtp_packet.Size());
|
||||
}
|
||||
|
||||
if (NAL_UNIT_TYPE::NALU == rtp_packet.NalUnitType()) {
|
||||
if (RtpPacket::NAL_UNIT_TYPE::NALU == rtp_packet.NalUnitType()) {
|
||||
compelete_video_frame_queue_.push(
|
||||
VideoFrame(rtp_packet.Payload(), rtp_packet.Size()));
|
||||
// if (on_receive_complete_frame_) {
|
||||
@@ -33,7 +33,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||
// on_receive_complete_frame_(
|
||||
// VideoFrame(rtp_packet.Payload(), rtp_packet.Size()));
|
||||
// }
|
||||
} else if (NAL_UNIT_TYPE::FU_A == rtp_packet.NalUnitType()) {
|
||||
} else if (RtpPacket::NAL_UNIT_TYPE::FU_A == rtp_packet.NalUnitType()) {
|
||||
incomplete_frame_list_[rtp_packet.SequenceNumber()] = rtp_packet;
|
||||
bool complete = CheckIsFrameCompleted(rtp_packet);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ IceTransmission::~IceTransmission() {
|
||||
}
|
||||
|
||||
int IceTransmission::InitIceTransmission(std::string &ip, int port) {
|
||||
rtp_codec_ = std::make_unique<RtpCodec>(PAYLOAD_TYPE::H264);
|
||||
rtp_codec_ = std::make_unique<RtpCodec>(RtpPacket::PAYLOAD_TYPE::H264);
|
||||
rtp_video_receiver_ = std::make_unique<RtpVideoReceiver>();
|
||||
rtp_video_receiver_->SetOnReceiveCompleteFrame(
|
||||
[this](VideoFrame &video_frame) -> void {
|
||||
|
||||
Reference in New Issue
Block a user