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

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

Issue 1459193002: Extract the parameters for the encoder stack from the CodecManager (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 1 month 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) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 bool CodecSupported(const CodecInst& codec) { 102 bool CodecSupported(const CodecInst& codec) {
103 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || 103 return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) ||
104 IsIlbc(codec) || IsG722(codec) || IsIsac(codec); 104 IsIlbc(codec) || IsG722(codec) || IsIsac(codec);
105 } 105 }
106 106
107 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; 107 const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0};
108 } // namespace 108 } // namespace
109 109
110 CodecManager::CodecManager() 110 CodecManager::CodecManager()
111 : dtx_enabled_(false), 111 : send_codec_inst_(kEmptyCodecInst), encoder_is_opus_(false) {
112 vad_mode_(VADNormal),
113 send_codec_inst_(kEmptyCodecInst),
114 red_enabled_(false),
115 codec_fec_enabled_(false),
116 encoder_is_opus_(false) {
117 // Register the default payload types for RED and CNG.
118 for (const CodecInst& ci : RentACodec::Database()) {
119 RentACodec::RegisterCngPayloadType(&cng_payload_types_, ci);
120 RentACodec::RegisterRedPayloadType(&red_payload_types_, ci);
121 }
122 thread_checker_.DetachFromThread(); 112 thread_checker_.DetachFromThread();
123 } 113 }
124 114
125 CodecManager::~CodecManager() = default; 115 CodecManager::~CodecManager() = default;
126 116
127 int CodecManager::RegisterEncoder(const CodecInst& send_codec) { 117 int CodecManager::RegisterEncoder(const CodecInst& send_codec) {
128 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 118 RTC_DCHECK(thread_checker_.CalledOnValidThread());
129 int codec_id = IsValidSendCodec(send_codec); 119 int codec_id = IsValidSendCodec(send_codec);
130 120
131 // Check for reported errors from function IsValidSendCodec(). 121 // Check for reported errors from function IsValidSendCodec().
132 if (codec_id < 0) { 122 if (codec_id < 0) {
133 return -1; 123 return -1;
134 } 124 }
135 125
136 int dummy_id = 0; 126 int dummy_id = 0;
137 switch (RentACodec::RegisterRedPayloadType(&red_payload_types_, send_codec)) { 127 switch (RentACodec::RegisterRedPayloadType(
128 &codec_stack_params_.red_payload_types, send_codec)) {
138 case RentACodec::RegistrationResult::kOk: 129 case RentACodec::RegistrationResult::kOk:
139 return 0; 130 return 0;
140 case RentACodec::RegistrationResult::kBadFreq: 131 case RentACodec::RegistrationResult::kBadFreq:
141 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, 132 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id,
142 "RegisterSendCodec() failed, invalid frequency for RED" 133 "RegisterSendCodec() failed, invalid frequency for RED"
143 " registration"); 134 " registration");
144 return -1; 135 return -1;
145 case RentACodec::RegistrationResult::kSkip: 136 case RentACodec::RegistrationResult::kSkip:
146 break; 137 break;
147 } 138 }
148 switch (RentACodec::RegisterCngPayloadType(&cng_payload_types_, send_codec)) { 139 switch (RentACodec::RegisterCngPayloadType(
140 &codec_stack_params_.cng_payload_types, send_codec)) {
149 case RentACodec::RegistrationResult::kOk: 141 case RentACodec::RegistrationResult::kOk:
150 return 0; 142 return 0;
151 case RentACodec::RegistrationResult::kBadFreq: 143 case RentACodec::RegistrationResult::kBadFreq:
152 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, 144 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id,
153 "RegisterSendCodec() failed, invalid frequency for CNG" 145 "RegisterSendCodec() failed, invalid frequency for CNG"
154 " registration"); 146 " registration");
155 return -1; 147 return -1;
156 case RentACodec::RegistrationResult::kSkip: 148 case RentACodec::RegistrationResult::kSkip:
157 break; 149 break;
158 } 150 }
159 151
160 // Set Stereo, and make sure VAD and DTX is turned off. 152 // Set Stereo, and make sure VAD and DTX is turned off.
161 if (send_codec.channels != 1) { 153 if (send_codec.channels != 1) {
162 if (dtx_enabled_) { 154 if (codec_stack_params_.use_cng) {
163 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, 155 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id,
164 "VAD/DTX is turned off, not supported when sending stereo."); 156 "VAD/DTX is turned off, not supported when sending stereo.");
165 } 157 }
166 dtx_enabled_ = false; 158 codec_stack_params_.use_cng = false;
167 } 159 }
168 160
169 // Check if the codec is already registered as send codec. 161 // Check if the codec is already registered as send codec.
170 bool new_codec = true; 162 bool new_codec = true;
171 if (CurrentEncoder()) { 163 if (CurrentEncoder()) {
172 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); 164 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_);
173 RTC_DCHECK(new_codec_id); 165 RTC_DCHECK(new_codec_id);
174 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); 166 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id);
175 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; 167 new_codec = !old_codec_id || *new_codec_id != *old_codec_id;
176 } 168 }
177 169
178 if (RedPayloadType(send_codec.plfreq) == -1) {
179 red_enabled_ = false;
180 }
181
182 encoder_is_opus_ = IsOpus(send_codec); 170 encoder_is_opus_ = IsOpus(send_codec);
183 171
184 if (new_codec) { 172 if (new_codec) {
185 // This is a new codec. Register it and return. 173 // This is a new codec. Register it and return.
186 RTC_DCHECK(CodecSupported(send_codec)); 174 RTC_DCHECK(CodecSupported(send_codec));
187 if (IsOpus(send_codec)) { 175 if (IsOpus(send_codec)) {
188 // VAD/DTX not supported. 176 // VAD/DTX not supported.
189 dtx_enabled_ = false; 177 codec_stack_params_.use_cng = false;
190 } 178 }
191 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); 179 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
192 if (!enc) 180 if (!enc)
193 return -1; 181 return -1;
194 RentEncoderStack(enc, send_codec.plfreq); 182 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_);
195 RTC_DCHECK(CurrentEncoder()); 183 RTC_DCHECK(CurrentEncoder());
196 184
197 codec_fec_enabled_ = codec_fec_enabled_ && 185 codec_stack_params_.use_codec_fec =
198 enc->SetFec(codec_fec_enabled_); 186 codec_stack_params_.use_codec_fec &&
187 enc->SetFec(codec_stack_params_.use_codec_fec);
199 188
200 send_codec_inst_ = send_codec; 189 send_codec_inst_ = send_codec;
201 return 0; 190 return 0;
202 } 191 }
203 192
204 // This is an existing codec; re-create it if any parameters have changed. 193 // This is an existing codec; re-create it if any parameters have changed.
205 if (send_codec_inst_.plfreq != send_codec.plfreq || 194 if (send_codec_inst_.plfreq != send_codec.plfreq ||
206 send_codec_inst_.pacsize != send_codec.pacsize || 195 send_codec_inst_.pacsize != send_codec.pacsize ||
207 send_codec_inst_.channels != send_codec.channels) { 196 send_codec_inst_.channels != send_codec.channels) {
208 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); 197 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
209 if (!enc) 198 if (!enc)
210 return -1; 199 return -1;
211 RentEncoderStack(enc, send_codec.plfreq); 200 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_);
212 RTC_DCHECK(CurrentEncoder()); 201 RTC_DCHECK(CurrentEncoder());
213 } 202 }
214 send_codec_inst_.plfreq = send_codec.plfreq; 203 send_codec_inst_.plfreq = send_codec.plfreq;
215 send_codec_inst_.pacsize = send_codec.pacsize; 204 send_codec_inst_.pacsize = send_codec.pacsize;
216 send_codec_inst_.channels = send_codec.channels; 205 send_codec_inst_.channels = send_codec.channels;
217 send_codec_inst_.pltype = send_codec.pltype; 206 send_codec_inst_.pltype = send_codec.pltype;
218 207
219 // Check if a change in Rate is required. 208 // Check if a change in Rate is required.
220 if (send_codec.rate != send_codec_inst_.rate) { 209 if (send_codec.rate != send_codec_inst_.rate) {
221 CurrentEncoder()->SetTargetBitrate(send_codec.rate); 210 CurrentEncoder()->SetTargetBitrate(send_codec.rate);
222 send_codec_inst_.rate = send_codec.rate; 211 send_codec_inst_.rate = send_codec.rate;
223 } 212 }
224 213
225 codec_fec_enabled_ = 214 codec_stack_params_.use_codec_fec =
226 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_); 215 codec_stack_params_.use_codec_fec &&
216 CurrentEncoder()->SetFec(codec_stack_params_.use_codec_fec);
227 217
228 return 0; 218 return 0;
229 } 219 }
230 220
231 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { 221 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) {
232 // Make up a CodecInst. 222 // Make up a CodecInst.
233 send_codec_inst_.channels = external_speech_encoder->NumChannels(); 223 send_codec_inst_.channels = external_speech_encoder->NumChannels();
234 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); 224 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz();
235 send_codec_inst_.pacsize = rtc::CheckedDivExact( 225 send_codec_inst_.pacsize = rtc::CheckedDivExact(
236 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * 226 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() *
237 send_codec_inst_.plfreq), 227 send_codec_inst_.plfreq),
238 100); 228 100);
239 send_codec_inst_.pltype = -1; // Not valid. 229 send_codec_inst_.pltype = -1; // Not valid.
240 send_codec_inst_.rate = -1; // Not valid. 230 send_codec_inst_.rate = -1; // Not valid.
241 static const char kName[] = "external"; 231 static const char kName[] = "external";
242 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); 232 memcpy(send_codec_inst_.plname, kName, sizeof(kName));
243 233
244 if (send_codec_inst_.channels != 1) 234 if (send_codec_inst_.channels != 1)
245 dtx_enabled_ = false; 235 codec_stack_params_.use_cng = false;
246 if (codec_fec_enabled_) { 236 if (codec_stack_params_.use_codec_fec) {
247 // Switch FEC on. On failure, remember that FEC is off. 237 // Switch FEC on. On failure, remember that FEC is off.
248 if (!external_speech_encoder->SetFec(true)) 238 if (!external_speech_encoder->SetFec(true))
249 codec_fec_enabled_ = false; 239 codec_stack_params_.use_codec_fec = false;
250 } else { 240 } else {
251 // Switch FEC off. This shouldn't fail. 241 // Switch FEC off. This shouldn't fail.
252 const bool success = external_speech_encoder->SetFec(false); 242 const bool success = external_speech_encoder->SetFec(false);
253 RTC_DCHECK(success); 243 RTC_DCHECK(success);
254 } 244 }
255 245
256 RentEncoderStack(external_speech_encoder, 246 rent_a_codec_.RentEncoderStack(external_speech_encoder, &codec_stack_params_);
257 external_speech_encoder->SampleRateHz());
258 } 247 }
259 248
260 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { 249 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const {
261 int dummy_id = 0; 250 int dummy_id = 0;
262 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 251 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
263 "SendCodec()"); 252 "SendCodec()");
264 253
265 if (!CurrentEncoder()) { 254 if (!CurrentEncoder()) {
266 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 255 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
267 "SendCodec Failed, no codec is registered"); 256 "SendCodec Failed, no codec is registered");
268 return rtc::Optional<CodecInst>(); 257 return rtc::Optional<CodecInst>();
269 } 258 }
270 return rtc::Optional<CodecInst>(send_codec_inst_); 259 return rtc::Optional<CodecInst>(send_codec_inst_);
271 } 260 }
272 261
273 bool CodecManager::SetCopyRed(bool enable) { 262 bool CodecManager::SetCopyRed(bool enable) {
274 if (enable && codec_fec_enabled_) { 263 if (enable && codec_stack_params_.use_codec_fec) {
275 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 264 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
276 "Codec internal FEC and RED cannot be co-enabled."); 265 "Codec internal FEC and RED cannot be co-enabled.");
277 return false; 266 return false;
278 } 267 }
279 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { 268 if (enable &&
269 codec_stack_params_.red_payload_types.count(send_codec_inst_.plfreq) <
270 1) {
280 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 271 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
281 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); 272 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq);
282 return false; 273 return false;
283 } 274 }
284 if (red_enabled_ != enable) { 275 if (codec_stack_params_.use_red != enable) {
285 red_enabled_ = enable; 276 codec_stack_params_.use_red = enable;
286 if (CurrentEncoder()) 277 if (CurrentEncoder())
287 RentEncoderStack(rent_a_codec_.GetEncoder(), send_codec_inst_.plfreq); 278 rent_a_codec_.RentEncoderStack(rent_a_codec_.GetEncoder(),
279 &codec_stack_params_);
288 } 280 }
289 return true; 281 return true;
290 } 282 }
291 283
292 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { 284 int CodecManager::SetVAD(bool enable, ACMVADMode mode) {
293 // Sanity check of the mode. 285 // Sanity check of the mode.
294 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || 286 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr ||
295 mode == VADVeryAggr); 287 mode == VADVeryAggr);
296 288
297 // Check that the send codec is mono. We don't support VAD/DTX for stereo 289 // Check that the send codec is mono. We don't support VAD/DTX for stereo
298 // sending. 290 // sending.
299 auto* enc = rent_a_codec_.GetEncoder(); 291 auto* enc = rent_a_codec_.GetEncoder();
300 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; 292 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false;
301 if (enable && stereo_send) { 293 if (enable && stereo_send) {
302 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, 294 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
303 "VAD/DTX not supported for stereo sending"); 295 "VAD/DTX not supported for stereo sending");
304 dtx_enabled_ = false; 296 codec_stack_params_.use_cng = false;
305 return -1; 297 return -1;
306 } 298 }
307 299
308 // If a send codec is registered, set VAD/DTX for the codec. 300 // If a send codec is registered, set VAD/DTX for the codec.
309 if (IsOpus(send_codec_inst_)) { 301 if (IsOpus(send_codec_inst_)) {
310 // VAD/DTX not supported. 302 // VAD/DTX not supported.
311 dtx_enabled_ = false; 303 codec_stack_params_.use_cng = false;
312 return 0; 304 return 0;
313 } 305 }
314 306
315 if (dtx_enabled_ != enable || vad_mode_ != mode) { 307 if (codec_stack_params_.use_cng != enable ||
316 dtx_enabled_ = enable; 308 codec_stack_params_.vad_mode != mode) {
317 vad_mode_ = mode; 309 codec_stack_params_.use_cng = enable;
310 codec_stack_params_.vad_mode = mode;
318 if (enc) 311 if (enc)
319 RentEncoderStack(enc, send_codec_inst_.plfreq); 312 rent_a_codec_.RentEncoderStack(enc, &codec_stack_params_);
320 } 313 }
321 return 0; 314 return 0;
322 } 315 }
323 316
324 void CodecManager::VAD(bool* dtx_enabled, 317 void CodecManager::VAD(bool* dtx_enabled,
325 bool* vad_enabled, 318 bool* vad_enabled,
326 ACMVADMode* mode) const { 319 ACMVADMode* mode) const {
327 *dtx_enabled = dtx_enabled_; 320 *dtx_enabled = *vad_enabled = codec_stack_params_.use_cng;
328 *vad_enabled = dtx_enabled_; 321 *mode = codec_stack_params_.vad_mode;
329 *mode = vad_mode_;
330 } 322 }
331 323
332 int CodecManager::SetCodecFEC(bool enable_codec_fec) { 324 int CodecManager::SetCodecFEC(bool enable_codec_fec) {
333 if (enable_codec_fec == true && red_enabled_ == true) { 325 if (enable_codec_fec && codec_stack_params_.use_red) {
334 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 326 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
335 "Codec internal FEC and RED cannot be co-enabled."); 327 "Codec internal FEC and RED cannot be co-enabled.");
336 return -1; 328 return -1;
337 } 329 }
338 330
339 RTC_CHECK(CurrentEncoder()); 331 RTC_CHECK(CurrentEncoder());
340 codec_fec_enabled_ = 332 codec_stack_params_.use_codec_fec =
341 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; 333 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec;
342 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; 334 return codec_stack_params_.use_codec_fec == enable_codec_fec ? 0 : -1;
343 } 335 }
344 336
345 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { 337 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) {
346 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; 338 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr;
347 } 339 }
348 340
349 int CodecManager::CngPayloadType(int rtp_timestamp_rate_hz) const {
350 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 ||
351 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000)
352 << rtp_timestamp_rate_hz << " Hz is not supported";
353 auto it = cng_payload_types_.find(rtp_timestamp_rate_hz);
354 return it == cng_payload_types_.end() ? -1 : it->second;
355 }
356
357 int CodecManager::RedPayloadType(int rtp_timestamp_rate_hz) const {
358 RTC_CHECK(rtp_timestamp_rate_hz == 8000 || rtp_timestamp_rate_hz == 16000 ||
359 rtp_timestamp_rate_hz == 32000 || rtp_timestamp_rate_hz == 48000)
360 << rtp_timestamp_rate_hz << " Hz is not supported";
361 auto it = red_payload_types_.find(rtp_timestamp_rate_hz);
362 return it == red_payload_types_.end() ? -1 : it->second;
363 }
364
365 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder,
366 int sample_rate_hz) {
367 auto cng_config =
368 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
369 CngPayloadType(sample_rate_hz), vad_mode_})
370 : rtc::Optional<RentACodec::CngConfig>();
371 auto red_pt = red_enabled_
372 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz))
373 : rtc::Optional<int>();
374 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt);
375 }
376
377 } // namespace acm2 341 } // namespace acm2
378 } // namespace webrtc 342 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/codec_manager.h ('k') | webrtc/modules/audio_coding/main/acm2/rent_a_codec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698