Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2004 Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifndef TALK_MEDIA_BASE_CODEC_H_
     29 #define TALK_MEDIA_BASE_CODEC_H_
     30 
     31 #include <map>
     32 #include <set>
     33 #include <string>
     34 #include <vector>
     35 
     36 #include "talk/media/base/constants.h"
     37 
     38 namespace cricket {
     39 
     40 typedef std::map<std::string, std::string> CodecParameterMap;
     41 
     42 extern const int kMaxPayloadId;
     43 
     44 class FeedbackParam {
     45  public:
     46   FeedbackParam(const std::string& id, const std::string& param)
     47       : id_(id),
     48         param_(param) {
     49   }
     50   explicit FeedbackParam(const std::string& id)
     51       : id_(id),
     52         param_(kParamValueEmpty) {
     53   }
     54   bool operator==(const FeedbackParam& other) const;
     55 
     56   const std::string& id() const { return id_; }
     57   const std::string& param() const { return param_; }
     58 
     59  private:
     60   std::string id_;  // e.g. "nack", "ccm"
     61   std::string param_;  // e.g. "", "rpsi", "fir"
     62 };
     63 
     64 class FeedbackParams {
     65  public:
     66   bool operator==(const FeedbackParams& other) const;
     67 
     68   bool Has(const FeedbackParam& param) const;
     69   void Add(const FeedbackParam& param);
     70 
     71   void Intersect(const FeedbackParams& from);
     72 
     73   const std::vector<FeedbackParam>& params() const { return params_; }
     74  private:
     75   bool HasDuplicateEntries() const;
     76 
     77   std::vector<FeedbackParam> params_;
     78 };
     79 
     80 struct Codec {
     81   int id;
     82   std::string name;
     83   int clockrate;
     84   int preference;
     85   CodecParameterMap params;
     86   FeedbackParams feedback_params;
     87 
     88   // Creates a codec with the given parameters.
     89   Codec(int id, const std::string& name, int clockrate, int preference)
     90       : id(id),
     91         name(name),
     92         clockrate(clockrate),
     93         preference(preference) {
     94   }
     95 
     96   // Creates an empty codec.
     97   Codec() : id(0), clockrate(0), preference(0) {}
     98 
     99   // Indicates if this codec is compatible with the specified codec.
    100   bool Matches(const Codec& codec) const;
    101 
    102   // Find the parameter for |name| and write the value to |out|.
    103   bool GetParam(const std::string& name, std::string* out) const;
    104   bool GetParam(const std::string& name, int* out) const;
    105 
    106   void SetParam(const std::string& name, const std::string& value);
    107   void SetParam(const std::string& name, int value);
    108 
    109   // It is safe to input a non-existent parameter.
    110   // Returns true if the parameter existed, false if it did not exist.
    111   bool RemoveParam(const std::string& name);
    112 
    113   bool HasFeedbackParam(const FeedbackParam& param) const;
    114   void AddFeedbackParam(const FeedbackParam& param);
    115 
    116   static bool Preferable(const Codec& first, const Codec& other) {
    117     return first.preference > other.preference;
    118   }
    119 
    120   // Filter |this| feedbacks params such that only those shared by both |this|
    121   // and |other| are kept.
    122   void IntersectFeedbackParams(const Codec& other);
    123 
    124   Codec& operator=(const Codec& c) {
    125     this->id = c.id;  // id is reserved in objective-c
    126     name = c.name;
    127     clockrate = c.clockrate;
    128     preference = c.preference;
    129     params = c.params;
    130     feedback_params = c.feedback_params;
    131     return *this;
    132   }
    133 
    134   bool operator==(const Codec& c) const {
    135     return this->id == c.id &&  // id is reserved in objective-c
    136         name == c.name &&
    137         clockrate == c.clockrate &&
    138         preference == c.preference &&
    139         params == c.params &&
    140         feedback_params == c.feedback_params;
    141   }
    142 
    143   bool operator!=(const Codec& c) const {
    144     return !(*this == c);
    145   }
    146 };
    147 
    148 struct AudioCodec : public Codec {
    149   int bitrate;
    150   int channels;
    151 
    152   // Creates a codec with the given parameters.
    153   AudioCodec(int pt, const std::string& nm, int cr, int br, int cs, int pr)
    154       : Codec(pt, nm, cr, pr),
    155         bitrate(br),
    156         channels(cs) {
    157   }
    158 
    159   // Creates an empty codec.
    160   AudioCodec() : Codec(), bitrate(0), channels(0) {}
    161 
    162   // Indicates if this codec is compatible with the specified codec.
    163   bool Matches(const AudioCodec& codec) const;
    164 
    165   static bool Preferable(const AudioCodec& first, const AudioCodec& other) {
    166     return first.preference > other.preference;
    167   }
    168 
    169   std::string ToString() const;
    170 
    171   AudioCodec& operator=(const AudioCodec& c) {
    172     this->id = c.id;  // id is reserved in objective-c
    173     name = c.name;
    174     clockrate = c.clockrate;
    175     bitrate = c.bitrate;
    176     channels = c.channels;
    177     preference =  c.preference;
    178     params = c.params;
    179     feedback_params = c.feedback_params;
    180     return *this;
    181   }
    182 
    183   bool operator==(const AudioCodec& c) const {
    184     return this->id == c.id &&  // id is reserved in objective-c
    185            name == c.name &&
    186            clockrate == c.clockrate &&
    187            bitrate == c.bitrate &&
    188            channels == c.channels &&
    189            preference == c.preference &&
    190            params == c.params &&
    191            feedback_params == c.feedback_params;
    192   }
    193 
    194   bool operator!=(const AudioCodec& c) const {
    195     return !(*this == c);
    196   }
    197 };
    198 
    199 struct VideoCodec : public Codec {
    200   int width;
    201   int height;
    202   int framerate;
    203 
    204   // Creates a codec with the given parameters.
    205   VideoCodec(int pt, const std::string& nm, int w, int h, int fr, int pr)
    206       : Codec(pt, nm, kVideoCodecClockrate, pr),
    207         width(w),
    208         height(h),
    209         framerate(fr) {
    210   }
    211 
    212   // Creates an empty codec.
    213   VideoCodec()
    214       : Codec(),
    215         width(0),
    216         height(0),
    217         framerate(0) {
    218     clockrate = kVideoCodecClockrate;
    219   }
    220 
    221   static bool Preferable(const VideoCodec& first, const VideoCodec& other) {
    222     return first.preference > other.preference;
    223   }
    224 
    225   std::string ToString() const;
    226 
    227   VideoCodec& operator=(const VideoCodec& c) {
    228     this->id = c.id;  // id is reserved in objective-c
    229     name = c.name;
    230     clockrate = c.clockrate;
    231     width = c.width;
    232     height = c.height;
    233     framerate = c.framerate;
    234     preference =  c.preference;
    235     params = c.params;
    236     feedback_params = c.feedback_params;
    237     return *this;
    238   }
    239 
    240   bool operator==(const VideoCodec& c) const {
    241     return this->id == c.id &&  // id is reserved in objective-c
    242            name == c.name &&
    243            clockrate == c.clockrate &&
    244            width == c.width &&
    245            height == c.height &&
    246            framerate == c.framerate &&
    247            preference == c.preference &&
    248            params == c.params &&
    249            feedback_params == c.feedback_params;
    250   }
    251 
    252   bool operator!=(const VideoCodec& c) const {
    253     return !(*this == c);
    254   }
    255 
    256   static VideoCodec CreateRtxCodec(int rtx_payload_type,
    257                                    int associated_payload_type);
    258 
    259   enum CodecType {
    260     CODEC_VIDEO,
    261     CODEC_RED,
    262     CODEC_ULPFEC,
    263     CODEC_RTX,
    264   };
    265 
    266   CodecType GetCodecType() const;
    267   // Validates a VideoCodec's payload type, dimensions and bitrates etc. If they
    268   // don't make sense (such as max < min bitrate), and error is logged and
    269   // ValidateCodecFormat returns false.
    270   bool ValidateCodecFormat() const;
    271 };
    272 
    273 struct DataCodec : public Codec {
    274   DataCodec(int id, const std::string& name, int preference)
    275       : Codec(id, name, kDataCodecClockrate, preference) {
    276   }
    277 
    278   DataCodec() : Codec() {
    279     clockrate = kDataCodecClockrate;
    280   }
    281 
    282   std::string ToString() const;
    283 };
    284 
    285 struct VideoEncoderConfig {
    286   static const int kDefaultMaxThreads = -1;
    287   static const int kDefaultCpuProfile = -1;
    288 
    289   VideoEncoderConfig()
    290       : max_codec(),
    291         num_threads(kDefaultMaxThreads),
    292         cpu_profile(kDefaultCpuProfile) {
    293   }
    294 
    295   VideoEncoderConfig(const VideoCodec& c)
    296       : max_codec(c),
    297         num_threads(kDefaultMaxThreads),
    298         cpu_profile(kDefaultCpuProfile) {
    299   }
    300 
    301   VideoEncoderConfig(const VideoCodec& c, int t, int p)
    302       : max_codec(c),
    303         num_threads(t),
    304         cpu_profile(p) {
    305   }
    306 
    307   VideoEncoderConfig& operator=(const VideoEncoderConfig& config) {
    308     max_codec = config.max_codec;
    309     num_threads = config.num_threads;
    310     cpu_profile = config.cpu_profile;
    311     return *this;
    312   }
    313 
    314   bool operator==(const VideoEncoderConfig& config) const {
    315     return max_codec == config.max_codec &&
    316            num_threads == config.num_threads &&
    317            cpu_profile == config.cpu_profile;
    318   }
    319 
    320   bool operator!=(const VideoEncoderConfig& config) const {
    321     return !(*this == config);
    322   }
    323 
    324   VideoCodec max_codec;
    325   int num_threads;
    326   int cpu_profile;
    327 };
    328 
    329 }  // namespace cricket
    330 
    331 #endif  // TALK_MEDIA_BASE_CODEC_H_
    332