tor-browser

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

rtp_config.cc (8289B)


      1 /*
      2 *  Copyright (c) 2017 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 "call/rtp_config.h"
     12 
     13 #include <algorithm>
     14 #include <cstddef>
     15 #include <cstdint>
     16 #include <iterator>
     17 #include <optional>
     18 #include <string>
     19 #include <vector>
     20 
     21 #include "absl/algorithm/container.h"
     22 #include "api/array_view.h"
     23 #include "api/rtp_headers.h"
     24 #include "rtc_base/checks.h"
     25 #include "rtc_base/strings/string_builder.h"
     26 
     27 namespace webrtc {
     28 
     29 namespace {
     30 
     31 uint32_t FindAssociatedSsrc(uint32_t ssrc,
     32                            const std::vector<uint32_t>& ssrcs,
     33                            const std::vector<uint32_t>& associated_ssrcs) {
     34  RTC_DCHECK_EQ(ssrcs.size(), associated_ssrcs.size());
     35  for (size_t i = 0; i < ssrcs.size(); ++i) {
     36    if (ssrcs[i] == ssrc)
     37      return associated_ssrcs[i];
     38  }
     39  RTC_DCHECK_NOTREACHED();
     40  return 0;
     41 }
     42 
     43 }  // namespace
     44 
     45 std::string LntfConfig::ToString() const {
     46  return enabled ? "{enabled: true}" : "{enabled: false}";
     47 }
     48 
     49 std::string NackConfig::ToString() const {
     50  char buf[1024];
     51  SimpleStringBuilder ss(buf);
     52  ss << "{rtp_history_ms: " << rtp_history_ms;
     53  ss << '}';
     54  return ss.str();
     55 }
     56 
     57 std::string UlpfecConfig::ToString() const {
     58  char buf[1024];
     59  SimpleStringBuilder ss(buf);
     60  ss << "{ulpfec_payload_type: " << ulpfec_payload_type;
     61  ss << ", red_payload_type: " << red_payload_type;
     62  ss << ", red_rtx_payload_type: " << red_rtx_payload_type;
     63  ss << '}';
     64  return ss.str();
     65 }
     66 
     67 bool UlpfecConfig::operator==(const UlpfecConfig& other) const {
     68  return ulpfec_payload_type == other.ulpfec_payload_type &&
     69         red_payload_type == other.red_payload_type &&
     70         red_rtx_payload_type == other.red_rtx_payload_type;
     71 }
     72 
     73 std::string RtpStreamConfig::ToString() const {
     74  char buf[1024];
     75  SimpleStringBuilder ss(buf);
     76  ss << "{ssrc: " << ssrc;
     77  ss << ", rid: " << rid;
     78  ss << ", payload_name: " << payload_name;
     79  ss << ", payload_type: " << payload_type;
     80  ss << ", raw_payload: " << (raw_payload ? "true" : "false");
     81  if (rtx.has_value()) {
     82    ss << ", rtx: " << rtx->ToString();
     83  }
     84  ss << '}';
     85  return ss.str();
     86 }
     87 
     88 std::string RtpStreamConfig::Rtx::ToString() const {
     89  char buf[1024];
     90  SimpleStringBuilder ss(buf);
     91  ss << "{ssrc: " << ssrc;
     92  ss << ", payload_type: " << payload_type;
     93  ss << '}';
     94  return ss.str();
     95 }
     96 
     97 RtpConfig::RtpConfig() = default;
     98 RtpConfig::RtpConfig(const RtpConfig&) = default;
     99 RtpConfig::~RtpConfig() = default;
    100 
    101 RtpConfig::Flexfec::Flexfec() = default;
    102 RtpConfig::Flexfec::Flexfec(const Flexfec&) = default;
    103 RtpConfig::Flexfec::~Flexfec() = default;
    104 
    105 std::string RtpConfig::ToString() const {
    106  char buf[2 * 1024];
    107  SimpleStringBuilder ss(buf);
    108  ss << "{ssrcs: [";
    109  for (size_t i = 0; i < ssrcs.size(); ++i) {
    110    ss << ssrcs[i];
    111    if (i != ssrcs.size() - 1)
    112      ss << ", ";
    113  }
    114  ss << "], rids: [";
    115  for (size_t i = 0; i < rids.size(); ++i) {
    116    ss << rids[i];
    117    if (i != rids.size() - 1)
    118      ss << ", ";
    119  }
    120  ss << "], mid: '" << mid << "'";
    121  ss << ", rtcp_mode: "
    122     << (rtcp_mode == RtcpMode::kCompound ? "RtcpMode::kCompound"
    123                                          : "RtcpMode::kReducedSize");
    124  ss << ", max_packet_size: " << max_packet_size;
    125  ss << ", extmap-allow-mixed: " << (extmap_allow_mixed ? "true" : "false");
    126  ss << ", extensions: [";
    127  for (size_t i = 0; i < extensions.size(); ++i) {
    128    ss << extensions[i].ToString();
    129    if (i != extensions.size() - 1)
    130      ss << ", ";
    131  }
    132  ss << ']';
    133 
    134  ss << ", lntf: " << lntf.ToString();
    135  ss << ", nack: {rtp_history_ms: " << nack.rtp_history_ms << '}';
    136  ss << ", ulpfec: " << ulpfec.ToString();
    137  ss << ", payload_name: " << payload_name;
    138  ss << ", payload_type: " << payload_type;
    139  ss << ", raw_payload: " << (raw_payload ? "true" : "false");
    140 
    141  ss << ", stream_configs: [";
    142  for (size_t i = 0; i < stream_configs.size(); ++i) {
    143    ss << stream_configs[i].ToString();
    144    if (i != stream_configs.size() - 1)
    145      ss << ", ";
    146  }
    147  ss << ']';
    148 
    149  ss << ", flexfec: {payload_type: " << flexfec.payload_type;
    150  ss << ", ssrc: " << flexfec.ssrc;
    151  ss << ", protected_media_ssrcs: [";
    152  for (size_t i = 0; i < flexfec.protected_media_ssrcs.size(); ++i) {
    153    ss << flexfec.protected_media_ssrcs[i];
    154    if (i != flexfec.protected_media_ssrcs.size() - 1)
    155      ss << ", ";
    156  }
    157  ss << "]}";
    158 
    159  ss << ", rtx: " << rtx.ToString();
    160  ss << ", c_name: " << c_name;
    161  ss << '}';
    162  return ss.str();
    163 }
    164 
    165 RtpConfig::Rtx::Rtx() = default;
    166 RtpConfig::Rtx::Rtx(const Rtx&) = default;
    167 RtpConfig::Rtx::~Rtx() = default;
    168 
    169 std::string RtpConfig::Rtx::ToString() const {
    170  char buf[1024];
    171  SimpleStringBuilder ss(buf);
    172  ss << "{ssrcs: [";
    173  for (size_t i = 0; i < ssrcs.size(); ++i) {
    174    ss << ssrcs[i];
    175    if (i != ssrcs.size() - 1)
    176      ss << ", ";
    177  }
    178  ss << ']';
    179 
    180  ss << ", payload_type: " << payload_type;
    181  ss << '}';
    182  return ss.str();
    183 }
    184 
    185 bool RtpConfig::IsMediaSsrc(uint32_t ssrc) const {
    186  return absl::c_linear_search(ssrcs, ssrc);
    187 }
    188 
    189 bool RtpConfig::IsRtxSsrc(uint32_t ssrc) const {
    190  return absl::c_linear_search(rtx.ssrcs, ssrc);
    191 }
    192 
    193 bool RtpConfig::IsFlexfecSsrc(uint32_t ssrc) const {
    194  return flexfec.payload_type != -1 && ssrc == flexfec.ssrc;
    195 }
    196 
    197 std::optional<uint32_t> RtpConfig::GetRtxSsrcAssociatedWithMediaSsrc(
    198    uint32_t media_ssrc) const {
    199  RTC_DCHECK(IsMediaSsrc(media_ssrc));
    200  // If we don't use RTX there is no association.
    201  if (rtx.ssrcs.empty())
    202    return std::nullopt;
    203  // If we use RTX there MUST be an association ssrcs[i] <-> rtx.ssrcs[i].
    204  RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
    205  return FindAssociatedSsrc(media_ssrc, ssrcs, rtx.ssrcs);
    206 }
    207 
    208 uint32_t RtpConfig::GetMediaSsrcAssociatedWithRtxSsrc(uint32_t rtx_ssrc) const {
    209  RTC_DCHECK(IsRtxSsrc(rtx_ssrc));
    210  // If we use RTX there MUST be an association ssrcs[i] <-> rtx.ssrcs[i].
    211  RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
    212  return FindAssociatedSsrc(rtx_ssrc, rtx.ssrcs, ssrcs);
    213 }
    214 
    215 uint32_t RtpConfig::GetMediaSsrcAssociatedWithFlexfecSsrc(
    216    uint32_t flexfec_ssrc) const {
    217  RTC_DCHECK(IsFlexfecSsrc(flexfec_ssrc));
    218  // If we use FlexFEC there MUST be an associated media ssrc.
    219  //
    220  // TODO(brandtr/hbos): The current implementation only supports an association
    221  // with a single media ssrc. If multiple ssrcs are to be supported in the
    222  // future, in order not to break GetStats()'s packet and byte counters, we
    223  // must be able to tell how many packets and bytes have contributed to which
    224  // SSRC.
    225  RTC_DCHECK_EQ(1u, flexfec.protected_media_ssrcs.size());
    226  uint32_t media_ssrc = flexfec.protected_media_ssrcs[0];
    227  RTC_DCHECK(IsMediaSsrc(media_ssrc));
    228  return media_ssrc;
    229 }
    230 
    231 std::optional<std::string> RtpConfig::GetRidForSsrc(uint32_t ssrc) const {
    232  auto it = std::find(ssrcs.begin(), ssrcs.end(), ssrc);
    233  if (it != ssrcs.end()) {
    234    size_t ssrc_index = std::distance(ssrcs.begin(), it);
    235    if (ssrc_index < rids.size()) {
    236      return rids[ssrc_index];
    237    }
    238  }
    239  return std::nullopt;
    240 }
    241 
    242 RtpStreamConfig RtpConfig::GetStreamConfig(size_t index) const {
    243  // GetStreamConfig function usually returns stream_configs[index], but if
    244  // stream_configs is not initialized (i.e., index >= stream_configs.size()),
    245  // it creates and returns an RtpStreamConfig using fields such as ssrcs, rids,
    246  // payload_name, and payload_type from RtpConfig.
    247  RTC_DCHECK_LT(index, ssrcs.size());
    248  if (index < stream_configs.size()) {
    249    return stream_configs[index];
    250  }
    251  RtpStreamConfig stream_config;
    252  stream_config.ssrc = ssrcs[index];
    253  if (index < rids.size()) {
    254    stream_config.rid = rids[index];
    255  }
    256  stream_config.payload_name = payload_name;
    257  stream_config.payload_type = payload_type;
    258  stream_config.raw_payload = raw_payload;
    259  if (!rtx.ssrcs.empty()) {
    260    RTC_DCHECK_EQ(ssrcs.size(), rtx.ssrcs.size());
    261    auto& stream_config_rtx = stream_config.rtx.emplace(RtpStreamConfig::Rtx());
    262    stream_config_rtx.ssrc = rtx.ssrcs[index];
    263    stream_config_rtx.payload_type = rtx.payload_type;
    264  }
    265 
    266  return stream_config;
    267 }
    268 
    269 }  // namespace webrtc