diff --git a/src/rtcp/rtcp_packet.cpp b/src/rtcp/rtcp_packet.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/rtcp/rtcp_packet.h b/src/rtcp/rtcp_packet.h new file mode 100644 index 0000000..2399cdd --- /dev/null +++ b/src/rtcp/rtcp_packet.h @@ -0,0 +1,185 @@ +#ifndef _RTCP_PACKET_H_ +#define _RTCP_PACKET_H_ + +#include + +#include + +// 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 \ No newline at end of file diff --git a/src/rtp/rtp_codec.cpp b/src/rtp/rtp_codec.cpp index 9f58028..a89ee0c 100644 --- a/src/rtp/rtp_codec.cpp +++ b/src/rtp/rtp_codec.cpp @@ -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_ = diff --git a/src/rtp/rtp_codec.h b/src/rtp/rtp_codec.h index cd4fdec..73e263b 100644 --- a/src/rtp/rtp_codec.h +++ b/src/rtp/rtp_codec.h @@ -9,7 +9,7 @@ class RtpCodec { public: - RtpCodec(PAYLOAD_TYPE payload_type); + RtpCodec(RtpPacket::PAYLOAD_TYPE payload_type); ~RtpCodec(); public: diff --git a/src/rtp/rtp_packet.h b/src/rtp/rtp_packet.h index 733cd79..04ce623 100644 --- a/src/rtp/rtp_packet.h +++ b/src/rtp/rtp_packet.h @@ -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_; } diff --git a/src/rtp/rtp_video_receiver.cpp b/src/rtp/rtp_video_receiver.cpp index 5c37886..402f077 100644 --- a/src/rtp/rtp_video_receiver.cpp +++ b/src/rtp/rtp_video_receiver.cpp @@ -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); } diff --git a/src/transmission/ice_transmission.cpp b/src/transmission/ice_transmission.cpp index 84f450e..5e9aa14 100644 --- a/src/transmission/ice_transmission.cpp +++ b/src/transmission/ice_transmission.cpp @@ -47,7 +47,7 @@ IceTransmission::~IceTransmission() { } int IceTransmission::InitIceTransmission(std::string &ip, int port) { - rtp_codec_ = std::make_unique(PAYLOAD_TYPE::H264); + rtp_codec_ = std::make_unique(RtpPacket::PAYLOAD_TYPE::H264); rtp_video_receiver_ = std::make_unique(); rtp_video_receiver_->SetOnReceiveCompleteFrame( [this](VideoFrame &video_frame) -> void {