mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
RTC: Fix TWCC send bug
This commit is contained in:
parent
7ac4a4f4ca
commit
bd1752a4b2
3 changed files with 59 additions and 33 deletions
|
@ -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_);
|
||||
}
|
||||
|
||||
if((err = session_->send_rtcp(pkt, buffer->pos())) != srs_success) {
|
||||
return srs_error_wrap(err, "send twcc, 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);
|
||||
}
|
||||
|
||||
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…
Reference in a new issue