1 /* 2 * Copyright (c) 2012 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 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" 12 13 #include <assert.h> 14 #include <utility> // pair 15 16 #include "webrtc/base/checks.h" 17 #include "webrtc/base/logging.h" 18 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" 19 20 namespace webrtc { 21 22 DecoderDatabase::DecoderDatabase() 23 : active_decoder_(-1), active_cng_decoder_(-1) {} 24 25 DecoderDatabase::~DecoderDatabase() {} 26 27 DecoderDatabase::DecoderInfo::~DecoderInfo() { 28 if (!external) delete decoder; 29 } 30 31 bool DecoderDatabase::Empty() const { return decoders_.empty(); } 32 33 int DecoderDatabase::Size() const { return static_cast<int>(decoders_.size()); } 34 35 void DecoderDatabase::Reset() { 36 decoders_.clear(); 37 active_decoder_ = -1; 38 active_cng_decoder_ = -1; 39 } 40 41 int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, 42 NetEqDecoder codec_type, 43 const std::string& name) { 44 if (rtp_payload_type > 0x7F) { 45 return kInvalidRtpPayloadType; 46 } 47 if (!CodecSupported(codec_type)) { 48 return kCodecNotSupported; 49 } 50 const int fs_hz = CodecSampleRateHz(codec_type); 51 DecoderInfo info(codec_type, name, fs_hz, NULL, false); 52 auto ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); 53 if (ret.second == false) { 54 // Database already contains a decoder with type |rtp_payload_type|. 55 return kDecoderExists; 56 } 57 return kOK; 58 } 59 60 int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, 61 NetEqDecoder codec_type, 62 const std::string& codec_name, 63 int fs_hz, 64 AudioDecoder* decoder) { 65 if (rtp_payload_type > 0x7F) { 66 return kInvalidRtpPayloadType; 67 } 68 if (!CodecSupported(codec_type)) { 69 return kCodecNotSupported; 70 } 71 if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) { 72 return kInvalidSampleRate; 73 } 74 if (!decoder) { 75 return kInvalidPointer; 76 } 77 std::pair<DecoderMap::iterator, bool> ret; 78 DecoderInfo info(codec_type, codec_name, fs_hz, decoder, true); 79 ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); 80 if (ret.second == false) { 81 // Database already contains a decoder with type |rtp_payload_type|. 82 return kDecoderExists; 83 } 84 return kOK; 85 } 86 87 int DecoderDatabase::Remove(uint8_t rtp_payload_type) { 88 if (decoders_.erase(rtp_payload_type) == 0) { 89 // No decoder with that |rtp_payload_type|. 90 return kDecoderNotFound; 91 } 92 if (active_decoder_ == rtp_payload_type) { 93 active_decoder_ = -1; // No active decoder. 94 } 95 if (active_cng_decoder_ == rtp_payload_type) { 96 active_cng_decoder_ = -1; // No active CNG decoder. 97 } 98 return kOK; 99 } 100 101 const DecoderDatabase::DecoderInfo* DecoderDatabase::GetDecoderInfo( 102 uint8_t rtp_payload_type) const { 103 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); 104 if (it == decoders_.end()) { 105 // Decoder not found. 106 return NULL; 107 } 108 return &(*it).second; 109 } 110 111 uint8_t DecoderDatabase::GetRtpPayloadType( 112 NetEqDecoder codec_type) const { 113 DecoderMap::const_iterator it; 114 for (it = decoders_.begin(); it != decoders_.end(); ++it) { 115 if ((*it).second.codec_type == codec_type) { 116 // Match found. 117 return (*it).first; 118 } 119 } 120 // No match. 121 return kRtpPayloadTypeError; 122 } 123 124 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) { 125 if (IsDtmf(rtp_payload_type) || IsRed(rtp_payload_type)) { 126 // These are not real decoders. 127 return NULL; 128 } 129 DecoderMap::iterator it = decoders_.find(rtp_payload_type); 130 if (it == decoders_.end()) { 131 // Decoder not found. 132 return NULL; 133 } 134 DecoderInfo* info = &(*it).second; 135 if (!info->decoder) { 136 // Create the decoder object. 137 AudioDecoder* decoder = CreateAudioDecoder(info->codec_type); 138 assert(decoder); // Should not be able to have an unsupported codec here. 139 info->decoder = decoder; 140 } 141 return info->decoder; 142 } 143 144 bool DecoderDatabase::IsType(uint8_t rtp_payload_type, 145 NetEqDecoder codec_type) const { 146 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); 147 if (it == decoders_.end()) { 148 // Decoder not found. 149 return false; 150 } 151 return ((*it).second.codec_type == codec_type); 152 } 153 154 bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const { 155 if (IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGnb) || 156 IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGwb) || 157 IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGswb32kHz) || 158 IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGswb48kHz)) { 159 return true; 160 } else { 161 return false; 162 } 163 } 164 165 bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const { 166 return IsType(rtp_payload_type, NetEqDecoder::kDecoderAVT); 167 } 168 169 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const { 170 return IsType(rtp_payload_type, NetEqDecoder::kDecoderRED); 171 } 172 173 int DecoderDatabase::SetActiveDecoder(uint8_t rtp_payload_type, 174 bool* new_decoder) { 175 // Check that |rtp_payload_type| exists in the database. 176 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); 177 if (it == decoders_.end()) { 178 // Decoder not found. 179 return kDecoderNotFound; 180 } 181 assert(new_decoder); 182 *new_decoder = false; 183 if (active_decoder_ < 0) { 184 // This is the first active decoder. 185 *new_decoder = true; 186 } else if (active_decoder_ != rtp_payload_type) { 187 // Moving from one active decoder to another. Delete the first one. 188 DecoderMap::iterator it = decoders_.find(active_decoder_); 189 if (it == decoders_.end()) { 190 // Decoder not found. This should not be possible. 191 assert(false); 192 return kDecoderNotFound; 193 } 194 if (!(*it).second.external) { 195 // Delete the AudioDecoder object, unless it is an externally created 196 // decoder. 197 delete (*it).second.decoder; 198 (*it).second.decoder = NULL; 199 } 200 *new_decoder = true; 201 } 202 active_decoder_ = rtp_payload_type; 203 return kOK; 204 } 205 206 AudioDecoder* DecoderDatabase::GetActiveDecoder() { 207 if (active_decoder_ < 0) { 208 // No active decoder. 209 return NULL; 210 } 211 return GetDecoder(active_decoder_); 212 } 213 214 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { 215 // Check that |rtp_payload_type| exists in the database. 216 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); 217 if (it == decoders_.end()) { 218 // Decoder not found. 219 return kDecoderNotFound; 220 } 221 if (active_cng_decoder_ >= 0 && active_cng_decoder_ != rtp_payload_type) { 222 // Moving from one active CNG decoder to another. Delete the first one. 223 DecoderMap::iterator it = decoders_.find(active_cng_decoder_); 224 if (it == decoders_.end()) { 225 // Decoder not found. This should not be possible. 226 assert(false); 227 return kDecoderNotFound; 228 } 229 if (!(*it).second.external) { 230 // Delete the AudioDecoder object, unless it is an externally created 231 // decoder. 232 delete (*it).second.decoder; 233 (*it).second.decoder = NULL; 234 } 235 } 236 active_cng_decoder_ = rtp_payload_type; 237 return kOK; 238 } 239 240 AudioDecoder* DecoderDatabase::GetActiveCngDecoder() { 241 if (active_cng_decoder_ < 0) { 242 // No active CNG decoder. 243 return NULL; 244 } 245 return GetDecoder(active_cng_decoder_); 246 } 247 248 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const { 249 PacketList::const_iterator it; 250 for (it = packet_list.begin(); it != packet_list.end(); ++it) { 251 if (decoders_.find((*it)->header.payloadType) == decoders_.end()) { 252 // Payload type is not found. 253 LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type " 254 << static_cast<int>((*it)->header.payloadType); 255 return kDecoderNotFound; 256 } 257 } 258 return kOK; 259 } 260 261 262 } // namespace webrtc 263