From 99a1d06d9b809b1069ca4b76abbb4eb2e3ca3e5f Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Thu, 22 Apr 2021 18:56:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3TWCC=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=90=86=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtcp/RtcpFCI.cpp | 47 ++++++++++++++++++++++++++++++++++---------- src/Rtcp/RtcpFCI.h | 2 +- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/Rtcp/RtcpFCI.cpp b/src/Rtcp/RtcpFCI.cpp index eec9e7f9..3f465aa9 100644 --- a/src/Rtcp/RtcpFCI.cpp +++ b/src/Rtcp/RtcpFCI.cpp @@ -261,9 +261,35 @@ uint32_t FCI_TWCC::getReferenceTime() const { ret |= ref_time[2]; return ret; } +//3.1.5. Receive Delta +// +// Deltas are represented as multiples of 250us: +// +// o If the "Packet received, small delta" symbol has been appended to +// the status list, an 8-bit unsigned receive delta will be appended +// to recv delta list, representing a delta in the range [0, 63.75] +// ms. +// +// o If the "Packet received, large or negative delta" symbol has been +// appended to the status list, a 16-bit signed receive delta will be +// appended to recv delta list, representing a delta in the range +// [-8192.0, 8191.75] ms. +// +// o If the delta exceeds even the larger limits, a new feedback +// message must be used, where the 24-bit base receive delta can +// cover very large gaps. +// +// The smaller receive delta upper bound of 63.75 ms means that this is +// only viable at about 1000/25.5 ~= 16 packets per second and above. +// With a packet size of 1200 bytes/packet that amounts to a bitrate of +// about 150 kbit/s. +// +// The 0.25 ms resolution means that up to 4000 packets per second can +// be represented. With a 1200 bytes/packet payload, that amounts to +// 38.4 Mbit/s payload bandwidth. -static uint16_t getRecvDelta(SymbolStatus status, uint8_t *&ptr, const uint8_t *end){ - uint16_t delta = 0; +static int16_t getRecvDelta(SymbolStatus status, uint8_t *&ptr, const uint8_t *end){ + int16_t delta = 0; switch (status) { case SymbolStatus::not_received : { //丢包, recv delta为0个字节 @@ -298,29 +324,29 @@ map > FCI_TWCC::getPacketCh auto end = (uint8_t *) this + total_size; CHECK(ptr < end); auto seq = base_seq; - auto stamp = getReferenceTime(); for (uint8_t i = 0; i < pkt_status_count;) { CHECK(ptr + RunLengthChunk::kSize <= end) RunLengthChunk *chunk = (RunLengthChunk *) ptr; if (!chunk->type) { //RunLengthChunk - ptr += RunLengthChunk::kSize; for (auto j = 0; j < chunk->getRunLength(); ++j) { - ret.emplace(seq++, std::make_pair((SymbolStatus) chunk->symbol, stamp)); - stamp += getRecvDelta((SymbolStatus) chunk->symbol, ptr, end); + ret.emplace(seq++, std::make_pair((SymbolStatus) chunk->symbol, 0)); ++i; } } else { //StatusVecChunk StatusVecChunk *chunk = (StatusVecChunk *) ptr; - ptr += StatusVecChunk::kSize; for (auto &symbol : chunk->getSymbolList()) { - ret.emplace(seq++, std::make_pair(symbol, stamp)); - stamp += getRecvDelta(symbol, ptr, end); + ret.emplace(seq++, std::make_pair(symbol, 0)); ++i; } } + ptr += 2; + } + for (auto &pr : ret) { + CHECK(ptr <= end) + pr.second.second = 250 * getRecvDelta(pr.second.first, ptr, end); } return ret; } @@ -328,8 +354,9 @@ map > FCI_TWCC::getPacketCh string FCI_TWCC::dumpString(size_t total_size) const { _StrPrinter printer; auto map = getPacketChunkList(total_size); + printer << "twcc fci, base_seq:" << base_seq << ",pkt_status_count:" << pkt_status_count << ", ref time:" << getReferenceTime() << ", fb count:" << (int)fb_pkt_count << "\n"; for (auto &pr : map) { - printer << " seq:" << pr.first <<", packet status:" << (int)(pr.second.first) << ", stamp:" << pr.second.second << "\n"; + printer << "rtp seq:" << pr.first <<", packet status:" << (int)(pr.second.first) << ", delta:" << pr.second.second << "\n"; } return std::move(printer); } diff --git a/src/Rtcp/RtcpFCI.h b/src/Rtcp/RtcpFCI.h index 8df51f32..6676c42c 100644 --- a/src/Rtcp/RtcpFCI.h +++ b/src/Rtcp/RtcpFCI.h @@ -406,7 +406,7 @@ public: void net2Host(size_t total_size); uint32_t getReferenceTime() const; - map > getPacketChunkList(size_t total_size) const; + map > getPacketChunkList(size_t total_size) const; string dumpString(size_t total_size) const; } PACKED;