diff --git a/3rdpart/assert.h b/3rdpart/assert.h index e5699be1..00369393 100644 --- a/3rdpart/assert.h +++ b/3rdpart/assert.h @@ -21,6 +21,8 @@ extern void Assert_Throw(int failed, const char *exp, const char *func, const ch } #endif +#define CHECK(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__) + #ifndef NDEBUG #ifdef assert #undef assert diff --git a/src/Rtcp/RtcpFCI.cpp b/src/Rtcp/RtcpFCI.cpp index 3f465aa9..79e09c25 100644 --- a/src/Rtcp/RtcpFCI.cpp +++ b/src/Rtcp/RtcpFCI.cpp @@ -8,13 +8,16 @@ * may be found in the AUTHORS file in the root of the source tree. */ - -#include "assert.h" #include "RtcpFCI.h" -#define CHECK(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__); +#include "Util/logger.h" +using namespace toolkit; namespace mediakit { +void FCI_SLI::check(size_t size){ + CHECK(size == kSize); +} + FCI_SLI::FCI_SLI(uint16_t first, uint16_t number, uint8_t pic_id) { //13 bits first &= 0x1FFF; @@ -27,19 +30,15 @@ FCI_SLI::FCI_SLI(uint16_t first, uint16_t number, uint8_t pic_id) { } uint16_t FCI_SLI::getFirst() const { - return data >> 19; + return ntohl(data) >> 19; } uint16_t FCI_SLI::getNumber() const { - return (data >> 6) & 0x1FFF; + return (ntohl(data) >> 6) & 0x1FFF; } uint8_t FCI_SLI::getPicID() const { - return data & 0x3F; -} - -void FCI_SLI::net2Host() { - data = ntohl(data); + return ntohl(data) & 0x3F; } string FCI_SLI::dumpString() const { @@ -48,29 +47,52 @@ string FCI_SLI::dumpString() const { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void FCI_FIR::net2Host() { - ssrc = ntohl(ssrc); - reserved = ntohl(reserved) >> 8; +void FCI_FIR::check(size_t size){ + CHECK(size == kSize); +} + +uint32_t FCI_FIR::getSSRC() const{ + return ntohl(ssrc); +} + +uint8_t FCI_FIR::getSeq() const{ + return seq_number; +} + +uint32_t FCI_FIR::getReserved() const{ + return (reserved[0] << 16) | (reserved[1] << 8) | reserved[2]; } string FCI_FIR::dumpString() const { - return StrPrinter << "ssrc:" << ssrc << ", seq_number:" << seq_number << ", reserved:" << reserved; + return StrPrinter << "ssrc:" << getSSRC() << ", seq_number:" << (int)getSeq() << ", reserved:" << getReserved(); } FCI_FIR::FCI_FIR(uint32_t ssrc, uint8_t seq_number, uint32_t reserved) { this->ssrc = htonl(ssrc); this->seq_number = seq_number; - this->reserved = htonl(reserved) >> 8; + this->reserved[0] = (reserved >> 16) & 0xFF; + this->reserved[1] = (reserved >> 8) & 0xFF; + this->reserved[2] = reserved & 0xFF; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -string FCI_REMB::create(const initializer_list &ssrcs, uint32_t bitrate) { +static const char kRembMagic[] = "REMB"; + +void FCI_REMB::check(size_t size){ + CHECK(size >= kSize); + CHECK(memcmp(magic, kRembMagic, sizeof(magic)) == 0); + auto num_ssrc = bitrate[0]; + auto expect_size = kSize + 4 * num_ssrc; + CHECK(size == expect_size); +} + +string FCI_REMB::create(const vector &ssrcs, uint32_t bitrate) { CHECK(ssrcs.size() > 0 && ssrcs.size() <= 0xFF); string ret; ret.resize(kSize + ssrcs.size() * 4); FCI_REMB *thiz = (FCI_REMB *) ret.data(); - memcpy(thiz->magic, "REMB", 4); + memcpy(thiz->magic, kRembMagic, sizeof(magic)); /* bitrate --> BR Exp/BR Mantissa */ uint8_t b = 0; @@ -97,24 +119,12 @@ string FCI_REMB::create(const initializer_list &ssrcs, uint32_t bitrat //设置ssrc列表 auto ptr = thiz->ssrc_feedback; - for (auto &ssrc : ssrcs) { + for (auto ssrc : ssrcs) { *(ptr++) = htonl(ssrc); } return ret; } -void FCI_REMB::net2Host(size_t total_size) { - CHECK(total_size >= kSize); - CHECK(memcmp(magic, "REMB", 4) == 0); - auto num_ssrc = bitrate[0]; - auto expect_size = kSize + 4 * num_ssrc; - CHECK(total_size == expect_size); - auto ptr = ssrc_feedback; - while (num_ssrc--) { - *(ptr++) = ntohl(*ptr); - } -} - uint32_t FCI_REMB::getBitRate() const { uint8_t exp = (bitrate[1] >> 2) & 0x3F; uint32_t mantissa = (bitrate[1] & 0x03) << 16; @@ -123,12 +133,12 @@ uint32_t FCI_REMB::getBitRate() const { return mantissa << exp; } -vector FCI_REMB::getSSRC() { - vector ret; +vector FCI_REMB::getSSRC() { + vector ret; auto num_ssrc = bitrate[0]; auto ptr = ssrc_feedback; while (num_ssrc--) { - ret.emplace_back(ptr++); + ret.emplace_back(ntohl(*ptr++)); } return ret; } @@ -137,30 +147,51 @@ string FCI_REMB::dumpString() const { _StrPrinter printer; printer << "bitrate:" << getBitRate() << ", ssrc:"; for (auto &ssrc : ((FCI_REMB *) this)->getSSRC()) { - printer << *ssrc << " "; + printer << ssrc << " "; } return printer; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void FCI_NACK::net2Host() { - pid = ntohs(pid); - blp = ntohs(blp); +FCI_NACK::FCI_NACK(uint16_t pid_h, const vector &type) { + uint16_t blp_h = 0; + int i = kBitSize; + for (auto item : type) { + --i; + if (item) { + blp_h |= (1 << i); + } + } + blp = htons(blp_h); + pid = htons(pid_h); +} + +void FCI_NACK::check(size_t size){ + CHECK(size == kSize); +} + +uint16_t FCI_NACK::getPid() const { + return ntohs(pid); +} + +uint16_t FCI_NACK::getBlp() const { + return ntohs(blp); } vector FCI_NACK::getBitArray() const { vector ret; ret.resize(kBitSize); + auto blp_h = getBlp(); for (size_t i = 0; i < kBitSize; ++i) { - ret[i] = blp & (1 << (kBitSize - i - 1)); + ret[i] = blp_h & (1 << (kBitSize - i - 1)); } return ret; } string FCI_NACK::dumpString() const { _StrPrinter printer; - printer << "pid:" << pid << ",blp:"; + printer << "pid:" << getPid() << ",blp:"; for (auto &flag : getBitArray()) { printer << flag << " "; } @@ -169,6 +200,37 @@ string FCI_NACK::dumpString() const { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +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; + RunLengthChunk::RunLengthChunk(SymbolStatus status, uint16_t run_length) { type = 0; symbol = (uint8_t)status & 0x03; @@ -189,6 +251,37 @@ string RunLengthChunk::dumpString() const{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +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| symbol list | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +#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 getSymbolList() const; + //构造函数 + StatusVecChunk(const vector &status); + //打印本对象 + string dumpString() const; +} PACKED; + StatusVecChunk::StatusVecChunk(const vector &status) { uint16_t value = 0; type = 1; @@ -248,10 +341,16 @@ string StatusVecChunk::dumpString() const { /////////////////////////////////////////////////////// -void FCI_TWCC::net2Host(size_t total_size) { - CHECK(total_size >= kSize); - base_seq = ntohs(base_seq); - pkt_status_count = ntohs(pkt_status_count); +void FCI_TWCC::check(size_t size){ + CHECK(size >= kSize); +} + +uint16_t FCI_TWCC::getBaseSeq() const { + return ntohs(base_seq); +} + +uint16_t FCI_TWCC::getPacketCount() const { + return ntohs(pkt_status_count); } uint32_t FCI_TWCC::getReferenceTime() const { @@ -323,10 +422,10 @@ map > FCI_TWCC::getPacketCh auto ptr = (uint8_t *) this + kSize; auto end = (uint8_t *) this + total_size; CHECK(ptr < end); - auto seq = base_seq; + auto seq = getBaseSeq(); - for (uint8_t i = 0; i < pkt_status_count;) { - CHECK(ptr + RunLengthChunk::kSize <= end) + for (uint8_t i = 0; i < getPacketCount();) { + CHECK(ptr + RunLengthChunk::kSize <= end); RunLengthChunk *chunk = (RunLengthChunk *) ptr; if (!chunk->type) { //RunLengthChunk @@ -345,7 +444,7 @@ map > FCI_TWCC::getPacketCh ptr += 2; } for (auto &pr : ret) { - CHECK(ptr <= end) + CHECK(ptr <= end); pr.second.second = 250 * getRecvDelta(pr.second.first, ptr, end); } return ret; @@ -354,11 +453,55 @@ 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"; + printer << "twcc fci, base_seq:" << getBaseSeq() << ",pkt_status_count:" << getPacketCount() << ", ref time:" << getReferenceTime() << ", fb count:" << (int)fb_pkt_count << "\n"; for (auto &pr : map) { printer << "rtp seq:" << pr.first <<", packet status:" << (int)(pr.second.first) << ", delta:" << pr.second.second << "\n"; } return std::move(printer); } -}//namespace mediakit \ No newline at end of file +}//namespace mediakit + +#if 1 +using namespace mediakit; +void testFCI() { + { + FCI_SLI fci(8191, 0, 63); + InfoL << hexdump(&fci, FCI_SLI::kSize) << fci.dumpString(); + } + { + FCI_FIR fci(123456, 139, 456789); + InfoL << hexdump(&fci, FCI_FIR::kSize) << fci.dumpString(); + } + { + auto str = FCI_REMB::create({1234, 2345, 5678}, 4 * 1024 * 1024); + FCI_REMB *ptr = (FCI_REMB *) str.data(); + InfoL << hexdump(str.data(), str.size()) << ptr->dumpString(); + } + { + FCI_NACK nack(1234, vector({1, 0, 0, 0, 1, 0, 1, 0, 1, 0})); + InfoL << hexdump(&nack, FCI_NACK::kSize) << nack.dumpString(); + } + + { + RunLengthChunk chunk(SymbolStatus::large_delta, 8024); + InfoL << hexdump(&chunk, RunLengthChunk::kSize) << chunk.dumpString(); + } + + auto lam = [](const initializer_list &lst) { + vector 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) << chunk.dumpString(); + } + { + StatusVecChunk chunk(lam({0, 1, 2, 2, 0, 1, 2})); + InfoL << hexdump(&chunk, StatusVecChunk::kSize) << chunk.dumpString(); + } +} +#endif \ No newline at end of file diff --git a/src/Rtcp/RtcpFCI.h b/src/Rtcp/RtcpFCI.h index 6676c42c..a3d5e96e 100644 --- a/src/Rtcp/RtcpFCI.h +++ b/src/Rtcp/RtcpFCI.h @@ -12,6 +12,7 @@ #define ZLMEDIAKIT_RTCPFCI_H #include "Rtcp.h" +#include "assert.h" namespace mediakit { @@ -46,10 +47,11 @@ public: static size_t constexpr kSize = 4; FCI_SLI(uint16_t first, uint16_t number, uint8_t pic_id); + + void check(size_t size); uint16_t getFirst() const; uint16_t getNumber() const; uint8_t getPicID() const; - void net2Host(); string dumpString() const; private: @@ -108,15 +110,20 @@ public: // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ class FCI_FIR { public: - uint32_t ssrc; - uint32_t seq_number: 8; - uint32_t reserved: 24; - static size_t constexpr kSize = 8; + FCI_FIR(uint32_t ssrc, uint8_t seq_number, uint32_t reserved = 0); - void net2Host(); + + void check(size_t size); + uint32_t getSSRC() const; + uint8_t getSeq() const; + uint32_t getReserved() const; string dumpString() const; +private: + uint32_t ssrc; + uint8_t seq_number; + uint8_t reserved[3]; } PACKED; //PSFB fmt = 5 @@ -131,6 +138,13 @@ public: class FCI_TSTR { public: static size_t constexpr kSize = 8; + + void check(size_t size) { + CHECK(size == kSize); + } + +private: + uint8_t data[kSize]; } PACKED; //PSFB fmt = 6 @@ -160,6 +174,13 @@ class FCI_TSTN : public FCI_TSTR{ class FCI_VBCM { public: static size_t constexpr kSize = 12; + + void check(size_t size) { + CHECK(size == kSize); + } + +private: + uint8_t data[kSize]; } PACKED; //PSFB fmt = 15 @@ -194,12 +215,13 @@ class FCI_REMB { public: static size_t constexpr kSize = 8; - static string create(const std::initializer_list &ssrcs, uint32_t bitrate); - void net2Host(size_t total_size); + static string create(const std::vector &ssrcs, uint32_t bitrate); + void check(size_t size); string dumpString() const; uint32_t getBitRate() const; - vector getSSRC(); + vector getSSRC(); +private: //Unique identifier 'R' 'E' 'M' 'B' char magic[4]; //Num SSRC (8 bits)/BR Exp (6 bits)/ BR Mantissa (18 bits) @@ -207,7 +229,6 @@ public: // SSRC feedback (32 bits) Consists of one or more SSRC entries which // this feedback message applies to. uint32_t ssrc_feedback[1]; - } PACKED; /////////////////////////////////////////// RTPFB //////////////////////////////////////////////////// @@ -221,32 +242,25 @@ public: // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ class FCI_NACK { public: - static constexpr size_t kBitSize = 16; static constexpr size_t kSize = 4; + FCI_NACK(uint16_t pid_h, const vector &type); + + void check(size_t size); + uint16_t getPid() const; + uint16_t getBlp() const; + vector getBitArray() const; + string dumpString() const; + +private: + static constexpr size_t kBitSize = 16; + +private: // The PID field is used to specify a lost packet. The PID field // refers to the RTP sequence number of the lost packet. uint16_t pid; // bitmask of following lost packets (BLP): 16 bits uint16_t blp; - - void net2Host(); - vector getBitArray() const; - string dumpString() const; - - template - FCI_NACK(uint16_t pid_h, const Type &type){ - uint16_t blp_h = 0; - int i = kBitSize; - for (auto &item : type) { - --i; - if (item) { - blp_h |= (1 << i); - } - } - blp = htons(blp_h); - pid = htons(pid_h); - } } PACKED; //RTPFB fmt = 3 @@ -262,6 +276,11 @@ class FCI_TMMBR { public: static size_t constexpr kSize = 8; + void check(size_t size) { + CHECK(size == kSize); + } + +private: //SSRC (32 bits): The SSRC value of the media sender that is // requested to obey the new maximum bit rate. uint32_t ssrc; @@ -269,17 +288,13 @@ public: // MxTBR Exp (6 bits): The exponential scaling of the mantissa for the // maximum total media bit rate value. The value is an // unsigned integer [0..63]. - uint32_t max_tbr_exp: 6; - // MxTBR Mantissa (17 bits): The mantissa of the maximum total media // bit rate value as an unsigned integer. - uint32_t max_mantissa: 17; - // Measured Overhead (9 bits): The measured average packet overhead // value in bytes. The measurement SHALL be done according // to the description in section 4.2.1.2. The value is an // unsigned integer [0..511]. - uint32_t measured_overhead: 9; + uint32_t max_tbr; } PACKED; //RTPFB fmt = 4 @@ -307,68 +322,6 @@ enum class SymbolStatus : uint8_t{ 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| symbol list | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -#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 getSymbolList() const; - //构造函数 - StatusVecChunk(const vector &status); - - string dumpString() const; -} PACKED; - //RTPFB fmt = 15 //https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1 //https://zhuanlan.zhihu.com/p/206656654 @@ -395,6 +348,14 @@ class FCI_TWCC{ public: static size_t constexpr kSize = 8; + void check(size_t size); + string dumpString(size_t total_size) const; + uint16_t getBaseSeq() const; + uint32_t getReferenceTime() const; + uint16_t getPacketCount() const; + map > getPacketChunkList(size_t total_size) const; + +private: //base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号 uint16_t base_seq; //packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算 @@ -403,12 +364,6 @@ public: uint8_t ref_time[3]; //feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 | uint8_t fb_pkt_count; - - void net2Host(size_t total_size); - uint32_t getReferenceTime() const; - map > getPacketChunkList(size_t total_size) const; - string dumpString(size_t total_size) const; - } PACKED; } //namespace mediakit diff --git a/tests/test_rtcp_fci.cpp b/tests/test_rtcp_fci.cpp index aecc821d..1dda1143 100644 --- a/tests/test_rtcp_fci.cpp +++ b/tests/test_rtcp_fci.cpp @@ -15,55 +15,11 @@ using namespace std; using namespace toolkit; using namespace mediakit; +extern void testFCI(); + int main() { - //初始化日志系统 - Logger::Instance().add(std::make_shared ()); + Logger::Instance().add(std::make_shared()); - { - FCI_SLI fci(0xFFFF, 0, 0xFF); - InfoL << 0b10101010101 << " " << 0b01010101010 << " " << (int) 0b101010 << " " << hexdump(&fci, FCI_SLI::kSize); - fci.net2Host(); - InfoL << fci.dumpString(); - } - { - FCI_FIR fci(123456, 139, 456789); - InfoL << hexdump(&fci, FCI_FIR::kSize); - fci.net2Host(); - InfoL << fci.dumpString(); - } - { - auto str = FCI_REMB::create({1234,2345,5678}, 4 * 1024 * 1024); - FCI_REMB *ptr = (FCI_REMB *)str.data(); - ptr->net2Host(str.size()); - InfoL << ptr->dumpString(); - } - { - FCI_NACK nack(1234, vector({1, 0, 0, 0, 1, 0, 1, 0, 1, 0})); - nack.net2Host(); - InfoL << nack.dumpString(); - } - { - RunLengthChunk chunk(SymbolStatus::large_delta, 8024); - InfoL << hexdump(&chunk, RunLengthChunk::kSize); - InfoL << chunk.dumpString(); - } - - auto lam = [](const initializer_list &lst){ - vector 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(); - } + testFCI(); return 0; } diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 272d6dd9..6a20fc40 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -19,8 +19,6 @@ using namespace std; using namespace mediakit; -#define CHECK(exp) Assert_Throw(!(exp), #exp, __FUNCTION__, __FILE__, __LINE__); - //https://datatracker.ietf.org/doc/rfc4566/?include_text=1 //https://blog.csdn.net/aggresss/article/details/109850434 //https://aggresss.blog.csdn.net/article/details/106436703 diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index d37e5a88..800daa1d 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -557,7 +557,6 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { FCI_TWCC *twcc = (FCI_TWCC *) (fci); auto fci_size = rtpfb->getSize() - 12; InfoL << hexdump(fci, fci_size); - twcc->net2Host(fci_size); InfoL << "\n" << twcc->dumpString(fci_size); } break;