mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
完善rtcp feedback相关代码
This commit is contained in:
parent
caceb90b40
commit
8702ad101b
@ -52,7 +52,7 @@ const char *rtpfbTypeToStr(RTPFBType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static size_t alignSize(size_t bytes) {
|
static size_t alignSize(size_t bytes) {
|
||||||
return (size_t)((bytes + 3) / 4) << 2;
|
return (size_t)((bytes + 3) >> 2 ) << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, size_t total_bytes) {
|
static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, size_t total_bytes) {
|
||||||
@ -64,23 +64,32 @@ static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, si
|
|||||||
//items总个数
|
//items总个数
|
||||||
rtcp->report_count = report_count;
|
rtcp->report_count = report_count;
|
||||||
rtcp->pt = (uint8_t) type;
|
rtcp->pt = (uint8_t) type;
|
||||||
//不包含rtcp头的长度
|
rtcp->setSize(total_bytes);
|
||||||
rtcp->length = htons((uint16_t)((total_bytes / 4) - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void RtcpHeader::net2Host() {
|
|
||||||
length = ntohs(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
string RtcpHeader::dumpHeader() const{
|
string RtcpHeader::dumpHeader() const{
|
||||||
_StrPrinter printer;
|
_StrPrinter printer;
|
||||||
printer << "version:" << version << "\r\n";
|
printer << "version:" << version << "\r\n";
|
||||||
printer << "padding:" << padding << "\r\n";
|
printer << "padding:" << padding << "\r\n";
|
||||||
printer << "report_count:" << 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";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default : {
|
||||||
|
printer << "report_count:" << report_count << "\r\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printer << "pt:" << rtcpTypeToStr((RtcpType)pt) << "\r\n";
|
printer << "pt:" << rtcpTypeToStr((RtcpType)pt) << "\r\n";
|
||||||
printer << "length:" << length << "\r\n";
|
printer << "size:" << getSize() << "\r\n";
|
||||||
printer << "--------\r\n";
|
printer << "--------\r\n";
|
||||||
return std::move(printer);
|
return std::move(printer);
|
||||||
}
|
}
|
||||||
@ -102,8 +111,9 @@ string RtcpHeader::dumpString() const {
|
|||||||
return rtcp->dumpString();
|
return rtcp->dumpString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RtcpType::RTCP_RTPFB:
|
||||||
case RtcpType::RTCP_PSFB: {
|
case RtcpType::RTCP_PSFB: {
|
||||||
RtcpPli *rtcp = (RtcpPli *)this;
|
RtcpFB *rtcp = (RtcpFB *)this;
|
||||||
return rtcp->dumpString();
|
return rtcp->dumpString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,12 +122,18 @@ string RtcpHeader::dumpString() const {
|
|||||||
return rtcp->dumpString();
|
return rtcp->dumpString();
|
||||||
}
|
}
|
||||||
|
|
||||||
default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), length << 2);
|
default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), getSize() - sizeof(*this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RtcpHeader::getSize() const {
|
size_t RtcpHeader::getSize() const {
|
||||||
return (1 + length) << 2;
|
//加上rtcp头长度
|
||||||
|
return (1 + ntohs(length)) << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcpHeader::setSize(size_t size) {
|
||||||
|
//不包含rtcp头的长度
|
||||||
|
length = htons((uint16_t)((size >> 2) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcpHeader::net2Host(size_t len){
|
void RtcpHeader::net2Host(size_t len){
|
||||||
@ -140,9 +156,10 @@ void RtcpHeader::net2Host(size_t len){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RtcpType::RTCP_RTPFB:
|
||||||
case RtcpType::RTCP_PSFB: {
|
case RtcpType::RTCP_PSFB: {
|
||||||
RtcpPli *pli = (RtcpPli *)this;
|
RtcpFB *fb = (RtcpFB *)this;
|
||||||
pli->net2Host(len);
|
fb->net2Host(len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +169,6 @@ void RtcpHeader::net2Host(size_t len){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RtcpType::RTCP_RTPFB: {
|
|
||||||
RtcpPli *pli = (RtcpPli *)this;
|
|
||||||
pli->net2Host(len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt));
|
default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,8 +179,8 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len){
|
|||||||
char *ptr = data;
|
char *ptr = data;
|
||||||
while (remain > (ssize_t) sizeof(RtcpHeader)) {
|
while (remain > (ssize_t) sizeof(RtcpHeader)) {
|
||||||
RtcpHeader *rtcp = (RtcpHeader *) ptr;
|
RtcpHeader *rtcp = (RtcpHeader *) ptr;
|
||||||
auto rtcp_len = (1 + ntohs(rtcp->length)) << 2;
|
auto rtcp_len = rtcp->getSize();
|
||||||
if (remain < rtcp_len) {
|
if (remain < (ssize_t)rtcp_len) {
|
||||||
WarnL << "非法的rtcp包,声明的长度超过实际数据长度";
|
WarnL << "非法的rtcp包,声明的长度超过实际数据长度";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -189,7 +201,6 @@ class BufferRtcp : public Buffer {
|
|||||||
public:
|
public:
|
||||||
BufferRtcp(std::shared_ptr<RtcpHeader> rtcp) {
|
BufferRtcp(std::shared_ptr<RtcpHeader> rtcp) {
|
||||||
_rtcp = std::move(rtcp);
|
_rtcp = std::move(rtcp);
|
||||||
_size = (ntohs(_rtcp->length) + 1) << 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~BufferRtcp() override {}
|
~BufferRtcp() override {}
|
||||||
@ -199,7 +210,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const override {
|
size_t size() const override {
|
||||||
return _size;
|
return _rtcp->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -258,21 +269,17 @@ if (size < kMinSize) { \
|
|||||||
throw std::out_of_range(StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \
|
throw std::out_of_range(StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_LENGTH(size, item_count) \
|
#define CHECK_REPORT_COUNT(item_count) \
|
||||||
/*修正个数,防止getItemList时内存越界*/ \
|
/*修正个数,防止getItemList时内存越界*/ \
|
||||||
if (report_count != item_count) { \
|
if (report_count != item_count) { \
|
||||||
WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " << item_count; \
|
WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " << item_count; \
|
||||||
report_count = item_count; \
|
report_count = item_count; \
|
||||||
} \
|
|
||||||
if ((size_t) (length + 1) << 2 != size) { \
|
|
||||||
WarnL << rtcpTypeToStr((RtcpType)pt) << " length字段不正确:" << (size_t) (length + 1) << 2 << " != " << size; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcpSR::net2Host(size_t size) {
|
void RtcpSR::net2Host(size_t size) {
|
||||||
static const size_t kMinSize = sizeof(RtcpSR) - sizeof(items);
|
static const size_t kMinSize = sizeof(RtcpSR) - sizeof(items);
|
||||||
CHECK_MIN_SIZE(size, kMinSize);
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
|
|
||||||
RtcpHeader::net2Host();
|
|
||||||
ssrc = ntohl(ssrc);
|
ssrc = ntohl(ssrc);
|
||||||
ntpmsw = ntohl(ntpmsw);
|
ntpmsw = ntohl(ntpmsw);
|
||||||
ntplsw = ntohl(ntplsw);
|
ntplsw = ntohl(ntplsw);
|
||||||
@ -287,7 +294,7 @@ void RtcpSR::net2Host(size_t size) {
|
|||||||
++ptr;
|
++ptr;
|
||||||
++item_count;
|
++item_count;
|
||||||
}
|
}
|
||||||
CHECK_LENGTH(size, item_count);
|
CHECK_REPORT_COUNT(item_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<ReportItem*> RtcpSR::getItemList(){
|
vector<ReportItem*> RtcpSR::getItemList(){
|
||||||
@ -352,7 +359,6 @@ string RtcpRR::dumpString() const{
|
|||||||
void RtcpRR::net2Host(size_t size) {
|
void RtcpRR::net2Host(size_t size) {
|
||||||
static const size_t kMinSize = sizeof(RtcpRR) - sizeof(items);
|
static const size_t kMinSize = sizeof(RtcpRR) - sizeof(items);
|
||||||
CHECK_MIN_SIZE(size, kMinSize);
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
RtcpHeader::net2Host();
|
|
||||||
ssrc = ntohl(ssrc);
|
ssrc = ntohl(ssrc);
|
||||||
|
|
||||||
ReportItem *ptr = &items;
|
ReportItem *ptr = &items;
|
||||||
@ -362,7 +368,7 @@ void RtcpRR::net2Host(size_t size) {
|
|||||||
++ptr;
|
++ptr;
|
||||||
++item_count;
|
++item_count;
|
||||||
}
|
}
|
||||||
CHECK_LENGTH(size, item_count);
|
CHECK_REPORT_COUNT(item_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<ReportItem*> RtcpRR::getItemList() {
|
vector<ReportItem*> RtcpRR::getItemList() {
|
||||||
@ -382,7 +388,7 @@ void SdesItem::net2Host() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t SdesItem::totalBytes() const{
|
size_t SdesItem::totalBytes() const{
|
||||||
return alignSize(minSize() + length);
|
return alignSize(minSize() + txt_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SdesItem::minSize() {
|
size_t SdesItem::minSize() {
|
||||||
@ -393,14 +399,14 @@ string SdesItem::dumpString() const{
|
|||||||
_StrPrinter printer;
|
_StrPrinter printer;
|
||||||
printer << "ssrc:" << ssrc << "\r\n";
|
printer << "ssrc:" << ssrc << "\r\n";
|
||||||
printer << "type:" << sdesTypeToStr((SdesType) type) << "\r\n";
|
printer << "type:" << sdesTypeToStr((SdesType) type) << "\r\n";
|
||||||
printer << "length:" << (int) length << "\r\n";
|
printer << "txt_len:" << (int) txt_len << "\r\n";
|
||||||
printer << "text:" << (length ? string(text, length) : "") << "\r\n";
|
printer << "text:" << (txt_len ? string(text, txt_len) : "") << "\r\n";
|
||||||
return std::move(printer);
|
return std::move(printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::shared_ptr<RtcpSdes> RtcpSdes::create(const std::initializer_list<string> &item_text) {
|
std::shared_ptr<RtcpSdes> RtcpSdes::create(const std::vector<string> &item_text) {
|
||||||
size_t item_total_size = 0;
|
size_t item_total_size = 0;
|
||||||
for (auto &text : item_text) {
|
for (auto &text : item_text) {
|
||||||
//统计所有SdesItem对象占用的空间
|
//统计所有SdesItem对象占用的空间
|
||||||
@ -410,9 +416,9 @@ std::shared_ptr<RtcpSdes> RtcpSdes::create(const std::initializer_list<string> &
|
|||||||
auto ptr = (RtcpSdes *) new char[bytes];
|
auto ptr = (RtcpSdes *) new char[bytes];
|
||||||
auto item_ptr = &ptr->items;
|
auto item_ptr = &ptr->items;
|
||||||
for (auto &text : item_text) {
|
for (auto &text : item_text) {
|
||||||
item_ptr->length = (0xFF & text.size());
|
item_ptr->txt_len = (0xFF & text.size());
|
||||||
//确保赋值\0为RTCP_SDES_END
|
//确保赋值\0为RTCP_SDES_END
|
||||||
memcpy(item_ptr->text, text.data(), item_ptr->length + 1);
|
memcpy(item_ptr->text, text.data(), item_ptr->txt_len + 1);
|
||||||
item_ptr = (SdesItem *) ((char *) item_ptr + item_ptr->totalBytes());
|
item_ptr = (SdesItem *) ((char *) item_ptr + item_ptr->totalBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +443,6 @@ string RtcpSdes::dumpString() const {
|
|||||||
void RtcpSdes::net2Host(size_t size) {
|
void RtcpSdes::net2Host(size_t size) {
|
||||||
static const size_t kMinSize = sizeof(RtcpSdes) - sizeof(items);
|
static const size_t kMinSize = sizeof(RtcpSdes) - sizeof(items);
|
||||||
CHECK_MIN_SIZE(size, kMinSize);
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
RtcpHeader::net2Host();
|
|
||||||
SdesItem *ptr = &items;
|
SdesItem *ptr = &items;
|
||||||
int item_count = 0;
|
int item_count = 0;
|
||||||
for(int i = 0; i < (int)report_count && (char *)(ptr) + SdesItem::minSize() <= (char *)(this) + size; ++i){
|
for(int i = 0; i < (int)report_count && (char *)(ptr) + SdesItem::minSize() <= (char *)(this) + size; ++i){
|
||||||
@ -445,7 +450,7 @@ void RtcpSdes::net2Host(size_t size) {
|
|||||||
ptr = (SdesItem *) ((char *) ptr + ptr->totalBytes());
|
ptr = (SdesItem *) ((char *) ptr + ptr->totalBytes());
|
||||||
++item_count;
|
++item_count;
|
||||||
}
|
}
|
||||||
CHECK_LENGTH(size, item_count);
|
CHECK_REPORT_COUNT(item_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<SdesItem *> RtcpSdes::getItemList() {
|
vector<SdesItem *> RtcpSdes::getItemList() {
|
||||||
@ -460,34 +465,52 @@ vector<SdesItem *> RtcpSdes::getItemList() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::shared_ptr<RtcpPli> RtcpPli::create() {
|
std::shared_ptr<RtcpFB> RtcpFB::create_l(RtcpType type, int fmt, const void *fci, size_t fci_len) {
|
||||||
auto bytes = alignSize(sizeof(RtcpPli));
|
if (!fci) {
|
||||||
|
fci_len = 0;
|
||||||
|
}
|
||||||
|
auto bytes = alignSize(sizeof(RtcpFB) + fci_len);
|
||||||
auto ptr = (RtcpRR *) new char[bytes];
|
auto ptr = (RtcpRR *) new char[bytes];
|
||||||
setupHeader(ptr, RtcpType::RTCP_PSFB, 1, bytes);
|
if (fci && fci_len) {
|
||||||
return std::shared_ptr<RtcpPli>((RtcpPli *) ptr, [](RtcpPli *ptr) {
|
memcpy(ptr + sizeof(RtcpFB), fci, fci_len);
|
||||||
|
}
|
||||||
|
setupHeader(ptr, type, fmt, bytes);
|
||||||
|
return std::shared_ptr<RtcpFB>((RtcpFB *) ptr, [](RtcpFB *ptr) {
|
||||||
delete[] (char *) ptr;
|
delete[] (char *) ptr;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
string RtcpPli::dumpString() const {
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
string RtcpFB::dumpString() const {
|
||||||
_StrPrinter printer;
|
_StrPrinter printer;
|
||||||
printer << RtcpHeader::dumpHeader();
|
printer << RtcpHeader::dumpHeader();
|
||||||
printer << "ssrc:" << ssrc << "\r\n";
|
printer << "ssrc:" << ssrc << "\r\n";
|
||||||
printer << "ssrc_media:" << ssrc_media;
|
printer << "ssrc_media:" << ssrc_media << "\r\n";
|
||||||
|
auto fci = (uint8_t *)&ssrc_media + sizeof(ssrc_media);
|
||||||
|
auto fci_len = getSize() - sizeof(RtcpFB);
|
||||||
|
if (fci_len) {
|
||||||
|
printer << "fci:" << hexdump(fci, fci_len);
|
||||||
|
}
|
||||||
return std::move(printer);
|
return std::move(printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtcpPli::net2Host(size_t size) {
|
void RtcpFB::net2Host(size_t size) {
|
||||||
static const size_t kMinSize = sizeof(RtcpPli);
|
static const size_t kMinSize = sizeof(RtcpFB);
|
||||||
CHECK_MIN_SIZE(size, kMinSize);
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
RtcpHeader::net2Host();
|
|
||||||
ssrc = ntohl(ssrc);
|
ssrc = ntohl(ssrc);
|
||||||
ssrc_media = ntohl(ssrc_media);
|
ssrc_media = ntohl(ssrc_media);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
std::shared_ptr<RtcpBye> RtcpBye::create(const std::initializer_list<uint32_t> &ssrcs, const string &reason) {
|
std::shared_ptr<RtcpBye> RtcpBye::create(const std::vector<uint32_t> &ssrcs, const string &reason) {
|
||||||
assert(reason.size() <= 0xFF);
|
assert(reason.size() <= 0xFF);
|
||||||
auto bytes = alignSize(sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size());
|
auto bytes = alignSize(sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size());
|
||||||
auto ptr = (RtcpBye *) new char[bytes];
|
auto ptr = (RtcpBye *) new char[bytes];
|
||||||
@ -541,8 +564,6 @@ string RtcpBye::dumpString() const {
|
|||||||
void RtcpBye::net2Host(size_t size) {
|
void RtcpBye::net2Host(size_t size) {
|
||||||
static const size_t kMinSize = sizeof(RtcpHeader);
|
static const size_t kMinSize = sizeof(RtcpHeader);
|
||||||
CHECK_MIN_SIZE(size, kMinSize);
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
RtcpHeader::net2Host();
|
|
||||||
|
|
||||||
uint32_t *ssrc_ptr = &ssrc;
|
uint32_t *ssrc_ptr = &ssrc;
|
||||||
size_t offset = kMinSize;
|
size_t offset = kMinSize;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -552,7 +573,7 @@ void RtcpBye::net2Host(size_t size) {
|
|||||||
offset += sizeof(ssrc);
|
offset += sizeof(ssrc);
|
||||||
}
|
}
|
||||||
//修正ssrc个数
|
//修正ssrc个数
|
||||||
CHECK_LENGTH(size, i);
|
CHECK_REPORT_COUNT(i);
|
||||||
|
|
||||||
if (offset < size) {
|
if (offset < size) {
|
||||||
uint8_t *reason_len_ptr = &reason_len + sizeof(ssrc) * (report_count - 1);
|
uint8_t *reason_len_ptr = &reason_len + sizeof(ssrc) * (report_count - 1);
|
||||||
|
@ -179,6 +179,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
//rtcp类型,RtcpType
|
//rtcp类型,RtcpType
|
||||||
uint32_t pt: 8;
|
uint32_t pt: 8;
|
||||||
|
|
||||||
|
private:
|
||||||
//长度
|
//长度
|
||||||
uint32_t length: 16;
|
uint32_t length: 16;
|
||||||
|
|
||||||
@ -207,15 +209,16 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据length字段获取rtcp总长度
|
* 根据length字段获取rtcp总长度
|
||||||
* 使用net2Host转换成主机字节序后才可使用此函数
|
|
||||||
*/
|
*/
|
||||||
size_t getSize() const;
|
size_t getSize() const;
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
/**
|
||||||
* 网络字节序转换为主机字节序
|
* 设置rtcp length字段
|
||||||
|
* @param size rtcp总长度,单位字节
|
||||||
*/
|
*/
|
||||||
void net2Host();
|
void setSize(size_t size);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印字段详情
|
* 打印字段详情
|
||||||
@ -476,7 +479,7 @@ public:
|
|||||||
//SdesType
|
//SdesType
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
//text长度股,可以为0
|
//text长度股,可以为0
|
||||||
uint8_t length;
|
uint8_t txt_len;
|
||||||
//不定长
|
//不定长
|
||||||
char text[1];
|
char text[1];
|
||||||
//最后以RTCP_SDES_END结尾
|
//最后以RTCP_SDES_END结尾
|
||||||
@ -521,7 +524,7 @@ public:
|
|||||||
* @param item_text SdesItem列表,只赋值length和text部分
|
* @param item_text SdesItem列表,只赋值length和text部分
|
||||||
* @return SDES包
|
* @return SDES包
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<RtcpSdes> create(const std::initializer_list<string> &item_text);
|
static std::shared_ptr<RtcpSdes> create(const std::vector<string> &item_text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取SdesItem对象指针列表
|
* 获取SdesItem对象指针列表
|
||||||
@ -560,8 +563,8 @@ private:
|
|||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
// : Feedback Control Information (FCI) :
|
// : Feedback Control Information (FCI) :
|
||||||
// : :
|
// : :
|
||||||
|
// rtcpfb和psfb的数据结构一致
|
||||||
class RtcpPli : public RtcpHeader {
|
class RtcpFB : public RtcpHeader {
|
||||||
public:
|
public:
|
||||||
friend class RtcpHeader;
|
friend class RtcpHeader;
|
||||||
uint32_t ssrc;
|
uint32_t ssrc;
|
||||||
@ -569,9 +572,14 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* 创建pli包
|
* 创建psfb类型的反馈包
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<RtcpPli> create();
|
static std::shared_ptr<RtcpFB> create(PSFBType fmt, const void *fci = nullptr, size_t fci_len = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建rtpfb类型的反馈包
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<RtcpFB> create(RTPFBType fmt, const void *fci = nullptr, size_t fci_len = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -585,6 +593,9 @@ private:
|
|||||||
* @param size 字节长度,防止内存越界
|
* @param size 字节长度,防止内存越界
|
||||||
*/
|
*/
|
||||||
void net2Host(size_t size);
|
void net2Host(size_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::shared_ptr<RtcpFB> create_l(RtcpType type, int fmt, const void *fci, size_t fci_len);
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
//BYE
|
//BYE
|
||||||
@ -621,7 +632,7 @@ public:
|
|||||||
* @param reason 原因
|
* @param reason 原因
|
||||||
* @return rtcp bye包
|
* @return rtcp bye包
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<RtcpBye> create(const std::initializer_list<uint32_t> &ssrc, const string &reason);
|
static std::shared_ptr<RtcpBye> create(const std::vector<uint32_t> &ssrc, const string &reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取ssrc列表
|
* 获取ssrc列表
|
||||||
|
@ -544,21 +544,9 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
|
|||||||
onShutdown(SockException(Err_eof, "rtcp bye message received"));
|
onShutdown(SockException(Err_eof, "rtcp bye message received"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RtcpType::RTCP_PSFB: {
|
case RtcpType::RTCP_PSFB:
|
||||||
//todo 支持pli等更多类型的rtcp
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RtcpType::RTCP_RTPFB: {
|
case RtcpType::RTCP_RTPFB: {
|
||||||
//todo 测试打印twcc
|
InfoL << rtcp->dumpString();
|
||||||
RtcpPli *rtpfb = (RtcpPli *)rtcp;
|
|
||||||
auto fci = (uint8_t *)rtpfb + sizeof (RtcpPli);
|
|
||||||
if(rtpfb->report_count == 15){
|
|
||||||
//TWCC
|
|
||||||
FCI_TWCC *twcc = (FCI_TWCC *) (fci);
|
|
||||||
auto fci_size = rtpfb->getSize() - 12;
|
|
||||||
InfoL << hexdump(fci, fci_size);
|
|
||||||
InfoL << "\n" << twcc->dumpString(fci_size);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
@ -591,10 +579,10 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
|
|||||||
if (_pli_ticker.elapsedTime() > 2000) {
|
if (_pli_ticker.elapsedTime() > 2000) {
|
||||||
//定期发送pli请求关键帧,方便非rtc等协议
|
//定期发送pli请求关键帧,方便非rtc等协议
|
||||||
_pli_ticker.resetTime();
|
_pli_ticker.resetTime();
|
||||||
auto pli = RtcpPli::create();
|
auto pli = RtcpFB::create(PSFBType::RTCP_PSFB_PLI);
|
||||||
pli->ssrc = htonl(0);
|
pli->ssrc = htonl(0);
|
||||||
pli->ssrc_media = htonl(_recv_video_ssrc);
|
pli->ssrc_media = htonl(_recv_video_ssrc);
|
||||||
sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true);
|
sendRtcpPacket((char *) pli.get(), pli->getSize(), true);
|
||||||
}
|
}
|
||||||
if (_push_src) {
|
if (_push_src) {
|
||||||
_push_src->onWrite(std::move(rtp), false);
|
_push_src->onWrite(std::move(rtp), false);
|
||||||
|
Loading…
Reference in New Issue
Block a user