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 class FeedbackParam {
     43  public:
     44   FeedbackParam(const std::string& id, const std::string& param)
     45       : id_(id),
     46         param_(param) {
     47   }
     48   explicit FeedbackParam(const std::string& id)
     49       : id_(id),
     50         param_(kParamValueEmpty) {
     51   }
     52   bool operator==(const FeedbackParam& other) const;
     53 
     54   const std::string& id() const { return id_; }
     55   const std::string& param() const { return param_; }
     56 
     57  private:
     58   std::string id_;  // e.g. "nack", "ccm"
     59   std::string param_;  // e.g. "", "rpsi", "fir"
     60 };
     61 
     62 class FeedbackParams {
     63  public:
     64   bool operator==(const FeedbackParams& other) const;
     65 
     66   bool Has(const FeedbackParam& param) const;
     67   void Add(const FeedbackParam& param);
     68 
     69   void Intersect(const FeedbackParams& from);
     70 
     71   const std::vector<FeedbackParam>& params() const { return params_; }
     72  private:
     73   bool HasDuplicateEntries() const;
     74 
     75   std::vector<FeedbackParam> params_;
     76 };
     77 
     78 struct Codec {
     79   int id;
     80   std::string name;
     81   int clockrate;
     82   int preference;
     83   CodecParameterMap params;
     84   FeedbackParams feedback_params;
     85 
     86   // Creates a codec with the given parameters.
     87   Codec(int id, const std::string& name, int clockrate, int preference)
     88       : id(id),
     89         name(name),
     90         clockrate(clockrate),
     91         preference(preference) {
     92   }
     93 
     94   // Creates an empty codec.
     95   Codec() : id(0), clockrate(0), preference(0) {}
     96 
     97   // Indicates if this codec is compatible with the specified codec.
     98   bool Matches(const Codec& codec) const;
     99 
    100   // Find the parameter for |name| and write the value to |out|.
    101   bool GetParam(const std::string& name, std::string* out) const;
    102   bool GetParam(const std::string& name, int* out) const;
    103 
    104   void SetParam(const std::string& name, const std::string& value);
    105   void SetParam(const std::string& name, int value);
    106 
    107   bool HasFeedbackParam(const FeedbackParam& param) const;
    108   void AddFeedbackParam(const FeedbackParam& param);
    109 
    110   static bool Preferable(const Codec& first, const Codec& other) {
    111     return first.preference > other.preference;
    112   }
    113 
    114   // Filter |this| feedbacks params such that only those shared by both |this|
    115   // and |other| are kept.
    116   void IntersectFeedbackParams(const Codec& other);
    117 
    118   Codec& operator=(const Codec& c) {
    119     this->id = c.id;  // id is reserved in objective-c
    120     name = c.name;
    121     clockrate = c.clockrate;
    122     preference = c.preference;
    123     params = c.params;
    124     feedback_params = c.feedback_params;
    125     return *this;
    126   }
    127 
    128   bool operator==(const Codec& c) const {
    129     return this->id == c.id &&  // id is reserved in objective-c
    130         name == c.name &&
    131         clockrate == c.clockrate &&
    132         preference == c.preference &&
    133         params == c.params &&
    134         feedback_params == c.feedback_params;
    135   }
    136 
    137   bool operator!=(const Codec& c) const {
    138     return !(*this == c);
    139   }
    140 };
    141 
    142 struct AudioCodec : public Codec {
    143   int bitrate;
    144   int channels;
    145 
    146   // Creates a codec with the given parameters.
    147   AudioCodec(int pt, const std::string& nm, int cr, int br, int cs, int pr)
    148       : Codec(pt, nm, cr, pr),
    149         bitrate(br),
    150         channels(cs) {
    151   }
    152 
    153   // Creates an empty codec.
    154   AudioCodec() : Codec(), bitrate(0), channels(0) {}
    155 
    156   // Indicates if this codec is compatible with the specified codec.
    157   bool Matches(const AudioCodec& codec) const;
    158 
    159   static bool Preferable(const AudioCodec& first, const AudioCodec& other) {
    160     return first.preference > other.preference;
    161   }
    162 
    163   std::string ToString() const;
    164 
    165   AudioCodec& operator=(const AudioCodec& c) {
    166     this->id = c.id;  // id is reserved in objective-c
    167     name = c.name;
    168     clockrate = c.clockrate;
    169     bitrate = c.bitrate;
    170     channels = c.channels;
    171     preference =  c.preference;
    172     params = c.params;
    173     feedback_params = c.feedback_params;
    174     return *this;
    175   }
    176 
    177   bool operator==(const AudioCodec& c) const {
    178     return this->id == c.id &&  // id is reserved in objective-c
    179            name == c.name &&
    180            clockrate == c.clockrate &&
    181            bitrate == c.bitrate &&
    182            channels == c.channels &&
    183            preference == c.preference &&
    184            params == c.params &&
    185            feedback_params == c.feedback_params;
    186   }
    187 
    188   bool operator!=(const AudioCodec& c) const {
    189     return !(*this == c);
    190   }
    191 };
    192 
    193 struct VideoCodec : public Codec {
    194   int width;
    195   int height;
    196   int framerate;
    197 
    198   // Creates a codec with the given parameters.
    199   VideoCodec(int pt, const std::string& nm, int w, int h, int fr, int pr)
    200       : Codec(pt, nm, kVideoCodecClockrate, pr),
    201         width(w),
    202         height(h),
    203         framerate(fr) {
    204   }
    205 
    206   // Creates an empty codec.
    207   VideoCodec()
    208       : Codec(),
    209         width(0),
    210         height(0),
    211         framerate(0) {
    212     clockrate = kVideoCodecClockrate;
    213   }
    214 
    215   static bool Preferable(const VideoCodec& first, const VideoCodec& other) {
    216     return first.preference > other.preference;
    217   }
    218 
    219   std::string ToString() const;
    220 
    221   VideoCodec& operator=(const VideoCodec& c) {
    222     this->id = c.id;  // id is reserved in objective-c
    223     name = c.name;
    224     clockrate = c.clockrate;
    225     width = c.width;
    226     height = c.height;
    227     framerate = c.framerate;
    228     preference =  c.preference;
    229     params = c.params;
    230     feedback_params = c.feedback_params;
    231     return *this;
    232   }
    233 
    234   bool operator==(const VideoCodec& c) const {
    235     return this->id == c.id &&  // id is reserved in objective-c
    236            name == c.name &&
    237            clockrate == c.clockrate &&
    238            width == c.width &&
    239            height == c.height &&
    240            framerate == c.framerate &&
    241            preference == c.preference &&
    242            params == c.params &&
    243            feedback_params == c.feedback_params;
    244   }
    245 
    246   bool operator!=(const VideoCodec& c) const {
    247     return !(*this == c);
    248   }
    249 
    250   static VideoCodec CreateRtxCodec(int rtx_payload_type,
    251                                    int associated_payload_type);
    252 
    253   enum CodecType {
    254     CODEC_VIDEO,
    255     CODEC_RED,
    256     CODEC_ULPFEC,
    257     CODEC_RTX,
    258   };
    259 
    260   CodecType GetCodecType() const;
    261   // Validates a VideoCodec's payload type, dimensions and bitrates etc. If they
    262   // don't make sense (such as max < min bitrate), and error is logged and
    263   // ValidateCodecFormat returns false.
    264   bool ValidateCodecFormat() const;
    265 };
    266 
    267 struct DataCodec : public Codec {
    268   DataCodec(int id, const std::string& name, int preference)
    269       : Codec(id, name, kDataCodecClockrate, preference) {
    270   }
    271 
    272   DataCodec() : Codec() {
    273     clockrate = kDataCodecClockrate;
    274   }
    275 
    276   std::string ToString() const;
    277 };
    278 
    279 struct VideoEncoderConfig {
    280   static const int kDefaultMaxThreads = -1;
    281   static const int kDefaultCpuProfile = -1;
    282 
    283   VideoEncoderConfig()
    284       : max_codec(),
    285         num_threads(kDefaultMaxThreads),
    286         cpu_profile(kDefaultCpuProfile) {
    287   }
    288 
    289   VideoEncoderConfig(const VideoCodec& c)
    290       : max_codec(c),
    291         num_threads(kDefaultMaxThreads),
    292         cpu_profile(kDefaultCpuProfile) {
    293   }
    294 
    295   VideoEncoderConfig(const VideoCodec& c, int t, int p)
    296       : max_codec(c),
    297         num_threads(t),
    298         cpu_profile(p) {
    299   }
    300 
    301   VideoEncoderConfig& operator=(const VideoEncoderConfig& config) {
    302     max_codec = config.max_codec;
    303     num_threads = config.num_threads;
    304     cpu_profile = config.cpu_profile;
    305     return *this;
    306   }
    307 
    308   bool operator==(const VideoEncoderConfig& config) const {
    309     return max_codec == config.max_codec &&
    310            num_threads == config.num_threads &&
    311            cpu_profile == config.cpu_profile;
    312   }
    313 
    314   bool operator!=(const VideoEncoderConfig& config) const {
    315     return !(*this == config);
    316   }
    317 
    318   VideoCodec max_codec;
    319   int num_threads;
    320   int cpu_profile;
    321 };
    322 
    323 }  // namespace cricket
    324 
    325 #endif  // TALK_MEDIA_BASE_CODEC_H_
    326