diff --git a/src/Rtcp/Rtcp.cpp b/src/Rtcp/Rtcp.cpp index 0e541053..105d9706 100644 --- a/src/Rtcp/Rtcp.cpp +++ b/src/Rtcp/Rtcp.cpp @@ -68,12 +68,26 @@ static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, si 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; + } else { + rtcp->padding = 0; + } +} + ///////////////////////////////////////////////////////////////////////////// string RtcpHeader::dumpHeader() const{ _StrPrinter printer; printer << "version:" << version << "\r\n"; - printer << "padding:" << padding << "\r\n"; + if (padding) { + printer << "padding:" << padding << " " << getPaddingSize() << "\r\n"; + } else { + printer << "padding:" << padding << "\r\n"; + } + switch ((RtcpType)pt) { case RtcpType::RTCP_RTPFB : { printer << "report_count:" << rtpfbTypeToStr((RTPFBType) report_count) << "\r\n"; @@ -132,6 +146,13 @@ size_t RtcpHeader::getSize() const { return (1 + ntohs(length)) << 2; } +size_t RtcpHeader::getPaddingSize() const{ + if (!padding) { + return 0; + } + return ((uint8_t *) this)[getSize() - 1]; +} + void RtcpHeader::setSize(size_t size) { //不包含rtcp头的长度 length = htons((uint16_t)((size >> 2) - 1)); @@ -226,9 +247,11 @@ Buffer::Ptr RtcpHeader::toBuffer(std::shared_ptr rtcp) { ///////////////////////////////////////////////////////////////////////////// std::shared_ptr RtcpSR::create(size_t item_count) { - auto bytes = alignSize(sizeof(RtcpSR) - sizeof(ReportItem) + item_count * sizeof(ReportItem)); + auto real_size = sizeof(RtcpSR) - sizeof(ReportItem) + item_count * sizeof(ReportItem); + auto bytes = alignSize(real_size); auto ptr = (RtcpSR *) new char[bytes]; setupHeader(ptr, RtcpType::RTCP_SR, item_count, bytes); + setupPadding(ptr, bytes - real_size); return std::shared_ptr(ptr, [](RtcpSR *ptr) { delete[] (char *) ptr; }); @@ -336,9 +359,11 @@ void ReportItem::net2Host() { ///////////////////////////////////////////////////////////////////////////// std::shared_ptr RtcpRR::create(size_t item_count) { - auto bytes = alignSize(sizeof(RtcpRR) - sizeof(ReportItem) + item_count * sizeof(ReportItem)); + auto real_size = sizeof(RtcpRR) - sizeof(ReportItem) + item_count * sizeof(ReportItem); + auto bytes = alignSize(real_size); auto ptr = (RtcpRR *) new char[bytes]; setupHeader(ptr, RtcpType::RTCP_RR, item_count, bytes); + setupPadding(ptr, bytes - real_size); return std::shared_ptr(ptr, [](RtcpRR *ptr) { delete[] (char *) ptr; }); @@ -413,7 +438,8 @@ std::shared_ptr RtcpSdes::create(const std::vector &item_text) //统计所有SdesItem对象占用的空间 item_total_size += alignSize(SdesItem::minSize() + (0xFF & text.size())); } - auto bytes = alignSize(sizeof(RtcpSdes) - sizeof(SdesItem) + item_total_size); + auto real_size = sizeof(RtcpSdes) - sizeof(SdesItem) + item_total_size; + auto bytes = alignSize(real_size); auto ptr = (RtcpSdes *) new char[bytes]; auto item_ptr = &ptr->items; for (auto &text : item_text) { @@ -424,6 +450,7 @@ std::shared_ptr RtcpSdes::create(const std::vector &item_text) } setupHeader(ptr, RtcpType::RTCP_SDES, item_text.size(), bytes); + setupPadding(ptr, bytes - real_size); return std::shared_ptr(ptr, [](RtcpSdes *ptr) { delete [] (char *) ptr; }); @@ -470,12 +497,14 @@ std::shared_ptr RtcpFB::create_l(RtcpType type, int fmt, const void *fci if (!fci) { fci_len = 0; } - auto bytes = alignSize(sizeof(RtcpFB) + fci_len); + auto real_size = sizeof(RtcpFB) + fci_len; + auto bytes = alignSize(real_size); auto ptr = (RtcpRR *) new char[bytes]; if (fci && fci_len) { memcpy(ptr + sizeof(RtcpFB), fci, fci_len); } setupHeader(ptr, type, fmt, bytes); + setupPadding(ptr, bytes - real_size); return std::shared_ptr((RtcpFB *) ptr, [](RtcpFB *ptr) { delete[] (char *) ptr; }); @@ -495,7 +524,8 @@ string RtcpFB::dumpString() const { printer << "ssrc:" << ssrc << "\r\n"; printer << "ssrc_media:" << ssrc_media << "\r\n"; auto fci_data = (uint8_t *)&ssrc_media + sizeof(ssrc_media); - auto fci_len = getSize() - sizeof(RtcpFB); + auto fci_len = (ssize_t)getSize() - getPaddingSize() - sizeof(RtcpFB); + CHECK(fci_len >= 0); switch ((RtcpType) pt) { case RtcpType::RTCP_PSFB : { switch ((PSFBType) report_count) { @@ -568,9 +598,11 @@ void RtcpFB::net2Host(size_t size) { std::shared_ptr RtcpBye::create(const std::vector &ssrcs, const string &reason) { assert(reason.size() <= 0xFF); - auto bytes = alignSize(sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size()); + auto real_size = sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size(); + auto bytes = alignSize(real_size); auto ptr = (RtcpBye *) new char[bytes]; setupHeader(ptr, RtcpType::RTCP_BYE, ssrcs.size(), bytes); + setupPadding(ptr, bytes - real_size); auto *ssrc_ptr = &(((RtcpBye *) ptr)->ssrc); for (auto ssrc : ssrcs) { diff --git a/src/Rtcp/Rtcp.h b/src/Rtcp/Rtcp.h index 5637e4ee..836699d2 100644 --- a/src/Rtcp/Rtcp.h +++ b/src/Rtcp/Rtcp.h @@ -172,7 +172,7 @@ public: #else //reception report count uint32_t report_count: 5; - //padding,固定为0 + //padding,末尾是否有追加填充 uint32_t padding: 1; //版本号,固定为2 uint32_t version: 2; @@ -212,6 +212,11 @@ public: */ size_t getSize() const; + /** + * 后面追加padding数据长度 + */ + size_t getPaddingSize() const; + /** * 设置rtcp length字段 * @param size rtcp总长度,单位字节