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/modules/audio_coding/neteq/interface/audio_decoder.h" 17 18 namespace webrtc { 19 20 DecoderDatabase::DecoderDatabase() 21 : active_decoder_(-1), active_cng_decoder_(-1) {} 22 23 DecoderDatabase::~DecoderDatabase() {} 24 25 DecoderDatabase::DecoderInfo::~DecoderInfo() { 26 if (!external) delete decoder; 27 } 28 29 bool DecoderDatabase::Empty() const { return decoders_.empty(); } 30 31 int DecoderDatabase::Size() const { return static_cast<int>(decoders_.size()); } 32 33 void DecoderDatabase::Reset() { 34 decoders_.clear(); 35 active_decoder_ = -1; 36 active_cng_decoder_ = -1; 37 } 38 39 int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, 40 NetEqDecoder codec_type) { 41 if (rtp_payload_type > kMaxRtpPayloadType) { 42 return kInvalidRtpPayloadType; 43 } 44 if (!AudioDecoder::CodecSupported(codec_type)) { 45 return kCodecNotSupported; 46 } 47 int fs_hz = AudioDecoder::CodecSampleRateHz(codec_type); 48 std::pair<DecoderMap::iterator, bool> ret; 49 DecoderInfo info(codec_type, fs_hz, NULL, false); 50 ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); 51 if (ret.second == false) { 52 // Database already contains a decoder with type |rtp_payload_type|. 53 return kDecoderExists; 54 } 55 return kOK; 56 } 57 58 int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, 59 NetEqDecoder codec_type, 60 int fs_hz, 61 AudioDecoder* decoder) { 62 if (rtp_payload_type > 0x7F) { 63 return kInvalidRtpPayloadType; 64 } 65 if (!AudioDecoder::CodecSupported(codec_type)) { 66 return kCodecNotSupported; 67 } 68 if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) { 69 return kInvalidSampleRate; 70 } 71 if (!decoder) { 72 return kInvalidPointer; 73 } 74 decoder->Init(); 75 std::pair<DecoderMap::iterator, bool> ret; 76 DecoderInfo info(codec_type, fs_hz, decoder, true); 77 ret = decoders_.insert( 78 std::pair<uint8_t, DecoderInfo>(rtp_payload_type, info)); 79 if (ret.second == false) { 80 // Database already contains a decoder with type |rtp_payload_type|. 81 return kDecoderExists; 82 } 83 return kOK; 84 } 85 86 int DecoderDatabase::Remove(uint8_t rtp_payload_type) { 87 if (decoders_.erase(rtp_payload_type) == 0) { 88 // No decoder with that |rtp_payload_type|. 89 return kDecoderNotFound; 90 } 91 if (active_decoder_ == rtp_payload_type) { 92 active_decoder_ = -1; // No active decoder. 93 } 94 if (active_cng_decoder_ == rtp_payload_type) { 95 active_cng_decoder_ = -1; // No active CNG decoder. 96 } 97 return kOK; 98 } 99 100 const DecoderDatabase::DecoderInfo* DecoderDatabase::GetDecoderInfo( 101 uint8_t rtp_payload_type) const { 102 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); 103 if (it == decoders_.end()) { 104 // Decoder not found. 105 return NULL; 106 } 107 return &(*it).second; 108 } 109 110 uint8_t DecoderDatabase::GetRtpPayloadType( 111 NetEqDecoder codec_type) const { 112 DecoderMap::const_iterator it; 113 for (it = decoders_.begin(); it != decoders_.end(); ++it) { 114 if ((*it).second.codec_type == codec_type) { 115 // Match found. 116 return (*it).first; 117 } 118 } 119 // No match. 120 return kRtpPayloadTypeError; 121 } 122 123 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) { 124 if (IsDtmf(rtp_payload_type) || IsRed(rtp_payload_type)) { 125 // These are not real decoders. 126 return NULL; 127 } 128 DecoderMap::iterator it = decoders_.find(rtp_payload_type); 129 if (it == decoders_.end()) { 130 // Decoder not found. 131 return NULL; 132 } 133 DecoderInfo* info = &(*it).second; 134 if (!info->decoder) { 135 // Create the decoder object. 136 AudioDecoder* decoder = AudioDecoder::CreateAudioDecoder(info->codec_type); 137 assert(decoder); // Should not be able to have an unsupported codec here. 138 info->decoder = decoder; 139 info->decoder->Init(); 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, kDecoderCNGnb) || 156 IsType(rtp_payload_type, kDecoderCNGwb) || 157 IsType(rtp_payload_type, kDecoderCNGswb32kHz) || 158 IsType(rtp_payload_type, 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, kDecoderAVT); 167 } 168 169 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const { 170 return IsType(rtp_payload_type, 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 return kDecoderNotFound; 254 } 255 } 256 return kOK; 257 } 258 259 260 } // namespace webrtc 261