tor-browser

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

tmmbr.cc (4344B)


      1 /*
      2 *  Copyright (c) 2016 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/tmmbr.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 
     16 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
     17 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
     18 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
     19 #include "rtc_base/checks.h"
     20 #include "rtc_base/logging.h"
     21 
     22 namespace webrtc {
     23 namespace rtcp {
     24 // RFC 4585: Feedback format.
     25 // Common packet format:
     26 //
     27 //   0                   1                   2                   3
     28 //   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
     29 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     30 //  |V=2|P|   FMT   |       PT      |          length               |
     31 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     32 //  |                  SSRC of packet sender                        |
     33 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     34 //  |             SSRC of media source (unused) = 0                 |
     35 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     36 //  :            Feedback Control Information (FCI)                 :
     37 //  :                                                               :
     38 // Temporary Maximum Media Stream Bit Rate Request (TMMBR) (RFC 5104).
     39 // The Feedback Control Information (FCI) for the TMMBR
     40 // consists of one or more FCI entries.
     41 // FCI:
     42 //   0                   1                   2                   3
     43 //   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
     44 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     45 //  |                              SSRC                             |
     46 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     47 //  | MxTBR Exp |  MxTBR Mantissa                 |Measured Overhead|
     48 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     49 
     50 Tmmbr::Tmmbr() = default;
     51 
     52 Tmmbr::~Tmmbr() = default;
     53 
     54 bool Tmmbr::Parse(const CommonHeader& packet) {
     55  RTC_DCHECK_EQ(packet.type(), kPacketType);
     56  RTC_DCHECK_EQ(packet.fmt(), kFeedbackMessageType);
     57 
     58  if (packet.payload_size_bytes() < kCommonFeedbackLength + TmmbItem::kLength) {
     59    RTC_LOG(LS_WARNING) << "Payload length " << packet.payload_size_bytes()
     60                        << " is too small for a TMMBR.";
     61    return false;
     62  }
     63  size_t items_size_bytes = packet.payload_size_bytes() - kCommonFeedbackLength;
     64  if (items_size_bytes % TmmbItem::kLength != 0) {
     65    RTC_LOG(LS_WARNING) << "Payload length " << packet.payload_size_bytes()
     66                        << " is not valid for a TMMBR.";
     67    return false;
     68  }
     69  ParseCommonFeedback(packet.payload());
     70 
     71  const uint8_t* next_item = packet.payload() + kCommonFeedbackLength;
     72  size_t number_of_items = items_size_bytes / TmmbItem::kLength;
     73  items_.resize(number_of_items);
     74  for (TmmbItem& item : items_) {
     75    if (!item.Parse(next_item))
     76      return false;
     77    next_item += TmmbItem::kLength;
     78  }
     79  return true;
     80 }
     81 
     82 void Tmmbr::AddTmmbr(const TmmbItem& item) {
     83  items_.push_back(item);
     84 }
     85 
     86 size_t Tmmbr::BlockLength() const {
     87  return kHeaderLength + kCommonFeedbackLength +
     88         TmmbItem::kLength * items_.size();
     89 }
     90 
     91 bool Tmmbr::Create(uint8_t* packet,
     92                   size_t* index,
     93                   size_t max_length,
     94                   PacketReadyCallback callback) const {
     95  RTC_DCHECK(!items_.empty());
     96  while (*index + BlockLength() > max_length) {
     97    if (!OnBufferFull(packet, index, callback))
     98      return false;
     99  }
    100  const size_t index_end = *index + BlockLength();
    101 
    102  CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
    103               index);
    104  RTC_DCHECK_EQ(0, Rtpfb::media_ssrc());
    105  CreateCommonFeedback(packet + *index);
    106  *index += kCommonFeedbackLength;
    107  for (const TmmbItem& item : items_) {
    108    item.Create(packet + *index);
    109    *index += TmmbItem::kLength;
    110  }
    111  RTC_CHECK_EQ(index_end, *index);
    112  return true;
    113 }
    114 }  // namespace rtcp
    115 }  // namespace webrtc