mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
添加TWCC部分代码
This commit is contained in:
parent
dc3d59952e
commit
5db6154707
@ -167,5 +167,83 @@ string FCI_NACK::dumpString() const {
|
|||||||
return std::move(printer);
|
return std::move(printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
RunLengthChunk::RunLengthChunk(SymbolStatus status, uint16_t run_length) {
|
||||||
|
type = 0;
|
||||||
|
symbol = (uint8_t)status & 0x03;
|
||||||
|
run_length_high = (run_length >> 8) & 0x1F;
|
||||||
|
run_length_low = run_length & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t RunLengthChunk::getRunLength() const {
|
||||||
|
CHECK(type == 0);
|
||||||
|
return run_length_high << 8 | run_length_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
string RunLengthChunk::dumpString() const{
|
||||||
|
_StrPrinter printer;
|
||||||
|
printer << "run length chunk, symbol:" << (int)symbol << ", run length:" << getRunLength();
|
||||||
|
return std::move(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
StatusVecChunk::StatusVecChunk(const vector<SymbolStatus> &status) {
|
||||||
|
uint16_t value = 0;
|
||||||
|
type = 1;
|
||||||
|
if (status.size() == 14) {
|
||||||
|
symbol = 0;
|
||||||
|
} else if (status.size() == 7) {
|
||||||
|
symbol = 1;
|
||||||
|
} else {
|
||||||
|
//非法
|
||||||
|
CHECK(0);
|
||||||
|
}
|
||||||
|
int i = 13;
|
||||||
|
for (auto &item : status) {
|
||||||
|
CHECK(item <= SymbolStatus::reserved);
|
||||||
|
if (!symbol) {
|
||||||
|
CHECK(item <= SymbolStatus::small_delta);
|
||||||
|
value |= (int) item << i;
|
||||||
|
--i;
|
||||||
|
} else {
|
||||||
|
value |= (int) item << (i - 1);
|
||||||
|
i -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbol_list_low = value & 0xFF;
|
||||||
|
symbol_list_high = (value >> 8 ) & 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<SymbolStatus> StatusVecChunk::getSymbolList() const {
|
||||||
|
CHECK(type == 1);
|
||||||
|
vector<SymbolStatus> ret;
|
||||||
|
auto thiz = ntohs(*((uint16_t *) this));
|
||||||
|
if (symbol == 0) {
|
||||||
|
//s = 0 时,表示symbollist的每一个bit能表示一个数据包的到达状态
|
||||||
|
for (int i = 13; i >= 0; --i) {
|
||||||
|
SymbolStatus status = (SymbolStatus) ((bool) (thiz & (1 << i)));
|
||||||
|
ret.emplace_back(status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//s = 1 时,表示symbollist每两个bit表示一个数据包的状态
|
||||||
|
for (int i = 12; i >= 0; i -= 2) {
|
||||||
|
SymbolStatus status = (SymbolStatus) ((thiz & (3 << i)) >> i);
|
||||||
|
ret.emplace_back(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
string StatusVecChunk::dumpString() const {
|
||||||
|
_StrPrinter printer;
|
||||||
|
printer << "status vector chunk, symbol:" << (int) symbol << ", symbol list:";
|
||||||
|
auto vec = getSymbolList();
|
||||||
|
for (auto &item : vec) {
|
||||||
|
printer << (int) item << " ";
|
||||||
|
}
|
||||||
|
return std::move(printer);
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -222,6 +222,7 @@ public:
|
|||||||
class FCI_NACK {
|
class FCI_NACK {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t kBitSize = 16;
|
static constexpr size_t kBitSize = 16;
|
||||||
|
static constexpr size_t kSize = 4;
|
||||||
|
|
||||||
// The PID field is used to specify a lost packet. The PID field
|
// The PID field is used to specify a lost packet. The PID field
|
||||||
// refers to the RTP sequence number of the lost packet.
|
// refers to the RTP sequence number of the lost packet.
|
||||||
@ -259,6 +260,8 @@ public:
|
|||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
class FCI_TMMBR {
|
class FCI_TMMBR {
|
||||||
public:
|
public:
|
||||||
|
static size_t constexpr kSize = 8;
|
||||||
|
|
||||||
//SSRC (32 bits): The SSRC value of the media sender that is
|
//SSRC (32 bits): The SSRC value of the media sender that is
|
||||||
// requested to obey the new maximum bit rate.
|
// requested to obey the new maximum bit rate.
|
||||||
uint32_t ssrc;
|
uint32_t ssrc;
|
||||||
@ -315,8 +318,92 @@ public:
|
|||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
// | recv delta | recv delta | zero padding |
|
// | recv delta | recv delta | zero padding |
|
||||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
enum class SymbolStatus : uint8_t{
|
||||||
|
//Packet not received
|
||||||
|
not_received = 0,
|
||||||
|
//Packet received, small delta (所谓small detal是指能用一个字节表示的数值)
|
||||||
|
small_delta = 1,
|
||||||
|
// Packet received, large ornegative delta (large即是能用两个字节表示的数值)
|
||||||
|
large_delta = 2,
|
||||||
|
//Reserved
|
||||||
|
reserved = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
class RunLengthChunk {
|
||||||
|
public:
|
||||||
|
static size_t constexpr kSize = 2;
|
||||||
|
// 0 1
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |T| S | Run Length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
// Run Length 低8位
|
||||||
|
uint16_t run_length_low: 8;
|
||||||
|
|
||||||
|
//获取Run Length
|
||||||
|
uint16_t getRunLength() const;
|
||||||
|
//构造函数
|
||||||
|
RunLengthChunk(SymbolStatus status, uint16_t run_length);
|
||||||
|
|
||||||
|
string dumpString() const;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
class StatusVecChunk {
|
||||||
|
public:
|
||||||
|
static size_t constexpr kSize = 2;
|
||||||
|
// 0 1
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
// |T| S | Run Length |
|
||||||
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
// symbol_list 低8位
|
||||||
|
uint16_t symbol_list_low: 8;
|
||||||
|
|
||||||
|
//获取symbollist
|
||||||
|
vector<SymbolStatus> getSymbolList() const;
|
||||||
|
//构造函数
|
||||||
|
StatusVecChunk(const vector<SymbolStatus> &status);
|
||||||
|
|
||||||
|
string dumpString() const;
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
class FCI_TWCC{
|
class FCI_TWCC{
|
||||||
public:
|
public:
|
||||||
|
static size_t constexpr kSize = 12;
|
||||||
|
|
||||||
|
//base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号
|
||||||
|
uint16_t base_seq;
|
||||||
|
//packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算
|
||||||
|
uint16_t pkt_status_count;
|
||||||
|
//reference time,基准时间,绝对时间;计算该包中每个媒体包的到达时间都要基于这个基准时间计算
|
||||||
|
uint8_t ref_time[3];
|
||||||
|
//feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 |
|
||||||
|
uint8_t fb_pkt_count;
|
||||||
|
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
@ -42,5 +42,28 @@ int main() {
|
|||||||
nack.net2Host();
|
nack.net2Host();
|
||||||
InfoL << nack.dumpString();
|
InfoL << nack.dumpString();
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
RunLengthChunk chunk(SymbolStatus::large_delta, 8024);
|
||||||
|
InfoL << hexdump(&chunk, RunLengthChunk::kSize);
|
||||||
|
InfoL << chunk.dumpString();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lam = [](const initializer_list<int> &lst){
|
||||||
|
vector<SymbolStatus> ret;
|
||||||
|
for(auto &num : lst){
|
||||||
|
ret.emplace_back((SymbolStatus)num);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
{
|
||||||
|
StatusVecChunk chunk(lam({0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1}));
|
||||||
|
InfoL << hexdump(&chunk, StatusVecChunk::kSize);
|
||||||
|
InfoL << chunk.dumpString();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
StatusVecChunk chunk(lam({0, 1, 2, 3, 0, 1, 2}));
|
||||||
|
InfoL << hexdump(&chunk, StatusVecChunk::kSize);
|
||||||
|
InfoL << chunk.dumpString();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user