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 const rtc::scoped_refptr<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_); |
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 // Decoder not found. This should not be possible. |
kwiberg-webrtc
2016/08/25 10:53:20
The comment is redundant now.
ossu
2016/08/25 13:43:04
Acknowledged.
| |
239 // Decoder not found. This should not be possible. | 213 RTC_DCHECK(old_info); |
240 assert(false); | 214 old_info->DropDecoder(); |
241 return kDecoderNotFound; | |
242 } | |
243 it->second.DropDecoder(); | |
244 *new_decoder = true; | 215 *new_decoder = true; |
245 } | 216 } |
246 active_decoder_type_ = rtp_payload_type; | 217 active_decoder_type_ = rtp_payload_type; |
247 return kOK; | 218 return kOK; |
248 } | 219 } |
249 | 220 |
250 AudioDecoder* DecoderDatabase::GetActiveDecoder() { | 221 AudioDecoder* DecoderDatabase::GetActiveDecoder() const { |
251 if (active_decoder_type_ < 0) { | 222 if (active_decoder_type_ < 0) { |
252 // No active decoder. | 223 // No active decoder. |
253 return NULL; | 224 return NULL; |
254 } | 225 } |
255 return GetDecoder(active_decoder_type_); | 226 return GetDecoder(active_decoder_type_); |
256 } | 227 } |
257 | 228 |
258 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { | 229 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) { |
259 // Check that |rtp_payload_type| exists in the database. | 230 // Check that |rtp_payload_type| exists in the database. |
260 DecoderMap::const_iterator it = decoders_.find(rtp_payload_type); | 231 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); |
261 if (it == decoders_.end()) { | 232 if (!info) { |
262 // Decoder not found. | 233 // Decoder not found. |
263 return kDecoderNotFound; | 234 return kDecoderNotFound; |
264 } | 235 } |
265 if (active_cng_decoder_type_ >= 0 && | 236 if (active_cng_decoder_type_ >= 0 && |
266 active_cng_decoder_type_ != rtp_payload_type) { | 237 active_cng_decoder_type_ != rtp_payload_type) { |
267 // Moving from one active CNG decoder to another. Delete the first one. | 238 // Moving from one active CNG decoder to another. Delete the first one. |
268 DecoderMap::iterator it = decoders_.find(active_cng_decoder_type_); | 239 // Decoder not found. This should not be possible. |
kwiberg-webrtc
2016/08/25 10:53:20
Again, comment redundant.
ossu
2016/08/25 13:43:04
Acknowledged.
| |
269 if (it == decoders_.end()) { | 240 RTC_DCHECK(active_cng_decoder_); |
270 // Decoder not found. This should not be possible. | |
271 assert(false); | |
272 return kDecoderNotFound; | |
273 } | |
274 active_cng_decoder_.reset(); | 241 active_cng_decoder_.reset(); |
275 } | 242 } |
276 active_cng_decoder_type_ = rtp_payload_type; | 243 active_cng_decoder_type_ = rtp_payload_type; |
277 return kOK; | 244 return kOK; |
278 } | 245 } |
279 | 246 |
280 ComfortNoiseDecoder* DecoderDatabase::GetActiveCngDecoder() { | 247 ComfortNoiseDecoder* DecoderDatabase::GetActiveCngDecoder() const { |
281 if (active_cng_decoder_type_ < 0) { | 248 if (active_cng_decoder_type_ < 0) { |
282 // No active CNG decoder. | 249 // No active CNG decoder. |
283 return NULL; | 250 return NULL; |
284 } | 251 } |
285 if (!active_cng_decoder_) { | 252 if (!active_cng_decoder_) { |
286 active_cng_decoder_.reset(new ComfortNoiseDecoder); | 253 active_cng_decoder_.reset(new ComfortNoiseDecoder); |
287 } | 254 } |
288 return active_cng_decoder_.get(); | 255 return active_cng_decoder_.get(); |
289 } | 256 } |
290 | 257 |
258 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) const { | |
259 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); | |
260 return info ? info->GetDecoder() : nullptr; | |
261 } | |
262 | |
263 bool DecoderDatabase::IsType(uint8_t rtp_payload_type, | |
264 NetEqDecoder codec_type) const { | |
265 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); | |
266 return info && info->codec_type == codec_type; | |
267 } | |
268 | |
269 bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const { | |
270 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); | |
271 return info && info->IsComfortNoise(); | |
272 } | |
273 | |
274 bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const { | |
275 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); | |
276 return info && info->IsDtmf(); | |
277 } | |
278 | |
279 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const { | |
280 const DecoderInfo *info = GetDecoderInfo(rtp_payload_type); | |
281 return info && info->IsRed(); | |
282 } | |
283 | |
291 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const { | 284 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const { |
292 PacketList::const_iterator it; | 285 PacketList::const_iterator it; |
293 for (it = packet_list.begin(); it != packet_list.end(); ++it) { | 286 for (it = packet_list.begin(); it != packet_list.end(); ++it) { |
294 if (decoders_.find((*it)->header.payloadType) == decoders_.end()) { | 287 if (!GetDecoderInfo((*it)->header.payloadType)) { |
295 // Payload type is not found. | 288 // Payload type is not found. |
296 LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type " | 289 LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type " |
297 << static_cast<int>((*it)->header.payloadType); | 290 << static_cast<int>((*it)->header.payloadType); |
298 return kDecoderNotFound; | 291 return kDecoderNotFound; |
299 } | 292 } |
300 } | 293 } |
301 return kOK; | 294 return kOK; |
302 } | 295 } |
303 | 296 |
304 | 297 |
305 } // namespace webrtc | 298 } // namespace webrtc |
OLD | NEW |