mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 14:20:45 +01:00

The cumulative number of packets lost in a RTCP sender report can be negative if there are duplicates. This CL fixes a bug that the parser of RTCP reports treats the field as an unsigned integer, and incorrectly reports large packet losses when a negative loss is reported. Bug: webrtc:9601 Change-Id: I1109ac0741614d61bda743e13a390b7d3e147a9c Reviewed-on: https://webrtc-review.googlesource.com/92942 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Commit-Queue: Qingsi Wang <qingsi@google.com> Cr-Commit-Position: refs/heads/master@{#24234}
100 lines
3.9 KiB
C++
100 lines
3.9 KiB
C++
/*
|
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
|
|
|
|
#include "modules/rtp_rtcp/source/byte_io.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/logging.h"
|
|
|
|
namespace webrtc {
|
|
namespace rtcp {
|
|
|
|
// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
|
|
//
|
|
// RTCP report block (RFC 3550).
|
|
//
|
|
// 0 1 2 3
|
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
// 0 | SSRC_1 (SSRC of first source) |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// 4 | fraction lost | cumulative number of packets lost |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// 8 | extended highest sequence number received |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// 12 | interarrival jitter |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// 16 | last SR (LSR) |
|
|
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
// 20 | delay since last SR (DLSR) |
|
|
// 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
|
ReportBlock::ReportBlock()
|
|
: source_ssrc_(0),
|
|
fraction_lost_(0),
|
|
cumulative_lost_(0),
|
|
extended_high_seq_num_(0),
|
|
jitter_(0),
|
|
last_sr_(0),
|
|
delay_since_last_sr_(0) {}
|
|
|
|
bool ReportBlock::Parse(const uint8_t* buffer, size_t length) {
|
|
RTC_DCHECK(buffer != nullptr);
|
|
if (length < ReportBlock::kLength) {
|
|
RTC_LOG(LS_ERROR) << "Report Block should be 24 bytes long";
|
|
return false;
|
|
}
|
|
|
|
source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
|
|
fraction_lost_ = buffer[4];
|
|
cumulative_lost_ = ByteReader<int32_t, 3>::ReadBigEndian(&buffer[5]);
|
|
extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
|
|
jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]);
|
|
last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]);
|
|
delay_since_last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[20]);
|
|
|
|
return true;
|
|
}
|
|
|
|
void ReportBlock::Create(uint8_t* buffer) const {
|
|
// Runtime check should be done while setting cumulative_lost.
|
|
RTC_DCHECK_LT(cumulative_lost_signed(),
|
|
(1 << 23)); // Have only 3 bytes for it.
|
|
|
|
ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], source_ssrc());
|
|
ByteWriter<uint8_t>::WriteBigEndian(&buffer[4], fraction_lost());
|
|
ByteWriter<int32_t, 3>::WriteBigEndian(&buffer[5], cumulative_lost_signed());
|
|
ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], extended_high_seq_num());
|
|
ByteWriter<uint32_t>::WriteBigEndian(&buffer[12], jitter());
|
|
ByteWriter<uint32_t>::WriteBigEndian(&buffer[16], last_sr());
|
|
ByteWriter<uint32_t>::WriteBigEndian(&buffer[20], delay_since_last_sr());
|
|
}
|
|
|
|
bool ReportBlock::SetCumulativeLost(int32_t cumulative_lost) {
|
|
// We have only 3 bytes to store it, and it's a signed value.
|
|
if (cumulative_lost >= (1 << 23) || cumulative_lost < -(1 << 23)) {
|
|
RTC_LOG(LS_WARNING)
|
|
<< "Cumulative lost is too big to fit into Report Block";
|
|
return false;
|
|
}
|
|
cumulative_lost_ = cumulative_lost;
|
|
return true;
|
|
}
|
|
|
|
uint32_t ReportBlock::cumulative_lost() const {
|
|
if (cumulative_lost_ < 0) {
|
|
RTC_LOG(LS_VERBOSE) << "Ignoring negative value of cumulative_lost";
|
|
return 0;
|
|
}
|
|
return cumulative_lost_;
|
|
}
|
|
|
|
} // namespace rtcp
|
|
} // namespace webrtc
|