Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: webrtc/modules/audio_coding/neteq/decoder_database.cc

Issue 2276913002: DecoderDatabase: Made several methods nonvirtual to minimize mockable interface (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Made CheckPayloadTypes nonvirtual. Turned the rest of DecoderDatabase getters const. Fixed a coupleā€¦ Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698