RTC: Fix TWCC send bug

pull/2324/head
winlin 4 years ago
parent 7ac4a4f4ca
commit bd1752a4b2

@ -1345,23 +1345,25 @@ srs_error_t SrsRtcPublishStream::send_periodic_twcc()
++_srs_pps_srtcps->sugar;
char pkt[kRtcpPacketSize];
SrsBuffer *buffer = new SrsBuffer(pkt, sizeof(pkt));
SrsAutoFree(SrsBuffer, buffer);
// limit the max count=1024 to avoid dead loop.
for (int i = 0; i < 1024 && rtcp_twcc_.need_feedback(); ++i) {
char pkt[kMaxUDPDataSize];
SrsBuffer *buffer = new SrsBuffer(pkt, sizeof(pkt));
SrsAutoFree(SrsBuffer, buffer);
rtcp_twcc_.set_feedback_count(twcc_fb_count_);
twcc_fb_count_++;
rtcp_twcc_.set_feedback_count(twcc_fb_count_);
twcc_fb_count_++;
if((err = rtcp_twcc_.encode(buffer)) != srs_success) {
return srs_error_wrap(err, "encode, count=%u", twcc_fb_count_);
}
if((err = rtcp_twcc_.encode(buffer)) != srs_success) {
return srs_error_wrap(err, "encode, count=%u", twcc_fb_count_);
}
int nb_protected_buf = buffer->pos();
if ((err = session_->transport_->protect_rtcp(pkt, &nb_protected_buf)) != srs_success) {
return srs_error_wrap(err, "protect rtcp, size=%u", nb_protected_buf);
if((err = session_->send_rtcp(pkt, buffer->pos())) != srs_success) {
return srs_error_wrap(err, "send twcc, count=%u", twcc_fb_count_);
}
}
return session_->sendonly_skt->sendto(pkt, nb_protected_buf, 0);
return err;
}
srs_error_t SrsRtcPublishStream::on_rtcp(SrsRtcpCommon* rtcp)

