1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

RTC: Fix TWCC delta bug.

This commit is contained in:
winlin 2020-06-26 15:20:24 +08:00
parent 94a4eaffda
commit 62b70943d4
2 changed files with 78 additions and 72 deletions

View file

@ -773,6 +773,17 @@ srs_error_t SrsRtcpTWCC::encode(SrsBuffer *buffer)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
err = do_encode(buffer);
clear();
return err;
}
srs_error_t SrsRtcpTWCC::do_encode(SrsBuffer *buffer)
{
srs_error_t err = srs_success;
if(!buffer->require(nb_bytes())) { if(!buffer->require(nb_bytes())) {
return srs_error_new(ERROR_RTC_RTCP, "requires %d bytes", nb_bytes()); return srs_error_new(ERROR_RTC_RTCP, "requires %d bytes", nb_bytes());
} }
@ -787,85 +798,79 @@ srs_error_t SrsRtcpTWCC::encode(SrsBuffer *buffer)
uint16_t last_sn = base_sn_; uint16_t last_sn = base_sn_;
packet_count_ = recv_packes_.size(); packet_count_ = recv_packes_.size();
do { // encode chunk
// encode chunk SrsRtcpTWCC::SrsRtcpTWCCChunk chunk;
SrsRtcpTWCC::SrsRtcpTWCCChunk chunk; for(; it_sn != recv_sns_.end(); ++it_sn) {
for(; it_sn != recv_sns_.end(); ++it_sn) { uint16_t current_sn = *it_sn;
uint16_t current_sn = *it_sn; // calculate delta
// calculate delta it_ts = recv_packes_.find(current_sn);
it_ts = recv_packes_.find(current_sn); srs_utime_t delta_us = calculate_delta_us(it_ts->second, last_ts);
srs_utime_t delta_us = calculate_delta_us(it_ts->second, last_ts); int16_t delta = delta_us;
uint16_t delta = delta_us; if(delta != delta_us) {
if(delta != delta_us) { return srs_error_new(ERROR_RTC_RTCP, "twcc: delta:%" PRId64 ", exceeds the 16bits", delta_us);
return srs_error_new(ERROR_RTC_RTCP, "twcc: delta:%lld, exceeds the 16-bit base receive delta", delta_us);
}
if(current_sn > (last_sn + 1)) {
// lost packet
for(uint16_t lost_sn = last_sn + 1; lost_sn < current_sn; ++lost_sn) {
process_pkt_chunk(chunk, 0);
packet_count_++;
}
}
// FIXME 24-bit base receive delta not supported
int recv_delta_size = (delta >= 0 && delta <= 0xff) ? 1 : 2;
if ((err = process_pkt_chunk(chunk, recv_delta_size)) != srs_success) {
return srs_error_new(ERROR_RTC_RTCP, "delta_size %d, failed to append_recv_delta", recv_delta_size);
}
pkt_deltas_.push_back(delta);
last_ts += delta * kTwccFbDeltaUnit;
pkt_len += recv_delta_size;
last_sn = current_sn;
} }
if(0 < chunk.size) { if(current_sn > (last_sn + 1)) {
if((err = encode_remaining_chunk(chunk)) != srs_success) { // lost packet
return srs_error_wrap(err, "encode chunk"); for(uint16_t lost_sn = last_sn + 1; lost_sn < current_sn; ++lost_sn) {
process_pkt_chunk(chunk, 0);
packet_count_++;
} }
} }
// encode rtcp twcc packet // FIXME 24-bit base receive delta not supported
if((pkt_len % 4) == 0) { int recv_delta_size = (delta >= 0 && delta <= 0xff) ? 1 : 2;
header_.length = pkt_len / 4; if ((err = process_pkt_chunk(chunk, recv_delta_size)) != srs_success) {
return srs_error_new(ERROR_RTC_RTCP, "delta_size %d, failed to append_recv_delta", recv_delta_size);
}
pkt_deltas_.push_back(delta);
last_ts += delta * kTwccFbDeltaUnit;
pkt_len += recv_delta_size;
last_sn = current_sn;
}
if(0 < chunk.size) {
if((err = encode_remaining_chunk(chunk)) != srs_success) {
return srs_error_wrap(err, "encode chunk");
}
}
// encode rtcp twcc packet
if((pkt_len % 4) == 0) {
header_.length = pkt_len / 4;
} else {
header_.length = (pkt_len + 4 - (pkt_len%4)) / 4;
}
header_.length -= 1;
if(srs_success != (err = encode_header(buffer))) {
return srs_error_wrap(err, "encode header");
}
buffer->write_4bytes(sender_ssrc_);
buffer->write_4bytes(media_ssrc_);
buffer->write_2bytes(base_sn_);
buffer->write_2bytes(packet_count_);
buffer->write_3bytes(reference_time_);
buffer->write_1bytes(fb_pkt_count_);
for(vector<uint16_t>::iterator it = encoded_chucks_.begin(); it != encoded_chucks_.end(); ++it) {
buffer->write_2bytes(*it);
}
for(vector<uint16_t>::iterator it = pkt_deltas_.begin(); it != pkt_deltas_.end(); ++it) {
if(0 <= *it && 0xFF >= *it) {
// small delta
uint8_t delta = *it;
buffer->write_1bytes(delta);
} else { } else {
header_.length = (pkt_len + 4 - (pkt_len%4)) / 4; // large or negative delta
}
header_.length -= 1;
if(srs_success != (err = encode_header(buffer))) {
err = srs_error_wrap(err, "encode header");
break;
}
buffer->write_4bytes(sender_ssrc_);
buffer->write_4bytes(media_ssrc_);
buffer->write_2bytes(base_sn_);
buffer->write_2bytes(packet_count_);
buffer->write_3bytes(reference_time_);
buffer->write_1bytes(fb_pkt_count_);
for(vector<uint16_t>::iterator it = encoded_chucks_.begin(); it != encoded_chucks_.end(); ++it) {
buffer->write_2bytes(*it); buffer->write_2bytes(*it);
} }
for(vector<uint16_t>::iterator it = pkt_deltas_.begin(); it != pkt_deltas_.end(); ++it) { }
if(0 <= *it && 0xFF >= *it) { while((pkt_len % 4) != 0) {
// small delta buffer->write_1bytes(0);
uint8_t delta = *it; pkt_len++;
buffer->write_1bytes(delta); }
} else {
// large or negative delta
buffer->write_2bytes(*it);
}
}
while((pkt_len % 4) != 0) {
buffer->write_1bytes(0);
pkt_len++;
}
} while(0);
clear();
return err; return err;
} }

View file

@ -293,7 +293,8 @@ public:
virtual srs_error_t decode(SrsBuffer *buffer); virtual srs_error_t decode(SrsBuffer *buffer);
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer *buffer); virtual srs_error_t encode(SrsBuffer *buffer);
private:
srs_error_t do_encode(SrsBuffer *buffer);
}; };
class SrsRtcpNack : public SrsRtcpCommon class SrsRtcpNack : public SrsRtcpCommon