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