mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
添加rtcp bye相关代码
This commit is contained in:
parent
79267ae551
commit
f374f72312
@ -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
|
@ -124,6 +124,12 @@ public:
|
||||
*/
|
||||
string dumpString() const;
|
||||
|
||||
/**
|
||||
* 根据length字段获取rtcp总长度
|
||||
* 使用net2Host转换成主机字节序后才可使用此函数
|
||||
*/
|
||||
size_t getSize() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 网络字节序转换为主机字节序
|
||||
@ -465,9 +471,7 @@ public:
|
||||
|
||||
public:
|
||||
/**
|
||||
* 创建SDES包,只赋值了RtcpHeader以及SdesItem对象的length和text部分
|
||||
* @param item_text SdesItem列表,只赋值length和text部分
|
||||
* @return SDES包
|
||||
* 创建pli包
|
||||
*/
|
||||
static std::shared_ptr<RtcpPli> create();
|
||||
|
||||
@ -485,6 +489,66 @@ private:
|
||||
void net2Host(size_t size);
|
||||
} PACKED;
|
||||
|
||||
//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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|V=2|P| SC | PT=BYE=203 | length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| SSRC/CSRC |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
: ... :
|
||||
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
(opt) | length | reason for leaving ...
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
class RtcpBye : public RtcpHeader {
|
||||
public:
|
||||
friend class RtcpHeader;
|
||||
/* 变长,根据count决定有多少个ssrc */
|
||||
uint32_t ssrc;
|
||||
|
||||
/** 中间可能有若干个 ssrc **/
|
||||
|
||||
/* 可选 */
|
||||
uint8_t reason_len;
|
||||
char reason;
|
||||
|
||||
public:
|
||||
/**
|
||||
* 创建bye包
|
||||
* @param ssrc ssrc列表
|
||||
* @param reason 原因
|
||||
* @return rtcp bye包
|
||||
*/
|
||||
static std::shared_ptr<RtcpBye> create(const std::initializer_list<uint32_t> &ssrc, const string &reason);
|
||||
|
||||
/**
|
||||
* 获取ssrc列表
|
||||
*/
|
||||
vector<uint32_t *> getSSRC();
|
||||
|
||||
/**
|
||||
* 获取原因
|
||||
*/
|
||||
string getReason() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* 打印字段详情
|
||||
* 使用net2Host转换成主机字节序后才可使用此函数
|
||||
*/
|
||||
string dumpString() const;
|
||||
|
||||
/**
|
||||
* 网络字节序转换为主机字节序
|
||||
* @param size 字节长度,防止内存越界
|
||||
*/
|
||||
void net2Host(size_t size);
|
||||
} PACKED;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#pragma pack(pop)
|
||||
#endif // defined(_WIN32)
|
||||
|
Loading…
Reference in New Issue
Block a user