xref: /aosp_15_r20/external/webrtc/media/base/codec.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 <map>
15 #include <set>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/container/inlined_vector.h"
20 #include "absl/strings/string_view.h"
21 #include "absl/types/optional.h"
22 #include "api/field_trials_view.h"
23 #include "api/rtp_parameters.h"
24 #include "api/video_codecs/sdp_video_format.h"
25 #include "media/base/media_constants.h"
26 #include "rtc_base/system/rtc_export.h"
27 
28 namespace cricket {
29 
30 typedef std::map<std::string, std::string> CodecParameterMap;
31 
32 class FeedbackParam {
33  public:
34   FeedbackParam() = default;
FeedbackParam(absl::string_view id,const std::string & param)35   FeedbackParam(absl::string_view id, const std::string& param)
36       : id_(id), param_(param) {}
FeedbackParam(absl::string_view id)37   explicit FeedbackParam(absl::string_view id)
38       : id_(id), param_(kParamValueEmpty) {}
39 
40   bool operator==(const FeedbackParam& other) const;
41 
id()42   const std::string& id() const { return id_; }
param()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 
56   bool Has(const FeedbackParam& param) const;
57   void Add(const FeedbackParam& param);
58 
59   void Intersect(const FeedbackParams& from);
60 
params()61   const std::vector<FeedbackParam>& params() const { return params_; }
62 
63  private:
64   bool HasDuplicateEntries() const;
65 
66   std::vector<FeedbackParam> params_;
67 };
68 
69 struct RTC_EXPORT Codec {
70   int id;
71   std::string name;
72   int clockrate;
73   // Non key-value parameters such as the telephone-event "0‐15" are
74   // represented using an empty string as key, i.e. {"": "0-15"}.
75   CodecParameterMap params;
76   FeedbackParams feedback_params;
77 
78   virtual ~Codec();
79 
80   // Indicates if this codec is compatible with the specified codec.
81   bool Matches(const Codec& codec,
82                const webrtc::FieldTrialsView* field_trials = nullptr) const;
83   bool MatchesCapability(const webrtc::RtpCodecCapability& capability) const;
84 
85   // Find the parameter for `name` and write the value to `out`.
86   bool GetParam(const std::string& name, std::string* out) const;
87   bool GetParam(const std::string& name, int* out) const;
88 
89   void SetParam(const std::string& name, const std::string& value);
90   void SetParam(const std::string& name, int value);
91 
92   // It is safe to input a non-existent parameter.
93   // Returns true if the parameter existed, false if it did not exist.
94   bool RemoveParam(const std::string& name);
95 
96   bool HasFeedbackParam(const FeedbackParam& param) const;
97   void AddFeedbackParam(const FeedbackParam& param);
98 
99   // Filter `this` feedbacks params such that only those shared by both `this`
100   // and `other` are kept.
101   void IntersectFeedbackParams(const Codec& other);
102 
103   virtual webrtc::RtpCodecParameters ToCodecParameters() const;
104 
105   Codec& operator=(const Codec& c);
106   Codec& operator=(Codec&& c);
107 
108   bool operator==(const Codec& c) const;
109 
110   bool operator!=(const Codec& c) const { return !(*this == c); }
111 
112  protected:
113   // A Codec can't be created without a subclass.
114   // Creates a codec with the given parameters.
115   Codec(int id, const std::string& name, int clockrate);
116   // Creates an empty codec.
117   Codec();
118   Codec(const Codec& c);
119   Codec(Codec&& c);
120 };
121 
122 struct AudioCodec : public Codec {
123   int bitrate;
124   size_t channels;
125 
126   // Creates a codec with the given parameters.
127   AudioCodec(int id,
128              const std::string& name,
129              int clockrate,
130              int bitrate,
131              size_t channels);
132   // Creates an empty codec.
133   AudioCodec();
134   AudioCodec(const AudioCodec& c);
135   AudioCodec(AudioCodec&& c);
136   ~AudioCodec() override = default;
137 
138   // Indicates if this codec is compatible with the specified codec.
139   bool Matches(const AudioCodec& codec,
140                const webrtc::FieldTrialsView* field_trials = nullptr) const;
141 
142   std::string ToString() const;
143 
144   webrtc::RtpCodecParameters ToCodecParameters() const override;
145 
146   AudioCodec& operator=(const AudioCodec& c);
147   AudioCodec& operator=(AudioCodec&& c);
148 
149   bool operator==(const AudioCodec& c) const;
150 
151   bool operator!=(const AudioCodec& c) const { return !(*this == c); }
152 };
153 
154 struct RTC_EXPORT VideoCodec : public Codec {
155   absl::optional<std::string> packetization;
156   absl::InlinedVector<webrtc::ScalabilityMode, webrtc::kScalabilityModeCount>
157       scalability_modes;
158 
159   // Creates a codec with the given parameters.
160   VideoCodec(int id, const std::string& name);
161   // Creates a codec with the given name and empty id.
162   explicit VideoCodec(const std::string& name);
163   // Creates an empty codec.
164   VideoCodec();
165   VideoCodec(const VideoCodec& c);
166   explicit VideoCodec(const webrtc::SdpVideoFormat& c);
167   VideoCodec(VideoCodec&& c);
168   ~VideoCodec() override = default;
169 
170   // Indicates if this video codec is the same as the other video codec, e.g. if
171   // they are both VP8 or VP9, or if they are both H264 with the same H264
172   // profile. H264 levels however are not compared.
173   bool Matches(const VideoCodec& codec,
174                const webrtc::FieldTrialsView* field_trials = nullptr) const;
175 
176   std::string ToString() const;
177 
178   webrtc::RtpCodecParameters ToCodecParameters() const override;
179 
180   VideoCodec& operator=(const VideoCodec& c);
181   VideoCodec& operator=(VideoCodec&& c);
182 
183   bool operator==(const VideoCodec& c) const;
184 
185   bool operator!=(const VideoCodec& c) const { return !(*this == c); }
186 
187   // Return packetization which both `local_codec` and `remote_codec` support.
188   static absl::optional<std::string> IntersectPacketization(
189       const VideoCodec& local_codec,
190       const VideoCodec& remote_codec);
191 
192   static VideoCodec CreateRtxCodec(int rtx_payload_type,
193                                    int associated_payload_type);
194 
195   enum CodecType {
196     CODEC_VIDEO,
197     CODEC_RED,
198     CODEC_ULPFEC,
199     CODEC_FLEXFEC,
200     CODEC_RTX,
201   };
202 
203   CodecType GetCodecType() const;
204   // Validates a VideoCodec's payload type, dimensions and bitrates etc. If they
205   // don't make sense (such as max < min bitrate), and error is logged and
206   // ValidateCodecFormat returns false.
207   bool ValidateCodecFormat() const;
208 
209  private:
210   void SetDefaultParameters();
211 };
212 
213 // Get the codec setting associated with `payload_type`. If there
214 // is no codec associated with that payload type it returns nullptr.
215 template <class Codec>
FindCodecById(const std::vector<Codec> & codecs,int payload_type)216 const Codec* FindCodecById(const std::vector<Codec>& codecs, int payload_type) {
217   for (const auto& codec : codecs) {
218     if (codec.id == payload_type)
219       return &codec;
220   }
221   return nullptr;
222 }
223 
224 bool HasLntf(const Codec& codec);
225 bool HasNack(const Codec& codec);
226 bool HasRemb(const Codec& codec);
227 bool HasRrtr(const Codec& codec);
228 bool HasTransportCc(const Codec& codec);
229 // Returns the first codec in `supported_codecs` that matches `codec`, or
230 // nullptr if no codec matches.
231 const VideoCodec* FindMatchingCodec(
232     const std::vector<VideoCodec>& supported_codecs,
233     const VideoCodec& codec);
234 
235 RTC_EXPORT void AddH264ConstrainedBaselineProfileToSupportedFormats(
236     std::vector<webrtc::SdpVideoFormat>* supported_formats);
237 
238 }  // namespace cricket
239 
240 #endif  // MEDIA_BASE_CODEC_H_
241