tor-browser

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

target_bitrate.cc (5054B)


      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/target_bitrate.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 #include <vector>
     16 
     17 #include "modules/rtp_rtcp/source/byte_io.h"
     18 #include "rtc_base/checks.h"
     19 #include "rtc_base/numerics/safe_conversions.h"
     20 
     21 namespace webrtc {
     22 namespace rtcp {
     23 namespace {
     24 
     25 constexpr size_t kTargetBitrateHeaderSizeBytes = 4;
     26 
     27 }  // namespace
     28 
     29 TargetBitrate::BitrateItem::BitrateItem()
     30    : spatial_layer(0), temporal_layer(0), target_bitrate_kbps(0) {}
     31 
     32 TargetBitrate::BitrateItem::BitrateItem(uint8_t spatial_layer,
     33                                        uint8_t temporal_layer,
     34                                        uint32_t target_bitrate_kbps)
     35    : spatial_layer(spatial_layer),
     36      temporal_layer(temporal_layer),
     37      target_bitrate_kbps(target_bitrate_kbps) {}
     38 
     39 //  RFC 4585: Feedback format.
     40 //
     41 //  Common packet format:
     42 //
     43 //   0                   1                   2                   3
     44 //   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
     45 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     46 //  |     BT=42     |   reserved    |         block length          |
     47 //  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
     48 //
     49 //  Target bitrate item (repeat as many times as necessary).
     50 //
     51 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     52 //  |   S   |   T   |                Target Bitrate                 |
     53 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     54 //  :  ...                                                          :
     55 //
     56 //  Spatial Layer (S): 4 bits
     57 //    Indicates which temporal layer this bitrate concerns.
     58 //
     59 //  Temporal Layer (T): 4 bits
     60 //    Indicates which temporal layer this bitrate concerns.
     61 //
     62 //  Target Bitrate: 24 bits
     63 //    The encoder target bitrate for this layer, in kbps.
     64 //
     65 //  As an example of how S and T are intended to be used, VP8 simulcast will
     66 //  use a separate TargetBitrate message per stream, since they are transmitted
     67 //  on separate SSRCs, with temporal layers grouped by stream.
     68 //  If VP9 SVC is used, there will be only one SSRC, so each spatial and
     69 //  temporal layer combo used shall be specified in the TargetBitrate packet.
     70 
     71 TargetBitrate::TargetBitrate() = default;
     72 TargetBitrate::TargetBitrate(const TargetBitrate&) = default;
     73 TargetBitrate& TargetBitrate::operator=(const TargetBitrate&) = default;
     74 TargetBitrate::~TargetBitrate() = default;
     75 
     76 void TargetBitrate::Parse(const uint8_t* block, uint16_t block_length) {
     77  // Validate block header (should already have been parsed and checked).
     78  RTC_DCHECK_EQ(block[0], kBlockType);
     79  RTC_DCHECK_EQ(block_length, ByteReader<uint16_t>::ReadBigEndian(&block[2]));
     80 
     81  // Header specifies block length - 1, but since we ignore the header, which
     82  // occupies exactly on block, we can just treat this as payload length.
     83  const size_t payload_bytes = block_length * 4;
     84  const size_t num_items = payload_bytes / kBitrateItemSizeBytes;
     85  size_t index = kTargetBitrateHeaderSizeBytes;
     86  bitrates_.clear();
     87  for (size_t i = 0; i < num_items; ++i) {
     88    uint8_t layers = block[index];
     89    uint32_t bitrate_kbps =
     90        ByteReader<uint32_t, 3>::ReadBigEndian(&block[index + 1]);
     91    index += kBitrateItemSizeBytes;
     92    AddTargetBitrate((layers >> 4) & 0x0F, layers & 0x0F, bitrate_kbps);
     93  }
     94 }
     95 
     96 void TargetBitrate::AddTargetBitrate(uint8_t spatial_layer,
     97                                     uint8_t temporal_layer,
     98                                     uint32_t target_bitrate_kbps) {
     99  RTC_DCHECK_LE(spatial_layer, 0x0F);
    100  RTC_DCHECK_LE(temporal_layer, 0x0F);
    101  RTC_DCHECK_LE(target_bitrate_kbps, 0x00FFFFFFU);
    102  bitrates_.push_back(
    103      BitrateItem(spatial_layer, temporal_layer, target_bitrate_kbps));
    104 }
    105 
    106 const std::vector<TargetBitrate::BitrateItem>&
    107 TargetBitrate::GetTargetBitrates() const {
    108  return bitrates_;
    109 }
    110 
    111 size_t TargetBitrate::BlockLength() const {
    112  return kTargetBitrateHeaderSizeBytes +
    113         bitrates_.size() * kBitrateItemSizeBytes;
    114 }
    115 
    116 void TargetBitrate::Create(uint8_t* buffer) const {
    117  buffer[0] = kBlockType;
    118  buffer[1] = 0;  // Reserved.
    119  uint16_t block_length_words =
    120      dchecked_cast<uint16_t>((BlockLength() / 4) - 1);
    121  ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], block_length_words);
    122 
    123  size_t index = kTargetBitrateHeaderSizeBytes;
    124  for (const BitrateItem& item : bitrates_) {
    125    buffer[index] = (item.spatial_layer << 4) | item.temporal_layer;
    126    ByteWriter<uint32_t, 3>::WriteBigEndian(&buffer[index + 1],
    127                                            item.target_bitrate_kbps);
    128    index += kBitrateItemSizeBytes;
    129  }
    130 }
    131 
    132 }  // namespace rtcp
    133 }  // namespace webrtc