Commit cffc0743 by xiongguangjie

format code use clang-format

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