1 /* 2 * Copyright (c) 2015 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_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ 12 #define WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ 13 14 #include <stddef.h> 15 #include <map> 16 17 #include "webrtc/base/array_view.h" 18 #include "webrtc/base/constructormagic.h" 19 #include "webrtc/base/optional.h" 20 #include "webrtc/base/scoped_ptr.h" 21 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" 22 #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" 23 #include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" 24 #include "webrtc/typedefs.h" 25 26 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) 27 #include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h" 28 #else 29 // Dummy implementation, for when we don't have iSAC. 30 namespace webrtc { 31 class LockedIsacBandwidthInfo {}; 32 } 33 #endif 34 35 namespace webrtc { 36 37 struct CodecInst; 38 39 namespace acm2 { 40 41 class RentACodec { 42 public: 43 enum class CodecId { 44 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) 45 kISAC, 46 #endif 47 #ifdef WEBRTC_CODEC_ISAC 48 kISACSWB, 49 #endif 50 // Mono 51 kPCM16B, 52 kPCM16Bwb, 53 kPCM16Bswb32kHz, 54 // Stereo 55 kPCM16B_2ch, 56 kPCM16Bwb_2ch, 57 kPCM16Bswb32kHz_2ch, 58 // Mono 59 kPCMU, 60 kPCMA, 61 // Stereo 62 kPCMU_2ch, 63 kPCMA_2ch, 64 #ifdef WEBRTC_CODEC_ILBC 65 kILBC, 66 #endif 67 #ifdef WEBRTC_CODEC_G722 68 kG722, // Mono 69 kG722_2ch, // Stereo 70 #endif 71 #ifdef WEBRTC_CODEC_OPUS 72 kOpus, // Mono and stereo 73 #endif 74 kCNNB, 75 kCNWB, 76 kCNSWB, 77 #ifdef ENABLE_48000_HZ 78 kCNFB, 79 #endif 80 kAVT, 81 #ifdef WEBRTC_CODEC_RED 82 kRED, 83 #endif 84 kNumCodecs, // Implementation detail. Don't use. 85 86 // Set unsupported codecs to -1. 87 #if !defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX) 88 kISAC = -1, 89 #endif 90 #ifndef WEBRTC_CODEC_ISAC 91 kISACSWB = -1, 92 #endif 93 // 48 kHz not supported, always set to -1. 94 kPCM16Bswb48kHz = -1, 95 #ifndef WEBRTC_CODEC_ILBC 96 kILBC = -1, 97 #endif 98 #ifndef WEBRTC_CODEC_G722 99 kG722 = -1, // Mono 100 kG722_2ch = -1, // Stereo 101 #endif 102 #ifndef WEBRTC_CODEC_OPUS 103 kOpus = -1, // Mono and stereo 104 #endif 105 #ifndef WEBRTC_CODEC_RED 106 kRED = -1, 107 #endif 108 #ifndef ENABLE_48000_HZ 109 kCNFB = -1, 110 #endif 111 112 kNone = -1 113 }; 114 115 enum class NetEqDecoder { 116 kDecoderPCMu, 117 kDecoderPCMa, 118 kDecoderPCMu_2ch, 119 kDecoderPCMa_2ch, 120 kDecoderILBC, 121 kDecoderISAC, 122 kDecoderISACswb, 123 kDecoderPCM16B, 124 kDecoderPCM16Bwb, 125 kDecoderPCM16Bswb32kHz, 126 kDecoderPCM16Bswb48kHz, 127 kDecoderPCM16B_2ch, 128 kDecoderPCM16Bwb_2ch, 129 kDecoderPCM16Bswb32kHz_2ch, 130 kDecoderPCM16Bswb48kHz_2ch, 131 kDecoderPCM16B_5ch, 132 kDecoderG722, 133 kDecoderG722_2ch, 134 kDecoderRED, 135 kDecoderAVT, 136 kDecoderCNGnb, 137 kDecoderCNGwb, 138 kDecoderCNGswb32kHz, 139 kDecoderCNGswb48kHz, 140 kDecoderArbitrary, 141 kDecoderOpus, 142 kDecoderOpus_2ch, 143 }; 144 145 static inline size_t NumberOfCodecs() { 146 return static_cast<size_t>(CodecId::kNumCodecs); 147 } 148 149 static inline rtc::Optional<int> CodecIndexFromId(CodecId codec_id) { 150 const int i = static_cast<int>(codec_id); 151 return i >= 0 && i < static_cast<int>(NumberOfCodecs()) 152 ? rtc::Optional<int>(i) 153 : rtc::Optional<int>(); 154 } 155 156 static inline rtc::Optional<CodecId> CodecIdFromIndex(int codec_index) { 157 return static_cast<size_t>(codec_index) < NumberOfCodecs() 158 ? rtc::Optional<RentACodec::CodecId>( 159 static_cast<RentACodec::CodecId>(codec_index)) 160 : rtc::Optional<RentACodec::CodecId>(); 161 } 162 163 static rtc::Optional<CodecId> CodecIdByParams(const char* payload_name, 164 int sampling_freq_hz, 165 size_t channels); 166 static rtc::Optional<CodecInst> CodecInstById(CodecId codec_id); 167 static rtc::Optional<CodecId> CodecIdByInst(const CodecInst& codec_inst); 168 static rtc::Optional<CodecInst> CodecInstByParams(const char* payload_name, 169 int sampling_freq_hz, 170 size_t channels); 171 static bool IsCodecValid(const CodecInst& codec_inst); 172 173 static inline bool IsPayloadTypeValid(int payload_type) { 174 return payload_type >= 0 && payload_type <= 127; 175 } 176 177 static rtc::ArrayView<const CodecInst> Database(); 178 179 static rtc::Optional<bool> IsSupportedNumChannels(CodecId codec_id, 180 size_t num_channels); 181 182 static rtc::Optional<NetEqDecoder> NetEqDecoderFromCodecId( 183 CodecId codec_id, 184 size_t num_channels); 185 186 // Parse codec_inst and extract payload types. If the given CodecInst was for 187 // the wrong sort of codec, return kSkip; otherwise, if the rate was illegal, 188 // return kBadFreq; otherwise, update the given RTP timestamp rate (Hz) -> 189 // payload type map and return kOk. 190 enum class RegistrationResult { kOk, kSkip, kBadFreq }; 191 static RegistrationResult RegisterCngPayloadType(std::map<int, int>* pt_map, 192 const CodecInst& codec_inst); 193 static RegistrationResult RegisterRedPayloadType(std::map<int, int>* pt_map, 194 const CodecInst& codec_inst); 195 196 RentACodec(); 197 ~RentACodec(); 198 199 // Creates and returns an audio encoder built to the given specification. 200 // Returns null in case of error. The returned encoder is live until the next 201 // successful call to this function, or until the Rent-A-Codec is destroyed. 202 AudioEncoder* RentEncoder(const CodecInst& codec_inst); 203 204 struct StackParameters { 205 StackParameters(); 206 ~StackParameters(); 207 208 AudioEncoder* speech_encoder = nullptr; 209 bool use_codec_fec = false; 210 bool use_red = false; 211 bool use_cng = false; 212 ACMVADMode vad_mode = VADNormal; 213 214 // Maps from RTP timestamp rate (in Hz) to payload type. 215 std::map<int, int> cng_payload_types; 216 std::map<int, int> red_payload_types; 217 }; 218 219 // Creates and returns an audio encoder stack constructed to the given 220 // specification. If the specification isn't compatible with the encoder, it 221 // will be changed to match (things will be switched off). The returned 222 // encoder is live until the next successful call to this function, or until 223 // the Rent-A-Codec is destroyed. 224 AudioEncoder* RentEncoderStack(StackParameters* param); 225 226 // The last return value of RentEncoderStack, or null if it hasn't been 227 // called. 228 AudioEncoder* GetEncoderStack() const { return encoder_stack_; } 229 230 // Creates and returns an iSAC decoder, which will remain live until the 231 // Rent-A-Codec is destroyed. Subsequent calls will simply return the same 232 // object. 233 AudioDecoder* RentIsacDecoder(); 234 235 private: 236 rtc::scoped_ptr<AudioEncoder> speech_encoder_; 237 rtc::scoped_ptr<AudioEncoder> cng_encoder_; 238 rtc::scoped_ptr<AudioEncoder> red_encoder_; 239 rtc::scoped_ptr<AudioDecoder> isac_decoder_; 240 AudioEncoder* encoder_stack_ = nullptr; 241 LockedIsacBandwidthInfo isac_bandwidth_info_; 242 243 RTC_DISALLOW_COPY_AND_ASSIGN(RentACodec); 244 }; 245 246 } // namespace acm2 247 } // namespace webrtc 248 249 #endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ 250