tor-browser

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

codec.h (9308B)


      1 /*
      2 *  Copyright (c) 2004 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 #ifndef MEDIA_BASE_CODEC_H_
     12 #define MEDIA_BASE_CODEC_H_
     13 
     14 #include <cstddef>
     15 #include <optional>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "absl/container/inlined_vector.h"
     20 #include "absl/strings/str_format.h"
     21 #include "absl/strings/string_view.h"
     22 #include "api/audio_codecs/audio_format.h"
     23 #include "api/rtp_parameters.h"
     24 #include "api/video_codecs/scalability_mode.h"
     25 #include "api/video_codecs/sdp_video_format.h"
     26 #include "media/base/media_constants.h"
     27 #include "rtc_base/system/rtc_export.h"
     28 
     29 namespace webrtc {
     30 
     31 class FeedbackParam {
     32 public:
     33  FeedbackParam() = default;
     34  FeedbackParam(absl::string_view id, const std::string& param)
     35      : id_(id), param_(param) {}
     36  explicit FeedbackParam(absl::string_view id)
     37      : id_(id), param_(kParamValueEmpty) {}
     38 
     39  bool operator==(const FeedbackParam& other) const;
     40  bool operator!=(const FeedbackParam& c) const { return !(*this == c); }
     41 
     42  const std::string& id() const { return id_; }
     43  const std::string& param() const { return param_; }
     44 
     45 private:
     46  std::string id_;     // e.g. "nack", "ccm"
     47  std::string param_;  // e.g. "", "rpsi", "fir"
     48 };
     49 
     50 class FeedbackParams {
     51 public:
     52  FeedbackParams();
     53  ~FeedbackParams();
     54  bool operator==(const FeedbackParams& other) const;
     55  bool operator!=(const FeedbackParams& c) const { return !(*this == c); }
     56 
     57  bool Has(const FeedbackParam& param) const;
     58  void Add(const FeedbackParam& param);
     59  bool Remove(const FeedbackParam& param);
     60 
     61  void Intersect(const FeedbackParams& from);
     62 
     63  const std::vector<FeedbackParam>& params() const { return params_; }
     64 
     65 private:
     66  bool HasDuplicateEntries() const;
     67 
     68  std::vector<FeedbackParam> params_;
     69 };
     70 constexpr int kDefaultVideoClockRateHz = 90'000;
     71 constexpr int kDefaultAudioClockRateHz = 8'000;
     72 
     73 struct RTC_EXPORT Codec {
     74  enum class Type {
     75    kAudio,
     76    kVideo,
     77  };
     78 
     79  enum class ResiliencyType {
     80    kNone,
     81    kRed,
     82    kUlpfec,
     83    kFlexfec,
     84    kRtx,
     85  };
     86  // Value of "id" if it's not explicitly set. Exposed for tests.
     87  static const int kIdNotSet = -1;
     88 
     89  Type type;
     90  int id;
     91  std::string name;
     92  int clockrate;
     93 
     94  // Audio only
     95  // Can be used to override the target bitrate in the encoder.
     96  // TODO(orphis): Remove in favor of alternative APIs
     97  int bitrate;
     98  size_t channels;
     99 
    100  // Video only
    101  std::optional<std::string> packetization;
    102  absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
    103 
    104  // H.265 only
    105  std::optional<std::string> tx_mode;
    106 
    107  // Non key-value parameters such as the telephone-event "0‐15" are
    108  // represented using an empty string as key, i.e. {"": "0-15"}.
    109  // The equivalent of fmtp in SDP.
    110  CodecParameterMap params;
    111  // The equivalent of rtcp-fb in SDP.
    112  FeedbackParams feedback_params;
    113 
    114  Codec(const Codec& c);
    115  Codec(Codec&& c);
    116 
    117  virtual ~Codec();
    118 
    119  // Indicates if this codec is compatible with the specified codec by
    120  // checking the assigned id and profile values for the relevant video codecs.
    121  // The rules for this comparison, in particular the parameters are
    122  // codec-specific as described in RFC 3264 6.1:
    123  // https://www.rfc-editor.org/rfc/rfc3264#section-6.1
    124  // For H.264, packetization modes will be compared.
    125  // If H.265 is enabled, TxModes will be compared.
    126  // H.264 (and H.265, if enabled) levels are not compared.
    127  // In all other cases, parameters do not need to match.
    128  // This is used in SDP offer/answer codec matching.
    129  bool Matches(const Codec& codec) const;
    130 
    131  // This is an exact match similar to what is described in
    132  // https://w3c.github.io/webrtc-pc/#dfn-codec-match
    133  // with two differences:
    134  // - rtx which is included in capabilities  without the apt parameter
    135  //   so number of channels, clock rate or the equality of the parameters
    136  //   are not compared.
    137  // - parameters is compared element-wise, not as a string comparison.
    138  // This method should only be used to compare input on our end to something we
    139  // generated, done e.g. by setCodecPreferences or setParameters.
    140  bool MatchesRtpCodec(const RtpCodec& capability) const;
    141 
    142  // Find the parameter for `key` and write the value to `out`.
    143  bool GetParam(const std::string& key, std::string* out) const;
    144  bool GetParam(const std::string& key, int* out) const;
    145 
    146  void SetParam(const std::string& key, const std::string& value);
    147  void SetParam(const std::string& key, int value);
    148 
    149  // It is safe to input a non-existent parameter.
    150  // Returns true if the parameter existed, false if it did not exist.
    151  bool RemoveParam(const std::string& key);
    152 
    153  bool HasFeedbackParam(const FeedbackParam& param) const;
    154  void AddFeedbackParam(const FeedbackParam& param);
    155 
    156  // Filter `this` feedbacks params such that only those shared by both `this`
    157  // and `other` are kept.
    158  void IntersectFeedbackParams(const Codec& other);
    159 
    160  virtual RtpCodecParameters ToCodecParameters() const;
    161 
    162  // The codec represent an actual media codec, and not a resiliency codec.
    163  bool IsMediaCodec() const;
    164  // The codec represent a resiliency codec such as RED, RTX or FEC variants.
    165  bool IsResiliencyCodec() const;
    166  ResiliencyType GetResiliencyType() const;
    167 
    168  // Validates a VideoCodec's payload type, dimensions and bitrates etc. If they
    169  // don't make sense (such as max < min bitrate), and error is logged and
    170  // ValidateCodecFormat returns false.
    171  bool ValidateCodecFormat() const;
    172 
    173  std::string ToString() const;
    174 
    175  // Default constructor, for initialization.
    176  Codec() : Codec(Type::kAudio, kIdNotSet, "", kDefaultAudioClockRateHz) {}
    177  Codec& operator=(const Codec& c);
    178  Codec& operator=(Codec&& c);
    179 
    180  bool operator==(const Codec& c) const;
    181 
    182  bool operator!=(const Codec& c) const { return !(*this == c); }
    183 
    184  template <typename Sink>
    185  friend void AbslStringify(Sink& sink, const Codec& c) {
    186    absl::Format(&sink, "[%d:", c.id);
    187    switch (c.type) {
    188      case Codec::Type::kAudio:
    189        sink.Append("audio/");
    190        break;
    191      case Codec::Type::kVideo:
    192        sink.Append("video/");
    193    }
    194    absl::Format(&sink, "%s/%d/%d", c.name, c.clockrate, c.channels);
    195    if (c.packetization) {
    196      absl::Format(&sink, ",packetization=%s", *c.packetization);
    197    }
    198    for (auto param : c.params) {
    199      sink.Append(";");
    200      sink.Append(param.first);
    201      sink.Append("=");
    202      sink.Append(param.second);
    203    }
    204    sink.Append("]");
    205  }
    206 
    207 protected:
    208  // Creates an empty codec.
    209  explicit Codec(Type type);
    210  // Creates a codec with the given parameters.
    211  Codec(Type type, int id, const std::string& name, int clockrate);
    212  Codec(Type type,
    213        int id,
    214        const std::string& name,
    215        int clockrate,
    216        size_t channels);
    217 
    218  explicit Codec(const SdpAudioFormat& c);
    219  explicit Codec(const SdpVideoFormat& c);
    220 
    221  friend Codec CreateAudioCodec(int id,
    222                                const std::string& name,
    223                                int clockrate,
    224                                size_t channels);
    225  friend Codec CreateAudioCodec(const SdpAudioFormat& c);
    226  friend Codec CreateAudioRtxCodec(int rtx_payload_type,
    227                                   int associated_payload_type);
    228  friend Codec CreateVideoCodec(int id, const std::string& name);
    229  friend Codec CreateVideoCodec(const SdpVideoFormat& c);
    230  friend Codec CreateVideoRtxCodec(int rtx_payload_type,
    231                                   int associated_payload_type);
    232 };
    233 
    234 using Codecs = std::vector<Codec>;
    235 
    236 Codec CreateAudioCodec(int id,
    237                       const std::string& name,
    238                       int clockrate,
    239                       size_t channels);
    240 Codec CreateAudioCodec(const SdpAudioFormat& c);
    241 Codec CreateAudioRtxCodec(int rtx_payload_type, int associated_payload_type);
    242 Codec CreateVideoCodec(const std::string& name);
    243 Codec CreateVideoCodec(int id, const std::string& name);
    244 Codec CreateVideoCodec(const SdpVideoFormat& c);
    245 Codec CreateVideoCodec(int id, const SdpVideoFormat& sdp);
    246 Codec CreateVideoRtxCodec(int rtx_payload_type, int associated_payload_type);
    247 
    248 // Get the codec setting associated with `payload_type`. If there
    249 // is no codec associated with that payload type it returns nullptr.
    250 const Codec* FindCodecById(const std::vector<Codec>& codecs, int payload_type);
    251 
    252 bool HasLntf(const Codec& codec);
    253 bool HasNack(const Codec& codec);
    254 bool HasRemb(const Codec& codec);
    255 bool HasRrtr(const Codec& codec);
    256 
    257 // Returns the first codec in `supported_codecs` that matches `codec`, or
    258 // nullptr if no codec matches.
    259 const Codec* FindMatchingVideoCodec(const std::vector<Codec>& supported_codecs,
    260                                    const Codec& codec);
    261 
    262 // Returns all codecs in `supported_codecs` that matches `codec`.
    263 std::vector<const Codec*> FindAllMatchingCodecs(
    264    const std::vector<Codec>& supported_codecs,
    265    const Codec& codec);
    266 
    267 RTC_EXPORT void AddH264ConstrainedBaselineProfileToSupportedFormats(
    268    std::vector<SdpVideoFormat>* supported_formats);
    269 }  // namespace webrtc
    270 
    271 
    272 #endif  // MEDIA_BASE_CODEC_H_