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