OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" | 11 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" |
12 | 12 |
13 #include <assert.h> | |
14 #include <utility> // pair | 13 #include <utility> // pair |
15 | 14 |
16 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
18 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" | 17 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" |
19 | 18 |
20 namespace webrtc { | 19 namespace webrtc { |
21 | 20 |
22 DecoderDatabase::DecoderDatabase( | 21 DecoderDatabase::DecoderDatabase( |
23 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) | 22 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) |
24 : active_decoder_type_(-1), | 23 : active_decoder_type_(-1), |
25 active_cng_decoder_type_(-1), | 24 active_cng_decoder_type_(-1), |
26 decoder_factory_(decoder_factory) {} | 25 decoder_factory_(decoder_factory) {} |
27 | 26 |
28 DecoderDatabase::~DecoderDatabase() = default; | 27 DecoderDatabase::~DecoderDatabase() = default; |
29 | 28 |
30 DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct, | 29 DecoderDatabase::DecoderInfo::DecoderInfo( |
31 const std::string& nm) | 30 NetEqDecoder ct, |
| 31 const std::string& nm, |
| 32 AudioDecoderFactory* factory) |
32 : codec_type(ct), | 33 : codec_type(ct), |
33 name(nm), | 34 name(nm), |
34 audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), | 35 audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), |
| 36 factory_(factory), |
35 external_decoder_(nullptr), | 37 external_decoder_(nullptr), |
36 cng_decoder_(CngDecoder::Create(ct)) {} | 38 cng_decoder_(CngDecoder::Create(ct)) {} |
37 | 39 |
38 DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct, | 40 DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct, |
39 const std::string& nm, | 41 const std::string& nm, |
40 AudioDecoder* ext_dec) | 42 AudioDecoder* ext_dec) |
41 : codec_type(ct), | 43 : codec_type(ct), |
42 name(nm), | 44 name(nm), |
43 audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), | 45 audio_format_(acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct)), |
44 external_decoder_(ext_dec) { | 46 external_decoder_(ext_dec) { |
45 RTC_CHECK(ext_dec); | 47 RTC_CHECK(ext_dec); |
46 } | 48 } |
47 | 49 |
48 DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default; | 50 DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default; |
49 DecoderDatabase::DecoderInfo::~DecoderInfo() = default; | 51 DecoderDatabase::DecoderInfo::~DecoderInfo() = default; |
50 | 52 |
51 AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder( | 53 AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder() const { |
52 AudioDecoderFactory* factory) { | |
53 if (external_decoder_) { | 54 if (external_decoder_) { |
54 RTC_DCHECK(!decoder_); | 55 RTC_DCHECK(!decoder_); |
55 RTC_DCHECK(!cng_decoder_); | 56 RTC_DCHECK(!cng_decoder_); |
56 return external_decoder_; | 57 return external_decoder_; |
57 } | 58 } |
| 59 if (IsRed() || IsComfortNoise() || IsDtmf()) |
| 60 return nullptr; |
58 RTC_DCHECK(audio_format_); | 61 RTC_DCHECK(audio_format_); |
59 if (!decoder_) { | 62 if (!decoder_) { |
60 decoder_ = factory->MakeAudioDecoder(*audio_format_); | 63 RTC_DCHECK(factory_); |
| 64 decoder_ = factory_->MakeAudioDecoder(*audio_format_); |
61 } | 65 } |
62 RTC_DCHECK(decoder_) << "Failed to create: " << *audio_format_; | 66 RTC_DCHECK(decoder_) << "Failed to create: " << *audio_format_; |
63 return decoder_.get(); | 67 return decoder_.get(); |
64 } | 68 } |
65 | 69 |
| 70 |
| 71 bool DecoderDatabase::DecoderInfo::IsComfortNoise() const { |
| 72 return codec_type == NetEqDecoder::kDecoderCNGnb |
| 73 || codec_type == NetEqDecoder::kDecoderCNGwb |
| 74 || codec_type == NetEqDecoder::kDecoderCNGswb32kHz |
| 75 || codec_type == NetEqDecoder::kDecoderCNGswb48kHz; |
| 76 } |
| 77 |
| 78 bool DecoderDatabase::DecoderInfo::IsDtmf() const { |
| 79 return codec_type == NetEqDecoder::kDecoderAVT; |
| 80 } |
| 81 |
| 82 bool DecoderDatabase::DecoderInfo::IsRed() const { |
| 83 return codec_type == NetEqDecoder::kDecoderRED; |
| 84 } |
| 85 |
66 rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder> | 86 rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder> |
67 DecoderDatabase::DecoderInfo::CngDecoder::Create(NetEqDecoder ct) { | 87 DecoderDatabase::DecoderInfo::CngDecoder::Create(NetEqDecoder ct) { |
68 const auto cng = [](int sample_rate_hz) { | 88 const auto cng = [](int sample_rate_hz) { |
69 return rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder>( | 89 return rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder>( |
70 {sample_rate_hz}); | 90 {sample_rate_hz}); |
71 }; | 91 }; |
72 switch (ct) { | 92 switch (ct) { |
73 case NetEqDecoder::kDecoderCNGnb: | 93 case NetEqDecoder::kDecoderCNGnb: |
74 return cng(8000); | 94 return cng(8000); |
75 case NetEqDecoder::kDecoderCNGwb: | 95 case NetEqDecoder::kDecoderCNGwb: |
(...skipping 19 matching lines...) Expand all Loading... |
95 | 115 |
96 int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, | 116 int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, |
97 NetEqDecoder codec_type, | 117 NetEqDecoder codec_type, |
98 const std::string& name) { | 118 const std::string& name) { |
99 if (rtp_payload_type > 0x7F) { | 119 if (rtp_payload_type > 0x7F) { |
100 return kInvalidRtpPayloadType; | 120 return kInvalidRtpPayloadType; |
101 } | 121 } |
102 if (!CodecSupported(codec_type)) { | 122 if (!CodecSupported(codec_type)) { |
103 return kCodecNotSupported; | 123 return kCodecNotSupported; |
104 } | 124 } |
105 DecoderInfo info(codec_type, name); | 125 DecoderInfo info(codec_type, name, decoder_factory_.get()); |
106 auto ret = | 126 auto ret = |
107 decoders_.insert(std::make_pair(rtp_payload_type, std::move(info))); | 127 decoders_.insert(std::make_pair(rtp_payload_type, std::move(info))); |
108 if (ret.second == false) { | 128 if (ret.second == false) { |
109 // Database already contains a decoder with type |rtp_payload_type|. | 129 // Database already contains a decoder with type |rtp_payload_type|. |
110 return kDecoderExists; | 130 return kDecoderExists; |
111 } | 131 } |
112 return kOK; | 132 return kOK; |
113 } | 133 } |
114 | 134 |
115 int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, | 135 int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 for (it = decoders_.begin(); it != decoders_.end(); ++it) { | 185 for (it = decoders_.begin(); it != decoders_.end(); ++it) { |
166 if ((*it).second.codec_type == codec_type) { | 186 if ((*it).second.codec_type == codec_type) { |
167 // Match found. | 187 // Match found. |
168 return (*it).first; | 188 return (*it).first; |
169 } | 189 } |
170 } | 190 } |
171 // No match. | 191 // No match. |
172 return kRtpPayloadTypeError; | 192 return kRtpPayloadTypeError; |
173 } | 193 } |
174 | 194 |
175 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) { | |
176 if (IsDtmf(rtp_payload_type) || IsRed(rtp_payload_type) || | |
177 IsComfortNoise(rtp_payload_type)) { | |
178 // These are not real decoders. | |
179 return NULL; | |
180 } | |
181 DecoderMap::iterator it = decoders_.find(rtp_payload_type); | |
182 if (it == decoders_.end()) { | |
183 // Decoder not found. | |
184 return NULL; | |
185 } | |
186 DecoderInfo* info = &(*it).second; | |
187 return info->GetDecoder(decoder_factory_.get()); | |
188 } | |
189 | |
190 bool DecoderDatabase::IsType(uint8_t rtp_payload_type, | |
191 NetEqDecoder codec_type) const { | |
192 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); | |
193 if (it == decoders_.end()) { | |
194 // Decoder not found. | |
195 return false; | |
196 } | |
197 return ((*it).second.codec_type == codec_type); | |
198 } | |
199 | |
200 bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const { | |
201 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); | |
202 if (it == decoders_.end()) { | |
203 // Decoder not found. | |
204 return false; | |
205 } | |
206 const auto& type = it->second.codec_type; | |
207 return type == NetEqDecoder::kDecoderCNGnb | |
208 || type == NetEqDecoder::kDecoderCNGwb | |
209 || type == NetEqDecoder::kDecoderCNGswb32kHz | |
210 || type == NetEqDecoder::kDecoderCNGswb48kHz; | |
211 } | |
212 | |
213 bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const { | |
214 return IsType(rtp_payload_type, NetEqDecoder::kDecoderAVT); | |
215 } | |
216 | |
217 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const { | |
218 return IsType(rtp_payload_type, NetEqDecoder::kDecoderRED); | |
219 } | |
220 | |
221 int DecoderDatabase::SetActiveDecoder(uint8_t rtp_payload_type, | 195 int DecoderDatabase::SetActiveDecoder(uint8_t rtp_payload_type, |
222 bool* new_decoder) { | 196 bool* new_decoder) { |
223 // Check that |rtp_payload_type| exists in the database. | 197 // Check that |rtp_payload_type| exists in the database. |
224 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); | 198 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
225 if (it == decoders_.end()) { | 199 if (!info) { |
226 // Decoder not found. | 200 // Decoder not found. |
227 return kDecoderNotFound; | 201 return kDecoderNotFound; |
228 } | 202 } |
229 RTC_CHECK(!IsComfortNoise(rtp_payload_type)); | 203 RTC_CHECK(!info->IsComfortNoise()); |
230 assert(new_decoder); | 204 RTC_DCHECK(new_decoder); |
231 *new_decoder = false; | 205 *new_decoder = false; |
232 if (active_decoder_type_ < 0) { | 206 if (active_decoder_type_ < 0) { |
233 // This is the first active decoder. | 207 // This is the first active decoder. |
234 *new_decoder = true; | 208 *new_decoder = true; |
235 } else if (active_decoder_type_ != rtp_payload_type) { | 209 } else if (active_decoder_type_ != rtp_payload_type) { |
236 // Moving from one active decoder to another. Delete the first one. | 210 // Moving from one active decoder to another. Delete the first one. |
237 DecoderMap::iterator it = decoders_.find(active_decoder_type_); | 211 const DecoderInfo *old_info = GetDecoderInfo(active_decoder_type_); |
238 if (it == decoders_.end()) { | 212 RTC_DCHECK(old_info); |
239 // Decoder not found. This should not be possible. | 213 old_info->DropDecoder(); |
240 assert(false); | |
241 return kDecoderNotFound; | |
242 } | |
243 it->second.DropDecoder(); | |
244 *new_decoder = true; | 214 *new_decoder = true; |
245 } | 215 } |
246 active_decoder_type_ = rtp_payload_type; | 216 active_decoder_type_ = rtp_payload_type; |
247 return kOK; | 217 return kOK; |
248 } | 218 } |
249 | 219 |
250 AudioDecoder* DecoderDatabase::GetActiveDecoder() { | 220 AudioDecoder* DecoderDatabase::GetActiveDecoder() const { |
251 if (active_decoder_type_ < 0) { | 221 if (active_decoder_type_ < 0) { |
252 // No active decoder. | 222 // No active decoder. |
253 return NULL; | 223 return NULL; |
254 } | 224 } |
255 return GetDecoder(active_decoder_type_); | 225 return GetDecoder(active_decoder_type_); |
256 } | 226 } |
257 | 227 |
258 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { | 228 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { |
259 // Check that |rtp_payload_type| exists in the database. | 229 // Check that |rtp_payload_type| exists in the database. |
260 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); | 230 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
261 if (it == decoders_.end()) { | 231 if (!info) { |
262 // Decoder not found. | 232 // Decoder not found. |
263 return kDecoderNotFound; | 233 return kDecoderNotFound; |
264 } | 234 } |
265 if (active_cng_decoder_type_ >= 0 && | 235 if (active_cng_decoder_type_ >= 0 && |
266 active_cng_decoder_type_ != rtp_payload_type) { | 236 active_cng_decoder_type_ != rtp_payload_type) { |
267 // Moving from one active CNG decoder to another. Delete the first one. | 237 // Moving from one active CNG decoder to another. Delete the first one. |
268 DecoderMap::iterator it = decoders_.find(active_cng_decoder_type_); | 238 RTC_DCHECK(active_cng_decoder_); |
269 if (it == decoders_.end()) { | |
270 // Decoder not found. This should not be possible. | |
271 assert(false); | |
272 return kDecoderNotFound; | |
273 } | |
274 active_cng_decoder_.reset(); | 239 active_cng_decoder_.reset(); |
275 } | 240 } |
276 active_cng_decoder_type_ = rtp_payload_type; | 241 active_cng_decoder_type_ = rtp_payload_type; |
277 return kOK; | 242 return kOK; |
278 } | 243 } |
279 | 244 |
280 ComfortNoiseDecoder* DecoderDatabase::GetActiveCngDecoder() { | 245 ComfortNoiseDecoder* DecoderDatabase::GetActiveCngDecoder() const { |
281 if (active_cng_decoder_type_ < 0) { | 246 if (active_cng_decoder_type_ < 0) { |
282 // No active CNG decoder. | 247 // No active CNG decoder. |
283 return NULL; | 248 return NULL; |
284 } | 249 } |
285 if (!active_cng_decoder_) { | 250 if (!active_cng_decoder_) { |
286 active_cng_decoder_.reset(new ComfortNoiseDecoder); | 251 active_cng_decoder_.reset(new ComfortNoiseDecoder); |
287 } | 252 } |
288 return active_cng_decoder_.get(); | 253 return active_cng_decoder_.get(); |
289 } | 254 } |
290 | 255 |
| 256 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) const { |
| 257 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
| 258 return info ? info->GetDecoder() : nullptr; |
| 259 } |
| 260 |
| 261 bool DecoderDatabase::IsType(uint8_t rtp_payload_type, |
| 262 NetEqDecoder codec_type) const { |
| 263 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
| 264 return info && info->codec_type == codec_type; |
| 265 } |
| 266 |
| 267 bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const { |
| 268 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
| 269 return info && info->IsComfortNoise(); |
| 270 } |
| 271 |
| 272 bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const { |
| 273 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
| 274 return info && info->IsDtmf(); |
| 275 } |
| 276 |
| 277 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const { |
| 278 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
| 279 return info && info->IsRed(); |
| 280 } |
| 281 |
291 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const { | 282 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const { |
292 PacketList::const_iterator it; | 283 PacketList::const_iterator it; |
293 for (it = packet_list.begin(); it != packet_list.end(); ++it) { | 284 for (it = packet_list.begin(); it != packet_list.end(); ++it) { |
294 if (decoders_.find((*it)->header.payloadType) == decoders_.end()) { | 285 if (!GetDecoderInfo((*it)->header.payloadType)) { |
295 // Payload type is not found. | 286 // Payload type is not found. |
296 LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type " | 287 LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type " |
297 << static_cast<int>((*it)->header.payloadType); | 288 << static_cast<int>((*it)->header.payloadType); |
298 return kDecoderNotFound; | 289 return kDecoderNotFound; |
299 } | 290 } |
300 } | 291 } |
301 return kOK; | 292 return kOK; |
302 } | 293 } |
303 | 294 |
304 | 295 |
305 } // namespace webrtc | 296 } // namespace webrtc |
OLD | NEW |