Home | History | Annotate | Download | only in rtcp_packet
      1 /*
      2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h"
     12 
     13 #include "webrtc/base/checks.h"
     14 #include "webrtc/base/logging.h"
     15 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
     16 
     17 namespace webrtc {
     18 namespace rtcp {
     19 
     20 // From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
     21 //
     22 // RTCP report block (RFC 3550).
     23 //
     24 //     0                   1                   2                   3
     25 //     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
     26 //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
     27 //  0 |                 SSRC_1 (SSRC of first source)                 |
     28 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     29 //  4 | fraction lost |       cumulative number of packets lost       |
     30 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     31 //  8 |           extended highest sequence number received           |
     32 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     33 // 12 |                      interarrival jitter                      |
     34 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     35 // 16 |                         last SR (LSR)                         |
     36 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     37 // 20 |                   delay since last SR (DLSR)                  |
     38 // 24 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
     39 ReportBlock::ReportBlock()
     40     : source_ssrc_(0),
     41       fraction_lost_(0),
     42       cumulative_lost_(0),
     43       extended_high_seq_num_(0),
     44       jitter_(0),
     45       last_sr_(0),
     46       delay_since_last_sr_(0) {}
     47 
     48 bool ReportBlock::Parse(const uint8_t* buffer, size_t length) {
     49   RTC_DCHECK(buffer != nullptr);
     50   if (length < ReportBlock::kLength) {
     51     LOG(LS_ERROR) << "Report Block should be 24 bytes long";
     52     return false;
     53   }
     54 
     55   source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
     56   fraction_lost_ = buffer[4];
     57   cumulative_lost_ = ByteReader<uint32_t, 3>::ReadBigEndian(&buffer[5]);
     58   extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
     59   jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]);
     60   last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]);
     61   delay_since_last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[20]);
     62 
     63   return true;
     64 }
     65 
     66 void ReportBlock::Create(uint8_t* buffer) const {
     67   // Runtime check should be done while setting cumulative_lost.
     68   RTC_DCHECK_LT(cumulative_lost(), (1u << 24));  // Have only 3 bytes for it.
     69 
     70   ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], source_ssrc());
     71   ByteWriter<uint8_t>::WriteBigEndian(&buffer[4], fraction_lost());
     72   ByteWriter<uint32_t, 3>::WriteBigEndian(&buffer[5], cumulative_lost());
     73   ByteWriter<uint32_t>::WriteBigEndian(&buffer[8], extended_high_seq_num());
     74   ByteWriter<uint32_t>::WriteBigEndian(&buffer[12], jitter());
     75   ByteWriter<uint32_t>::WriteBigEndian(&buffer[16], last_sr());
     76   ByteWriter<uint32_t>::WriteBigEndian(&buffer[20], delay_since_last_sr());
     77 }
     78 
     79 bool ReportBlock::WithCumulativeLost(uint32_t cumulative_lost) {
     80   if (cumulative_lost >= (1u << 24)) {  // Have only 3 bytes to store it.
     81     LOG(LS_WARNING) << "Cumulative lost is too big to fit into Report Block";
     82     return false;
     83   }
     84   cumulative_lost_ = cumulative_lost;
     85   return true;
     86 }
     87 
     88 }  // namespace rtcp
     89 }  // namespace webrtc
     90