| /* | |
| * 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 |