tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

loss_notification.cc (4922B)


      1 /*
      2 *  Copyright (c) 2019 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 "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 
     16 #include "modules/rtp_rtcp/source/byte_io.h"
     17 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
     18 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
     19 #include "rtc_base/checks.h"
     20 
     21 namespace webrtc {
     22 namespace rtcp {
     23 
     24 // Loss Notification
     25 // -----------------
     26 //     0                   1                   2                   3
     27 //     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
     28 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     29 //    |V=2|P| FMT=15  |   PT=206      |             length            |
     30 //    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
     31 //  0 |                  SSRC of packet sender                        |
     32 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     33 //  4 |                  SSRC of media source                         |
     34 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     35 //  8 |  Unique identifier 'L' 'N' 'T' 'F'                            |
     36 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     37 // 12 | Last Decoded Sequence Number  | Last Received SeqNum Delta  |D|
     38 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     39 
     40 LossNotification::LossNotification()
     41    : last_decoded_(0), last_received_(0), decodability_flag_(false) {}
     42 
     43 LossNotification::LossNotification(uint16_t last_decoded,
     44                                   uint16_t last_received,
     45                                   bool decodability_flag)
     46    : last_decoded_(last_decoded),
     47      last_received_(last_received),
     48      decodability_flag_(decodability_flag) {}
     49 
     50 LossNotification::LossNotification(const LossNotification& rhs) = default;
     51 
     52 LossNotification::~LossNotification() = default;
     53 
     54 size_t LossNotification::BlockLength() const {
     55  return kHeaderLength + kCommonFeedbackLength + kLossNotificationPayloadLength;
     56 }
     57 
     58 bool LossNotification::Create(uint8_t* packet,
     59                              size_t* index,
     60                              size_t max_length,
     61                              PacketReadyCallback callback) const {
     62  while (*index + BlockLength() > max_length) {
     63    if (!OnBufferFull(packet, index, callback))
     64      return false;
     65  }
     66 
     67  const size_t index_end = *index + BlockLength();
     68 
     69  // Note: `index` updated by the function below.
     70  CreateHeader(Psfb::kAfbMessageType, kPacketType, HeaderLength(), packet,
     71               index);
     72 
     73  CreateCommonFeedback(packet + *index);
     74  *index += kCommonFeedbackLength;
     75 
     76  ByteWriter<uint32_t>::WriteBigEndian(packet + *index, kUniqueIdentifier);
     77  *index += sizeof(uint32_t);
     78 
     79  ByteWriter<uint16_t>::WriteBigEndian(packet + *index, last_decoded_);
     80  *index += sizeof(uint16_t);
     81 
     82  const uint16_t last_received_delta = last_received_ - last_decoded_;
     83  RTC_DCHECK_LE(last_received_delta, 0x7fff);
     84  const uint16_t last_received_delta_and_decodability =
     85      (last_received_delta << 1) | (decodability_flag_ ? 0x0001 : 0x0000);
     86 
     87  ByteWriter<uint16_t>::WriteBigEndian(packet + *index,
     88                                       last_received_delta_and_decodability);
     89  *index += sizeof(uint16_t);
     90 
     91  RTC_DCHECK_EQ(index_end, *index);
     92  return true;
     93 }
     94 
     95 bool LossNotification::Parse(const CommonHeader& packet) {
     96  RTC_DCHECK_EQ(packet.type(), kPacketType);
     97  RTC_DCHECK_EQ(packet.fmt(), Psfb::kAfbMessageType);
     98 
     99  if (packet.payload_size_bytes() <
    100      kCommonFeedbackLength + kLossNotificationPayloadLength) {
    101    return false;
    102  }
    103 
    104  const uint8_t* const payload = packet.payload();
    105 
    106  if (ByteReader<uint32_t>::ReadBigEndian(&payload[8]) != kUniqueIdentifier) {
    107    return false;
    108  }
    109 
    110  ParseCommonFeedback(payload);
    111 
    112  last_decoded_ = ByteReader<uint16_t>::ReadBigEndian(&payload[12]);
    113 
    114  const uint16_t last_received_delta_and_decodability =
    115      ByteReader<uint16_t>::ReadBigEndian(&payload[14]);
    116  last_received_ = last_decoded_ + (last_received_delta_and_decodability >> 1);
    117  decodability_flag_ = (last_received_delta_and_decodability & 0x0001);
    118 
    119  return true;
    120 }
    121 
    122 bool LossNotification::Set(uint16_t last_decoded,
    123                           uint16_t last_received,
    124                           bool decodability_flag) {
    125  const uint16_t delta = last_received - last_decoded;
    126  if (delta > 0x7fff) {
    127    return false;
    128  }
    129  last_received_ = last_received;
    130  last_decoded_ = last_decoded;
    131  decodability_flag_ = decodability_flag;
    132  return true;
    133 }
    134 
    135 }  // namespace rtcp
    136 }  // namespace webrtc