tor-browser

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

rtp_parameters.cc (10241B)


      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 #include "api/rtp_parameters.h"
     11 
     12 #include <algorithm>
     13 #include <cstdint>
     14 #include <string>
     15 #include <tuple>
     16 #include <vector>
     17 
     18 #include "absl/strings/string_view.h"
     19 #include "api/array_view.h"
     20 #include "api/rtp_transceiver_direction.h"
     21 #include "media/base/media_constants.h"
     22 #include "rtc_base/checks.h"
     23 #include "rtc_base/strings/string_builder.h"
     24 
     25 namespace webrtc {
     26 
     27 const char* DegradationPreferenceToString(
     28    DegradationPreference degradation_preference) {
     29  switch (degradation_preference) {
     30    case DegradationPreference::DISABLED:
     31      return "disabled";
     32    case DegradationPreference::MAINTAIN_FRAMERATE:
     33      return "maintain-framerate";
     34    case DegradationPreference::MAINTAIN_RESOLUTION:
     35      return "maintain-resolution";
     36    case DegradationPreference::BALANCED:
     37      return "balanced";
     38  }
     39  RTC_CHECK_NOTREACHED();
     40 }
     41 
     42 const double kDefaultBitratePriority = 1.0;
     43 
     44 RtcpFeedback::RtcpFeedback() = default;
     45 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
     46 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
     47                           RtcpFeedbackMessageType message_type)
     48    : type(type), message_type(message_type) {}
     49 RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
     50 RtcpFeedback::~RtcpFeedback() = default;
     51 
     52 RtpCodec::RtpCodec() = default;
     53 RtpCodec::RtpCodec(const RtpCodec&) = default;
     54 RtpCodec::~RtpCodec() = default;
     55 bool RtpCodec::IsResiliencyCodec() const {
     56  return name == kRtxCodecName || name == kRedCodecName ||
     57         name == kUlpfecCodecName || name == kFlexfecCodecName;
     58 }
     59 bool RtpCodec::IsMediaCodec() const {
     60  return !IsResiliencyCodec() && name != kComfortNoiseCodecName;
     61 }
     62 RtpCodecCapability::RtpCodecCapability() = default;
     63 RtpCodecCapability::~RtpCodecCapability() = default;
     64 
     65 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
     66 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
     67    absl::string_view uri)
     68    : uri(uri) {}
     69 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
     70    absl::string_view uri,
     71    int preferred_id)
     72    : uri(uri), preferred_id(preferred_id) {}
     73 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
     74    absl::string_view uri,
     75    int preferred_id,
     76    RtpTransceiverDirection direction)
     77    : uri(uri), preferred_id(preferred_id), direction(direction) {}
     78 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
     79    absl::string_view uri,
     80    int preferred_id,
     81    bool preferred_encrypt,
     82    RtpTransceiverDirection direction)
     83    : uri(uri),
     84      preferred_id(preferred_id),
     85      preferred_encrypt(preferred_encrypt),
     86      direction(direction) {}
     87 RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
     88 
     89 RtpExtension::RtpExtension() = default;
     90 RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {}
     91 RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt)
     92    : uri(uri), id(id), encrypt(encrypt) {}
     93 RtpExtension::~RtpExtension() = default;
     94 
     95 RtpFecParameters::RtpFecParameters() = default;
     96 RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
     97    : mechanism(mechanism) {}
     98 RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
     99    : ssrc(ssrc), mechanism(mechanism) {}
    100 RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
    101 RtpFecParameters::~RtpFecParameters() = default;
    102 
    103 RtpRtxParameters::RtpRtxParameters() = default;
    104 RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
    105 RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
    106 RtpRtxParameters::~RtpRtxParameters() = default;
    107 
    108 RtpEncodingParameters::RtpEncodingParameters() = default;
    109 RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
    110    default;
    111 RtpEncodingParameters::~RtpEncodingParameters() = default;
    112 
    113 RtpCodecParameters::RtpCodecParameters() = default;
    114 RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
    115 RtpCodecParameters::~RtpCodecParameters() = default;
    116 
    117 RtpCapabilities::RtpCapabilities() = default;
    118 RtpCapabilities::~RtpCapabilities() = default;
    119 
    120 RtcpParameters::RtcpParameters() = default;
    121 RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
    122 RtcpParameters::~RtcpParameters() = default;
    123 
    124 RtpParameters::RtpParameters() = default;
    125 RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
    126 RtpParameters::~RtpParameters() = default;
    127 
    128 std::string RtpExtension::ToString() const {
    129  char buf[256];
    130  SimpleStringBuilder sb(buf);
    131  sb << "{uri: " << uri;
    132  sb << ", id: " << id;
    133  if (encrypt) {
    134    sb << ", encrypt";
    135  }
    136  sb << '}';
    137  return sb.str();
    138 }
    139 
    140 bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
    141  return uri == RtpExtension::kAudioLevelUri ||
    142         uri == RtpExtension::kAbsSendTimeUri ||
    143         uri == RtpExtension::kAbsoluteCaptureTimeUri ||
    144         uri == RtpExtension::kTransportSequenceNumberUri ||
    145         uri == RtpExtension::kTransportSequenceNumberV2Uri ||
    146         uri == RtpExtension::kMidUri || uri == RtpExtension::kRidUri ||
    147         uri == RtpExtension::kRepairedRidUri ||
    148         uri == RtpExtension::kCsrcAudioLevelsUri;
    149 }
    150 
    151 bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
    152  return uri == RtpExtension::kTimestampOffsetUri ||
    153         uri == RtpExtension::kAbsSendTimeUri ||
    154         uri == RtpExtension::kAbsoluteCaptureTimeUri ||
    155         uri == RtpExtension::kVideoRotationUri ||
    156         uri == RtpExtension::kTransportSequenceNumberUri ||
    157         uri == RtpExtension::kTransportSequenceNumberV2Uri ||
    158         uri == RtpExtension::kPlayoutDelayUri ||
    159         uri == RtpExtension::kVideoContentTypeUri ||
    160         uri == RtpExtension::kVideoTimingUri || uri == RtpExtension::kMidUri ||
    161         uri == RtpExtension::kGenericFrameDescriptorUri00 ||
    162         uri == RtpExtension::kDependencyDescriptorUri ||
    163         uri == RtpExtension::kColorSpaceUri || uri == RtpExtension::kRidUri ||
    164         uri == RtpExtension::kRepairedRidUri ||
    165         uri == RtpExtension::kVideoLayersAllocationUri ||
    166         uri == RtpExtension::kVideoFrameTrackingIdUri ||
    167         uri == RtpExtension::kCorruptionDetectionUri;
    168 }
    169 
    170 bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
    171  return
    172 #if defined(ENABLE_EXTERNAL_AUTH)
    173      // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri"
    174      // here and filter out later if external auth is really used in
    175      // srtpfilter. External auth is used by Chromium and replaces the
    176      // extension header value of "kAbsSendTimeUri", so it must not be
    177      // encrypted (which can't be done by Chromium).
    178      uri != RtpExtension::kAbsSendTimeUri &&
    179 #endif
    180      uri != RtpExtension::kEncryptHeaderExtensionsUri;
    181 }
    182 
    183 // Returns whether a header extension with the given URI exists.
    184 // Note: This does not differentiate between encrypted and non-encrypted
    185 // extensions, so use with care!
    186 static bool HeaderExtensionWithUriExists(
    187    const std::vector<RtpExtension>& extensions,
    188    absl::string_view uri) {
    189  for (const auto& extension : extensions) {
    190    if (extension.uri == uri) {
    191      return true;
    192    }
    193  }
    194  return false;
    195 }
    196 
    197 const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
    198    const std::vector<RtpExtension>& extensions,
    199    absl::string_view uri,
    200    Filter filter) {
    201  const RtpExtension* fallback_extension = nullptr;
    202  for (const auto& extension : extensions) {
    203    if (extension.uri != uri) {
    204      continue;
    205    }
    206 
    207    switch (filter) {
    208      case kDiscardEncryptedExtension:
    209        // We only accept an unencrypted extension.
    210        if (!extension.encrypt) {
    211          return &extension;
    212        }
    213        break;
    214 
    215      case kPreferEncryptedExtension:
    216        // We prefer an encrypted extension but we can fall back to an
    217        // unencrypted extension.
    218        if (extension.encrypt) {
    219          return &extension;
    220        } else {
    221          fallback_extension = &extension;
    222        }
    223        break;
    224 
    225      case kRequireEncryptedExtension:
    226        // We only accept an encrypted extension.
    227        if (extension.encrypt) {
    228          return &extension;
    229        }
    230        break;
    231    }
    232  }
    233 
    234  // Returning fallback extension (if any)
    235  return fallback_extension;
    236 }
    237 
    238 const RtpExtension* RtpExtension::FindHeaderExtensionByUriAndEncryption(
    239    const std::vector<RtpExtension>& extensions,
    240    absl::string_view uri,
    241    bool encrypt) {
    242  for (const auto& extension : extensions) {
    243    if (extension.uri == uri && extension.encrypt == encrypt) {
    244      return &extension;
    245    }
    246  }
    247  return nullptr;
    248 }
    249 
    250 const std::vector<RtpExtension> RtpExtension::DeduplicateHeaderExtensions(
    251    const std::vector<RtpExtension>& extensions,
    252    Filter filter) {
    253  std::vector<RtpExtension> filtered;
    254 
    255  // If we do not discard encrypted extensions, add them first
    256  if (filter != kDiscardEncryptedExtension) {
    257    for (const auto& extension : extensions) {
    258      if (!extension.encrypt) {
    259        continue;
    260      }
    261      if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
    262        filtered.push_back(extension);
    263      }
    264    }
    265  }
    266 
    267  // If we do not require encrypted extensions, add missing, non-encrypted
    268  // extensions.
    269  if (filter != kRequireEncryptedExtension) {
    270    for (const auto& extension : extensions) {
    271      if (extension.encrypt) {
    272        continue;
    273      }
    274      if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
    275        filtered.push_back(extension);
    276      }
    277    }
    278  }
    279 
    280  // Sort the returned vector to make comparisons of header extensions reliable.
    281  // In order of priority, we sort by uri first, then encrypt and id last.
    282  std::sort(filtered.begin(), filtered.end(),
    283            [](const RtpExtension& a, const RtpExtension& b) {
    284              return std::tie(a.uri, a.encrypt, a.id) <
    285                     std::tie(b.uri, b.encrypt, b.id);
    286            });
    287 
    288  return filtered;
    289 }
    290 }  // namespace webrtc