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