diff --git a/src/media/socket_pair.cpp b/src/media/socket_pair.cpp index cadd00102bb0da63996747be561b3154b41ac03f..6580f67d73f5fd6d8866a24b9d8adfe6fbeda49a 100644 --- a/src/media/socket_pair.cpp +++ b/src/media/socket_pair.cpp @@ -219,6 +219,7 @@ SocketPair::SocketPair(std::unique_ptr<IceSocket> rtp_sock, , rtpDestAddrLen_() , rtcpDestAddr_() , rtcpDestAddrLen_() + , listRtcpHeader_() { auto queueRtpPacket = [this](uint8_t* buf, size_t len) { std::lock_guard<std::mutex> l(dataBuffMutex_); @@ -244,6 +245,36 @@ SocketPair::~SocketPair() closeSockets(); } +void +SocketPair::saveRtcpPacket(uint8_t* buf, size_t len) +{ + if (len < sizeof(rtcpRRHeader)) + return; + + auto header = reinterpret_cast<rtcpRRHeader*>(buf); + if(header->pt != 201) //201 = RR PT + return; + + std::lock_guard<std::mutex> lock(rtcpInfo_mutex_); + + if (listRtcpHeader_.size() >= MAX_LIST_SIZE) { + RING_WARN("Need to drop RTCP packets"); + listRtcpHeader_.pop_front(); + } + + listRtcpHeader_.push_back(*header); +} + +std::vector<rtcpRRHeader> +SocketPair::getRtcpInfo() +{ + std::lock_guard<std::mutex> lock(rtcpInfo_mutex_); + std::vector<rtcpRRHeader> vect(listRtcpHeader_.size()); + std::copy_n(listRtcpHeader_.begin(), listRtcpHeader_.size(), vect.begin()); + listRtcpHeader_.clear(); + return vect; +} + void SocketPair::createSRTP(const char* out_suite, const char* out_key, const char* in_suite, const char* in_key) @@ -422,6 +453,7 @@ SocketPair::readCallback(uint8_t* buf, int buf_size) // Priority to RTCP as its less invasive in bandwidth if (datatype & static_cast<int>(DataType::RTCP)) { len = readRtcpData(buf, buf_size); + saveRtcpPacket(buf, len); fromRTCP = true; } diff --git a/src/media/socket_pair.h b/src/media/socket_pair.h index f5992e6312718d8c4d05502ddd74a1fb618ef994..216b675e3e16e49bb370d4b788a4b32263046174 100644 --- a/src/media/socket_pair.h +++ b/src/media/socket_pair.h @@ -55,11 +55,32 @@ using socklen_t = int; #include <vector> #include <condition_variable> + namespace ring { class IceSocket; class SRTPProtoContext; +typedef struct { +#ifdef WORDS_BIGENDIAN + uint32_t version:2; /* protocol version */ + uint32_t p:1; /* padding flag */ + uint32_t rc:5; /* reception report count must be 201 for report */ + +#else + uint32_t rc:5; /* reception report count must be 201 for report */ + uint32_t p:1; /* padding flag */ + uint32_t version:2; /* protocol version */ +#endif + uint32_t pt:8; /* payload type */ + uint32_t len:16; /* length of RTCP packet */ + uint32_t ssrc; /* synchronization source identifier of packet send */ + uint32_t ssrc_1; /* synchronization source identifier of first source */ + uint32_t fraction_lost; /* 8 bits of fraction, 24 bits of total packets lost */ + uint32_t last_seq; /*last sequence number */ + uint32_t jitter; /*jitter */ +} rtcpRRHeader; + class SocketPair { public: SocketPair(const char* uri, int localPort); @@ -96,6 +117,7 @@ class SocketPair { void stopSendOp(bool state = true); private: + std::vector<rtcpRRHeader> getRtcpInfo(); NON_COPYABLE(SocketPair); int readCallback(uint8_t* buf, int buf_size); @@ -105,6 +127,7 @@ class SocketPair { int readRtpData(void* buf, int buf_size); int readRtcpData(void* buf, int buf_size); int writeData(uint8_t* buf, int buf_size); + void saveRtcpPacket(uint8_t* buf, size_t len); std::mutex dataBuffMutex_; std::condition_variable cv_; @@ -123,6 +146,13 @@ class SocketPair { std::atomic_bool interrupted_ {false}; std::atomic_bool noWrite_ {false}; std::unique_ptr<SRTPProtoContext> srtpContext_; + + std::list<rtcpRRHeader> listRtcpHeader_; + std::mutex rtcpInfo_mutex_; + static constexpr unsigned MAX_LIST_SIZE {20}; }; + + + } // namespace ring