/* * 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 "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h" #include "webrtc/base/checks.h" #include "webrtc/base/logging.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.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) { LOG(LS_ERROR) << "Report Block should be 24 bytes long"; return false; } source_ssrc_ = ByteReader::ReadBigEndian(&buffer[0]); fraction_lost_ = buffer[4]; cumulative_lost_ = ByteReader::ReadBigEndian(&buffer[5]); extended_high_seq_num_ = ByteReader::ReadBigEndian(&buffer[8]); jitter_ = ByteReader::ReadBigEndian(&buffer[12]); last_sr_ = ByteReader::ReadBigEndian(&buffer[16]); delay_since_last_sr_ = ByteReader::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(), (1u << 24)); // Have only 3 bytes for it. ByteWriter::WriteBigEndian(&buffer[0], source_ssrc()); ByteWriter::WriteBigEndian(&buffer[4], fraction_lost()); ByteWriter::WriteBigEndian(&buffer[5], cumulative_lost()); ByteWriter::WriteBigEndian(&buffer[8], extended_high_seq_num()); ByteWriter::WriteBigEndian(&buffer[12], jitter()); ByteWriter::WriteBigEndian(&buffer[16], last_sr()); ByteWriter::WriteBigEndian(&buffer[20], delay_since_last_sr()); } bool ReportBlock::WithCumulativeLost(uint32_t cumulative_lost) { if (cumulative_lost >= (1u << 24)) { // Have only 3 bytes to store it. LOG(LS_WARNING) << "Cumulative lost is too big to fit into Report Block"; return false; } cumulative_lost_ = cumulative_lost; return true; } } // namespace rtcp } // namespace webrtc