From ea74495b5ae650d73cbf96886bba724cc0aea667 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Wed, 13 Sep 2023 10:49:18 +0800 Subject: [PATCH] Fix rtcp header parse --- src/rtcp/rtcp_header.cpp | 22 +++++++- src/rtcp/rtcp_header.h | 13 ++++- src/rtp/rtp_video_receiver.cpp | 4 -- src/rtp/rtp_video_sender.cpp | 11 ++-- src/rtp/rtp_video_sender.h | 2 +- src/transmission/ice_transmission.cpp | 81 +++++++++++++++++++++------ src/transmission/ice_transmission.h | 5 ++ 7 files changed, 107 insertions(+), 31 deletions(-) diff --git a/src/rtcp/rtcp_header.cpp b/src/rtcp/rtcp_header.cpp index 002dd1b..4c56640 100644 --- a/src/rtcp/rtcp_header.cpp +++ b/src/rtcp/rtcp_header.cpp @@ -1,7 +1,27 @@ #include "rtcp_header.h" RtcpHeader::RtcpHeader() - : version_(0), padding_(0), count_or_format_(0), length_(0) {} + : version_(0), + padding_(0), + count_or_format_(0), + payload_type_(PAYLOAD_TYPE::UNKNOWN), + length_(0) {} + +RtcpHeader::RtcpHeader(const uint8_t* buffer, uint32_t size) { + if (size < 4) { + version_ = 2; + padding_ = 0; + count_or_format_ = 0; + payload_type_ = PAYLOAD_TYPE::UNKNOWN; + length_ = 0; + } else { + version_ = buffer[0] >> 6; + padding_ = buffer[0] >> 5 & 0x01; + count_or_format_ = buffer[0] & 0x1F; + payload_type_ = PAYLOAD_TYPE(buffer[1]); + length_ = buffer[2] << 8 + buffer[3]; + } +} RtcpHeader::~RtcpHeader() {} diff --git a/src/rtcp/rtcp_header.h b/src/rtcp/rtcp_header.h index 2b0cd3f..f147702 100644 --- a/src/rtcp/rtcp_header.h +++ b/src/rtcp/rtcp_header.h @@ -3,6 +3,8 @@ #include +#include "log.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 @@ -26,6 +28,7 @@ class RtcpHeader { public: RtcpHeader(); + RtcpHeader(const uint8_t* buffer, uint32_t size); ~RtcpHeader(); public: @@ -34,14 +37,18 @@ class RtcpHeader { void SetCountOrFormat(uint8_t count_or_format) { count_or_format_ = count_or_format; } - void SetPayloadType(uint8_t payload_type) { payload_type_ = payload_type; } + void SetPayloadType(PAYLOAD_TYPE 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_); } + PAYLOAD_TYPE PayloadType() const { + return PAYLOAD_TYPE((uint8_t)payload_type_); + } uint16_t Length() const { return length_; } int Encode(uint8_t version, uint8_t padding, uint8_t count_or_format, @@ -51,7 +58,7 @@ class RtcpHeader { uint8_t version_ : 2; uint8_t padding_ : 1; uint8_t count_or_format_ : 5; - uint8_t payload_type_ : 8; + PAYLOAD_TYPE payload_type_ : 8; uint16_t length_ : 16; }; diff --git a/src/rtp/rtp_video_receiver.cpp b/src/rtp/rtp_video_receiver.cpp index e0a02cc..402f077 100644 --- a/src/rtp/rtp_video_receiver.cpp +++ b/src/rtp/rtp_video_receiver.cpp @@ -9,10 +9,6 @@ RtpVideoReceiver::RtpVideoReceiver() {} RtpVideoReceiver::~RtpVideoReceiver() {} void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { - if (rtp_packet.PayloadType() == 200) { - LOG_ERROR("!!!!!!!!!!!!!!!!!!"); - } - if (!rtp_video_receive_statistics_) { rtp_video_receive_statistics_ = std::make_unique(); diff --git a/src/rtp/rtp_video_sender.cpp b/src/rtp/rtp_video_sender.cpp index 26a8582..7b7b98c 100644 --- a/src/rtp/rtp_video_sender.cpp +++ b/src/rtp/rtp_video_sender.cpp @@ -43,7 +43,7 @@ int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) { total_rtp_packets_sent_++; total_rtp_payload_sent_ += rtp_packet.PayloadSize(); - if (CheckIsTimeSendRtcpPacket()) { + if (CheckIsTimeSendSR()) { RtcpSenderReport rtcp_sr; RtcpSenderReport::SENDER_INFO sender_info; @@ -90,10 +90,11 @@ int RtpVideoSender::SendRtcpSR(RtcpSenderReport& rtcp_sr) { return 0; } -bool RtpVideoSender::CheckIsTimeSendRtcpPacket() { - auto now_ts = - std::chrono::high_resolution_clock::now().time_since_epoch().count() * - 1000000; +bool RtpVideoSender::CheckIsTimeSendSR() { + uint32_t now_ts = static_cast( + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count()); if (now_ts - last_send_rtcp_packet_ts_ >= RTCP_INTERVAL) { last_send_rtcp_packet_ts_ = now_ts; diff --git a/src/rtp/rtp_video_sender.h b/src/rtp/rtp_video_sender.h index 5f47481..7328870 100644 --- a/src/rtp/rtp_video_sender.h +++ b/src/rtp/rtp_video_sender.h @@ -26,7 +26,7 @@ class RtpVideoSender : public ThreadBase { int SendRtpPacket(RtpPacket &rtp_packet); int SendRtcpSR(RtcpSenderReport &rtcp_sr); - bool CheckIsTimeSendRtcpPacket(); + bool CheckIsTimeSendSR(); private: bool Process() override; diff --git a/src/transmission/ice_transmission.cpp b/src/transmission/ice_transmission.cpp index 763d2e1..2a14f94 100644 --- a/src/transmission/ice_transmission.cpp +++ b/src/transmission/ice_transmission.cpp @@ -109,17 +109,19 @@ int IceTransmission::InitIceTransmission(std::string &ip, int port) { } } }, - [](juice_agent_t *agent, const char *data, size_t size, void *user_ptr) { + [](juice_agent_t *agent, const char *buffer, size_t size, + void *user_ptr) { if (user_ptr) { IceTransmission *ice_transmission_obj = static_cast(user_ptr); if (ice_transmission_obj) { - RtpPacket packet((uint8_t *)data, size); - ice_transmission_obj->rtp_video_receiver_->InsertRtpPacket(packet); - // ice_transmission_obj->on_receive_ice_msg_cb_( - // (const char *)packet.Payload(), packet.PayloadSize(), - // ice_transmission_obj->remote_user_id_.data(), - // ice_transmission_obj->remote_user_id_.size()); + if (ice_transmission_obj->CheckIsVideoPacket(buffer, size)) { + RtpPacket packet((uint8_t *)buffer, size); + ice_transmission_obj->rtp_video_receiver_->InsertRtpPacket( + packet); + } else if (ice_transmission_obj->CheckIsRtcpPacket(buffer, size)) { + LOG_ERROR("Rtcp packet [{}]", (uint8_t)(buffer[1])); + } } } }, @@ -219,16 +221,61 @@ int IceTransmission::SendData(const char *data, size_t size) { if (rtp_video_sender_) { rtp_video_sender_->Enqueue(packets); } - - // for (auto &packet : packets) { - // ice_agent_->Send((const char *)packet.Buffer(), packet.Size()); - // } - - // std::vector packets = - // rtp_codec_->Encode((uint8_t *)(data), size); - - // send_ringbuffer_.insert(send_ringbuffer_.end(), packets.begin(), - // packets.end()); } return 0; +} + +uint8_t IceTransmission::CheckIsRtcpPacket(const char *buffer, size_t size) { + if (size < 4) { + return 0; + } + + uint8_t pt = buffer[1]; + + switch (pt) { + case RtcpHeader::PAYLOAD_TYPE::SR: { + return pt; + } + case RtcpHeader::PAYLOAD_TYPE::RR: { + return pt; + } + case RtcpHeader::PAYLOAD_TYPE::SDES: { + return pt; + } + case RtcpHeader::PAYLOAD_TYPE::BYE: { + return pt; + } + case RtcpHeader::PAYLOAD_TYPE::APP: { + return pt; + } + default: { + return 0; + } + } +} + +uint8_t IceTransmission::CheckIsVideoPacket(const char *buffer, size_t size) { + if (size < 4) { + return 0; + } + + uint8_t pt = buffer[1] & 0x7F; + if (RtpPacket::PAYLOAD_TYPE::H264 == pt) { + return pt; + } else { + return 0; + } +} + +uint8_t IceTransmission::CheckIsAudioPacket(const char *buffer, size_t size) { + if (size < 4) { + return 0; + } + + uint8_t pt = buffer[1] & 0x7F; + if (RtpPacket::PAYLOAD_TYPE::OPUS == pt) { + return pt; + } else { + return 0; + } } \ No newline at end of file diff --git a/src/transmission/ice_transmission.h b/src/transmission/ice_transmission.h index 8b94284..8277540 100644 --- a/src/transmission/ice_transmission.h +++ b/src/transmission/ice_transmission.h @@ -52,6 +52,11 @@ class IceTransmission { int SendAnswer(); + private: + uint8_t CheckIsRtcpPacket(const char *buffer, size_t size); + uint8_t CheckIsVideoPacket(const char *buffer, size_t size); + uint8_t CheckIsAudioPacket(const char *buffer, size_t size); + private: std::unique_ptr ice_agent_ = nullptr; std::shared_ptr ice_ws_transport_ = nullptr;