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

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc

Issue 1481493004: audio_coding: remove "main" directory (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased Created 5 years 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
(Empty)
1 /*
2 * Copyright (c) 2015 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/main/acm2/rent_a_codec.h"
12
13 #include "webrtc/base/logging.h"
14 #include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h"
15 #include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
16 #ifdef WEBRTC_CODEC_G722
17 #include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h"
18 #endif
19 #ifdef WEBRTC_CODEC_ILBC
20 #include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
21 #endif
22 #ifdef WEBRTC_CODEC_ISACFX
23 #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isac fix.h"
24 #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_encoder_isac fix.h"
25 #endif
26 #ifdef WEBRTC_CODEC_ISAC
27 #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isa c.h"
28 #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isa c.h"
29 #endif
30 #ifdef WEBRTC_CODEC_OPUS
31 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h"
32 #endif
33 #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
34 #ifdef WEBRTC_CODEC_RED
35 #include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
36 #endif
37 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
38 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
39
40 namespace webrtc {
41 namespace acm2 {
42
43 rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByParams(
44 const char* payload_name,
45 int sampling_freq_hz,
46 int channels) {
47 return CodecIdFromIndex(
48 ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels));
49 }
50
51 rtc::Optional<CodecInst> RentACodec::CodecInstById(CodecId codec_id) {
52 rtc::Optional<int> mi = CodecIndexFromId(codec_id);
53 return mi ? rtc::Optional<CodecInst>(Database()[*mi])
54 : rtc::Optional<CodecInst>();
55 }
56
57 rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByInst(
58 const CodecInst& codec_inst) {
59 return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst));
60 }
61
62 rtc::Optional<CodecInst> RentACodec::CodecInstByParams(const char* payload_name,
63 int sampling_freq_hz,
64 int channels) {
65 rtc::Optional<CodecId> codec_id =
66 CodecIdByParams(payload_name, sampling_freq_hz, channels);
67 if (!codec_id)
68 return rtc::Optional<CodecInst>();
69 rtc::Optional<CodecInst> ci = CodecInstById(*codec_id);
70 RTC_DCHECK(ci);
71
72 // Keep the number of channels from the function call. For most codecs it
73 // will be the same value as in default codec settings, but not for all.
74 ci->channels = channels;
75
76 return ci;
77 }
78
79 bool RentACodec::IsCodecValid(const CodecInst& codec_inst) {
80 return ACMCodecDB::CodecNumber(codec_inst) >= 0;
81 }
82
83 rtc::Optional<bool> RentACodec::IsSupportedNumChannels(CodecId codec_id,
84 int num_channels) {
85 auto i = CodecIndexFromId(codec_id);
86 return i ? rtc::Optional<bool>(
87 ACMCodecDB::codec_settings_[*i].channel_support >=
88 num_channels)
89 : rtc::Optional<bool>();
90 }
91
92 rtc::ArrayView<const CodecInst> RentACodec::Database() {
93 return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_,
94 NumberOfCodecs());
95 }
96
97 rtc::Optional<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId(
98 CodecId codec_id,
99 int num_channels) {
100 rtc::Optional<int> i = CodecIndexFromId(codec_id);
101 if (!i)
102 return rtc::Optional<NetEqDecoder>();
103 const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i];
104 return rtc::Optional<NetEqDecoder>(
105 (ned == NetEqDecoder::kDecoderOpus && num_channels == 2)
106 ? NetEqDecoder::kDecoderOpus_2ch
107 : ned);
108 }
109
110 RentACodec::RegistrationResult RentACodec::RegisterCngPayloadType(
111 std::map<int, int>* pt_map,
112 const CodecInst& codec_inst) {
113 if (STR_CASE_CMP(codec_inst.plname, "CN") != 0)
114 return RegistrationResult::kSkip;
115 switch (codec_inst.plfreq) {
116 case 8000:
117 case 16000:
118 case 32000:
119 case 48000:
120 (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
121 return RegistrationResult::kOk;
122 default:
123 return RegistrationResult::kBadFreq;
124 }
125 }
126
127 RentACodec::RegistrationResult RentACodec::RegisterRedPayloadType(
128 std::map<int, int>* pt_map,
129 const CodecInst& codec_inst) {
130 if (STR_CASE_CMP(codec_inst.plname, "RED") != 0)
131 return RegistrationResult::kSkip;
132 switch (codec_inst.plfreq) {
133 case 8000:
134 (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
135 return RegistrationResult::kOk;
136 default:
137 return RegistrationResult::kBadFreq;
138 }
139 }
140
141 namespace {
142
143 // Returns a new speech encoder, or null on error.
144 // TODO(kwiberg): Don't handle errors here (bug 5033)
145 rtc::scoped_ptr<AudioEncoder> CreateEncoder(
146 const CodecInst& speech_inst,
147 LockedIsacBandwidthInfo* bwinfo) {
148 #if defined(WEBRTC_CODEC_ISACFX)
149 if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
150 return rtc_make_scoped_ptr(new AudioEncoderIsacFix(speech_inst, bwinfo));
151 #endif
152 #if defined(WEBRTC_CODEC_ISAC)
153 if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
154 return rtc_make_scoped_ptr(new AudioEncoderIsac(speech_inst, bwinfo));
155 #endif
156 #ifdef WEBRTC_CODEC_OPUS
157 if (STR_CASE_CMP(speech_inst.plname, "opus") == 0)
158 return rtc_make_scoped_ptr(new AudioEncoderOpus(speech_inst));
159 #endif
160 if (STR_CASE_CMP(speech_inst.plname, "pcmu") == 0)
161 return rtc_make_scoped_ptr(new AudioEncoderPcmU(speech_inst));
162 if (STR_CASE_CMP(speech_inst.plname, "pcma") == 0)
163 return rtc_make_scoped_ptr(new AudioEncoderPcmA(speech_inst));
164 if (STR_CASE_CMP(speech_inst.plname, "l16") == 0)
165 return rtc_make_scoped_ptr(new AudioEncoderPcm16B(speech_inst));
166 #ifdef WEBRTC_CODEC_ILBC
167 if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0)
168 return rtc_make_scoped_ptr(new AudioEncoderIlbc(speech_inst));
169 #endif
170 #ifdef WEBRTC_CODEC_G722
171 if (STR_CASE_CMP(speech_inst.plname, "g722") == 0)
172 return rtc_make_scoped_ptr(new AudioEncoderG722(speech_inst));
173 #endif
174 LOG_F(LS_ERROR) << "Could not create encoder of type " << speech_inst.plname;
175 return rtc::scoped_ptr<AudioEncoder>();
176 }
177
178 rtc::scoped_ptr<AudioEncoder> CreateRedEncoder(AudioEncoder* encoder,
179 int red_payload_type) {
180 #ifdef WEBRTC_CODEC_RED
181 AudioEncoderCopyRed::Config config;
182 config.payload_type = red_payload_type;
183 config.speech_encoder = encoder;
184 return rtc::scoped_ptr<AudioEncoder>(new AudioEncoderCopyRed(config));
185 #else
186 return rtc::scoped_ptr<AudioEncoder>();
187 #endif
188 }
189
190 rtc::scoped_ptr<AudioEncoder> CreateCngEncoder(AudioEncoder* encoder,
191 int payload_type,
192 ACMVADMode vad_mode) {
193 AudioEncoderCng::Config config;
194 config.num_channels = encoder->NumChannels();
195 config.payload_type = payload_type;
196 config.speech_encoder = encoder;
197 switch (vad_mode) {
198 case VADNormal:
199 config.vad_mode = Vad::kVadNormal;
200 break;
201 case VADLowBitrate:
202 config.vad_mode = Vad::kVadLowBitrate;
203 break;
204 case VADAggr:
205 config.vad_mode = Vad::kVadAggressive;
206 break;
207 case VADVeryAggr:
208 config.vad_mode = Vad::kVadVeryAggressive;
209 break;
210 default:
211 FATAL();
212 }
213 return rtc::scoped_ptr<AudioEncoder>(new AudioEncoderCng(config));
214 }
215
216 rtc::scoped_ptr<AudioDecoder> CreateIsacDecoder(
217 LockedIsacBandwidthInfo* bwinfo) {
218 #if defined(WEBRTC_CODEC_ISACFX)
219 return rtc_make_scoped_ptr(new AudioDecoderIsacFix(bwinfo));
220 #elif defined(WEBRTC_CODEC_ISAC)
221 return rtc_make_scoped_ptr(new AudioDecoderIsac(bwinfo));
222 #else
223 FATAL() << "iSAC is not supported.";
224 return rtc::scoped_ptr<AudioDecoder>();
225 #endif
226 }
227
228 } // namespace
229
230 RentACodec::RentACodec() = default;
231 RentACodec::~RentACodec() = default;
232
233 AudioEncoder* RentACodec::RentEncoder(const CodecInst& codec_inst) {
234 rtc::scoped_ptr<AudioEncoder> enc =
235 CreateEncoder(codec_inst, &isac_bandwidth_info_);
236 if (!enc)
237 return nullptr;
238 speech_encoder_ = enc.Pass();
239 return speech_encoder_.get();
240 }
241
242 RentACodec::StackParameters::StackParameters() {
243 // Register the default payload types for RED and CNG.
244 for (const CodecInst& ci : RentACodec::Database()) {
245 RentACodec::RegisterCngPayloadType(&cng_payload_types, ci);
246 RentACodec::RegisterRedPayloadType(&red_payload_types, ci);
247 }
248 }
249
250 RentACodec::StackParameters::~StackParameters() = default;
251
252 AudioEncoder* RentACodec::RentEncoderStack(AudioEncoder* speech_encoder,
253 StackParameters* param) {
254 RTC_DCHECK(speech_encoder);
255
256 if (param->use_codec_fec) {
257 // Switch FEC on. On failure, remember that FEC is off.
258 if (!speech_encoder->SetFec(true))
259 param->use_codec_fec = false;
260 } else {
261 // Switch FEC off. This shouldn't fail.
262 const bool success = speech_encoder->SetFec(false);
263 RTC_DCHECK(success);
264 }
265
266 auto pt = [&speech_encoder](const std::map<int, int>& m) {
267 auto it = m.find(speech_encoder->SampleRateHz());
268 return it == m.end() ? rtc::Optional<int>()
269 : rtc::Optional<int>(it->second);
270 };
271 auto cng_pt = pt(param->cng_payload_types);
272 param->use_cng =
273 param->use_cng && cng_pt && speech_encoder->NumChannels() == 1;
274 auto red_pt = pt(param->red_payload_types);
275 param->use_red = param->use_red && red_pt;
276
277 if (param->use_cng || param->use_red) {
278 // The RED and CNG encoders need to be in sync with the speech encoder, so
279 // reset the latter to ensure its buffer is empty.
280 speech_encoder->Reset();
281 }
282 encoder_stack_ = speech_encoder;
283 if (param->use_red) {
284 red_encoder_ = CreateRedEncoder(encoder_stack_, *red_pt);
285 if (red_encoder_)
286 encoder_stack_ = red_encoder_.get();
287 } else {
288 red_encoder_.reset();
289 }
290 if (param->use_cng) {
291 cng_encoder_ = CreateCngEncoder(encoder_stack_, *cng_pt, param->vad_mode);
292 encoder_stack_ = cng_encoder_.get();
293 } else {
294 cng_encoder_.reset();
295 }
296 return encoder_stack_;
297 }
298
299 AudioDecoder* RentACodec::RentIsacDecoder() {
300 if (!isac_decoder_)
301 isac_decoder_ = CreateIsacDecoder(&isac_bandwidth_info_);
302 return isac_decoder_.get();
303 }
304
305 } // namespace acm2
306 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/rent_a_codec.h ('k') | webrtc/modules/audio_coding/main/acm2/rent_a_codec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698