添加rtcp bye相关代码

This commit is contained in:
xia-chu
2021-04-07 16:45:50 +08:00
parent 79267ae551
commit f374f72312
2 changed files with 182 additions and 4 deletions

View File

@@ -9,6 +9,7 @@
*/
#include <stddef.h>
#include <assert.h>
#include "Rtcp.h"
#include "Util/logger.h"
@@ -87,10 +88,20 @@ string RtcpHeader::dumpString() const {
RtcpPli *rtcp = (RtcpPli *)this;
return rtcp->dumpString();
}
case RtcpType::RTCP_BYE: {
RtcpBye *rtcp = (RtcpBye *)this;
return rtcp->dumpString();
}
default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), length << 2);
}
}
size_t RtcpHeader::getSize() const {
return (1 + length) << 2;
}
void RtcpHeader::net2Host(size_t len){
switch ((RtcpType)pt) {
case RtcpType::RTCP_SR: {
@@ -116,6 +127,12 @@ void RtcpHeader::net2Host(size_t len){
pli->net2Host(len);
break;
}
case RtcpType::RTCP_BYE: {
RtcpBye *bye = (RtcpBye *)this;
bye->net2Host(len);
break;
}
default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt));
}
}
@@ -127,6 +144,10 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len){
while (remain > (ssize_t) sizeof(RtcpHeader)) {
RtcpHeader *rtcp = (RtcpHeader *) ptr;
auto rtcp_len = (1 + ntohs(rtcp->length)) << 2;
if (remain < rtcp_len) {
WarnL << "非法的rtcp包,声明的长度超过实际数据长度";
break;
}
try {
rtcp->net2Host(rtcp_len);
ret.emplace_back(rtcp);
@@ -144,7 +165,7 @@ class BufferRtcp : public Buffer {
public:
BufferRtcp(std::shared_ptr<RtcpHeader> rtcp) {
_rtcp = std::move(rtcp);
_size = (htons(_rtcp->length) + 1) << 2;
_size = (ntohs(_rtcp->length) + 1) << 2;
}
~BufferRtcp() override {}
@@ -440,4 +461,97 @@ void RtcpPli::net2Host(size_t size) {
ssrc_media = ntohl(ssrc_media);
}
////////////////////////////////////////////////////////////////////
std::shared_ptr<RtcpBye> RtcpBye::create(const std::initializer_list<uint32_t> &ssrcs, const string &reason) {
assert(reason.size() <= 0xFF);
auto bytes = alignSize(sizeof(RtcpHeader) + sizeof(uint32_t) * ssrcs.size() + 1 + reason.size());
auto ptr = (RtcpBye *) new char[bytes];
setupHeader(ptr, RtcpType::RTCP_BYE, ssrcs.size(), bytes);
auto *ssrc_ptr = &(((RtcpBye *) ptr)->ssrc);
for (auto ssrc : ssrcs) {
*ssrc_ptr = htonl(ssrc);
++ssrc_ptr;
}
if (!reason.empty()) {
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;
});
}
vector<uint32_t *> RtcpBye::getSSRC() {
vector<uint32_t *> ret;
uint32_t *ssrc_ptr = &ssrc;
for (size_t i = 0; i < report_count; ++i) {
ret.emplace_back(ssrc_ptr);
ssrc_ptr += 1;
}
return ret;
}
string RtcpBye::getReason() const {
auto *reason_len_ptr = &reason_len + sizeof(ssrc) * (report_count - 1);
if (reason_len_ptr + 1 >= (uint8_t *) this + getSize()) {
return "";
}
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()) {
printer << "ssrc:" << *ssrc << "\r\n";
}
printer << "reason:" << getReason();
return std::move(printer);
}
void RtcpBye::net2Host(size_t size) {
static const size_t kMinSize = sizeof(RtcpHeader);
CHECK_MIN_SIZE(size, kMinSize);
RtcpHeader::net2Host();
uint32_t *ssrc_ptr = &ssrc;
size_t offset = kMinSize;
size_t i = 0;
for (; i < report_count && offset + sizeof(ssrc) <= size; ++i) {
*ssrc_ptr = ntohl(*ssrc_ptr);
ssrc_ptr += 1;
offset += sizeof(ssrc);
}
//修正ssrc个数
CHECK_LENGTH(size, 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) {
WarnL << "invalid rtcp bye reason length";
//修正reason_len长度
*reason_len_ptr = ((uint8_t *) this + size - reason_len_ptr - 1) & 0xFF;
}
}
}
#if 0
#include "Util/onceToken.h"
static toolkit::onceToken token([](){
auto bye = RtcpBye::create({1,2,3,4,5,6}, "this is a bye reason");
auto buffer = RtcpHeader::toBuffer(bye);
auto rtcps = RtcpHeader::loadFromBytes(buffer->data(), buffer->size());
for(auto rtcp : rtcps){
std::cout << rtcp->dumpString() << std::endl;
}
});
#endif
}//namespace mediakit