@ -716,9 +716,9 @@ SrsRtcpTWCC::SrsRtcpTWCC(uint32_t sender_ssrc) : pkt_len(0)
ssrc_ = sender_ssrc;
media_ssrc_ = 0;
base_sn_ = 0;
packet_count_ = 0;
reference_time_ = 0;
fb_pkt_count_ = 0;
next_base_sn_ = 0;
}
SrsRtcpTWCC::~SrsRtcpTWCC()
@ -731,6 +731,7 @@ void SrsRtcpTWCC::clear()
pkt_deltas_.clear();
recv_packets_.clear();
recv_sns_.clear();
next_base_sn_ = 0;
}
uint32_t SrsRtcpTWCC::get_media_ssrc() const
@ -751,11 +752,6 @@ uint8_t SrsRtcpTWCC::get_feedback_count() const
{
return fb_pkt_count_;
}
uint16_t SrsRtcpTWCC::get_packet_status_count() const
{
return packet_count_;
}
vector<uint16_t> SrsRtcpTWCC::get_packet_chucks() const
{
@ -776,11 +772,6 @@ void SrsRtcpTWCC::set_base_sn(uint16_t sn)
base_sn_ = sn;
}
void SrsRtcpTWCC::set_packet_status_count(uint16_t count)
{
packet_count_ = count;
}
void SrsRtcpTWCC::set_reference_time(uint32_t time)
{
reference_time_ = time;
@ -865,7 +856,7 @@ srs_error_t SrsRtcpTWCC::decode(SrsBuffer *buffer)
uint64_t SrsRtcpTWCC::nb_bytes()
{
return kRtcpPacketSize;
return kMaxUDPDataSize;
}
srs_utime_t SrsRtcpTWCC::calculate_delta_us(srs_utime_t ts, srs_utime_t last)
@ -1057,7 +1048,9 @@ srs_error_t SrsRtcpTWCC::encode(SrsBuffer *buffer)
err = do_encode(buffer);
clear();
if (err != srs_success || next_base_sn_ == 0) {
clear();
}
return err;
}
@ -1099,21 +1092,41 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
}
pkt_len = kTwccFbPktHeaderSize;
set<uint16_t, SrsSeqCompareLess>::iterator it_sn = recv_sns_.begin();
base_sn_ = *it_sn;
if (!next_base_sn_) {
base_sn_ = *it_sn;
} else {
base_sn_ = next_base_sn_;
it_sn = recv_sns_.find(base_sn_);
}
map<uint16_t, srs_utime_t>::iterator it_ts = recv_packets_.find(base_sn_);
srs_utime_t ts = it_ts->second;
reference_time_ = (ts % kTwccFbReferenceTimeDivisor) / kTwccFbTimeMultiplier;
srs_utime_t last_ts = (srs_utime_t)(reference_time_) * kTwccFbTimeMultiplier;
uint16_t last_sn = base_sn_;
packet_count_ = recv_packets_.size();
uint16_t packet_count = 0;
// encode chunk
SrsRtcpTWCC::SrsRtcpTWCCChunk chunk;
for(; it_sn != recv_sns_.end(); ++it_sn) {
// check whether exceed buffer len
// max recv_delta_size = 2
if (pkt_len + 2 >= buffer->left()) {
break;
}
uint16_t current_sn = *it_sn;
// calculate delta
it_ts = recv_packets_.find(current_sn);
if (it_ts == recv_packets_.end()) {
continue;
}
packet_count++;
srs_utime_t delta_us = calculate_delta_us(it_ts->second, last_ts);
int16_t delta = delta_us;
if(delta != delta_us) {
@ -1124,7 +1137,7 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
// lost packet
for(uint16_t lost_sn = last_sn + 1; lost_sn < current_sn; ++lost_sn) {
process_pkt_chunk(chunk, 0);
packet_count_++;
packet_count++;
}
}
@ -1138,6 +1151,13 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
last_ts += delta * kTwccFbDeltaUnit;
pkt_len += recv_delta_size;
last_sn = current_sn;
recv_packets_.erase(it_ts);
}
next_base_sn_ = 0;
if (it_sn != recv_sns_.end()) {
next_base_sn_ = *it_sn;
}
if(0 < chunk.size) {
@ -1159,7 +1179,7 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
}
buffer->write_4bytes(media_ssrc_);
buffer->write_2bytes(base_sn_);
buffer->write_2bytes(packet_count_);
buffer->write_2bytes(packet_count);
buffer->write_3bytes(reference_time_);
buffer->write_1bytes(fb_pkt_count_);
@ -1181,6 +1201,9 @@ srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
pkt_len++;
}
encoded_chucks_.clear();
pkt_deltas_.clear();
return err;
}

@ -36,6 +36,9 @@
const int kRtcpPacketSize = 1500;
const uint8_t kRtcpVersion = 0x2;
// 1500 - 20(ip_header) - 8(udp_header)
const int kMaxUDPDataSize = 1472;
// RTCP Packet Types, @see http://www.networksorcery.com/enp/protocol/rtcp.htm
enum SrsRtcpType
{
@ -266,7 +269,6 @@ class SrsRtcpTWCC : public SrsRtcpCommon
private:
uint32_t media_ssrc_;
uint16_t base_sn_;
uint16_t packet_count_;
int32_t reference_time_;
uint8_t fb_pkt_count_;
std::vector<uint16_t> encoded_chucks_;
@ -284,6 +286,7 @@ private:
};
int pkt_len;
uint16_t next_base_sn_;
private:
void clear();
srs_utime_t calculate_delta_us(srs_utime_t ts, srs_utime_t last);
@ -302,7 +305,6 @@ public:
uint32_t get_media_ssrc() const;
uint16_t get_base_sn() const;
uint16_t get_packet_status_count() const;
uint32_t get_reference_time() const;
uint8_t get_feedback_count() const;
std::vector<uint16_t> get_packet_chucks() const;
@ -310,7 +312,6 @@ public:
void set_media_ssrc(uint32_t ssrc);
void set_base_sn(uint16_t sn);
void set_packet_status_count(uint16_t count);
void set_reference_time(uint32_t time);
void set_feedback_count(uint8_t count);
void add_packet_chuck(uint16_t chuck);

Loading…
Cancel
Save