Commit cffc0743 by xiongguangjie

format code use clang-format

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