From 602b475a3c6de008e7ede65cb5767d4e05a5b4fc Mon Sep 17 00:00:00 2001 From: xiongguangjie Date: Tue, 12 Jul 2022 19:26:17 +0800 Subject: [PATCH 1/2] for rtc send can receive rtcp xr, player can calculate rtt , for metaRTC player send rtcp xr --- src/Rtcp/Rtcp.cpp | 107 ++++++++++++++++++++++++++++- src/Rtcp/Rtcp.h | 134 +++++++++++++++++++++++++++++++++++++ src/Rtcp/RtcpContext.cpp | 44 ++++++++++++ src/Rtcp/RtcpContext.h | 14 ++++ webrtc/WebRtcTransport.cpp | 17 +++++ 5 files changed, 315 insertions(+), 1 deletion(-) diff --git a/src/Rtcp/Rtcp.cpp b/src/Rtcp/Rtcp.cpp index ea6533d3..19abb51e 100644 --- a/src/Rtcp/Rtcp.cpp +++ b/src/Rtcp/Rtcp.cpp @@ -193,7 +193,20 @@ void RtcpHeader::net2Host(size_t len) { bye->net2Host(len); break; } - + case RtcpType::RTCP_XR:{ + RtcpXRRRTR* xr = (RtcpXRRRTR*)this; + if(xr->bt == 4){ + xr->net2Host(len); + //TraceL<dumpString(); + }else if(xr->bt == 5){ + RtcpXRDLRR* dlrr = (RtcpXRDLRR*)this; + dlrr->net2Host(len); + TraceL<dumpString(); + }else{ + throw std::runtime_error(StrPrinter << "rtcp xr bt " << xr->bt<<" not support"); + } + break; + } default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt)); } } @@ -691,6 +704,98 @@ void RtcpBye::net2Host(size_t size) { } } } +//////////////////////////////////////////// +string RtcpXRRRTR::dumpString() const { + _StrPrinter printer; + printer << RtcpHeader::dumpHeader(); + printer << "ssrc :" < RtcpXRDLRR::getItemList(){ + auto count = block_length/3; + RtcpXRDLRRReportItem *ptr = &items; + vector ret; + for (int i = 0; i < (int) count; ++i) { + ret.emplace_back(ptr); + ++ptr; + } + return ret; + +} +string RtcpXRDLRR::dumpString() const { + _StrPrinter printer; + printer << RtcpHeader::dumpHeader(); + printer << "ssrc :" <getItemList(); + auto i = 0; + for (auto &item : items_list) { + printer << "---- item:" << i++ << " ----\r\n"; + printer << item->dumpString(); + } + return std::move(printer); +} + +void RtcpXRDLRR::net2Host(size_t size) { + static const size_t kMinSize = sizeof(RtcpHeader); + CHECK_MIN_SIZE(size, kMinSize); + + ssrc = ntohl(ssrc); + block_length = ntohs(block_length); + + auto count = block_length/3; + for (int i = 0; i < (int) count; ++i) { + RtcpXRDLRRReportItem *ptr = &items; + ptr->net2Host(); + ptr++; + } +} + +std::shared_ptr RtcpXRDLRR::create(size_t item_count){ + auto real_size = sizeof(RtcpXRDLRR) - sizeof(RtcpXRDLRRReportItem) + item_count * sizeof(RtcpXRDLRRReportItem); + auto bytes = alignSize(real_size); + auto ptr = (RtcpXRDLRR *) new char[bytes]; + setupHeader(ptr, RtcpType::RTCP_XR, 0, bytes); + setupPadding(ptr, bytes - real_size); + return std::shared_ptr(ptr, [](RtcpXRDLRR *ptr) { + delete[] (char *) ptr; + }); +} #if 0 #include "Util/onceToken.h" diff --git a/src/Rtcp/Rtcp.h b/src/Rtcp/Rtcp.h index 29a334e6..223b9c59 100644 --- a/src/Rtcp/Rtcp.h +++ b/src/Rtcp/Rtcp.h @@ -687,6 +687,140 @@ private: void net2Host(size_t size); } PACKED; +/* +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|reserved | PT=XR=207 | length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| SSRC | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +: report blocks : ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +*/ +/* + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | BT=4 | reserved | block length = 2 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | NTP timestamp, most significant word | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | NTP timestamp, least significant word | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +*/ +class RtcpXRRRTR : public RtcpHeader +{ +public: + friend class RtcpHeader; + uint32_t ssrc; + // 4 + uint8_t bt; + uint8_t reserved; + // 2 + uint16_t block_length; + // ntp timestamp MSW(in second) + uint32_t ntpmsw; + // ntp timestamp LSW(in picosecond) + uint32_t ntplsw; +private: + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ + std::string dumpString() const; + + /** + * 网络字节序转换为主机字节序 + * @param size 字节长度,防止内存越界 + */ + void net2Host(size_t size); + +}PACKED; + +/* + + 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 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | BT=5 | reserved | block length | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | SSRC_1 (SSRC of first receiver) | sub- + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block + | last RR (LRR) | 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | delay since last RR (DLRR) | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | SSRC_2 (SSRC of second receiver) | sub- + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block + : ... : 2 + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +*/ +class RtcpXRDLRRReportItem +{ +public: + friend class RtcpXRDLRR; + uint32_t ssrc; + uint32_t lrr; + uint32_t dlrr; +private: + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ + std::string dumpString() const; + + /** + * 网络字节序转换为主机字节序 + * @param size 字节长度,防止内存越界 + */ + void net2Host(); +}PACKED; + + + +class RtcpXRDLRR : public RtcpHeader +{ +public: + friend class RtcpHeader; + uint32_t ssrc; + uint8_t bt; + uint8_t reserved; + uint16_t block_length; + RtcpXRDLRRReportItem items; + + /** + * 创建RtcpXRDLRR包,只赋值了RtcpHeader部分(网络字节序) + * @param item_count RtcpXRDLRRReportItem对象个数 + * @return RtcpXRDLRR包 + */ + static std::shared_ptr create(size_t item_count); + + /** + * 获取RtcpXRDLRRReportItem对象指针列表 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ + std::vector getItemList(); + +private: + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ + std::string dumpString() const; + + /** + * 网络字节序转换为主机字节序 + * @param size 字节长度,防止内存越界 + */ + void net2Host(size_t size); + +}PACKED; + + #if defined(_WIN32) #pragma pack(pop) #endif // defined(_WIN32) diff --git a/src/Rtcp/RtcpContext.cpp b/src/Rtcp/RtcpContext.cpp index f7795405..23abbb91 100644 --- a/src/Rtcp/RtcpContext.cpp +++ b/src/Rtcp/RtcpContext.cpp @@ -45,6 +45,10 @@ Buffer::Ptr RtcpContext::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) { throw std::runtime_error("没有实现, rtp发送者尝试发送rr包"); } +Buffer::Ptr RtcpContext::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) { + throw std::runtime_error("没有实现, rtp发送者尝试发送xr dlrr包"); +} + //////////////////////////////////////////////////////////////////////////////////// void RtcpContextForSend::onRtcp(RtcpHeader *rtcp) { @@ -72,6 +76,18 @@ void RtcpContextForSend::onRtcp(RtcpHeader *rtcp) { } break; } + case RtcpType::RTCP_XR:{ + auto rtcp_xr = (RtcpXRRRTR*)rtcp; + if(rtcp_xr->bt == 4){ + _xr_xrrtr_recv_last_rr[rtcp_xr->ssrc] = ((rtcp_xr->ntpmsw & 0xFFFF) << 16) | ((rtcp_xr->ntplsw >> 16) & 0xFFFF); + _xr_rrtr_recv_sys_stamp[rtcp_xr->ssrc] = getCurrentMillisecond(); + }else if(rtcp_xr->bt == 5){ + TraceL<<"for sender not recive dlrr"; + }else{ + TraceL<<"not support xr bt "<bt; + } + break; + } default: break; } } @@ -103,6 +119,34 @@ Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) { return RtcpHeader::toBuffer(std::move(rtcp)); } +toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc){ + auto rtcp = RtcpXRDLRR::create(1); + rtcp->bt = 5; + rtcp->reserved = 0; + rtcp->block_length = htons(3); + rtcp->ssrc = htonl(rtcp_ssrc); + rtcp->items.ssrc = htonl(rtp_ssrc); + + if(_xr_xrrtr_recv_last_rr.find(rtp_ssrc) == _xr_xrrtr_recv_last_rr.end()){ + rtcp->items.lrr = 0; + WarnL; + }else{ + rtcp->items.lrr = htonl(_xr_xrrtr_recv_last_rr[rtp_ssrc]); + } + + if(_xr_rrtr_recv_sys_stamp.find(rtp_ssrc) == _xr_rrtr_recv_sys_stamp.end()){ + rtcp->items.dlrr = 0; + WarnL; + } else { + // now - Last SR time,单位毫秒 + auto delay = getCurrentMillisecond() - _xr_rrtr_recv_sys_stamp[rtp_ssrc]; + // in units of 1/65536 seconds + auto dlsr = (uint32_t)(delay / 1000.0f * 65536); + rtcp->items.dlrr = htonl(dlsr); + } + return RtcpHeader::toBuffer(std::move(rtcp)); +} + //////////////////////////////////////////////////////////////////////////////////// void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) { diff --git a/src/Rtcp/RtcpContext.h b/src/Rtcp/RtcpContext.h index 59341b05..2ed936f8 100644 --- a/src/Rtcp/RtcpContext.h +++ b/src/Rtcp/RtcpContext.h @@ -55,6 +55,14 @@ public: */ virtual toolkit::Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc); + + /** + * @brief 创建xr的dlrr包,用于接收者估算rtt + * + * @return toolkit::Buffer::Ptr + */ + virtual toolkit::Buffer::Ptr createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc); + /** * 创建RR rtcp包 * @param rtcp_ssrc rtcp的ssrc @@ -86,8 +94,11 @@ protected: class RtcpContextForSend : public RtcpContext { public: toolkit::Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc) override; + void onRtcp(RtcpHeader *rtcp) override; + toolkit::Buffer::Ptr createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) override; + /** * 获取rtt * @param ssrc rtp ssrc @@ -98,6 +109,9 @@ public: private: std::map _rtt; std::map _sender_report_ntp; + + std::map _xr_rrtr_recv_sys_stamp; + std::map _xr_xrrtr_recv_last_rr; }; class RtcpContextForRecv : public RtcpContext { diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 42025238..5850cfb6 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -774,6 +774,23 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { } break; } + case RtcpType::RTCP_XR:{ + RtcpXRRRTR* xr = (RtcpXRRRTR *) rtcp; + if(xr->bt != 4){ + break; + } + auto it = _ssrc_to_track.find(xr->ssrc); + if (it == _ssrc_to_track.end()) { + WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); + return; + } + auto &track = it->second; + track->rtcp_context_send->onRtcp(rtcp); + auto xrdlrr = track->rtcp_context_send->createRtcpXRDLRR(track->answer_ssrc_rtp,track->answer_ssrc_rtp); + sendRtcpPacket(xrdlrr->data(), xrdlrr->size(), true); + + break; + } default: break; } } From cffc0743d72b6fea17e507e19fd237e2a1cf6f4c Mon Sep 17 00:00:00 2001 From: xiongguangjie Date: Thu, 14 Jul 2022 22:49:31 +0800 Subject: [PATCH 2/2] format code use clang-format --- src/Rtcp/Rtcp.cpp | 518 ++++++++++++++++----------------- src/Rtcp/Rtcp.h | 341 +++++++++++----------- src/Rtcp/RtcpContext.cpp | 150 +++++----- src/Rtcp/RtcpContext.h | 49 ++-- src/Rtcp/RtcpFCI.cpp | 274 +++++++++--------- src/Rtcp/RtcpFCI.h | 207 ++++++------- webrtc/WebRtcTransport.cpp | 574 +++++++++++++++++++------------------ 7 files changed, 1071 insertions(+), 1042 deletions(-) diff --git a/src/Rtcp/Rtcp.cpp b/src/Rtcp/Rtcp.cpp index 19abb51e..38d1decc 100644 --- a/src/Rtcp/Rtcp.cpp +++ b/src/Rtcp/Rtcp.cpp @@ -8,55 +8,67 @@ * may be found in the AUTHORS file in the root of the source tree. */ -#include -#include #include "Rtcp.h" -#include "Util/logger.h" #include "RtcpFCI.h" +#include "Util/logger.h" +#include +#include using namespace std; using namespace toolkit; namespace mediakit { -const char *rtcpTypeToStr(RtcpType type){ - switch (type){ -#define SWITCH_CASE(key, value) case RtcpType::key : return #value "(" #key ")"; +const char *rtcpTypeToStr(RtcpType type) { + switch (type) { +#define SWITCH_CASE(key, value) \ + case RtcpType::key: \ + return #value "(" #key ")"; RTCP_PT_MAP(SWITCH_CASE) #undef SWITCH_CASE - default: return "unknown rtcp pt"; + default: + return "unknown rtcp pt"; } } -const char *sdesTypeToStr(SdesType type){ - switch (type){ -#define SWITCH_CASE(key, value) case SdesType::key : return #value "(" #key ")"; +const char *sdesTypeToStr(SdesType type) { + switch (type) { +#define SWITCH_CASE(key, value) \ + case SdesType::key: \ + return #value "(" #key ")"; SDES_TYPE_MAP(SWITCH_CASE) #undef SWITCH_CASE - default: return "unknown source description type"; + default: + return "unknown source description type"; } } const char *psfbTypeToStr(PSFBType type) { - switch (type){ -#define SWITCH_CASE(key, value) case PSFBType::key : return #value "(" #key ")"; + switch (type) { +#define SWITCH_CASE(key, value) \ + case PSFBType::key: \ + return #value "(" #key ")"; PSFB_TYPE_MAP(SWITCH_CASE) #undef SWITCH_CASE - default: return "unknown payload-specific fb message fmt type"; + default: + return "unknown payload-specific fb message fmt type"; } } const char *rtpfbTypeToStr(RTPFBType type) { - switch (type){ -#define SWITCH_CASE(key, value) case RTPFBType::key : return #value "(" #key ")"; + switch (type) { +#define SWITCH_CASE(key, value) \ + case RTPFBType::key: \ + return #value "(" #key ")"; RTPFB_TYPE_MAP(SWITCH_CASE) #undef SWITCH_CASE - default: return "unknown transport layer feedback messages fmt type"; + default: + return "unknown transport layer feedback messages fmt type"; } } static size_t alignSize(size_t bytes) { - return (size_t) ((bytes + 3) >> 2) << 2; + return (size_t)((bytes + 3) >> 2) << 2; } static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, size_t total_bytes) { @@ -65,16 +77,16 @@ static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, si if (report_count > 0x1F) { throw std::invalid_argument(StrPrinter << "rtcp report_count最大赋值为31,当前为:" << report_count); } - //items总个数 + // items总个数 rtcp->report_count = report_count; - rtcp->pt = (uint8_t) type; + rtcp->pt = (uint8_t)type; rtcp->setSize(total_bytes); } static void setupPadding(RtcpHeader *rtcp, size_t padding_size) { if (padding_size) { rtcp->padding = 1; - ((uint8_t *) rtcp)[rtcp->getSize() - 1] = padding_size & 0xFF; + ((uint8_t *)rtcp)[rtcp->getSize() - 1] = padding_size & 0xFF; } else { rtcp->padding = 0; } @@ -91,123 +103,125 @@ string RtcpHeader::dumpHeader() const { printer << "padding:" << padding << "\r\n"; } - switch ((RtcpType) pt) { - case RtcpType::RTCP_RTPFB : { - printer << "report_count:" << rtpfbTypeToStr((RTPFBType) report_count) << "\r\n"; - break; - } - case RtcpType::RTCP_PSFB : { - printer << "report_count:" << psfbTypeToStr((PSFBType) report_count) << "\r\n"; - break; - } - default : { - printer << "report_count:" << report_count << "\r\n"; - break; - } + switch ((RtcpType)pt) { + case RtcpType::RTCP_RTPFB: { + printer << "report_count:" << rtpfbTypeToStr((RTPFBType)report_count) << "\r\n"; + break; + } + case RtcpType::RTCP_PSFB: { + printer << "report_count:" << psfbTypeToStr((PSFBType)report_count) << "\r\n"; + break; + } + default: { + printer << "report_count:" << report_count << "\r\n"; + break; + } } - printer << "pt:" << rtcpTypeToStr((RtcpType) pt) << "\r\n"; + printer << "pt:" << rtcpTypeToStr((RtcpType)pt) << "\r\n"; printer << "size:" << getSize() << "\r\n"; printer << "--------\r\n"; return std::move(printer); } string RtcpHeader::dumpString() const { - switch ((RtcpType) pt) { - case RtcpType::RTCP_SR: { - RtcpSR *rtcp = (RtcpSR *) this; - return rtcp->dumpString(); - } + switch ((RtcpType)pt) { + case RtcpType::RTCP_SR: { + RtcpSR *rtcp = (RtcpSR *)this; + return rtcp->dumpString(); + } - case RtcpType::RTCP_RR: { - RtcpRR *rtcp = (RtcpRR *) this; - return rtcp->dumpString(); - } + case RtcpType::RTCP_RR: { + RtcpRR *rtcp = (RtcpRR *)this; + return rtcp->dumpString(); + } - case RtcpType::RTCP_SDES: { - RtcpSdes *rtcp = (RtcpSdes *) this; - return rtcp->dumpString(); - } + case RtcpType::RTCP_SDES: { + RtcpSdes *rtcp = (RtcpSdes *)this; + return rtcp->dumpString(); + } - case RtcpType::RTCP_RTPFB: - case RtcpType::RTCP_PSFB: { - RtcpFB *rtcp = (RtcpFB *) this; - return rtcp->dumpString(); - } + case RtcpType::RTCP_RTPFB: + case RtcpType::RTCP_PSFB: { + RtcpFB *rtcp = (RtcpFB *)this; + return rtcp->dumpString(); + } - case RtcpType::RTCP_BYE: { - RtcpBye *rtcp = (RtcpBye *) this; - return rtcp->dumpString(); - } + case RtcpType::RTCP_BYE: { + RtcpBye *rtcp = (RtcpBye *)this; + return rtcp->dumpString(); + } - default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), getSize() - sizeof(*this)); + default: + return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), getSize() - sizeof(*this)); } } size_t RtcpHeader::getSize() const { - //加上rtcp头长度 + // 加上rtcp头长度 return (1 + ntohs(length)) << 2; } -size_t RtcpHeader::getPaddingSize() const{ +size_t RtcpHeader::getPaddingSize() const { if (!padding) { return 0; } - return ((uint8_t *) this)[getSize() - 1]; + return ((uint8_t *)this)[getSize() - 1]; } void RtcpHeader::setSize(size_t size) { - //不包含rtcp头的长度 - length = htons((uint16_t) ((size >> 2) - 1)); + // 不包含rtcp头的长度 + length = htons((uint16_t)((size >> 2) - 1)); } void RtcpHeader::net2Host(size_t len) { - switch ((RtcpType) pt) { - case RtcpType::RTCP_SR: { - RtcpSR *sr = (RtcpSR *) this; - sr->net2Host(len); - break; - } + switch ((RtcpType)pt) { + case RtcpType::RTCP_SR: { + RtcpSR *sr = (RtcpSR *)this; + sr->net2Host(len); + break; + } - case RtcpType::RTCP_RR: { - RtcpRR *rr = (RtcpRR *) this; - rr->net2Host(len); - break; - } + case RtcpType::RTCP_RR: { + RtcpRR *rr = (RtcpRR *)this; + rr->net2Host(len); + break; + } - case RtcpType::RTCP_SDES: { - RtcpSdes *sdes = (RtcpSdes *) this; - sdes->net2Host(len); - break; - } + case RtcpType::RTCP_SDES: { + RtcpSdes *sdes = (RtcpSdes *)this; + sdes->net2Host(len); + break; + } - case RtcpType::RTCP_RTPFB: - case RtcpType::RTCP_PSFB: { - RtcpFB *fb = (RtcpFB *) this; - fb->net2Host(len); - break; - } + case RtcpType::RTCP_RTPFB: + case RtcpType::RTCP_PSFB: { + RtcpFB *fb = (RtcpFB *)this; + fb->net2Host(len); + break; + } - case RtcpType::RTCP_BYE: { - RtcpBye *bye = (RtcpBye *) this; - bye->net2Host(len); - break; + case RtcpType::RTCP_BYE: { + RtcpBye *bye = (RtcpBye *)this; + bye->net2Host(len); + break; + } + case RtcpType::RTCP_XR: { + RtcpXRRRTR *xr = (RtcpXRRRTR *)this; + if (xr->bt == 4) { + xr->net2Host(len); + // TraceL<dumpString(); + } else if (xr->bt == 5) { + RtcpXRDLRR *dlrr = (RtcpXRDLRR *)this; + dlrr->net2Host(len); + TraceL << dlrr->dumpString(); + } else { + throw std::runtime_error(StrPrinter << "rtcp xr bt " << xr->bt << " not support"); } - case RtcpType::RTCP_XR:{ - RtcpXRRRTR* xr = (RtcpXRRRTR*)this; - if(xr->bt == 4){ - xr->net2Host(len); - //TraceL<dumpString(); - }else if(xr->bt == 5){ - RtcpXRDLRR* dlrr = (RtcpXRDLRR*)this; - dlrr->net2Host(len); - TraceL<dumpString(); - }else{ - throw std::runtime_error(StrPrinter << "rtcp xr bt " << xr->bt<<" not support"); - } - break; - } - default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt)); + break; + } + default: + throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType)this->pt)); } } @@ -215,10 +229,10 @@ vector RtcpHeader::loadFromBytes(char *data, size_t len) { vector ret; ssize_t remain = len; char *ptr = data; - while (remain > (ssize_t) sizeof(RtcpHeader)) { - RtcpHeader *rtcp = (RtcpHeader *) ptr; + while (remain > (ssize_t)sizeof(RtcpHeader)) { + RtcpHeader *rtcp = (RtcpHeader *)ptr; auto rtcp_len = rtcp->getSize(); - if (remain < (ssize_t) rtcp_len) { + if (remain < (ssize_t)rtcp_len) { WarnL << "非法的rtcp包,声明的长度超过实际数据长度"; break; } @@ -226,7 +240,7 @@ vector RtcpHeader::loadFromBytes(char *data, size_t len) { rtcp->net2Host(rtcp_len); ret.emplace_back(rtcp); } catch (std::exception &ex) { - //不能处理的rtcp包,或者无法解析的rtcp包,忽略掉 + // 不能处理的rtcp包,或者无法解析的rtcp包,忽略掉 WarnL << ex.what() << ",长度为:" << rtcp_len; } ptr += rtcp_len; @@ -237,19 +251,13 @@ vector RtcpHeader::loadFromBytes(char *data, size_t len) { class BufferRtcp : public Buffer { public: - BufferRtcp(std::shared_ptr rtcp) { - _rtcp = std::move(rtcp); - } + BufferRtcp(std::shared_ptr rtcp) { _rtcp = std::move(rtcp); } ~BufferRtcp() override {} - char *data() const override { - return (char *) _rtcp.get(); - } + char *data() const override { return (char *)_rtcp.get(); } - size_t size() const override { - return _rtcp->getSize(); - } + size_t size() const override { return _rtcp->getSize(); } private: std::shared_ptr _rtcp; @@ -264,36 +272,34 @@ Buffer::Ptr RtcpHeader::toBuffer(std::shared_ptr rtcp) { std::shared_ptr RtcpSR::create(size_t item_count) { auto real_size = sizeof(RtcpSR) - sizeof(ReportItem) + item_count * sizeof(ReportItem); auto bytes = alignSize(real_size); - auto ptr = (RtcpSR *) new char[bytes]; + auto ptr = (RtcpSR *)new char[bytes]; setupHeader(ptr, RtcpType::RTCP_SR, item_count, bytes); setupPadding(ptr, bytes - real_size); - return std::shared_ptr(ptr, [](RtcpSR *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr(ptr, [](RtcpSR *ptr) { delete[] (char *)ptr; }); } string RtcpSR::getNtpStamp() const { struct timeval tv; tv.tv_sec = ntpmsw - 0x83AA7E80; - tv.tv_usec = (decltype(tv.tv_usec)) (ntplsw / ((double) (((uint64_t) 1) << 32) * 1.0e-6)); + tv.tv_usec = (decltype(tv.tv_usec))(ntplsw / ((double)(((uint64_t)1) << 32) * 1.0e-6)); return LogChannel::printTime(tv); } uint64_t RtcpSR::getNtpUnixStampMS() const { if (ntpmsw < 0x83AA7E80) { - //ntp时间戳起始时间为1900年,但是utc时间戳起始时间为1970年,两者相差0x83AA7E80秒 - //ntp时间戳不得早于1970年,否则无法转换为utc时间戳 + // ntp时间戳起始时间为1900年,但是utc时间戳起始时间为1970年,两者相差0x83AA7E80秒 + // ntp时间戳不得早于1970年,否则无法转换为utc时间戳 return 0; } struct timeval tv; tv.tv_sec = ntpmsw - 0x83AA7E80; - tv.tv_usec = (decltype(tv.tv_usec)) (ntplsw / ((double) (((uint64_t) 1) << 32) * 1.0e-6)); + tv.tv_usec = (decltype(tv.tv_usec))(ntplsw / ((double)(((uint64_t)1) << 32) * 1.0e-6)); return 1000 * tv.tv_sec + tv.tv_usec / 1000; } void RtcpSR::setNtpStamp(struct timeval tv) { ntpmsw = htonl(tv.tv_sec + 0x83AA7E80); /* 0x83AA7E80 is the number of seconds from 1900 to 1970 */ - ntplsw = htonl((uint32_t) ((double) tv.tv_usec * (double) (((uint64_t) 1) << 32) * 1.0e-6)); + ntplsw = htonl((uint32_t)((double)tv.tv_usec * (double)(((uint64_t)1) << 32) * 1.0e-6)); } void RtcpSR::setNtpStamp(uint64_t unix_stamp_ms) { @@ -313,7 +319,7 @@ string RtcpSR::dumpString() const { printer << "rtpts:" << rtpts << "\r\n"; printer << "packet_count:" << packet_count << "\r\n"; printer << "octet_count:" << octet_count << "\r\n"; - auto items = ((RtcpSR *) this)->getItemList(); + auto items = ((RtcpSR *)this)->getItemList(); auto i = 0; for (auto &item : items) { printer << "---- item:" << i++ << " ----\r\n"; @@ -322,17 +328,19 @@ string RtcpSR::dumpString() const { return std::move(printer); } -#define CHECK_MIN_SIZE(size, kMinSize) \ -if (size < kMinSize) { \ - throw std::out_of_range(StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \ -} +#define CHECK_MIN_SIZE(size, kMinSize) \ + if (size < kMinSize) { \ + throw std::out_of_range( \ + StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \ + } -#define CHECK_REPORT_COUNT(item_count) \ -/*修正个数,防止getItemList时内存越界*/ \ -if (report_count != item_count) { \ - WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " << item_count; \ - report_count = item_count; \ -} +#define CHECK_REPORT_COUNT(item_count) \ + /*修正个数,防止getItemList时内存越界*/ \ + if (report_count != item_count) { \ + WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " \ + << item_count; \ + report_count = item_count; \ + } void RtcpSR::net2Host(size_t size) { static const size_t kMinSize = sizeof(RtcpSR) - sizeof(items); @@ -347,7 +355,7 @@ void RtcpSR::net2Host(size_t size) { ReportItem *ptr = &items; int item_count = 0; - for (int i = 0; i < (int) report_count && (char *) (ptr) + sizeof(ReportItem) <= (char *) (this) + size; ++i) { + for (int i = 0; i < (int)report_count && (char *)(ptr) + sizeof(ReportItem) <= (char *)(this) + size; ++i) { ptr->net2Host(); ++ptr; ++item_count; @@ -358,7 +366,7 @@ void RtcpSR::net2Host(size_t size) { vector RtcpSR::getItemList() { vector ret; ReportItem *ptr = &items; - for (int i = 0; i < (int) report_count; ++i) { + for (int i = 0; i < (int)report_count; ++i) { ret.emplace_back(ptr); ++ptr; } @@ -395,19 +403,17 @@ void ReportItem::net2Host() { std::shared_ptr RtcpRR::create(size_t item_count) { auto real_size = sizeof(RtcpRR) - sizeof(ReportItem) + item_count * sizeof(ReportItem); auto bytes = alignSize(real_size); - auto ptr = (RtcpRR *) new char[bytes]; + auto ptr = (RtcpRR *)new char[bytes]; setupHeader(ptr, RtcpType::RTCP_RR, item_count, bytes); setupPadding(ptr, bytes - real_size); - return std::shared_ptr(ptr, [](RtcpRR *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr(ptr, [](RtcpRR *ptr) { delete[] (char *)ptr; }); } string RtcpRR::dumpString() const { _StrPrinter printer; printer << RtcpHeader::dumpHeader(); printer << "ssrc:" << ssrc << "\r\n"; - auto items = ((RtcpRR *) this)->getItemList(); + auto items = ((RtcpRR *)this)->getItemList(); auto i = 0; for (auto &item : items) { printer << "---- item:" << i++ << " ----\r\n"; @@ -423,7 +429,7 @@ void RtcpRR::net2Host(size_t size) { ReportItem *ptr = &items; int item_count = 0; - for (int i = 0; i < (int) report_count && (char *) (ptr) + sizeof(ReportItem) <= (char *) (this) + size; ++i) { + for (int i = 0; i < (int)report_count && (char *)(ptr) + sizeof(ReportItem) <= (char *)(this) + size; ++i) { ptr->net2Host(); ++ptr; ++item_count; @@ -434,7 +440,7 @@ void RtcpRR::net2Host(size_t size) { vector RtcpRR::getItemList() { vector ret; ReportItem *ptr = &items; - for (int i = 0; i < (int) report_count; ++i) { + for (int i = 0; i < (int)report_count; ++i) { ret.emplace_back(ptr); ++ptr; } @@ -458,8 +464,8 @@ size_t SdesChunk::minSize() { string SdesChunk::dumpString() const { _StrPrinter printer; printer << "ssrc:" << ssrc << "\r\n"; - printer << "type:" << sdesTypeToStr((SdesType) type) << "\r\n"; - printer << "txt_len:" << (int) txt_len << "\r\n"; + printer << "type:" << sdesTypeToStr((SdesType)type) << "\r\n"; + printer << "txt_len:" << (int)txt_len << "\r\n"; printer << "text:" << (txt_len ? string(text, txt_len) : "") << "\r\n"; return std::move(printer); } @@ -469,32 +475,30 @@ string SdesChunk::dumpString() const { std::shared_ptr RtcpSdes::create(const std::vector &item_text) { size_t item_total_size = 0; for (auto &text : item_text) { - //统计所有SdesChunk对象占用的空间 + // 统计所有SdesChunk对象占用的空间 item_total_size += alignSize(SdesChunk::minSize() + (0xFF & text.size())); } auto real_size = sizeof(RtcpSdes) - sizeof(SdesChunk) + item_total_size; auto bytes = alignSize(real_size); - auto ptr = (RtcpSdes *) new char[bytes]; + auto ptr = (RtcpSdes *)new char[bytes]; memset(ptr, 0x00, bytes); auto item_ptr = &ptr->chunks; for (auto &text : item_text) { item_ptr->txt_len = (0xFF & text.size()); - //确保赋值\0为RTCP_SDES_END + // 确保赋值\0为RTCP_SDES_END memcpy(item_ptr->text, text.data(), item_ptr->txt_len + 1); - item_ptr = (SdesChunk *) ((char *) item_ptr + item_ptr->totalBytes()); + item_ptr = (SdesChunk *)((char *)item_ptr + item_ptr->totalBytes()); } setupHeader(ptr, RtcpType::RTCP_SDES, item_text.size(), bytes); setupPadding(ptr, bytes - real_size); - return std::shared_ptr(ptr, [](RtcpSdes *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr(ptr, [](RtcpSdes *ptr) { delete[] (char *)ptr; }); } string RtcpSdes::dumpString() const { _StrPrinter printer; printer << RtcpHeader::dumpHeader(); - auto items = ((RtcpSdes *) this)->getChunkList(); + auto items = ((RtcpSdes *)this)->getChunkList(); auto i = 0; for (auto &item : items) { printer << "---- item:" << i++ << " ----\r\n"; @@ -508,9 +512,9 @@ void RtcpSdes::net2Host(size_t size) { CHECK_MIN_SIZE(size, kMinSize); SdesChunk *ptr = &chunks; int item_count = 0; - for (int i = 0; i < (int) report_count && (char *) (ptr) + SdesChunk::minSize() <= (char *) (this) + size; ++i) { + for (int i = 0; i < (int)report_count && (char *)(ptr) + SdesChunk::minSize() <= (char *)(this) + size; ++i) { ptr->net2Host(); - ptr = (SdesChunk *) ((char *) ptr + ptr->totalBytes()); + ptr = (SdesChunk *)((char *)ptr + ptr->totalBytes()); ++item_count; } CHECK_REPORT_COUNT(item_count); @@ -519,9 +523,9 @@ void RtcpSdes::net2Host(size_t size) { vector RtcpSdes::getChunkList() { vector ret; SdesChunk *ptr = &chunks; - for (int i = 0; i < (int) report_count; ++i) { + for (int i = 0; i < (int)report_count; ++i) { ret.emplace_back(ptr); - ptr = (SdesChunk *) ((char *) ptr + ptr->totalBytes()); + ptr = (SdesChunk *)((char *)ptr + ptr->totalBytes()); } return ret; } @@ -534,31 +538,29 @@ std::shared_ptr RtcpFB::create_l(RtcpType type, int fmt, const void *fci } auto real_size = sizeof(RtcpFB) + fci_len; auto bytes = alignSize(real_size); - auto ptr = (RtcpFB *) new char[bytes]; + auto ptr = (RtcpFB *)new char[bytes]; if (fci && fci_len) { - memcpy((char *) ptr + sizeof(RtcpFB), fci, fci_len); + memcpy((char *)ptr + sizeof(RtcpFB), fci, fci_len); } setupHeader(ptr, type, fmt, bytes); setupPadding(ptr, bytes - real_size); - return std::shared_ptr((RtcpFB *) ptr, [](RtcpFB *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr((RtcpFB *)ptr, [](RtcpFB *ptr) { delete[] (char *)ptr; }); } std::shared_ptr RtcpFB::create(PSFBType fmt, const void *fci, size_t fci_len) { - return RtcpFB::create_l(RtcpType::RTCP_PSFB, (int) fmt, fci, fci_len); + return RtcpFB::create_l(RtcpType::RTCP_PSFB, (int)fmt, fci, fci_len); } std::shared_ptr RtcpFB::create(RTPFBType fmt, const void *fci, size_t fci_len) { - return RtcpFB::create_l(RtcpType::RTCP_RTPFB, (int) fmt, fci, fci_len); + return RtcpFB::create_l(RtcpType::RTCP_RTPFB, (int)fmt, fci, fci_len); } const void *RtcpFB::getFciPtr() const { - return (uint8_t *) &ssrc_media + sizeof(ssrc_media); + return (uint8_t *)&ssrc_media + sizeof(ssrc_media); } size_t RtcpFB::getFciSize() const { - auto fci_len = (ssize_t) getSize() - getPaddingSize() - sizeof(RtcpFB); + auto fci_len = (ssize_t)getSize() - getPaddingSize() - sizeof(RtcpFB); CHECK(fci_len >= 0); return fci_len; } @@ -568,58 +570,60 @@ string RtcpFB::dumpString() const { printer << RtcpHeader::dumpHeader(); printer << "ssrc:" << ssrc << "\r\n"; printer << "ssrc_media:" << ssrc_media << "\r\n"; - switch ((RtcpType) pt) { - case RtcpType::RTCP_PSFB : { - switch ((PSFBType) report_count) { - case PSFBType::RTCP_PSFB_SLI : { - auto &fci = getFci(); - printer << "fci:" << psfbTypeToStr((PSFBType) report_count) << " " << fci.dumpString(); - break; - } - case PSFBType::RTCP_PSFB_PLI : { - getFciSize(); - printer << "fci:" << psfbTypeToStr((PSFBType) report_count); - break; - } - - case PSFBType::RTCP_PSFB_FIR : { - auto &fci = getFci(); - printer << "fci:" << psfbTypeToStr((PSFBType) report_count) << " " << fci.dumpString(); - break; - } - - case PSFBType::RTCP_PSFB_REMB : { - auto &fci = getFci(); - printer << "fci:" << psfbTypeToStr((PSFBType) report_count) << " " << fci.dumpString(); - break; - } - default:{ - printer << "fci:" << psfbTypeToStr((PSFBType) report_count) << " " << hexdump(getFciPtr(), getFciSize()); - break; - } - } + switch ((RtcpType)pt) { + case RtcpType::RTCP_PSFB: { + switch ((PSFBType)report_count) { + case PSFBType::RTCP_PSFB_SLI: { + auto &fci = getFci(); + printer << "fci:" << psfbTypeToStr((PSFBType)report_count) << " " << fci.dumpString(); break; } - case RtcpType::RTCP_RTPFB : { - switch ((RTPFBType) report_count) { - case RTPFBType::RTCP_RTPFB_NACK : { - auto &fci = getFci(); - printer << "fci:" << rtpfbTypeToStr((RTPFBType) report_count) << " " << fci.dumpString(); - break; - } - case RTPFBType::RTCP_RTPFB_TWCC : { - auto &fci = getFci(); - printer << "fci:" << rtpfbTypeToStr((RTPFBType) report_count) << " " << fci.dumpString(getFciSize()); - break; - } - default: { - printer << "fci:" << rtpfbTypeToStr((RTPFBType) report_count) << " " << hexdump(getFciPtr(), getFciSize()); - break; - } - } + case PSFBType::RTCP_PSFB_PLI: { + getFciSize(); + printer << "fci:" << psfbTypeToStr((PSFBType)report_count); break; } - default: /*不可达*/ assert(0); break; + + case PSFBType::RTCP_PSFB_FIR: { + auto &fci = getFci(); + printer << "fci:" << psfbTypeToStr((PSFBType)report_count) << " " << fci.dumpString(); + break; + } + + case PSFBType::RTCP_PSFB_REMB: { + auto &fci = getFci(); + printer << "fci:" << psfbTypeToStr((PSFBType)report_count) << " " << fci.dumpString(); + break; + } + default: { + printer << "fci:" << psfbTypeToStr((PSFBType)report_count) << " " << hexdump(getFciPtr(), getFciSize()); + break; + } + } + break; + } + case RtcpType::RTCP_RTPFB: { + switch ((RTPFBType)report_count) { + case RTPFBType::RTCP_RTPFB_NACK: { + auto &fci = getFci(); + printer << "fci:" << rtpfbTypeToStr((RTPFBType)report_count) << " " << fci.dumpString(); + break; + } + case RTPFBType::RTCP_RTPFB_TWCC: { + auto &fci = getFci(); + printer << "fci:" << rtpfbTypeToStr((RTPFBType)report_count) << " " << fci.dumpString(getFciSize()); + break; + } + default: { + printer << "fci:" << rtpfbTypeToStr((RTPFBType)report_count) << " " << hexdump(getFciPtr(), getFciSize()); + break; + } + } + break; + } + default: /*不可达*/ + assert(0); + break; } return std::move(printer); } @@ -637,24 +641,22 @@ std::shared_ptr RtcpBye::create(const std::vector &ssrcs, con assert(reason.size() <= 0xFF); auto real_size = sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size(); auto bytes = alignSize(real_size); - auto ptr = (RtcpBye *) new char[bytes]; + auto ptr = (RtcpBye *)new char[bytes]; setupHeader(ptr, RtcpType::RTCP_BYE, ssrcs.size(), bytes); setupPadding(ptr, bytes - real_size); int i = 0; for (auto ssrc : ssrcs) { - ((RtcpBye *) ptr)->ssrc[i++] = htonl(ssrc); + ((RtcpBye *)ptr)->ssrc[i++] = htonl(ssrc); } if (!reason.empty()) { - uint8_t *reason_len_ptr = (uint8_t *) ptr + sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size(); + uint8_t *reason_len_ptr = (uint8_t *)ptr + sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size(); *reason_len_ptr = reason.size() & 0xFF; memcpy(reason_len_ptr + 1, reason.data(), *reason_len_ptr); } - return std::shared_ptr(ptr, [](RtcpBye *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr(ptr, [](RtcpBye *ptr) { delete[] (char *)ptr; }); } vector RtcpBye::getSSRC() { @@ -667,16 +669,16 @@ vector RtcpBye::getSSRC() { string RtcpBye::getReason() const { auto *reason_len_ptr = &reason_len + sizeof(ssrc) * (report_count - 1); - if (reason_len_ptr + 1 >= (uint8_t *) this + getSize()) { + if (reason_len_ptr + 1 >= (uint8_t *)this + getSize()) { return ""; } - return string((char *) reason_len_ptr + 1, *reason_len_ptr); + return string((char *)reason_len_ptr + 1, *reason_len_ptr); } string RtcpBye::dumpString() const { _StrPrinter printer; printer << RtcpHeader::dumpHeader(); - for (auto ssrc : ((RtcpBye *) this)->getSSRC()) { + for (auto ssrc : ((RtcpBye *)this)->getSSRC()) { printer << "ssrc:" << *ssrc << "\r\n"; } printer << "reason:" << getReason(); @@ -692,35 +694,37 @@ void RtcpBye::net2Host(size_t size) { ssrc[i] = ntohl(ssrc[i]); offset += sizeof(ssrc); } - //修正ssrc个数 + // 修正ssrc个数 CHECK_REPORT_COUNT(i); if (offset < size) { uint8_t *reason_len_ptr = &reason_len + sizeof(ssrc) * (report_count - 1); - if (reason_len_ptr + 1 + *reason_len_ptr > (uint8_t *) this + size) { + if (reason_len_ptr + 1 + *reason_len_ptr > (uint8_t *)this + size) { WarnL << "invalid rtcp bye reason length"; - //修正reason_len长度 - *reason_len_ptr = ((uint8_t *) this + size - reason_len_ptr - 1) & 0xFF; + // 修正reason_len长度 + *reason_len_ptr = ((uint8_t *)this + size - reason_len_ptr - 1) & 0xFF; } } } -//////////////////////////////////////////// +//////////////////////////////////////////// string RtcpXRRRTR::dumpString() const { _StrPrinter printer; printer << RtcpHeader::dumpHeader(); - printer << "ssrc :" < RtcpXRDLRR::getItemList(){ - auto count = block_length/3; +std::vector RtcpXRDLRR::getItemList() { + auto count = block_length / 3; RtcpXRDLRRReportItem *ptr = &items; vector ret; - for (int i = 0; i < (int) count; ++i) { + for (int i = 0; i < (int)count; ++i) { ret.emplace_back(ptr); ++ptr; } return ret; - } string RtcpXRDLRR::dumpString() const { _StrPrinter printer; printer << RtcpHeader::dumpHeader(); - printer << "ssrc :" <getItemList(); + printer << "ssrc :" << ssrc << "\r\n"; + printer << "bt :" << (int)bt << "\r\n"; + printer << "block_length : " << block_length << "\r\n"; + auto items_list = ((RtcpXRDLRR *)this)->getItemList(); auto i = 0; for (auto &item : items_list) { printer << "---- item:" << i++ << " ----\r\n"; @@ -778,23 +780,21 @@ void RtcpXRDLRR::net2Host(size_t size) { ssrc = ntohl(ssrc); block_length = ntohs(block_length); - auto count = block_length/3; - for (int i = 0; i < (int) count; ++i) { + auto count = block_length / 3; + for (int i = 0; i < (int)count; ++i) { RtcpXRDLRRReportItem *ptr = &items; ptr->net2Host(); ptr++; } } -std::shared_ptr RtcpXRDLRR::create(size_t item_count){ +std::shared_ptr RtcpXRDLRR::create(size_t item_count) { auto real_size = sizeof(RtcpXRDLRR) - sizeof(RtcpXRDLRRReportItem) + item_count * sizeof(RtcpXRDLRRReportItem); auto bytes = alignSize(real_size); - auto ptr = (RtcpXRDLRR *) new char[bytes]; + auto ptr = (RtcpXRDLRR *)new char[bytes]; setupHeader(ptr, RtcpType::RTCP_XR, 0, bytes); setupPadding(ptr, bytes - real_size); - return std::shared_ptr(ptr, [](RtcpXRDLRR *ptr) { - delete[] (char *) ptr; - }); + return std::shared_ptr(ptr, [](RtcpXRDLRR *ptr) { delete[] (char *)ptr; }); } #if 0 @@ -811,4 +811,4 @@ static toolkit::onceToken token([](){ }); #endif -}//namespace mediakit \ No newline at end of file +} // namespace mediakit \ No newline at end of file diff --git a/src/Rtcp/Rtcp.h b/src/Rtcp/Rtcp.h index 223b9c59..9275506c 100644 --- a/src/Rtcp/Rtcp.h +++ b/src/Rtcp/Rtcp.h @@ -11,11 +11,11 @@ #ifndef ZLMEDIAKIT_RTCP_H #define ZLMEDIAKIT_RTCP_H +#include "Common/macros.h" +#include "Network/Buffer.h" +#include "Util/util.h" #include #include -#include "Util/util.h" -#include "Network/Buffer.h" -#include "Common/macros.h" namespace mediakit { @@ -23,115 +23,115 @@ namespace mediakit { #pragma pack(push, 1) #endif // defined(_WIN32) -//http://www.networksorcery.com/enp/protocol/rtcp.htm -#define RTCP_PT_MAP(XX) \ - XX(RTCP_FIR, 192) \ - XX(RTCP_NACK, 193) \ - XX(RTCP_SMPTETC, 194) \ - XX(RTCP_IJ, 195) \ - XX(RTCP_SR, 200) \ - XX(RTCP_RR, 201) \ - XX(RTCP_SDES, 202) \ - XX(RTCP_BYE, 203) \ - XX(RTCP_APP, 204) \ - XX(RTCP_RTPFB, 205) \ - XX(RTCP_PSFB, 206) \ - XX(RTCP_XR, 207) \ - XX(RTCP_AVB, 208) \ - XX(RTCP_RSI, 209) \ - XX(RTCP_TOKEN, 210) +// http://www.networksorcery.com/enp/protocol/rtcp.htm +#define RTCP_PT_MAP(XX) \ + XX(RTCP_FIR, 192) \ + XX(RTCP_NACK, 193) \ + XX(RTCP_SMPTETC, 194) \ + XX(RTCP_IJ, 195) \ + XX(RTCP_SR, 200) \ + XX(RTCP_RR, 201) \ + XX(RTCP_SDES, 202) \ + XX(RTCP_BYE, 203) \ + XX(RTCP_APP, 204) \ + XX(RTCP_RTPFB, 205) \ + XX(RTCP_PSFB, 206) \ + XX(RTCP_XR, 207) \ + XX(RTCP_AVB, 208) \ + XX(RTCP_RSI, 209) \ + XX(RTCP_TOKEN, 210) -//https://tools.ietf.org/html/rfc3550#section-6.5 -#define SDES_TYPE_MAP(XX) \ - XX(RTCP_SDES_END, 0) \ - XX(RTCP_SDES_CNAME, 1) \ - XX(RTCP_SDES_NAME, 2) \ - XX(RTCP_SDES_EMAIL, 3) \ - XX(RTCP_SDES_PHONE, 4) \ - XX(RTCP_SDES_LOC, 5) \ - XX(RTCP_SDES_TOOL, 6) \ - XX(RTCP_SDES_NOTE, 7) \ - XX(RTCP_SDES_PRIVATE, 8) +// https://tools.ietf.org/html/rfc3550#section-6.5 +#define SDES_TYPE_MAP(XX) \ + XX(RTCP_SDES_END, 0) \ + XX(RTCP_SDES_CNAME, 1) \ + XX(RTCP_SDES_NAME, 2) \ + XX(RTCP_SDES_EMAIL, 3) \ + XX(RTCP_SDES_PHONE, 4) \ + XX(RTCP_SDES_LOC, 5) \ + XX(RTCP_SDES_TOOL, 6) \ + XX(RTCP_SDES_NOTE, 7) \ + XX(RTCP_SDES_PRIVATE, 8) -//https://datatracker.ietf.org/doc/rfc4585/?include_text=1 -//6.3. Payload-Specific Feedback Messages +// https://datatracker.ietf.org/doc/rfc4585/?include_text=1 +// 6.3. Payload-Specific Feedback Messages // -// Payload-Specific FB messages are identified by the value PT=PSFB as -// RTCP message type. +// Payload-Specific FB messages are identified by the value PT=PSFB as +// RTCP message type. // -// Three payload-specific FB messages are defined so far plus an -// application layer FB message. They are identified by means of the -// FMT parameter as follows: +// Three payload-specific FB messages are defined so far plus an +// application layer FB message. They are identified by means of the +// FMT parameter as follows: // -// 0: unassigned -// 1: Picture Loss Indication (PLI) -// 2: Slice Loss Indication (SLI) -// 3: Reference Picture Selection Indication (RPSI) -// 4: FIR https://tools.ietf.org/html/rfc5104#section-4.3.1.1 -// 5: TSTR https://tools.ietf.org/html/rfc5104#section-4.3.2.1 -// 6: TSTN https://tools.ietf.org/html/rfc5104#section-4.3.2.1 -// 7: VBCM https://tools.ietf.org/html/rfc5104#section-4.3.4.1 -// 8-14: unassigned -// 15: REMB / Application layer FB (AFB) message, https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03 -// 16-30: unassigned -// 31: reserved for future expansion of the sequence number space -#define PSFB_TYPE_MAP(XX) \ - XX(RTCP_PSFB_PLI, 1) \ - XX(RTCP_PSFB_SLI, 2) \ - XX(RTCP_PSFB_RPSI, 3) \ - XX(RTCP_PSFB_FIR, 4) \ - XX(RTCP_PSFB_TSTR, 5)\ - XX(RTCP_PSFB_TSTN, 6)\ - XX(RTCP_PSFB_VBCM, 7) \ - XX(RTCP_PSFB_REMB, 15) +// 0: unassigned +// 1: Picture Loss Indication (PLI) +// 2: Slice Loss Indication (SLI) +// 3: Reference Picture Selection Indication (RPSI) +// 4: FIR https://tools.ietf.org/html/rfc5104#section-4.3.1.1 +// 5: TSTR https://tools.ietf.org/html/rfc5104#section-4.3.2.1 +// 6: TSTN https://tools.ietf.org/html/rfc5104#section-4.3.2.1 +// 7: VBCM https://tools.ietf.org/html/rfc5104#section-4.3.4.1 +// 8-14: unassigned +// 15: REMB / Application layer FB (AFB) message, https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03 +// 16-30: unassigned +// 31: reserved for future expansion of the sequence number space +#define PSFB_TYPE_MAP(XX) \ + XX(RTCP_PSFB_PLI, 1) \ + XX(RTCP_PSFB_SLI, 2) \ + XX(RTCP_PSFB_RPSI, 3) \ + XX(RTCP_PSFB_FIR, 4) \ + XX(RTCP_PSFB_TSTR, 5) \ + XX(RTCP_PSFB_TSTN, 6) \ + XX(RTCP_PSFB_VBCM, 7) \ + XX(RTCP_PSFB_REMB, 15) -//https://tools.ietf.org/html/rfc4585#section-6.2 -//6.2. Transport Layer Feedback Messages +// https://tools.ietf.org/html/rfc4585#section-6.2 +// 6.2. Transport Layer Feedback Messages // -// Transport layer FB messages are identified by the value RTPFB as RTCP -// message type. +// Transport layer FB messages are identified by the value RTPFB as RTCP +// message type. // -// A single general purpose transport layer FB message is defined in -// this document: Generic NACK. It is identified by means of the FMT -// parameter as follows: +// A single general purpose transport layer FB message is defined in +// this document: Generic NACK. It is identified by means of the FMT +// parameter as follows: // -// 0: unassigned -// 1: Generic NACK -// 2: reserved https://tools.ietf.org/html/rfc5104#section-4.2 -// 3: TMMBR https://tools.ietf.org/html/rfc5104#section-4.2.1.1 -// 4: TMMBN https://tools.ietf.org/html/rfc5104#section-4.2.2.1 -// 5-14: unassigned -// 15 transport-cc https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01 -// 16-30: unassigned -// 31: reserved for future expansion of the identifier number space -#define RTPFB_TYPE_MAP(XX) \ - XX(RTCP_RTPFB_NACK, 1) \ - XX(RTCP_RTPFB_TMMBR, 3) \ - XX(RTCP_RTPFB_TMMBN, 4) \ - XX(RTCP_RTPFB_TWCC, 15) +// 0: unassigned +// 1: Generic NACK +// 2: reserved https://tools.ietf.org/html/rfc5104#section-4.2 +// 3: TMMBR https://tools.ietf.org/html/rfc5104#section-4.2.1.1 +// 4: TMMBN https://tools.ietf.org/html/rfc5104#section-4.2.2.1 +// 5-14: unassigned +// 15 transport-cc https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01 +// 16-30: unassigned +// 31: reserved for future expansion of the identifier number space +#define RTPFB_TYPE_MAP(XX) \ + XX(RTCP_RTPFB_NACK, 1) \ + XX(RTCP_RTPFB_TMMBR, 3) \ + XX(RTCP_RTPFB_TMMBN, 4) \ + XX(RTCP_RTPFB_TWCC, 15) -//rtcp类型枚举 +// rtcp类型枚举 enum class RtcpType : uint8_t { #define XX(key, value) key = value, RTCP_PT_MAP(XX) #undef XX }; -//sdes类型枚举 +// sdes类型枚举 enum class SdesType : uint8_t { #define XX(key, value) key = value, SDES_TYPE_MAP(XX) #undef XX }; -//psfb类型枚举 +// psfb类型枚举 enum class PSFBType : uint8_t { #define XX(key, value) key = value, PSFB_TYPE_MAP(XX) #undef XX }; -//rtpfb类型枚举 +// rtpfb类型枚举 enum class RTPFBType : uint8_t { #define XX(key, value) key = value, RTPFB_TYPE_MAP(XX) @@ -161,26 +161,26 @@ const char *rtpfbTypeToStr(RTPFBType type); class RtcpHeader { public: #if __BYTE_ORDER == __BIG_ENDIAN - //版本号,固定为2 - uint32_t version: 2; - //padding,固定为0 - uint32_t padding: 1; - //reception report count - uint32_t report_count: 5; + // 版本号,固定为2 + uint32_t version : 2; + // padding,固定为0 + uint32_t padding : 1; + // reception report count + uint32_t report_count : 5; #else - //reception report count - uint32_t report_count: 5; - //padding,末尾是否有追加填充 - uint32_t padding: 1; - //版本号,固定为2 - uint32_t version: 2; + // reception report count + uint32_t report_count : 5; + // padding,末尾是否有追加填充 + uint32_t padding : 1; + // 版本号,固定为2 + uint32_t version : 2; #endif - //rtcp类型,RtcpType - uint32_t pt: 8; + // rtcp类型,RtcpType + uint32_t pt : 8; private: - //长度 - uint32_t length: 16; + // 长度 + uint32_t length : 16; public: /** @@ -222,7 +222,6 @@ public: void setSize(size_t size); protected: - /** * 打印字段详情 * 使用net2Host转换成主机字节序后才可使用此函数 @@ -240,26 +239,26 @@ private: ///////////////////////////////////////////////////////////////////////////// -//ReportBlock +// ReportBlock class ReportItem { public: friend class RtcpSR; friend class RtcpRR; uint32_t ssrc; - //Fraction lost - uint32_t fraction: 8; - //Cumulative number of packets lost - uint32_t cumulative: 24; - //Sequence number cycles count + // Fraction lost + uint32_t fraction : 8; + // Cumulative number of packets lost + uint32_t cumulative : 24; + // Sequence number cycles count uint16_t seq_cycles; - //Highest sequence number received + // Highest sequence number received uint16_t seq_max; - //Interarrival jitter + // Interarrival jitter uint32_t jitter; - //Last SR timestamp, NTP timestamp,(ntpmsw & 0xFFFF) << 16 | (ntplsw >> 16) & 0xFFFF) + // Last SR timestamp, NTP timestamp,(ntpmsw & 0xFFFF) << 16 | (ntplsw >> 16) & 0xFFFF) uint32_t last_sr_stamp; - //Delay since last SR timestamp,expressed in units of 1/65536 seconds + // Delay since last SR timestamp,expressed in units of 1/65536 seconds uint32_t delay_since_last_sr; private: @@ -273,7 +272,7 @@ private: * 网络字节序转换为主机字节序 */ void net2Host(); -}PACKED; +} PACKED; /* * 6.4.1 SR: Sender Report RTCP Packet @@ -329,7 +328,7 @@ public: uint32_t packet_count; // sender octet count uint32_t octet_count; - //可能有很多个 + // 可能有很多个 ReportItem items; public: @@ -358,13 +357,13 @@ public: * 获取ReportItem对象指针列表 * 使用net2Host转换成主机字节序后才可使用此函数 */ - std::vector getItemList(); + std::vector getItemList(); private: /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -406,13 +405,13 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -//Receiver Report +// Receiver Report class RtcpRR : public RtcpHeader { public: friend class RtcpHeader; uint32_t ssrc; - //可能有很多个 + // 可能有很多个 ReportItem items; public: @@ -420,14 +419,14 @@ public: * 创建RR包,只赋值了RtcpHeader部分 * @param item_count ReportItem对象个数 * @return RR包 - */ + */ static std::shared_ptr create(size_t item_count); /** * 获取ReportItem对象指针列表 * 使用net2Host转换成主机字节序后才可使用此函数 */ - std::vector getItemList(); + std::vector getItemList(); private: /** @@ -475,20 +474,20 @@ SDES items 定义 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -//Source description Chunk +// Source description Chunk class SdesChunk { public: friend class RtcpSdes; uint32_t ssrc; - //SdesType + // SdesType uint8_t type; - //text长度股,可以为0 + // text长度股,可以为0 uint8_t txt_len; - //不定长 + // 不定长 char text[1]; - //最后以RTCP_SDES_END结尾 - //只字段为占位字段,不代表真实位置 + // 最后以RTCP_SDES_END结尾 + // 只字段为占位字段,不代表真实位置 uint8_t end; public: @@ -511,16 +510,16 @@ private: /** * 网络字节序转换为主机字节序 - */ + */ void net2Host(); } PACKED; -//Source description +// Source description class RtcpSdes : public RtcpHeader { public: friend class RtcpHeader; - //可能有很多个 + // 可能有很多个 SdesChunk chunks; public: @@ -535,13 +534,13 @@ public: * 获取SdesChunk对象指针列表 * 使用net2Host转换成主机字节序后才可使用此函数 */ - std::vector getChunkList(); + std::vector getChunkList(); private: /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -591,11 +590,11 @@ public: * @tparam Type 对象类型 * @return 对象指针 */ - template - const Type& getFci() const{ + template + const Type &getFci() const { auto fci_data = getFciPtr(); auto fci_len = getFciSize(); - Type *fci = (Type *) fci_data; + Type *fci = (Type *)fci_data; fci->check(fci_len); return *fci; } @@ -612,9 +611,9 @@ public: private: /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -627,7 +626,7 @@ private: static std::shared_ptr create_l(RtcpType type, int fmt, const void *fci, size_t fci_len); } PACKED; -//BYE +// BYE /* 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 @@ -675,9 +674,9 @@ public: private: /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -712,8 +711,7 @@ private: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -class RtcpXRRRTR : public RtcpHeader -{ +class RtcpXRRRTR : public RtcpHeader { public: friend class RtcpHeader; uint32_t ssrc; @@ -722,15 +720,16 @@ public: uint8_t reserved; // 2 uint16_t block_length; - // ntp timestamp MSW(in second) + // ntp timestamp MSW(in second) uint32_t ntpmsw; // ntp timestamp LSW(in picosecond) uint32_t ntplsw; + private: - /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -739,7 +738,7 @@ private: */ void net2Host(size_t size); -}PACKED; +} PACKED; /* @@ -759,18 +758,18 @@ private: : ... : 2 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ */ -class RtcpXRDLRRReportItem -{ +class RtcpXRDLRRReportItem { public: friend class RtcpXRDLRR; uint32_t ssrc; uint32_t lrr; uint32_t dlrr; + private: - /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -778,12 +777,9 @@ private: * @param size 字节长度,防止内存越界 */ void net2Host(); -}PACKED; +} PACKED; - - -class RtcpXRDLRR : public RtcpHeader -{ +class RtcpXRDLRR : public RtcpHeader { public: friend class RtcpHeader; uint32_t ssrc; @@ -799,17 +795,17 @@ public: */ static std::shared_ptr create(size_t item_count); - /** + /** * 获取RtcpXRDLRRReportItem对象指针列表 * 使用net2Host转换成主机字节序后才可使用此函数 */ - std::vector getItemList(); + std::vector getItemList(); private: - /** - * 打印字段详情 - * 使用net2Host转换成主机字节序后才可使用此函数 - */ + /** + * 打印字段详情 + * 使用net2Host转换成主机字节序后才可使用此函数 + */ std::string dumpString() const; /** @@ -818,12 +814,11 @@ private: */ void net2Host(size_t size); -}PACKED; - +} PACKED; #if defined(_WIN32) #pragma pack(pop) #endif // defined(_WIN32) -} //namespace mediakit -#endif //ZLMEDIAKIT_RTCP_H +} // namespace mediakit +#endif // ZLMEDIAKIT_RTCP_H diff --git a/src/Rtcp/RtcpContext.cpp b/src/Rtcp/RtcpContext.cpp index 23abbb91..796d3303 100644 --- a/src/Rtcp/RtcpContext.cpp +++ b/src/Rtcp/RtcpContext.cpp @@ -14,7 +14,8 @@ using namespace toolkit; namespace mediakit { -void RtcpContext::onRtp(uint16_t /*seq*/, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t /*sample_rate*/, size_t bytes) { +void RtcpContext::onRtp( + uint16_t /*seq*/, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t /*sample_rate*/, size_t bytes) { ++_packets; _bytes += bytes; _last_rtp_stamp = stamp; @@ -52,43 +53,45 @@ Buffer::Ptr RtcpContext::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) //////////////////////////////////////////////////////////////////////////////////// void RtcpContextForSend::onRtcp(RtcpHeader *rtcp) { - switch ((RtcpType) rtcp->pt) { - case RtcpType::RTCP_RR: { - auto rtcp_rr = (RtcpRR *) rtcp; - for (auto item : rtcp_rr->getItemList()) { - if (!item->last_sr_stamp) { - continue; - } - auto it = _sender_report_ntp.find(item->last_sr_stamp); - if (it == _sender_report_ntp.end()) { - continue; - } - //发送sr到收到rr之间的时间戳增量 - auto ms_inc = getCurrentMillisecond() - it->second; - //rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒 - auto delay_ms = (uint64_t) item->delay_since_last_sr * 1000 / 65536; - auto rtt = (int) (ms_inc - delay_ms); - if (rtt >= 0) { - //rtt不可能小于0 - _rtt[item->ssrc] = rtt; - //InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt; - } + switch ((RtcpType)rtcp->pt) { + case RtcpType::RTCP_RR: { + auto rtcp_rr = (RtcpRR *)rtcp; + for (auto item : rtcp_rr->getItemList()) { + if (!item->last_sr_stamp) { + continue; } - break; - } - case RtcpType::RTCP_XR:{ - auto rtcp_xr = (RtcpXRRRTR*)rtcp; - if(rtcp_xr->bt == 4){ - _xr_xrrtr_recv_last_rr[rtcp_xr->ssrc] = ((rtcp_xr->ntpmsw & 0xFFFF) << 16) | ((rtcp_xr->ntplsw >> 16) & 0xFFFF); - _xr_rrtr_recv_sys_stamp[rtcp_xr->ssrc] = getCurrentMillisecond(); - }else if(rtcp_xr->bt == 5){ - TraceL<<"for sender not recive dlrr"; - }else{ - TraceL<<"not support xr bt "<bt; + auto it = _sender_report_ntp.find(item->last_sr_stamp); + if (it == _sender_report_ntp.end()) { + continue; + } + // 发送sr到收到rr之间的时间戳增量 + auto ms_inc = getCurrentMillisecond() - it->second; + // rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒 + auto delay_ms = (uint64_t)item->delay_since_last_sr * 1000 / 65536; + auto rtt = (int)(ms_inc - delay_ms); + if (rtt >= 0) { + // rtt不可能小于0 + _rtt[item->ssrc] = rtt; + // InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt; } - break; } - default: break; + break; + } + case RtcpType::RTCP_XR: { + auto rtcp_xr = (RtcpXRRRTR *)rtcp; + if (rtcp_xr->bt == 4) { + _xr_xrrtr_recv_last_rr[rtcp_xr->ssrc] + = ((rtcp_xr->ntpmsw & 0xFFFF) << 16) | ((rtcp_xr->ntplsw >> 16) & 0xFFFF); + _xr_rrtr_recv_sys_stamp[rtcp_xr->ssrc] = getCurrentMillisecond(); + } else if (rtcp_xr->bt == 5) { + TraceL << "for sender not recive dlrr"; + } else { + TraceL << "not support xr bt " << rtcp_xr->bt; + } + break; + } + default: + break; } } @@ -105,21 +108,21 @@ Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) { rtcp->setNtpStamp(_last_ntp_stamp_ms); rtcp->rtpts = htonl(_last_rtp_stamp); rtcp->ssrc = htonl(rtcp_ssrc); - rtcp->packet_count = htonl((uint32_t) _packets); - rtcp->octet_count = htonl((uint32_t) _bytes); + rtcp->packet_count = htonl((uint32_t)_packets); + rtcp->octet_count = htonl((uint32_t)_bytes); - //记录上次发送的sender report信息,用于后续统计rtt + // 记录上次发送的sender report信息,用于后续统计rtt auto last_sr_lsr = ((ntohl(rtcp->ntpmsw) & 0xFFFF) << 16) | ((ntohl(rtcp->ntplsw) >> 16) & 0xFFFF); _sender_report_ntp[last_sr_lsr] = getCurrentMillisecond(); if (_sender_report_ntp.size() >= 5) { - //删除最早的sr rtcp + // 删除最早的sr rtcp _sender_report_ntp.erase(_sender_report_ntp.begin()); } return RtcpHeader::toBuffer(std::move(rtcp)); } -toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc){ +toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc) { auto rtcp = RtcpXRDLRR::create(1); rtcp->bt = 5; rtcp->reserved = 0; @@ -127,14 +130,14 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui rtcp->ssrc = htonl(rtcp_ssrc); rtcp->items.ssrc = htonl(rtp_ssrc); - if(_xr_xrrtr_recv_last_rr.find(rtp_ssrc) == _xr_xrrtr_recv_last_rr.end()){ + if (_xr_xrrtr_recv_last_rr.find(rtp_ssrc) == _xr_xrrtr_recv_last_rr.end()) { rtcp->items.lrr = 0; WarnL; - }else{ + } else { rtcp->items.lrr = htonl(_xr_xrrtr_recv_last_rr[rtp_ssrc]); } - if(_xr_rrtr_recv_sys_stamp.find(rtp_ssrc) == _xr_rrtr_recv_sys_stamp.end()){ + if (_xr_rrtr_recv_sys_stamp.find(rtp_ssrc) == _xr_rrtr_recv_sys_stamp.end()) { rtcp->items.dlrr = 0; WarnL; } else { @@ -149,39 +152,41 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui //////////////////////////////////////////////////////////////////////////////////// -void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) { +void RtcpContextForRecv::onRtp( + uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ms, uint32_t sample_rate, size_t bytes) { { - //接收者才做复杂的统计运算 + // 接收者才做复杂的统计运算 auto sys_stamp = getCurrentMillisecond(); if (_last_rtp_sys_stamp) { - //计算时间戳抖动值 - double diff = double((int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp)) * (sample_rate / double(1000.0)) - - (int64_t(stamp) - int64_t(_last_rtp_stamp))); + // 计算时间戳抖动值 + double diff = double( + (int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp)) * (sample_rate / double(1000.0)) + - (int64_t(stamp) - int64_t(_last_rtp_stamp))); if (diff < 0) { diff = -diff; } - //抖动单位为采样次数 + // 抖动单位为采样次数 _jitter += (diff - _jitter) / 16.0; } else { _jitter = 0; } if (_last_rtp_seq > 0xFF00 && seq < 0xFF && (!_seq_cycles || _packets - _last_cycle_packets > 0x1FFF)) { - //上次seq大于0xFF00且本次seq小于0xFF, - //且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环 + // 上次seq大于0xFF00且本次seq小于0xFF, + // 且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环 ++_seq_cycles; _last_cycle_packets = _packets; _seq_max = seq; } else if (seq > _seq_max) { - //本次回环前最大seq + // 本次回环前最大seq _seq_max = seq; } if (!_seq_base) { - //记录第一个rtp的seq + // 记录第一个rtp的seq _seq_base = seq; } else if (!_seq_cycles && seq < _seq_base) { - //未发生回环,那么取最新的seq为基准seq + // 未发生回环,那么取最新的seq为基准seq _seq_base = seq; } @@ -192,21 +197,22 @@ void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_ } void RtcpContextForRecv::onRtcp(RtcpHeader *rtcp) { - switch ((RtcpType) rtcp->pt) { - case RtcpType::RTCP_SR: { - auto rtcp_sr = (RtcpSR *) rtcp; - /** - last SR timestamp (LSR): 32 bits - The middle 32 bits out of 64 in the NTP timestamp (as explained in - Section 4) received as part of the most recent RTCP sender report - (SR) packet from source SSRC_n. If no SR has been received yet, - the field is set to zero. - */ - _last_sr_lsr = ((rtcp_sr->ntpmsw & 0xFFFF) << 16) | ((rtcp_sr->ntplsw >> 16) & 0xFFFF); - _last_sr_ntp_sys = getCurrentMillisecond(); - break; - } - default: break; + switch ((RtcpType)rtcp->pt) { + case RtcpType::RTCP_SR: { + auto rtcp_sr = (RtcpSR *)rtcp; + /** + last SR timestamp (LSR): 32 bits + The middle 32 bits out of 64 in the NTP timestamp (as explained in + Section 4) received as part of the most recent RTCP sender report + (SR) packet from source SSRC_n. If no SR has been received yet, + the field is set to zero. + */ + _last_sr_lsr = ((rtcp_sr->ntpmsw & 0xFFFF) << 16) | ((rtcp_sr->ntplsw >> 16) & 0xFFFF); + _last_sr_ntp_sys = getCurrentMillisecond(); + break; + } + default: + break; } } @@ -236,7 +242,7 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss auto rtcp = RtcpRR::create(1); rtcp->ssrc = htonl(rtcp_ssrc); - ReportItem *item = (ReportItem *) &rtcp->items; + ReportItem *item = (ReportItem *)&rtcp->items; item->ssrc = htonl(rtp_ssrc); uint8_t fraction = 0; @@ -255,9 +261,9 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss // now - Last SR time,单位毫秒 auto delay = getCurrentMillisecond() - _last_sr_ntp_sys; // in units of 1/65536 seconds - auto dlsr = (uint32_t) (delay / 1000.0f * 65536); + auto dlsr = (uint32_t)(delay / 1000.0f * 65536); item->delay_since_last_sr = htonl(_last_sr_lsr ? dlsr : 0); return RtcpHeader::toBuffer(rtcp); } -}//namespace mediakit \ No newline at end of file +} // namespace mediakit \ No newline at end of file diff --git a/src/Rtcp/RtcpContext.h b/src/Rtcp/RtcpContext.h index 2ed936f8..31b6167d 100644 --- a/src/Rtcp/RtcpContext.h +++ b/src/Rtcp/RtcpContext.h @@ -11,9 +11,9 @@ #ifndef ZLMEDIAKIT_RTCPCONTEXT_H #define ZLMEDIAKIT_RTCPCONTEXT_H -#include -#include #include "Rtcp.h" +#include +#include namespace mediakit { @@ -55,11 +55,10 @@ public: */ virtual toolkit::Buffer::Ptr createRtcpSR(uint32_t rtcp_ssrc); - /** * @brief 创建xr的dlrr包,用于接收者估算rtt - * - * @return toolkit::Buffer::Ptr + * + * @return toolkit::Buffer::Ptr */ virtual toolkit::Buffer::Ptr createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc); @@ -82,11 +81,11 @@ public: virtual size_t geLostInterval(); protected: - //收到或发送的rtp的字节数 + // 收到或发送的rtp的字节数 size_t _bytes = 0; - //收到或发送的rtp的个数 + // 收到或发送的rtp的个数 size_t _packets = 0; - //上次的rtp时间戳,毫秒 + // 上次的rtp时间戳,毫秒 uint32_t _last_rtp_stamp = 0; uint64_t _last_ntp_stamp_ms = 0; }; @@ -107,11 +106,11 @@ public: uint32_t getRtt(uint32_t ssrc) const; private: - std::map _rtt; - std::map _sender_report_ntp; + std::map _rtt; + std::map _sender_report_ntp; - std::map _xr_rrtr_recv_sys_stamp; - std::map _xr_xrrtr_recv_last_rr; + std::map _xr_rrtr_recv_sys_stamp; + std::map _xr_xrrtr_recv_last_rr; }; class RtcpContextForRecv : public RtcpContext { @@ -125,29 +124,29 @@ public: void onRtcp(RtcpHeader *rtcp) override; private: - //时间戳抖动值 + // 时间戳抖动值 double _jitter = 0; - //第一个seq的值 + // 第一个seq的值 uint16_t _seq_base = 0; - //rtp最大seq + // rtp最大seq uint16_t _seq_max = 0; - //rtp回环次数 + // rtp回环次数 uint16_t _seq_cycles = 0; - //上次回环发生时,记录的rtp包数 + // 上次回环发生时,记录的rtp包数 size_t _last_cycle_packets = 0; - //上次的seq + // 上次的seq uint16_t _last_rtp_seq = 0; - //上次的rtp的系统时间戳(毫秒)用于统计抖动 + // 上次的rtp的系统时间戳(毫秒)用于统计抖动 uint64_t _last_rtp_sys_stamp = 0; - //上次统计的丢包总数 + // 上次统计的丢包总数 size_t _last_lost = 0; - //上次统计应收rtp包总数 + // 上次统计应收rtp包总数 size_t _last_expected = 0; - //上次收到sr包时计算出的Last SR timestamp + // 上次收到sr包时计算出的Last SR timestamp uint32_t _last_sr_lsr = 0; - //上次收到sr时的系统时间戳,单位毫秒 + // 上次收到sr时的系统时间戳,单位毫秒 uint64_t _last_sr_ntp_sys = 0; }; -}//namespace mediakit -#endif //ZLMEDIAKIT_RTCPCONTEXT_H +} // namespace mediakit +#endif // ZLMEDIAKIT_RTCPCONTEXT_H diff --git a/src/Rtcp/RtcpFCI.cpp b/src/Rtcp/RtcpFCI.cpp index 2bc8e27f..c6508217 100644 --- a/src/Rtcp/RtcpFCI.cpp +++ b/src/Rtcp/RtcpFCI.cpp @@ -16,16 +16,16 @@ using namespace toolkit; namespace mediakit { -void FCI_SLI::check(size_t size){ +void FCI_SLI::check(size_t size) { CHECK(size >= kSize); } FCI_SLI::FCI_SLI(uint16_t first, uint16_t number, uint8_t pic_id) { - //13 bits + // 13 bits first &= 0x1FFF; - //13 bits + // 13 bits number &= 0x1FFF; - //6 bits + // 6 bits pic_id &= 0x3F; data = (first << 19) | (number << 6) | pic_id; data = htonl(data); @@ -49,19 +49,19 @@ string FCI_SLI::dumpString() const { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void FCI_FIR::check(size_t size){ +void FCI_FIR::check(size_t size) { CHECK(size >= kSize); } -uint32_t FCI_FIR::getSSRC() const{ +uint32_t FCI_FIR::getSSRC() const { return ntohl(ssrc); } -uint8_t FCI_FIR::getSeq() const{ +uint8_t FCI_FIR::getSeq() const { return seq_number; } -uint32_t FCI_FIR::getReserved() const{ +uint32_t FCI_FIR::getReserved() const { return (reserved[0] << 16) | (reserved[1] << 8) | reserved[2]; } @@ -81,7 +81,7 @@ FCI_FIR::FCI_FIR(uint32_t ssrc, uint8_t seq_number, uint32_t reserved) { static const char kRembMagic[] = "REMB"; -void FCI_REMB::check(size_t size){ +void FCI_REMB::check(size_t size) { CHECK(size >= kSize); CHECK(memcmp(magic, kRembMagic, sizeof(magic)) == 0); auto num_ssrc = bitrate[0]; @@ -93,7 +93,7 @@ string FCI_REMB::create(const vector &ssrcs, uint32_t bitrate) { CHECK(ssrcs.size() > 0 && ssrcs.size() <= 0xFF); string ret; ret.resize(kSize + ssrcs.size() * 4); - FCI_REMB *thiz = (FCI_REMB *) ret.data(); + FCI_REMB *thiz = (FCI_REMB *)ret.data(); memcpy(thiz->magic, kRembMagic, sizeof(magic)); /* bitrate --> BR Exp/BR Mantissa */ @@ -101,7 +101,7 @@ string FCI_REMB::create(const vector &ssrcs, uint32_t bitrate) { uint8_t exp = 0; uint32_t mantissa = 0; for (b = 0; b < 32; b++) { - if (bitrate <= ((uint32_t) 0x3FFFF << b)) { + if (bitrate <= ((uint32_t)0x3FFFF << b)) { exp = b; break; } @@ -110,16 +110,16 @@ string FCI_REMB::create(const vector &ssrcs, uint32_t bitrate) { b = 31; } mantissa = bitrate >> b; - //Num SSRC (8 bits) + // Num SSRC (8 bits) thiz->bitrate[0] = ssrcs.size() & 0xFF; - //BR Exp (6 bits)/BR Mantissa (18 bits) - thiz->bitrate[1] = (uint8_t) ((exp << 2) + ((mantissa >> 16) & 0x03)); - //BR Mantissa (18 bits) - thiz->bitrate[2] = (uint8_t) (mantissa >> 8); - //BR Mantissa (18 bits) - thiz->bitrate[3] = (uint8_t) (mantissa); + // BR Exp (6 bits)/BR Mantissa (18 bits) + thiz->bitrate[1] = (uint8_t)((exp << 2) + ((mantissa >> 16) & 0x03)); + // BR Mantissa (18 bits) + thiz->bitrate[2] = (uint8_t)(mantissa >> 8); + // BR Mantissa (18 bits) + thiz->bitrate[3] = (uint8_t)(mantissa); - //设置ssrc列表 + // 设置ssrc列表 int i = 0; for (auto ssrc : ssrcs) { thiz->ssrc_feedback[i++] = htonl(ssrc); @@ -149,7 +149,7 @@ vector FCI_REMB::getSSRC() { string FCI_REMB::dumpString() const { _StrPrinter printer; printer << "bitrate:" << getBitRate() << ", ssrc:"; - for (auto &ssrc : ((FCI_REMB *) this)->getSSRC()) { + for (auto &ssrc : ((FCI_REMB *)this)->getSSRC()) { printer << ssrc << " "; } return std::move(printer); @@ -171,7 +171,7 @@ FCI_NACK::FCI_NACK(uint16_t pid_h, const vector &type) { pid = htons(pid_h); } -void FCI_NACK::check(size_t size){ +void FCI_NACK::check(size_t size) { CHECK(size >= kSize); } @@ -186,7 +186,7 @@ uint16_t FCI_NACK::getBlp() const { vector FCI_NACK::getBitArray() const { vector ret; ret.resize(kBitSize + 1); - //nack第一个包丢包 + // nack第一个包丢包 ret[0] = true; auto blp_h = getBlp(); @@ -220,25 +220,25 @@ public: // |T| S | Run Length | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #if __BYTE_ORDER == __BIG_ENDIAN - uint16_t type: 1; - uint16_t symbol: 2; - uint16_t run_length_high: 5; + uint16_t type : 1; + uint16_t symbol : 2; + uint16_t run_length_high : 5; #else // Run Length 高5位 - uint16_t run_length_high: 5; - //参考SymbolStatus定义 - uint16_t symbol: 2; - //固定为0 - uint16_t type: 1; + uint16_t run_length_high : 5; + // 参考SymbolStatus定义 + uint16_t symbol : 2; + // 固定为0 + uint16_t type : 1; #endif // Run Length 低8位 - uint16_t run_length_low: 8; + uint16_t run_length_low : 8; - //获取Run Length + // 获取Run Length uint16_t getRunLength() const; - //构造函数 + // 构造函数 RunLengthChunk(SymbolStatus status, uint16_t run_length); - //打印本对象 + // 打印本对象 string dumpString() const; } PACKED; @@ -254,7 +254,7 @@ uint16_t RunLengthChunk::getRunLength() const { return run_length_high << 8 | run_length_low; } -string RunLengthChunk::dumpString() const{ +string RunLengthChunk::dumpString() const { _StrPrinter printer; printer << "run length chunk, symbol:" << (int)symbol << ", run length:" << getRunLength(); return std::move(printer); @@ -271,30 +271,30 @@ public: // |T|S| symbol list | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #if __BYTE_ORDER == __BIG_ENDIAN - uint16_t type: 1; - uint16_t symbol: 1; - uint16_t symbol_list_high: 6; + uint16_t type : 1; + uint16_t symbol : 1; + uint16_t symbol_list_high : 6; #else // symbol_list 高6位 - uint16_t symbol_list_high: 6; - //symbol_list中元素是1个还是2个bit - uint16_t symbol: 1; - //固定为1 - uint16_t type: 1; + uint16_t symbol_list_high : 6; + // symbol_list中元素是1个还是2个bit + uint16_t symbol : 1; + // 固定为1 + uint16_t type : 1; #endif // symbol_list 低8位 - uint16_t symbol_list_low: 8; + uint16_t symbol_list_low : 8; - //获取symbollist + // 获取symbollist vector getSymbolList() const; - //构造函数 + // 构造函数 StatusVecChunk(bool symbol_bit, const vector &status); - //打印本对象 + // 打印本对象 string dumpString() const; } PACKED; StatusVecChunk::StatusVecChunk(bool symbol_bit, const vector &status) { - CHECK( status.size() << symbol_bit <= 14); + CHECK(status.size() << symbol_bit <= 14); uint16_t value = 0; type = 1; symbol = symbol_bit; @@ -303,31 +303,31 @@ StatusVecChunk::StatusVecChunk(bool symbol_bit, const vector &stat CHECK(item <= SymbolStatus::reserved); if (!symbol) { CHECK(item <= SymbolStatus::small_delta); - value |= (int) item << i; + value |= (int)item << i; --i; } else { - value |= (int) item << (i - 1); + value |= (int)item << (i - 1); i -= 2; } } symbol_list_low = value & 0xFF; - symbol_list_high = (value >> 8 ) & 0x3F; + symbol_list_high = (value >> 8) & 0x3F; } vector StatusVecChunk::getSymbolList() const { CHECK(type == 1); vector ret; - auto thiz = ntohs(*((uint16_t *) this)); + auto thiz = ntohs(*((uint16_t *)this)); if (symbol == 0) { - //s = 0 时,表示symbollist的每一个bit能表示一个数据包的到达状态 + // s = 0 时,表示symbollist的每一个bit能表示一个数据包的到达状态 for (int i = 13; i >= 0; --i) { - SymbolStatus status = (SymbolStatus) ((bool) (thiz & (1 << i))); + SymbolStatus status = (SymbolStatus)((bool)(thiz & (1 << i))); ret.emplace_back(status); } } else { - //s = 1 时,表示symbollist每两个bit表示一个数据包的状态 + // s = 1 时,表示symbollist每两个bit表示一个数据包的状态 for (int i = 12; i >= 0; i -= 2) { - SymbolStatus status = (SymbolStatus) ((thiz & (3 << i)) >> i); + SymbolStatus status = (SymbolStatus)((thiz & (3 << i)) >> i); ret.emplace_back(status); } } @@ -336,17 +336,17 @@ vector StatusVecChunk::getSymbolList() const { string StatusVecChunk::dumpString() const { _StrPrinter printer; - printer << "status vector chunk, symbol:" << (int) symbol << ", symbol list:"; + printer << "status vector chunk, symbol:" << (int)symbol << ", symbol list:"; auto vec = getSymbolList(); for (auto &item : vec) { - printer << (int) item << " "; + printer << (int)item << " "; } return std::move(printer); } /////////////////////////////////////////////////////// -void FCI_TWCC::check(size_t size){ +void FCI_TWCC::check(size_t size) { CHECK(size >= kSize); } @@ -365,87 +365,87 @@ uint32_t FCI_TWCC::getReferenceTime() const { ret |= ref_time[2]; return ret; } -//3.1.5. Receive Delta +// 3.1.5. Receive Delta // -// Deltas are represented as multiples of 250us: +// Deltas are represented as multiples of 250us: // -// o If the "Packet received, small delta" symbol has been appended to -// the status list, an 8-bit unsigned receive delta will be appended -// to recv delta list, representing a delta in the range [0, 63.75] -// ms. +// o If the "Packet received, small delta" symbol has been appended to +// the status list, an 8-bit unsigned receive delta will be appended +// to recv delta list, representing a delta in the range [0, 63.75] +// ms. // -// o If the "Packet received, large or negative delta" symbol has been -// appended to the status list, a 16-bit signed receive delta will be -// appended to recv delta list, representing a delta in the range -// [-8192.0, 8191.75] ms. +// o If the "Packet received, large or negative delta" symbol has been +// appended to the status list, a 16-bit signed receive delta will be +// appended to recv delta list, representing a delta in the range +// [-8192.0, 8191.75] ms. // -// o If the delta exceeds even the larger limits, a new feedback -// message must be used, where the 24-bit base receive delta can -// cover very large gaps. +// o If the delta exceeds even the larger limits, a new feedback +// message must be used, where the 24-bit base receive delta can +// cover very large gaps. // -// The smaller receive delta upper bound of 63.75 ms means that this is -// only viable at about 1000/25.5 ~= 16 packets per second and above. -// With a packet size of 1200 bytes/packet that amounts to a bitrate of -// about 150 kbit/s. +// The smaller receive delta upper bound of 63.75 ms means that this is +// only viable at about 1000/25.5 ~= 16 packets per second and above. +// With a packet size of 1200 bytes/packet that amounts to a bitrate of +// about 150 kbit/s. // -// The 0.25 ms resolution means that up to 4000 packets per second can -// be represented. With a 1200 bytes/packet payload, that amounts to -// 38.4 Mbit/s payload bandwidth. +// The 0.25 ms resolution means that up to 4000 packets per second can +// be represented. With a 1200 bytes/packet payload, that amounts to +// 38.4 Mbit/s payload bandwidth. -static int16_t getRecvDelta(SymbolStatus status, uint8_t *&ptr, const uint8_t *end){ +static int16_t getRecvDelta(SymbolStatus status, uint8_t *&ptr, const uint8_t *end) { int16_t delta = 0; switch (status) { - case SymbolStatus::not_received : { - //丢包, recv delta为0个字节 - break; - } - case SymbolStatus::small_delta : { - CHECK(ptr + 1 <= end); - //时间戳增量小于256, recv delta为1个字节 - delta = *ptr; - ptr += 1; - break; - } - case SymbolStatus::large_delta : { - CHECK(ptr + 2 <= end); - //时间戳增量256~65535间,recv delta为2个字节 - delta = *ptr << 8 | *(ptr + 1); - ptr += 2; - break; - } - case SymbolStatus::reserved : { - //没有时间戳 - break; - } - default: - //这个逻辑分支不可达到 - CHECK(0); - break; + case SymbolStatus::not_received: { + // 丢包, recv delta为0个字节 + break; + } + case SymbolStatus::small_delta: { + CHECK(ptr + 1 <= end); + // 时间戳增量小于256, recv delta为1个字节 + delta = *ptr; + ptr += 1; + break; + } + case SymbolStatus::large_delta: { + CHECK(ptr + 2 <= end); + // 时间戳增量256~65535间,recv delta为2个字节 + delta = *ptr << 8 | *(ptr + 1); + ptr += 2; + break; + } + case SymbolStatus::reserved: { + // 没有时间戳 + break; + } + default: + // 这个逻辑分支不可达到 + CHECK(0); + break; } return delta; } FCI_TWCC::TwccPacketStatus FCI_TWCC::getPacketChunkList(size_t total_size) const { TwccPacketStatus ret; - auto ptr = (uint8_t *) this + kSize; - auto end = (uint8_t *) this + total_size; + auto ptr = (uint8_t *)this + kSize; + auto end = (uint8_t *)this + total_size; CHECK(ptr < end); auto seq = getBaseSeq(); auto rtp_count = getPacketCount(); for (uint8_t i = 0; i < rtp_count;) { CHECK(ptr + RunLengthChunk::kSize <= end); - RunLengthChunk *chunk = (RunLengthChunk *) ptr; + RunLengthChunk *chunk = (RunLengthChunk *)ptr; if (!chunk->type) { - //RunLengthChunk + // RunLengthChunk for (auto j = 0; j < chunk->getRunLength(); ++j) { - ret.emplace(seq++, std::make_pair((SymbolStatus) chunk->symbol, 0)); + ret.emplace(seq++, std::make_pair((SymbolStatus)chunk->symbol, 0)); if (++i >= rtp_count) { break; } } } else { - //StatusVecChunk - StatusVecChunk *chunk = (StatusVecChunk *) ptr; + // StatusVecChunk + StatusVecChunk *chunk = (StatusVecChunk *)ptr; for (auto &symbol : chunk->getSymbolList()) { ret.emplace(seq++, std::make_pair(symbol, 0)); if (++i >= rtp_count) { @@ -465,23 +465,29 @@ FCI_TWCC::TwccPacketStatus FCI_TWCC::getPacketChunkList(size_t total_size) const string FCI_TWCC::dumpString(size_t total_size) const { _StrPrinter printer; auto map = getPacketChunkList(total_size); - printer << "twcc fci, base_seq:" << getBaseSeq() << ", pkt_status_count:" << getPacketCount() << ", ref time:" << getReferenceTime() << ", fb count:" << (int)fb_pkt_count << "\n"; + printer << "twcc fci, base_seq:" << getBaseSeq() << ", pkt_status_count:" << getPacketCount() + << ", ref time:" << getReferenceTime() << ", fb count:" << (int)fb_pkt_count << "\n"; for (auto &pr : map) { - printer << "rtp seq:" << pr.first <<", packet status:" << (int)(pr.second.first) << ", delta:" << pr.second.second << "\n"; + printer << "rtp seq:" << pr.first << ", packet status:" << (int)(pr.second.first) + << ", delta:" << pr.second.second << "\n"; } return std::move(printer); } -static void appendDeltaString(string &delta_str, FCI_TWCC::TwccPacketStatus &status, int count){ +static void appendDeltaString(string &delta_str, FCI_TWCC::TwccPacketStatus &status, int count) { for (auto it = status.begin(); it != status.end() && count--;) { switch (it->second.first) { - //large delta模式先写高字节,再写低字节 - case SymbolStatus::large_delta: delta_str.push_back((it->second.second >> 8) & 0xFF); - //small delta模式只写低字节 - case SymbolStatus::small_delta: delta_str.push_back(it->second.second & 0xFF); break; - default: break; + // large delta模式先写高字节,再写低字节 + case SymbolStatus::large_delta: + delta_str.push_back((it->second.second >> 8) & 0xFF); + // small delta模式只写低字节 + case SymbolStatus::small_delta: + delta_str.push_back(it->second.second & 0xFF); + break; + default: + break; } - //移除已经处理过的数据 + // 移除已经处理过的数据 it = status.erase(it); } } @@ -489,7 +495,7 @@ static void appendDeltaString(string &delta_str, FCI_TWCC::TwccPacketStatus &sta string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatus &status) { string fci; fci.resize(FCI_TWCC::kSize); - FCI_TWCC *ptr = (FCI_TWCC *) (fci.data()); + FCI_TWCC *ptr = (FCI_TWCC *)(fci.data()); ptr->base_seq = htons(status.begin()->first); ptr->pkt_status_count = htons(status.size()); ptr->fb_pkt_count = fb_pkt_count; @@ -500,21 +506,21 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu string delta_str; while (!status.empty()) { { - //第一个rtp的状态 + // 第一个rtp的状态 auto symbol = status.begin()->second.first; int16_t count = 0; for (auto &pr : status) { if (pr.second.first != symbol) { - //状态发送变更了,本chunk结束 + // 状态发送变更了,本chunk结束 break; } if (++count >= (0xFFFF >> 3)) { - //RunLengthChunk 13个bit表明rtp个数,最多可以表述0xFFFF >> 3个rtp状态 + // RunLengthChunk 13个bit表明rtp个数,最多可以表述0xFFFF >> 3个rtp状态 break; } } if (count >= 7) { - //连续状态相同个数大于6个时,使用RunLengthChunk模式比较节省带宽 + // 连续状态相同个数大于6个时,使用RunLengthChunk模式比较节省带宽 RunLengthChunk chunk(symbol, count); fci.append((char *)&chunk, RunLengthChunk::kSize); appendDeltaString(delta_str, status, count); @@ -523,20 +529,20 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu } { - //StatusVecChunk模式 - //symbol_list中元素是1个bit + // StatusVecChunk模式 + // symbol_list中元素是1个bit auto symbol = 0; vector vec; for (auto &pr : status) { vec.push_back(pr.second.first); if (pr.second.first >= SymbolStatus::large_delta) { - //symbol_list中元素是2个bit + // symbol_list中元素是2个bit symbol = 1; } if (vec.size() << symbol >= 14) { - //symbol为0时,最多存放14个rtp的状态 - //symbol为1时,最多存放7个rtp的状态 + // symbol为0时,最多存放14个rtp的状态 + // symbol为1时,最多存放7个rtp的状态 break; } } @@ -547,9 +553,9 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu } } - //recv delta部分 + // recv delta部分 fci.append(delta_str); return fci; } -}//namespace mediakit \ No newline at end of file +} // namespace mediakit \ No newline at end of file diff --git a/src/Rtcp/RtcpFCI.h b/src/Rtcp/RtcpFCI.h index 99b4aebf..8a14e5f3 100644 --- a/src/Rtcp/RtcpFCI.h +++ b/src/Rtcp/RtcpFCI.h @@ -11,37 +11,37 @@ #ifndef ZLMEDIAKIT_RTCPFCI_H #define ZLMEDIAKIT_RTCPFCI_H -#include "Rtcp.h" #include "Common/config.h" +#include "Rtcp.h" namespace mediakit { /////////////////////////////////////////// PSFB //////////////////////////////////////////////////// -//PSFB fmt = 2 -//https://tools.ietf.org/html/rfc4585#section-6.3.2.2 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | First | Number | PictureID | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -//First: 13 bits -// The macroblock (MB) address of the first lost macroblock. The MB -// numbering is done such that the macroblock in the upper left -// corner of the picture is considered macroblock number 1 and the -// number for each macroblock increases from left to right and then -// from top to bottom in raster-scan order (such that if there is a -// total of N macroblocks in a picture, the bottom right macroblock -// is considered macroblock number N). +// PSFB fmt = 2 +// https://tools.ietf.org/html/rfc4585#section-6.3.2.2 +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | First | Number | PictureID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// First: 13 bits +// The macroblock (MB) address of the first lost macroblock. The MB +// numbering is done such that the macroblock in the upper left +// corner of the picture is considered macroblock number 1 and the +// number for each macroblock increases from left to right and then +// from top to bottom in raster-scan order (such that if there is a +// total of N macroblocks in a picture, the bottom right macroblock +// is considered macroblock number N). // -// Number: 13 bits -// The number of lost macroblocks, in scan order as discussed above. +// Number: 13 bits +// The number of lost macroblocks, in scan order as discussed above. // -// PictureID: 6 bits -// The six least significant bits of the codec-specific identifier -// that is used to reference the picture in which the loss of the -// macroblock(s) has occurred. For many video codecs, the PictureID -// is identical to the Temporal Reference. +// PictureID: 6 bits +// The six least significant bits of the codec-specific identifier +// that is used to reference the picture in which the loss of the +// macroblock(s) has occurred. For many video codecs, the PictureID +// is identical to the Temporal Reference. class FCI_SLI { public: static size_t constexpr kSize = 4; @@ -101,15 +101,15 @@ public: } PACKED; #endif -//PSFB fmt = 4 -//https://tools.ietf.org/html/rfc5104#section-4.3.1.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 | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Seq nr. | Reserved | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// PSFB fmt = 4 +// https://tools.ietf.org/html/rfc5104#section-4.3.1.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 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Seq nr. | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ class FCI_FIR { public: static size_t constexpr kSize = 8; @@ -188,34 +188,34 @@ private: #endif -//PSFB fmt = 15 -//https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Unique identifier 'R' 'E' 'M' 'B' | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Num SSRC | BR Exp | BR Mantissa | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | SSRC feedback | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | ... | -// Num SSRC (8 bits): Number of SSRCs in this message. +// PSFB fmt = 15 +// https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03 +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Unique identifier 'R' 'E' 'M' 'B' | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Num SSRC | BR Exp | BR Mantissa | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | SSRC feedback | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ... | +// Num SSRC (8 bits): Number of SSRCs in this message. // -// BR Exp (6 bits): The exponential scaling of the mantissa for the -// maximum total media bit rate value, ignoring all packet -// overhead. The value is an unsigned integer [0..63], as -// in RFC 5104 section 4.2.2.1. +// BR Exp (6 bits): The exponential scaling of the mantissa for the +// maximum total media bit rate value, ignoring all packet +// overhead. The value is an unsigned integer [0..63], as +// in RFC 5104 section 4.2.2.1. // -// BR Mantissa (18 bits): The mantissa of the maximum total media bit -// rate (ignoring all packet overhead) that the sender of -// the REMB estimates. The BR is the estimate of the -// traveled path for the SSRCs reported in this message. -// The value is an unsigned integer in number of bits per -// second. +// BR Mantissa (18 bits): The mantissa of the maximum total media bit +// rate (ignoring all packet overhead) that the sender of +// the REMB estimates. The BR is the estimate of the +// traveled path for the SSRCs reported in this message. +// The value is an unsigned integer in number of bits per +// second. // -// SSRC feedback (32 bits) Consists of one or more SSRC entries which -// this feedback message applies to. +// SSRC feedback (32 bits) Consists of one or more SSRC entries which +// this feedback message applies to. class FCI_REMB { public: static size_t constexpr kSize = 8; @@ -227,9 +227,9 @@ public: std::vector getSSRC(); private: - //Unique identifier 'R' 'E' 'M' 'B' + // Unique identifier 'R' 'E' 'M' 'B' char magic[4]; - //Num SSRC (8 bits)/BR Exp (6 bits)/ BR Mantissa (18 bits) + // Num SSRC (8 bits)/BR Exp (6 bits)/ BR Mantissa (18 bits) uint8_t bitrate[4]; // SSRC feedback (32 bits) Consists of one or more SSRC entries which // this feedback message applies to. @@ -238,13 +238,13 @@ private: /////////////////////////////////////////// RTPFB //////////////////////////////////////////////////// -//RTPFB fmt = 1 -//https://tools.ietf.org/html/rfc4585#section-6.2.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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | PID | BLP | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// RTPFB fmt = 1 +// https://tools.ietf.org/html/rfc4585#section-6.2.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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | PID | BLP | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ class FCI_NACK { public: static constexpr size_t kSize = 4; @@ -255,8 +255,8 @@ public: void check(size_t size); uint16_t getPid() const; uint16_t getBlp() const; - //返回丢包列表,总长度17,第一个包必丢 - // TODO: replace std::bitset + // 返回丢包列表,总长度17,第一个包必丢 + // TODO: replace std::bitset std::vector getBitArray() const; std::string dumpString() const; @@ -318,47 +318,48 @@ public: } PACKED; #endif -enum class SymbolStatus : uint8_t{ - //Packet not received +enum class SymbolStatus : uint8_t { + // Packet not received not_received = 0, - //Packet received, small delta (所谓small detal是指能用一个字节表示的数值) + // Packet received, small delta (所谓small detal是指能用一个字节表示的数值) small_delta = 1, // Packet received, large ornegative delta (large即是能用两个字节表示的数值) large_delta = 2, - //Reserved + // Reserved reserved = 3 }; -//RTPFB fmt = 15 -//https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1 -//https://zhuanlan.zhihu.com/p/206656654 -// 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 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | base sequence number | packet status count | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | reference time | fb pkt. count | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | packet chunk | packet chunk | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// . . -// . . -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | packet chunk | recv delta | recv delta | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// . . -// . . -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | recv delta | recv delta | zero padding | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -class FCI_TWCC{ +// RTPFB fmt = 15 +// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1 +// https://zhuanlan.zhihu.com/p/206656654 +// 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 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | base sequence number | packet status count | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | reference time | fb pkt. count | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | packet chunk | packet chunk | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// . . +// . . +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | packet chunk | recv delta | recv delta | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// . . +// . . +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | recv delta | recv delta | zero padding | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +class FCI_TWCC { public: static size_t constexpr kSize = 8; - using TwccPacketStatus = std::map >; + using TwccPacketStatus + = std::map>; void check(size_t size); std::string dumpString(size_t total_size) const; uint16_t getBaseSeq() const; - //单位64ms + // 单位64ms uint32_t getReferenceTime() const; uint16_t getPacketCount() const; TwccPacketStatus getPacketChunkList(size_t total_size) const; @@ -366,15 +367,15 @@ public: static std::string create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatus &status); private: - //base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号 + // base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号 uint16_t base_seq; - //packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算 + // packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算 uint16_t pkt_status_count; - //reference time,基准时间,绝对时间;计算该包中每个媒体包的到达时间都要基于这个基准时间计算 + // reference time,基准时间,绝对时间;计算该包中每个媒体包的到达时间都要基于这个基准时间计算 uint8_t ref_time[3]; - //feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 | + // feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 | uint8_t fb_pkt_count; } PACKED; -} //namespace mediakit -#endif //ZLMEDIAKIT_RTCPFCI_H +} // namespace mediakit +#endif // ZLMEDIAKIT_RTCPFCI_H diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 5850cfb6..af6e981a 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -9,11 +9,11 @@ */ #include "WebRtcTransport.h" -#include -#include "RtpExt.h" #include "Rtcp/Rtcp.h" #include "Rtcp/RtcpFCI.h" +#include "RtpExt.h" #include "Rtsp/RtpReceiver.h" +#include #define RTP_SSRC_OFFSET 1 #define RTX_SSRC_OFFSET 2 @@ -25,17 +25,17 @@ using namespace std; using namespace mediakit; -//RTC配置项目 +// RTC配置项目 namespace RTC { #define RTC_FIELD "rtc." -//rtp和rtcp接受超时时间 -const string kTimeOutSec = RTC_FIELD"timeoutSec"; -//服务器外网ip -const string kExternIP = RTC_FIELD"externIP"; -//设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质 -const string kRembBitRate = RTC_FIELD"rembBitRate"; -//webrtc单端口udp服务器 -const string kPort = RTC_FIELD"port"; +// rtp和rtcp接受超时时间 +const string kTimeOutSec = RTC_FIELD "timeoutSec"; +// 服务器外网ip +const string kExternIP = RTC_FIELD "externIP"; +// 设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质 +const string kRembBitRate = RTC_FIELD "rembBitRate"; +// webrtc单端口udp服务器 +const string kPort = RTC_FIELD "port"; static onceToken token([]() { mINI::Instance()[kTimeOutSec] = 15; @@ -44,9 +44,9 @@ static onceToken token([]() { mINI::Instance()[kPort] = 8000; }); -}//namespace RTC +} // namespace RTC -static atomic s_key{0}; +static atomic s_key { 0 }; static void translateIPFromEnv(std::vector &v) { for (auto iter = v.begin(); iter != v.end();) { @@ -69,12 +69,12 @@ WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) { _packet_pool.setSize(64); } -void WebRtcTransport::onCreate(){ +void WebRtcTransport::onCreate() { _dtls_transport = std::make_shared(_poller, this); _ice_server = std::make_shared(this, _identifier, makeRandStr(24)); } -void WebRtcTransport::onDestory(){ +void WebRtcTransport::onDestory() { #ifdef ENABLE_SCTP _sctp = nullptr; #endif @@ -82,7 +82,7 @@ void WebRtcTransport::onDestory(){ _ice_server = nullptr; } -const EventPoller::Ptr& WebRtcTransport::getPoller() const{ +const EventPoller::Ptr &WebRtcTransport::getPoller() const { return _poller; } @@ -92,8 +92,9 @@ const string &WebRtcTransport::getIdentifier() const { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void WebRtcTransport::OnIceServerSendStunPacket(const RTC::IceServer *iceServer, const RTC::StunPacket *packet, RTC::TransportTuple *tuple) { - sendSockData((char *) packet->GetData(), packet->GetSize(), tuple); +void WebRtcTransport::OnIceServerSendStunPacket( + const RTC::IceServer *iceServer, const RTC::StunPacket *packet, RTC::TransportTuple *tuple) { + sendSockData((char *)packet->GetData(), packet->GetSize(), tuple); } void WebRtcTransport::OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) { @@ -120,16 +121,13 @@ void WebRtcTransport::OnIceServerDisconnected(const RTC::IceServer *iceServer) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void WebRtcTransport::OnDtlsTransportConnected( - const RTC::DtlsTransport *dtlsTransport, - RTC::SrtpSession::CryptoSuite srtpCryptoSuite, - uint8_t *srtpLocalKey, - size_t srtpLocalKeyLen, - uint8_t *srtpRemoteKey, - size_t srtpRemoteKeyLen, - std::string &remoteCert) { + const RTC::DtlsTransport *dtlsTransport, RTC::SrtpSession::CryptoSuite srtpCryptoSuite, uint8_t *srtpLocalKey, + size_t srtpLocalKeyLen, uint8_t *srtpRemoteKey, size_t srtpRemoteKeyLen, std::string &remoteCert) { InfoL; - _srtp_session_send = std::make_shared(RTC::SrtpSession::Type::OUTBOUND, srtpCryptoSuite, srtpLocalKey, srtpLocalKeyLen); - _srtp_session_recv = std::make_shared(RTC::SrtpSession::Type::INBOUND, srtpCryptoSuite, srtpRemoteKey, srtpRemoteKeyLen); + _srtp_session_send = std::make_shared( + RTC::SrtpSession::Type::OUTBOUND, srtpCryptoSuite, srtpLocalKey, srtpLocalKeyLen); + _srtp_session_recv = std::make_shared( + RTC::SrtpSession::Type::INBOUND, srtpCryptoSuite, srtpRemoteKey, srtpRemoteKeyLen); #ifdef ENABLE_SCTP _sctp = std::make_shared(getPoller(), this, 128, 128, 262144, true); _sctp->TransportConnected(); @@ -137,7 +135,8 @@ void WebRtcTransport::OnDtlsTransportConnected( onStartWebRTC(); } -void WebRtcTransport::OnDtlsTransportSendData(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) { +void WebRtcTransport::OnDtlsTransportSendData( + const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) { sendSockData((char *)data, len, nullptr); } @@ -155,7 +154,8 @@ void WebRtcTransport::OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransp onShutdown(SockException(Err_shutdown, "dtls close notify received")); } -void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) { +void WebRtcTransport::OnDtlsTransportApplicationDataReceived( + const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) { #ifdef ENABLE_SCTP _sctp->ProcessSctpData(data, len); #else @@ -165,63 +165,64 @@ void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTran ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef ENABLE_SCTP -void WebRtcTransport::OnSctpAssociationConnecting(RTC::SctpAssociation* sctpAssociation) { +void WebRtcTransport::OnSctpAssociationConnecting(RTC::SctpAssociation *sctpAssociation) { TraceL; } -void WebRtcTransport::OnSctpAssociationConnected(RTC::SctpAssociation* sctpAssociation) { +void WebRtcTransport::OnSctpAssociationConnected(RTC::SctpAssociation *sctpAssociation) { InfoL << getIdentifier(); } -void WebRtcTransport::OnSctpAssociationFailed(RTC::SctpAssociation* sctpAssociation) { +void WebRtcTransport::OnSctpAssociationFailed(RTC::SctpAssociation *sctpAssociation) { WarnL << getIdentifier(); } -void WebRtcTransport::OnSctpAssociationClosed(RTC::SctpAssociation* sctpAssociation) { +void WebRtcTransport::OnSctpAssociationClosed(RTC::SctpAssociation *sctpAssociation) { InfoL << getIdentifier(); } -void WebRtcTransport::OnSctpAssociationSendData(RTC::SctpAssociation* sctpAssociation, const uint8_t* data, size_t len) { +void WebRtcTransport::OnSctpAssociationSendData( + RTC::SctpAssociation *sctpAssociation, const uint8_t *data, size_t len) { _dtls_transport->SendApplicationData(data, len); } -void WebRtcTransport::OnSctpAssociationMessageReceived(RTC::SctpAssociation *sctpAssociation, uint16_t streamId, - uint32_t ppid, const uint8_t *msg, size_t len) { +void WebRtcTransport::OnSctpAssociationMessageReceived( + RTC::SctpAssociation *sctpAssociation, uint16_t streamId, uint32_t ppid, const uint8_t *msg, size_t len) { InfoL << getIdentifier() << " " << streamId << " " << ppid << " " << len << " " << string((char *)msg, len); RTC::SctpStreamParameters params; params.streamId = streamId; - //回显数据 + // 回显数据 _sctp->SendSctpMessage(params, ppid, msg, len); } #endif ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void WebRtcTransport::sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple){ +void WebRtcTransport::sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple) { auto pkt = _packet_pool.obtain2(); pkt->assign(buf, len); onSendSockData(std::move(pkt), true, tuple ? tuple : _ice_server->GetSelectedTuple()); } -RTC::TransportTuple* WebRtcTransport::getSelectedTuple() const{ - return _ice_server->GetSelectedTuple(); +RTC::TransportTuple *WebRtcTransport::getSelectedTuple() const { + return _ice_server->GetSelectedTuple(); } void WebRtcTransport::sendRtcpRemb(uint32_t ssrc, size_t bit_rate) { - auto remb = FCI_REMB::create({ssrc}, (uint32_t)bit_rate); + auto remb = FCI_REMB::create({ ssrc }, (uint32_t)bit_rate); auto fb = RtcpFB::create(PSFBType::RTCP_PSFB_REMB, remb.data(), remb.size()); fb->ssrc = htonl(0); fb->ssrc_media = htonl(ssrc); - sendRtcpPacket((char *) fb.get(), fb->getSize(), true); + sendRtcpPacket((char *)fb.get(), fb->getSize(), true); } void WebRtcTransport::sendRtcpPli(uint32_t ssrc) { auto pli = RtcpFB::create(PSFBType::RTCP_PSFB_PLI); pli->ssrc = htonl(0); pli->ssrc_media = htonl(ssrc); - sendRtcpPacket((char *) pli.get(), pli->getSize(), true); + sendRtcpPacket((char *)pli.get(), pli->getSize(), true); } -string getFingerprint(const string &algorithm_str, const std::shared_ptr &transport){ +string getFingerprint(const string &algorithm_str, const std::shared_ptr &transport) { auto algorithm = RTC::DtlsTransport::GetFingerprintAlgorithm(algorithm_str); for (auto &finger_prints : transport->GetLocalFingerprints()) { if (finger_prints.algorithm == algorithm) { @@ -231,21 +232,22 @@ string getFingerprint(const string &algorithm_str, const std::shared_ptrmedia[0].fingerprint.algorithm); + remote_fingerprint.algorithm + = RTC::DtlsTransport::GetFingerprintAlgorithm(_offer_sdp->media[0].fingerprint.algorithm); remote_fingerprint.value = _offer_sdp->media[0].fingerprint.hash; _dtls_transport->SetRemoteFingerprint(remote_fingerprint); } void WebRtcTransport::onRtcConfigure(RtcConfigure &configure) const { - //开启remb后关闭twcc,因为开启twcc后remb无效 + // 开启remb后关闭twcc,因为开启twcc后remb无效 GET_CONFIG(size_t, remb_bit_rate, RTC::kRembBitRate); configure.enableTWCC(!remb_bit_rate); } -std::string WebRtcTransport::getAnswerSdp(const string &offer){ +std::string WebRtcTransport::getAnswerSdp(const string &offer) { try { //// 解析offer sdp //// _offer_sdp = std::make_shared(); @@ -259,8 +261,8 @@ std::string WebRtcTransport::getAnswerSdp(const string &offer){ fingerprint.algorithm = _offer_sdp->media[0].fingerprint.algorithm; fingerprint.hash = getFingerprint(fingerprint.algorithm, _dtls_transport); RtcConfigure configure; - configure.setDefaultSetting(_ice_server->GetUsernameFragment(), _ice_server->GetPassword(), - RtpDirection::sendrecv, fingerprint); + configure.setDefaultSetting( + _ice_server->GetUsernameFragment(), _ice_server->GetPassword(), RtpDirection::sendrecv, fingerprint); onRtcConfigure(configure); //// 生成answer sdp //// @@ -279,22 +281,22 @@ static bool is_dtls(char *buf) { } static bool is_rtp(char *buf) { - RtpHeader *header = (RtpHeader *) buf; + RtpHeader *header = (RtpHeader *)buf; return ((header->pt < 64) || (header->pt >= 96)); } static bool is_rtcp(char *buf) { - RtpHeader *header = (RtpHeader *) buf; + RtpHeader *header = (RtpHeader *)buf; return ((header->pt >= 64) && (header->pt < 96)); } -static string getPeerAddress(RTC::TransportTuple *tuple){ +static string getPeerAddress(RTC::TransportTuple *tuple) { return SockUtil::inet_ntoa(tuple); } void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tuple) { - if (RTC::StunPacket::IsStun((const uint8_t *) buf, len)) { - std::unique_ptr packet(RTC::StunPacket::Parse((const uint8_t *) buf, len)); + if (RTC::StunPacket::IsStun((const uint8_t *)buf, len)) { + std::unique_ptr packet(RTC::StunPacket::Parse((const uint8_t *)buf, len)); if (!packet) { WarnL << "parse stun error" << std::endl; return; @@ -303,7 +305,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup return; } if (is_dtls(buf)) { - _dtls_transport->ProcessDtlsData((uint8_t *) buf, len); + _dtls_transport->ProcessDtlsData((uint8_t *)buf, len); return; } if (is_rtp(buf)) { @@ -311,7 +313,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup WarnL << "received rtp packet when dtls not completed from:" << getPeerAddress(tuple); return; } - if (_srtp_session_recv->DecryptSrtp((uint8_t *) buf, &len)) { + if (_srtp_session_recv->DecryptSrtp((uint8_t *)buf, &len)) { onRtp(buf, len, _ticker.createdTime()); } return; @@ -321,7 +323,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup WarnL << "received rtcp packet when dtls not completed from:" << getPeerAddress(tuple); return; } - if (_srtp_session_recv->DecryptSrtcp((uint8_t *) buf, &len)) { + if (_srtp_session_recv->DecryptSrtcp((uint8_t *)buf, &len)) { onRtcp(buf, len); } return; @@ -331,8 +333,8 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup void WebRtcTransport::sendRtpPacket(const char *buf, int len, bool flush, void *ctx) { if (_srtp_session_send) { auto pkt = _packet_pool.obtain2(); - //预留rtx加入的两个字节 - pkt->setCapacity((size_t) len + SRTP_MAX_TRAILER_LEN + 2); + // 预留rtx加入的两个字节 + pkt->setCapacity((size_t)len + SRTP_MAX_TRAILER_LEN + 2); pkt->assign(buf, len); onBeforeEncryptRtp(pkt->data(), len, ctx); if (_srtp_session_send->EncryptRtp(reinterpret_cast(pkt->data()), &len)) { @@ -345,8 +347,8 @@ void WebRtcTransport::sendRtpPacket(const char *buf, int len, bool flush, void * void WebRtcTransport::sendRtcpPacket(const char *buf, int len, bool flush, void *ctx) { if (_srtp_session_send) { auto pkt = _packet_pool.obtain2(); - //预留rtx加入的两个字节 - pkt->setCapacity((size_t) len + SRTP_MAX_TRAILER_LEN + 2); + // 预留rtx加入的两个字节 + pkt->setCapacity((size_t)len + SRTP_MAX_TRAILER_LEN + 2); pkt->assign(buf, len); onBeforeEncryptRtcp(pkt->data(), len, ctx); if (_srtp_session_send->EncryptRtcp(reinterpret_cast(pkt->data()), &len)) { @@ -358,29 +360,31 @@ void WebRtcTransport::sendRtcpPacket(const char *buf, int len, bool flush, void /////////////////////////////////////////////////////////////////////////////////// -void WebRtcTransportImp::onCreate(){ +void WebRtcTransportImp::onCreate() { WebRtcTransport::onCreate(); registerSelf(); weak_ptr weak_self = static_pointer_cast(shared_from_this()); GET_CONFIG(float, timeoutSec, RTC::kTimeOutSec); - _timer = std::make_shared(timeoutSec / 2, [weak_self]() { - auto strong_self = weak_self.lock(); - if (!strong_self) { - return false; - } - if (strong_self->_alive_ticker.elapsedTime() > timeoutSec * 1000) { - strong_self->onShutdown(SockException(Err_timeout, "接受rtp和rtcp超时")); - } - return true; - }, getPoller()); + _timer = std::make_shared( + timeoutSec / 2, + [weak_self]() { + auto strong_self = weak_self.lock(); + if (!strong_self) { + return false; + } + if (strong_self->_alive_ticker.elapsedTime() > timeoutSec * 1000) { + strong_self->onShutdown(SockException(Err_timeout, "接受rtp和rtcp超时")); + } + return true; + }, + getPoller()); - _twcc_ctx.setOnSendTwccCB([this](uint32_t ssrc, string fci) { - onSendTwcc(ssrc, fci); - }); + _twcc_ctx.setOnSendTwccCB([this](uint32_t ssrc, string fci) { onSendTwcc(ssrc, fci); }); } -WebRtcTransportImp::WebRtcTransportImp(const EventPoller::Ptr &poller) : WebRtcTransport(poller) { +WebRtcTransportImp::WebRtcTransportImp(const EventPoller::Ptr &poller) + : WebRtcTransport(poller) { InfoL << getIdentifier(); } @@ -398,14 +402,14 @@ void WebRtcTransportImp::onSendSockData(Buffer::Ptr buf, bool flush, RTC::Transp WarnL << "send data failed:" << buf->size(); return; } - //一次性发送一帧的rtp数据,提高网络io性能 + // 一次性发送一帧的rtp数据,提高网络io性能 _selected_session->setSendFlushFlag(flush); _selected_session->send(std::move(buf)); } /////////////////////////////////////////////////////////////////// -bool WebRtcTransportImp::canSendRtp() const{ +bool WebRtcTransportImp::canSendRtp() const { for (auto &m : _answer_sdp->media) { if (m.direction == RtpDirection::sendrecv || m.direction == RtpDirection::sendonly) { return true; @@ -414,7 +418,7 @@ bool WebRtcTransportImp::canSendRtp() const{ return false; } -bool WebRtcTransportImp::canRecvRtp() const{ +bool WebRtcTransportImp::canRecvRtp() const { for (auto &m : _answer_sdp->media) { if (m.direction == RtpDirection::sendrecv || m.direction == RtpDirection::recvonly) { return true; @@ -424,7 +428,7 @@ bool WebRtcTransportImp::canRecvRtp() const{ } void WebRtcTransportImp::onStartWebRTC() { - //获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息 + // 获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息 for (auto &m_answer : _answer_sdp->media) { if (m_answer.type == TrackApplication) { continue; @@ -441,42 +445,43 @@ void WebRtcTransportImp::onStartWebRTC() { track->plan_rtx = m_answer.getRelatedRtxPlan(track->plan_rtp->pt); track->rtcp_context_send = std::make_shared(); - //rtp track type --> MediaTrack + // rtp track type --> MediaTrack if (m_answer.direction == RtpDirection::sendonly || m_answer.direction == RtpDirection::sendrecv) { - //该类型的track 才支持发送 + // 该类型的track 才支持发送 _type_to_track[m_answer.type] = track; } - //send ssrc --> MediaTrack + // send ssrc --> MediaTrack _ssrc_to_track[track->answer_ssrc_rtp] = track; _ssrc_to_track[track->answer_ssrc_rtx] = track; - //recv ssrc --> MediaTrack + // recv ssrc --> MediaTrack _ssrc_to_track[track->offer_ssrc_rtp] = track; _ssrc_to_track[track->offer_ssrc_rtx] = track; - //rtp pt --> MediaTrack - _pt_to_track.emplace(track->plan_rtp->pt, std::unique_ptr(new WrappedRtpTrack(track, _twcc_ctx, *this))); + // rtp pt --> MediaTrack + _pt_to_track.emplace( + track->plan_rtp->pt, std::unique_ptr(new WrappedRtpTrack(track, _twcc_ctx, *this))); if (track->plan_rtx) { - //rtx pt --> MediaTrack + // rtx pt --> MediaTrack _pt_to_track.emplace(track->plan_rtx->pt, std::unique_ptr(new WrappedRtxTrack(track))); } - //记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id + // 记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id track->rtp_ext_ctx = std::make_shared(*m_offer); weak_ptr weak_track = track; track->rtp_ext_ctx->setOnGetRtp([this, weak_track](uint8_t pt, uint32_t ssrc, const string &rid) { - //ssrc --> MediaTrack + // ssrc --> MediaTrack auto track = weak_track.lock(); assert(track); _ssrc_to_track[ssrc] = std::move(track); - InfoL << "get rtp, pt:" << (int) pt << ", ssrc:" << ssrc << ", rid:" << rid; + InfoL << "get rtp, pt:" << (int)pt << ", ssrc:" << ssrc << ", rid:" << rid; }); size_t index = 0; for (auto &ssrc : m_offer->rtp_ssrc_sim) { - //记录ssrc对应的MediaTrack + // 记录ssrc对应的MediaTrack _ssrc_to_track[ssrc.ssrc] = track; if (m_offer->rtp_rids.size() > index) { - //支持firefox的simulcast, 提前映射好ssrc和rid的关系 + // 支持firefox的simulcast, 提前映射好ssrc和rid的关系 track->rtp_ext_ctx->setRid(ssrc.ssrc, m_offer->rtp_rids[index]); } else { // SDP munging没有rid, 它通过group-ssrc:SIM给出ssrc列表; @@ -493,7 +498,7 @@ void WebRtcTransportImp::onStartWebRTC() { } void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) { - //修改answer sdp的ip、端口信息 + // 修改answer sdp的ip、端口信息 GET_CONFIG_FUNC(std::vector, extern_ips, RTC::kExternIP, [](string str) { std::vector ret; if (str.length()) { @@ -515,7 +520,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) { } if (!canSendRtp()) { - //设置我们发送的rtp的ssrc + // 设置我们发送的rtp的ssrc return; } @@ -524,13 +529,13 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) { continue; } if (!m.rtp_rtx_ssrc.empty()) { - //已经生成了ssrc + // 已经生成了ssrc continue; } - //添加answer sdp的ssrc信息 + // 添加answer sdp的ssrc信息 m.rtp_rtx_ssrc.emplace_back(); auto &ssrc = m.rtp_rtx_ssrc.back(); - //发送的ssrc我们随便定义,因为在发送rtp时会修改为此值 + // 发送的ssrc我们随便定义,因为在发送rtp时会修改为此值 ssrc.ssrc = m.type + RTP_SSRC_OFFSET; ssrc.cname = RTP_CNAME; ssrc.label = RTP_LABEL; @@ -538,7 +543,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) { ssrc.msid = RTP_MSID; if (m.getRelatedRtxPlan(m.plan[0].pt)) { - //rtx ssrc + // rtx ssrc ssrc.rtx_ssrc = ssrc.ssrc + RTX_SSRC_OFFSET; } } @@ -546,20 +551,25 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) { void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp) { switch (type) { - case SdpType::answer: onCheckAnswer(sdp); break; - case SdpType::offer: break; - default: /*不可达*/ assert(0); break; + case SdpType::answer: + onCheckAnswer(sdp); + break; + case SdpType::offer: + break; + default: /*不可达*/ + assert(0); + break; } } -SdpAttrCandidate::Ptr makeIceCandidate(std::string ip, uint16_t port, - uint32_t priority = 100, std::string proto = "udp") { +SdpAttrCandidate::Ptr +makeIceCandidate(std::string ip, uint16_t port, uint32_t priority = 100, std::string proto = "udp") { auto candidate = std::make_shared(); - //rtp端口 + // rtp端口 candidate->component = 1; candidate->transport = proto; candidate->foundation = proto + "candidate"; - //优先级,单candidate时随便 + // 优先级,单candidate时随便 candidate->priority = priority; candidate->address = ip; candidate->port = port; @@ -569,10 +579,10 @@ SdpAttrCandidate::Ptr makeIceCandidate(std::string ip, uint16_t port, void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const { WebRtcTransport::onRtcConfigure(configure); - + GET_CONFIG(uint16_t, local_port, RTC::kPort); - //添加接收端口candidate信息 - GET_CONFIG_FUNC(std::vector, extern_ips, RTC::kExternIP, [](string str){ + // 添加接收端口candidate信息 + GET_CONFIG_FUNC(std::vector, extern_ips, RTC::kExternIP, [](string str) { std::vector ret; if (str.length()) { ret = split(str, ","); @@ -593,19 +603,18 @@ void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const { } } - /////////////////////////////////////////////////////////////////// -class RtpChannel : public RtpTrackImp, public std::enable_shared_from_this { +class RtpChannel + : public RtpTrackImp + , public std::enable_shared_from_this { public: RtpChannel(EventPoller::Ptr poller, RtpTrackImp::OnSorted cb, function on_nack) { _poller = std::move(poller); _on_nack = std::move(on_nack); setOnSorted(std::move(cb)); - _nack_ctx.setOnNack([this](const FCI_NACK &nack) { - onNack(nack); - }); + _nack_ctx.setOnNack([this](const FCI_NACK &nack) { onNack(nack); }); } ~RtpChannel() override = default; @@ -618,7 +627,7 @@ public: auto seq = rtp->getSeq(); _nack_ctx.received(seq, is_rtx); if (!is_rtx) { - //统计rtp接受情况,便于生成nack rtcp包 + // 统计rtp接受情况,便于生成nack rtcp包 _rtcp_context.onRtp(seq, rtp->getStamp(), rtp->ntp_stamp, sample_rate, len); } return rtp; @@ -630,7 +639,7 @@ public: } int getLossRate() { - auto expected = _rtcp_context.getExpectedPacketsInterval(); + auto expected = _rtcp_context.getExpectedPacketsInterval(); if (!expected) { return 0; } @@ -638,7 +647,7 @@ public: } private: - void starNackTimer(){ + void starNackTimer() { if (_delay_task) { return; } @@ -669,7 +678,7 @@ private: function _on_nack; }; -std::shared_ptr MediaTrack::getRtpChannel(uint32_t ssrc) const{ +std::shared_ptr MediaTrack::getRtpChannel(uint32_t ssrc) const { auto it_chn = rtp_channel.find(rtp_ext_ctx->getRid(ssrc)); if (it_chn == rtp_channel.end()) { return nullptr; @@ -693,105 +702,107 @@ int WebRtcTransportImp::getLossRate(mediakit::TrackType type) { void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { _bytes_usage += len; - auto rtcps = RtcpHeader::loadFromBytes((char *) buf, len); + auto rtcps = RtcpHeader::loadFromBytes((char *)buf, len); for (auto rtcp : rtcps) { - switch ((RtcpType) rtcp->pt) { - case RtcpType::RTCP_SR : { - //对方汇报rtp发送情况 - RtcpSR *sr = (RtcpSR *) rtcp; - auto it = _ssrc_to_track.find(sr->ssrc); + switch ((RtcpType)rtcp->pt) { + case RtcpType::RTCP_SR: { + // 对方汇报rtp发送情况 + RtcpSR *sr = (RtcpSR *)rtcp; + auto it = _ssrc_to_track.find(sr->ssrc); + if (it != _ssrc_to_track.end()) { + auto &track = it->second; + auto rtp_chn = track->getRtpChannel(sr->ssrc); + if (!rtp_chn) { + WarnL << "未识别的sr rtcp包:" << rtcp->dumpString(); + } else { + // InfoL << "接收丢包率,ssrc:" << sr->ssrc << ",loss rate(%):" << rtp_chn->getLossRate(); + // 设置rtp时间戳与ntp时间戳的对应关系 + rtp_chn->setNtpStamp(sr->rtpts, sr->getNtpUnixStampMS()); + auto rr = rtp_chn->createRtcpRR(sr, track->answer_ssrc_rtp); + sendRtcpPacket(rr->data(), rr->size(), true); + } + } else { + WarnL << "未识别的sr rtcp包:" << rtcp->dumpString(); + } + break; + } + case RtcpType::RTCP_RR: { + _alive_ticker.resetTime(); + // 对方汇报rtp接收情况 + RtcpRR *rr = (RtcpRR *)rtcp; + for (auto item : rr->getItemList()) { + auto it = _ssrc_to_track.find(item->ssrc); if (it != _ssrc_to_track.end()) { auto &track = it->second; - auto rtp_chn = track->getRtpChannel(sr->ssrc); - if (!rtp_chn) { - WarnL << "未识别的sr rtcp包:" << rtcp->dumpString(); - } else { - //InfoL << "接收丢包率,ssrc:" << sr->ssrc << ",loss rate(%):" << rtp_chn->getLossRate(); - //设置rtp时间戳与ntp时间戳的对应关系 - rtp_chn->setNtpStamp(sr->rtpts, sr->getNtpUnixStampMS()); - auto rr = rtp_chn->createRtcpRR(sr, track->answer_ssrc_rtp); - sendRtcpPacket(rr->data(), rr->size(), true); - } + track->rtcp_context_send->onRtcp(rtcp); + auto sr = track->rtcp_context_send->createRtcpSR(track->answer_ssrc_rtp); + sendRtcpPacket(sr->data(), sr->size(), true); } else { - WarnL << "未识别的sr rtcp包:" << rtcp->dumpString(); + WarnL << "未识别的rr rtcp包:" << rtcp->dumpString(); } - break; } - case RtcpType::RTCP_RR : { - _alive_ticker.resetTime(); - //对方汇报rtp接收情况 - RtcpRR *rr = (RtcpRR *) rtcp; - for (auto item : rr->getItemList()) { - auto it = _ssrc_to_track.find(item->ssrc); - if (it != _ssrc_to_track.end()) { - auto &track = it->second; - track->rtcp_context_send->onRtcp(rtcp); - auto sr = track->rtcp_context_send->createRtcpSR(track->answer_ssrc_rtp); - sendRtcpPacket(sr->data(), sr->size(), true); - } else { - WarnL << "未识别的rr rtcp包:" << rtcp->dumpString(); - } - } - break; - } - case RtcpType::RTCP_BYE : { - //对方汇报停止发送rtp - RtcpBye *bye = (RtcpBye *) rtcp; - for (auto ssrc : bye->getSSRC()) { - auto it = _ssrc_to_track.find(*ssrc); - if (it == _ssrc_to_track.end()) { - WarnL << "未识别的bye rtcp包:" << rtcp->dumpString(); - continue; - } - _ssrc_to_track.erase(it); - } - onShutdown(SockException(Err_eof, "rtcp bye message received")); - break; - } - case RtcpType::RTCP_PSFB: - case RtcpType::RTCP_RTPFB: { - if ((RtcpType) rtcp->pt == RtcpType::RTCP_PSFB) { - break; - } - //RTPFB - switch ((RTPFBType) rtcp->report_count) { - case RTPFBType::RTCP_RTPFB_NACK : { - RtcpFB *fb = (RtcpFB *) rtcp; - auto it = _ssrc_to_track.find(fb->ssrc_media); - if (it == _ssrc_to_track.end()) { - WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); - return; - } - auto &track = it->second; - auto &fci = fb->getFci(); - track->nack_list.forEach(fci, [&](const RtpPacket::Ptr &rtp) { - //rtp重传 - onSendRtp(rtp, true, true); - }); - break; - } - default: break; - } - break; - } - case RtcpType::RTCP_XR:{ - RtcpXRRRTR* xr = (RtcpXRRRTR *) rtcp; - if(xr->bt != 4){ - break; - } - auto it = _ssrc_to_track.find(xr->ssrc); + break; + } + case RtcpType::RTCP_BYE: { + // 对方汇报停止发送rtp + RtcpBye *bye = (RtcpBye *)rtcp; + for (auto ssrc : bye->getSSRC()) { + auto it = _ssrc_to_track.find(*ssrc); if (it == _ssrc_to_track.end()) { - WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); - return; + WarnL << "未识别的bye rtcp包:" << rtcp->dumpString(); + continue; + } + _ssrc_to_track.erase(it); + } + onShutdown(SockException(Err_eof, "rtcp bye message received")); + break; + } + case RtcpType::RTCP_PSFB: + case RtcpType::RTCP_RTPFB: { + if ((RtcpType)rtcp->pt == RtcpType::RTCP_PSFB) { + break; + } + // RTPFB + switch ((RTPFBType)rtcp->report_count) { + case RTPFBType::RTCP_RTPFB_NACK: { + RtcpFB *fb = (RtcpFB *)rtcp; + auto it = _ssrc_to_track.find(fb->ssrc_media); + if (it == _ssrc_to_track.end()) { + WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); + return; } auto &track = it->second; - track->rtcp_context_send->onRtcp(rtcp); - auto xrdlrr = track->rtcp_context_send->createRtcpXRDLRR(track->answer_ssrc_rtp,track->answer_ssrc_rtp); - sendRtcpPacket(xrdlrr->data(), xrdlrr->size(), true); - + auto &fci = fb->getFci(); + track->nack_list.forEach(fci, [&](const RtpPacket::Ptr &rtp) { + // rtp重传 + onSendRtp(rtp, true, true); + }); break; } - default: break; + default: + break; + } + break; + } + case RtcpType::RTCP_XR: { + RtcpXRRRTR *xr = (RtcpXRRRTR *)rtcp; + if (xr->bt != 4) { + break; + } + auto it = _ssrc_to_track.find(xr->ssrc); + if (it == _ssrc_to_track.end()) { + WarnL << "未识别的 rtcp包:" << rtcp->dumpString(); + return; + } + auto &track = it->second; + track->rtcp_context_send->onRtcp(rtcp); + auto xrdlrr = track->rtcp_context_send->createRtcpXRDLRR(track->answer_ssrc_rtp, track->answer_ssrc_rtp); + sendRtcpPacket(xrdlrr->data(), xrdlrr->size(), true); + + break; + } + default: + break; } } } @@ -799,18 +810,18 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { /////////////////////////////////////////////////////////////////// void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, MediaTrack &track) { - //rid --> RtpReceiverImp + // rid --> RtpReceiverImp auto &ref = track.rtp_channel[rid]; weak_ptr weak_self = dynamic_pointer_cast(shared_from_this()); - ref = std::make_shared(getPoller(), [&track, this, rid](RtpPacket::Ptr rtp) mutable { - onSortedRtp(track, rid, std::move(rtp)); - }, [&track, weak_self, ssrc](const FCI_NACK &nack) mutable { - //nack发送可能由定时器异步触发 - auto strong_self = weak_self.lock(); - if (strong_self) { - strong_self->onSendNack(track, nack, ssrc); - } - }); + ref = std::make_shared( + getPoller(), [&track, this, rid](RtpPacket::Ptr rtp) mutable { onSortedRtp(track, rid, std::move(rtp)); }, + [&track, weak_self, ssrc](const FCI_NACK &nack) mutable { + // nack发送可能由定时器异步触发 + auto strong_self = weak_self.lock(); + if (strong_self) { + strong_self->onSendNack(track, nack, ssrc); + } + }); InfoL << "create rtp receiver of ssrc:" << ssrc << ", rid:" << rid << ", codec:" << track.plan_rtp->codec; } @@ -822,8 +833,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) { _bytes_usage += len; _alive_ticker.resetTime(); - RtpHeader *rtp = (RtpHeader *) buf; - //根据接收到的rtp的pt信息,找到该流的信息 + RtpHeader *rtp = (RtpHeader *)buf; + // 根据接收到的rtp的pt信息,找到该流的信息 auto it = _pt_to_track.find(rtp->pt); if (it == _pt_to_track.end()) { WarnL << "unknown rtp pt:" << (int)rtp->pt; @@ -840,10 +851,10 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R return; } #endif - + auto ssrc = ntohl(rtp->ssrc); - //修改ext id至统一 + // 修改ext id至统一 string rid; auto twcc_ext = track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc); @@ -856,66 +867,67 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R _transport.createRtpChannel(rid, ssrc, *track); } - //解析并排序rtp - ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *) buf, len, false); + // 解析并排序rtp + ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *)buf, len, false); } void WrappedRtxTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) { - //修改ext id至统一 + // 修改ext id至统一 string rid; track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc); auto &ref = track->rtp_channel[rid]; if (!ref) { - //再接收到对应的rtp前,丢弃rtx包 - WarnL << "unknown rtx rtp, rid:" << rid << ", ssrc:" << ntohl(rtp->ssrc) << ", codec:" << track->plan_rtp->codec << ", seq:" << ntohs(rtp->seq); + // 再接收到对应的rtp前,丢弃rtx包 + WarnL << "unknown rtx rtp, rid:" << rid << ", ssrc:" << ntohl(rtp->ssrc) << ", codec:" << track->plan_rtp->codec + << ", seq:" << ntohs(rtp->seq); return; } - //这里是rtx重传包 - // https://datatracker.ietf.org/doc/html/rfc4588#section-4 + // 这里是rtx重传包 + // https://datatracker.ietf.org/doc/html/rfc4588#section-4 auto payload = rtp->getPayloadData(); auto size = rtp->getPayloadSize(len); if (size < 2) { return; } - //前两个字节是原始的rtp的seq + // 前两个字节是原始的rtp的seq auto origin_seq = payload[0] << 8 | payload[1]; // rtx 转换为 rtp rtp->pt = track->plan_rtp->pt; rtp->seq = htons(origin_seq); rtp->ssrc = htonl(ref->getSSRC()); - memmove((uint8_t *) buf + 2, buf, payload - (uint8_t *) buf); + memmove((uint8_t *)buf + 2, buf, payload - (uint8_t *)buf); buf += 2; len -= 2; - ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *) buf, len, true); + ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *)buf, len, true); } void WebRtcTransportImp::onSendNack(MediaTrack &track, const FCI_NACK &nack, uint32_t ssrc) { auto rtcp = RtcpFB::create(RTPFBType::RTCP_RTPFB_NACK, &nack, FCI_NACK::kSize); rtcp->ssrc = htonl(track.answer_ssrc_rtp); rtcp->ssrc_media = htonl(ssrc); - sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true); + sendRtcpPacket((char *)rtcp.get(), rtcp->getSize(), true); } void WebRtcTransportImp::onSendTwcc(uint32_t ssrc, const string &twcc_fci) { auto rtcp = RtcpFB::create(RTPFBType::RTCP_RTPFB_TWCC, twcc_fci.data(), twcc_fci.size()); rtcp->ssrc = htonl(0); rtcp->ssrc_media = htonl(ssrc); - sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true); + sendRtcpPacket((char *)rtcp.get(), rtcp->getSize(), true); } /////////////////////////////////////////////////////////////////// void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp) { if (track.media->type == TrackVideo && _pli_ticker.elapsedTime() > 2000) { - //定期发送pli请求关键帧,方便非rtc等协议 + // 定期发送pli请求关键帧,方便非rtc等协议 _pli_ticker.resetTime(); sendRtcpPli(rtp->getSSRC()); - //开启remb,则发送remb包调节比特率 + // 开启remb,则发送remb包调节比特率 GET_CONFIG(size_t, remb_bit_rate, RTC::kRembBitRate); if (remb_bit_rate && _answer_sdp->supportRtcpFb(SdpConst::kRembRtcpFb)) { sendRtcpRemb(rtp->getSSRC(), remb_bit_rate); @@ -930,12 +942,14 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPa void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx) { auto &track = _type_to_track[rtp->type]; if (!track) { - //忽略,对方不支持该编码类型 + // 忽略,对方不支持该编码类型 return; } if (!rtx) { - //统计rtp发送情况,好做sr汇报 - track->rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, rtp->size() - RtpPacket::kRtpTcpHeaderSize); + // 统计rtp发送情况,好做sr汇报 + track->rtcp_context_send->onRtp( + rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, + rtp->size() - RtpPacket::kRtpTcpHeaderSize); track->nack_list.pushBack(rtp); #if 0 //此处模拟发送丢包 @@ -944,45 +958,45 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r } #endif } else { - //发送rtx重传包 - //TraceL << "send rtx rtp:" << rtp->getSeq(); + // 发送rtx重传包 + // TraceL << "send rtx rtp:" << rtp->getSeq(); } - pair ctx{rtx, track.get()}; + pair ctx { rtx, track.get() }; sendRtpPacket(rtp->data() + RtpPacket::kRtpTcpHeaderSize, rtp->size() - RtpPacket::kRtpTcpHeaderSize, flush, &ctx); _bytes_usage += rtp->size() - RtpPacket::kRtpTcpHeaderSize; } void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, int &len, void *ctx) { - auto pr = (pair *) ctx; - auto header = (RtpHeader *) buf; + auto pr = (pair *)ctx; + auto header = (RtpHeader *)buf; if (!pr->first || !pr->second->plan_rtx) { - //普通的rtp,或者不支持rtx, 修改目标pt和ssrc + // 普通的rtp,或者不支持rtx, 修改目标pt和ssrc pr->second->rtp_ext_ctx->changeRtpExtId(header, false); header->pt = pr->second->plan_rtp->pt; header->ssrc = htonl(pr->second->answer_ssrc_rtp); } else { - //重传的rtp, rtx + // 重传的rtp, rtx pr->second->rtp_ext_ctx->changeRtpExtId(header, false); header->pt = pr->second->plan_rtx->pt; if (pr->second->answer_ssrc_rtx) { - //有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc + // 有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc header->ssrc = htonl(pr->second->answer_ssrc_rtx); } else { - //未单独指定rtx的ssrc,那么使用rtp的ssrc + // 未单独指定rtx的ssrc,那么使用rtp的ssrc header->ssrc = htonl(pr->second->answer_ssrc_rtp); } auto origin_seq = ntohs(header->seq); - //seq跟原来的不一样 + // seq跟原来的不一样 header->seq = htons(_rtx_seq[pr->second->media->type]); ++_rtx_seq[pr->second->media->type]; auto payload = header->getPayloadData(); auto payload_size = header->getPayloadSize(len); if (payload_size) { - //rtp负载后移两个字节,这两个字节用于存放osn - //https://datatracker.ietf.org/doc/html/rfc4588#section-4 + // rtp负载后移两个字节,这两个字节用于存放osn + // https://datatracker.ietf.org/doc/html/rfc4588#section-4 memmove(payload + 2, payload, payload_size); } payload[0] = origin_seq >> 8; @@ -991,7 +1005,7 @@ void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, int &len, void *ctx } } -void WebRtcTransportImp::onShutdown(const SockException &ex){ +void WebRtcTransportImp::onShutdown(const SockException &ex) { WarnL << ex.what(); unrefSelf(); for (auto &pr : _history_sessions) { @@ -1005,8 +1019,9 @@ void WebRtcTransportImp::onShutdown(const SockException &ex){ void WebRtcTransportImp::setSession(Session::Ptr session) { _history_sessions.emplace(session.get(), session); if (_selected_session) { - InfoL << "rtc network changed: " << _selected_session->get_peer_ip() << ":" << _selected_session->get_peer_port() - << " -> " << session->get_peer_ip() << ":" << session->get_peer_port() << ", id:" << getIdentifier(); + InfoL << "rtc network changed: " << _selected_session->get_peer_ip() << ":" + << _selected_session->get_peer_port() << " -> " << session->get_peer_ip() << ":" + << session->get_peer_port() << ", id:" << getIdentifier(); } _selected_session = std::move(session); unrefSelf(); @@ -1016,18 +1031,18 @@ const Session::Ptr &WebRtcTransportImp::getSession() const { return _selected_session; } -uint64_t WebRtcTransportImp::getBytesUsage() const{ +uint64_t WebRtcTransportImp::getBytesUsage() const { return _bytes_usage; } -uint64_t WebRtcTransportImp::getDuration() const{ +uint64_t WebRtcTransportImp::getDuration() const { return _alive_ticker.createdTime() / 1000; } ///////////////////////////////////////////////////////////////////////////////////////////// void WebRtcTransportImp::registerSelf() { - _self = static_pointer_cast(shared_from_this()); + _self = static_pointer_cast(shared_from_this()); WebRtcTransportManager::Instance().addItem(getIdentifier(), _self); } @@ -1079,8 +1094,8 @@ void WebRtcPluginManager::registerPlugin(const string &type, Plugin cb) { _map_creator[type] = std::move(cb); } -void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, const string &offer, const WebRtcArgs &args, - const onCreateRtc &cb) { +void WebRtcPluginManager::getAnswerSdp( + Session &sender, const string &type, const string &offer, const WebRtcArgs &args, const onCreateRtc &cb) { lock_guard lck(_mtx_creator); auto it = _map_creator.find(type); if (it == _map_creator.end()) { @@ -1090,17 +1105,20 @@ void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, cons it->second(sender, offer, args, cb); } +#include "WebRtcEchoTest.h" #include "WebRtcPlayer.h" #include "WebRtcPusher.h" -#include "WebRtcEchoTest.h" -void echo_plugin(Session &sender, const string &offer, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void echo_plugin( + Session &sender, const string &offer, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { cb(*WebRtcEchoTest::create(EventPollerPool::Instance().getPoller())); } -void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void push_plugin( + Session &sender, const string &offer_sdp, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { MediaInfo info(args["url"]); - Broadcast::PublishAuthInvoker invoker = [cb, offer_sdp, info](const string &err, const ProtocolOption &option) mutable { + Broadcast::PublishAuthInvoker invoker = [cb, offer_sdp, + info](const string &err, const ProtocolOption &option) mutable { if (!err.empty()) { cb(WebRtcException(SockException(Err_other, err))); return; @@ -1112,15 +1130,15 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg auto push_failed = (bool)src; while (src) { - //尝试断连后继续推流 + // 尝试断连后继续推流 auto rtsp_src = dynamic_pointer_cast(src); if (!rtsp_src) { - //源不是rtsp推流产生的 + // 源不是rtsp推流产生的 break; } auto ownership = rtsp_src->getOwnership(); if (!ownership) { - //获取推流源所有权失败 + // 获取推流源所有权失败 break; } push_src = std::move(rtsp_src); @@ -1139,20 +1157,23 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg push_src_ownership = push_src->getOwnership(); push_src->setProtocolOption(option); } - auto rtc = WebRtcPusher::create(EventPollerPool::Instance().getPoller(), push_src, push_src_ownership, info, option); + auto rtc + = WebRtcPusher::create(EventPollerPool::Instance().getPoller(), push_src, push_src_ownership, info, option); push_src->setListener(rtc); cb(*rtc); }; - //rtsp推流需要鉴权 - auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, MediaOriginType::rtc_push, info, invoker, static_cast(sender)); + // rtsp推流需要鉴权 + auto flag = NoticeCenter::Instance().emitEvent( + Broadcast::kBroadcastMediaPublish, MediaOriginType::rtc_push, info, invoker, static_cast(sender)); if (!flag) { - //该事件无人监听,默认不鉴权 + // 该事件无人监听,默认不鉴权 invoker("", ProtocolOption()); } } -void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void play_plugin( + Session &sender, const string &offer_sdp, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { MediaInfo info(args["url"]); auto session_ptr = sender.shared_from_this(); Broadcast::AuthInvoker invoker = [cb, offer_sdp, info, session_ptr](const string &err) mutable { @@ -1161,7 +1182,7 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg return; } - //webrtc播放的是rtsp的源 + // webrtc播放的是rtsp的源 info._schema = RTSP_SCHEMA; MediaSource::findAsync(info, session_ptr, [=](const MediaSource::Ptr &src_in) mutable { auto src = dynamic_pointer_cast(src_in); @@ -1169,22 +1190,23 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg cb(WebRtcException(SockException(Err_other, "stream not found"))); return; } - //还原成rtc,目的是为了hook时识别哪种播放协议 + // 还原成rtc,目的是为了hook时识别哪种播放协议 info._schema = RTC_SCHEMA; auto rtc = WebRtcPlayer::create(EventPollerPool::Instance().getPoller(), src, info); cb(*rtc); }); }; - //广播通用播放url鉴权事件 - auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed, info, invoker, static_cast(sender)); + // 广播通用播放url鉴权事件 + auto flag = NoticeCenter::Instance().emitEvent( + Broadcast::kBroadcastMediaPlayed, info, invoker, static_cast(sender)); if (!flag) { - //该事件无人监听,默认不鉴权 + // 该事件无人监听,默认不鉴权 invoker(""); } } -static onceToken s_rtc_auto_register([](){ +static onceToken s_rtc_auto_register([]() { WebRtcPluginManager::Instance().registerPlugin("echo", echo_plugin); WebRtcPluginManager::Instance().registerPlugin("push", push_plugin); WebRtcPluginManager::Instance().registerPlugin("play", play_plugin);