OLD | NEW |
---|---|
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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 if (send_codec.channels != 1) { | 233 if (send_codec.channels != 1) { |
234 if (dtx_enabled_) { | 234 if (dtx_enabled_) { |
235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, | 235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, |
236 "VAD/DTX is turned off, not supported when sending stereo."); | 236 "VAD/DTX is turned off, not supported when sending stereo."); |
237 } | 237 } |
238 dtx_enabled_ = false; | 238 dtx_enabled_ = false; |
239 } | 239 } |
240 | 240 |
241 // Check if the codec is already registered as send codec. | 241 // Check if the codec is already registered as send codec. |
242 bool new_codec = true; | 242 bool new_codec = true; |
243 if (codec_owner_.Encoder()) { | 243 if (CurrentEncoder()) { |
244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); | 244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); |
245 RTC_DCHECK(new_codec_id); | 245 RTC_DCHECK(new_codec_id); |
246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); | 246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); |
247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; | 247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; |
248 } | 248 } |
249 | 249 |
250 if (RedPayloadType(send_codec.plfreq) == -1) { | 250 if (RedPayloadType(send_codec.plfreq) == -1) { |
251 red_enabled_ = false; | 251 red_enabled_ = false; |
252 } | 252 } |
253 | 253 |
254 encoder_is_opus_ = IsOpus(send_codec); | 254 encoder_is_opus_ = IsOpus(send_codec); |
255 | 255 |
256 if (new_codec) { | 256 if (new_codec) { |
257 // This is a new codec. Register it and return. | 257 // This is a new codec. Register it and return. |
258 RTC_DCHECK(CodecSupported(send_codec)); | 258 RTC_DCHECK(CodecSupported(send_codec)); |
259 if (IsOpus(send_codec)) { | 259 if (IsOpus(send_codec)) { |
260 // VAD/DTX not supported. | 260 // VAD/DTX not supported. |
261 dtx_enabled_ = false; | 261 dtx_enabled_ = false; |
262 } | 262 } |
263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
264 if (!enc) | 264 if (!enc) |
265 return -1; | 265 return -1; |
266 codec_owner_.SetEncoders( | 266 RentEncoderStack(enc, send_codec.plfreq); |
267 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, | 267 RTC_DCHECK(CurrentEncoder()); |
268 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); | |
269 RTC_DCHECK(codec_owner_.Encoder()); | |
270 | 268 |
271 codec_fec_enabled_ = codec_fec_enabled_ && | 269 codec_fec_enabled_ = codec_fec_enabled_ && |
272 enc->SetFec(codec_fec_enabled_); | 270 enc->SetFec(codec_fec_enabled_); |
273 | 271 |
274 send_codec_inst_ = send_codec; | 272 send_codec_inst_ = send_codec; |
275 return 0; | 273 return 0; |
276 } | 274 } |
277 | 275 |
278 // This is an existing codec; re-create it if any parameters have changed. | 276 // This is an existing codec; re-create it if any parameters have changed. |
279 if (send_codec_inst_.plfreq != send_codec.plfreq || | 277 if (send_codec_inst_.plfreq != send_codec.plfreq || |
280 send_codec_inst_.pacsize != send_codec.pacsize || | 278 send_codec_inst_.pacsize != send_codec.pacsize || |
281 send_codec_inst_.channels != send_codec.channels) { | 279 send_codec_inst_.channels != send_codec.channels) { |
282 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); | 280 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); |
283 if (!enc) | 281 if (!enc) |
284 return -1; | 282 return -1; |
285 codec_owner_.SetEncoders( | 283 RentEncoderStack(enc, send_codec.plfreq); |
286 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, | 284 RTC_DCHECK(CurrentEncoder()); |
287 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); | |
288 RTC_DCHECK(codec_owner_.Encoder()); | |
289 } | 285 } |
290 send_codec_inst_.plfreq = send_codec.plfreq; | 286 send_codec_inst_.plfreq = send_codec.plfreq; |
291 send_codec_inst_.pacsize = send_codec.pacsize; | 287 send_codec_inst_.pacsize = send_codec.pacsize; |
292 send_codec_inst_.channels = send_codec.channels; | 288 send_codec_inst_.channels = send_codec.channels; |
293 send_codec_inst_.pltype = send_codec.pltype; | 289 send_codec_inst_.pltype = send_codec.pltype; |
294 | 290 |
295 // Check if a change in Rate is required. | 291 // Check if a change in Rate is required. |
296 if (send_codec.rate != send_codec_inst_.rate) { | 292 if (send_codec.rate != send_codec_inst_.rate) { |
297 codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); | 293 CurrentEncoder()->SetTargetBitrate(send_codec.rate); |
298 send_codec_inst_.rate = send_codec.rate; | 294 send_codec_inst_.rate = send_codec.rate; |
299 } | 295 } |
300 | 296 |
301 codec_fec_enabled_ = | 297 codec_fec_enabled_ = |
302 codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); | 298 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_); |
303 | 299 |
304 return 0; | 300 return 0; |
305 } | 301 } |
306 | 302 |
307 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { | 303 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { |
308 // Make up a CodecInst. | 304 // Make up a CodecInst. |
309 send_codec_inst_.channels = external_speech_encoder->NumChannels(); | 305 send_codec_inst_.channels = external_speech_encoder->NumChannels(); |
310 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); | 306 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); |
311 send_codec_inst_.pacsize = rtc::CheckedDivExact( | 307 send_codec_inst_.pacsize = rtc::CheckedDivExact( |
312 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * | 308 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * |
313 send_codec_inst_.plfreq), | 309 send_codec_inst_.plfreq), |
314 100); | 310 100); |
315 send_codec_inst_.pltype = -1; // Not valid. | 311 send_codec_inst_.pltype = -1; // Not valid. |
316 send_codec_inst_.rate = -1; // Not valid. | 312 send_codec_inst_.rate = -1; // Not valid. |
317 static const char kName[] = "external"; | 313 static const char kName[] = "external"; |
318 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); | 314 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); |
319 | 315 |
320 if (send_codec_inst_.channels != 1) | 316 if (send_codec_inst_.channels != 1) |
321 dtx_enabled_ = false; | 317 dtx_enabled_ = false; |
322 if (codec_fec_enabled_) { | 318 if (codec_fec_enabled_) { |
323 // Switch FEC on. On failure, remember that FEC is off. | 319 // Switch FEC on. On failure, remember that FEC is off. |
324 if (!external_speech_encoder->SetFec(true)) | 320 if (!external_speech_encoder->SetFec(true)) |
325 codec_fec_enabled_ = false; | 321 codec_fec_enabled_ = false; |
326 } else { | 322 } else { |
327 // Switch FEC off. This shouldn't fail. | 323 // Switch FEC off. This shouldn't fail. |
328 const bool success = external_speech_encoder->SetFec(false); | 324 const bool success = external_speech_encoder->SetFec(false); |
329 RTC_DCHECK(success); | 325 RTC_DCHECK(success); |
330 } | 326 } |
331 int cng_pt = dtx_enabled_ | 327 |
332 ? CngPayloadType(external_speech_encoder->SampleRateHz()) | 328 RentEncoderStack(external_speech_encoder, |
333 : -1; | 329 external_speech_encoder->SampleRateHz()); |
334 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | |
335 codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt); | |
336 } | 330 } |
337 | 331 |
338 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { | 332 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { |
339 int dummy_id = 0; | 333 int dummy_id = 0; |
340 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 334 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
341 "SendCodec()"); | 335 "SendCodec()"); |
342 | 336 |
343 if (!codec_owner_.Encoder()) { | 337 if (!CurrentEncoder()) { |
344 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, | 338 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, |
345 "SendCodec Failed, no codec is registered"); | 339 "SendCodec Failed, no codec is registered"); |
346 return rtc::Optional<CodecInst>(); | 340 return rtc::Optional<CodecInst>(); |
347 } | 341 } |
348 return rtc::Optional<CodecInst>(send_codec_inst_); | 342 return rtc::Optional<CodecInst>(send_codec_inst_); |
349 } | 343 } |
350 | 344 |
351 bool CodecManager::SetCopyRed(bool enable) { | 345 bool CodecManager::SetCopyRed(bool enable) { |
352 if (enable && codec_fec_enabled_) { | 346 if (enable && codec_fec_enabled_) { |
353 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 347 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
354 "Codec internal FEC and RED cannot be co-enabled."); | 348 "Codec internal FEC and RED cannot be co-enabled."); |
355 return false; | 349 return false; |
356 } | 350 } |
357 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { | 351 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { |
358 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 352 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
359 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); | 353 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); |
360 return false; | 354 return false; |
361 } | 355 } |
362 if (red_enabled_ != enable) { | 356 if (red_enabled_ != enable) { |
363 red_enabled_ = enable; | 357 red_enabled_ = enable; |
364 if (codec_owner_.Encoder()) { | 358 if (CurrentEncoder()) |
365 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; | 359 RentEncoderStack(rent_a_codec_.GetEncoder(), send_codec_inst_.plfreq); |
366 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | |
367 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); | |
368 } | |
369 } | 360 } |
370 return true; | 361 return true; |
371 } | 362 } |
372 | 363 |
373 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { | 364 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { |
374 // Sanity check of the mode. | 365 // Sanity check of the mode. |
375 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || | 366 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || |
376 mode == VADVeryAggr); | 367 mode == VADVeryAggr); |
377 | 368 |
378 // Check that the send codec is mono. We don't support VAD/DTX for stereo | 369 // Check that the send codec is mono. We don't support VAD/DTX for stereo |
379 // sending. | 370 // sending. |
380 const auto* enc = codec_owner_.Encoder(); | 371 auto* enc = rent_a_codec_.GetEncoder(); |
381 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; | 372 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; |
382 if (enable && stereo_send) { | 373 if (enable && stereo_send) { |
383 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, | 374 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, |
384 "VAD/DTX not supported for stereo sending"); | 375 "VAD/DTX not supported for stereo sending"); |
385 dtx_enabled_ = false; | 376 dtx_enabled_ = false; |
386 return -1; | 377 return -1; |
387 } | 378 } |
388 | 379 |
389 // If a send codec is registered, set VAD/DTX for the codec. | 380 // If a send codec is registered, set VAD/DTX for the codec. |
390 if (IsOpus(send_codec_inst_)) { | 381 if (IsOpus(send_codec_inst_)) { |
391 // VAD/DTX not supported. | 382 // VAD/DTX not supported. |
392 dtx_enabled_ = false; | 383 dtx_enabled_ = false; |
393 return 0; | 384 return 0; |
394 } | 385 } |
395 | 386 |
396 if (dtx_enabled_ != enable || vad_mode_ != mode) { | 387 if (dtx_enabled_ != enable || vad_mode_ != mode) { |
397 dtx_enabled_ = enable; | 388 dtx_enabled_ = enable; |
398 vad_mode_ = mode; | 389 vad_mode_ = mode; |
399 if (enc) { | 390 if (enc) |
400 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; | 391 RentEncoderStack(enc, send_codec_inst_.plfreq); |
401 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; | |
402 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); | |
403 } | |
404 } | 392 } |
405 return 0; | 393 return 0; |
406 } | 394 } |
407 | 395 |
408 void CodecManager::VAD(bool* dtx_enabled, | 396 void CodecManager::VAD(bool* dtx_enabled, |
409 bool* vad_enabled, | 397 bool* vad_enabled, |
410 ACMVADMode* mode) const { | 398 ACMVADMode* mode) const { |
411 *dtx_enabled = dtx_enabled_; | 399 *dtx_enabled = dtx_enabled_; |
412 *vad_enabled = dtx_enabled_; | 400 *vad_enabled = dtx_enabled_; |
413 *mode = vad_mode_; | 401 *mode = vad_mode_; |
414 } | 402 } |
415 | 403 |
416 int CodecManager::SetCodecFEC(bool enable_codec_fec) { | 404 int CodecManager::SetCodecFEC(bool enable_codec_fec) { |
417 if (enable_codec_fec == true && red_enabled_ == true) { | 405 if (enable_codec_fec == true && red_enabled_ == true) { |
418 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, | 406 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, |
419 "Codec internal FEC and RED cannot be co-enabled."); | 407 "Codec internal FEC and RED cannot be co-enabled."); |
420 return -1; | 408 return -1; |
421 } | 409 } |
422 | 410 |
423 RTC_CHECK(codec_owner_.Encoder()); | 411 RTC_CHECK(CurrentEncoder()); |
424 codec_fec_enabled_ = | 412 codec_fec_enabled_ = |
425 codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; | 413 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec; |
426 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; | 414 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; |
427 } | 415 } |
428 | 416 |
429 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { | 417 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { |
430 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; | 418 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; |
431 } | 419 } |
432 | 420 |
433 int CodecManager::CngPayloadType(int sample_rate_hz) const { | 421 int CodecManager::CngPayloadType(int sample_rate_hz) const { |
434 switch (sample_rate_hz) { | 422 switch (sample_rate_hz) { |
435 case 8000: | 423 case 8000: |
(...skipping 17 matching lines...) Expand all Loading... | |
453 case 16000: | 441 case 16000: |
454 case 32000: | 442 case 32000: |
455 case 48000: | 443 case 48000: |
456 return -1; | 444 return -1; |
457 default: | 445 default: |
458 FATAL() << sample_rate_hz << " Hz is not supported"; | 446 FATAL() << sample_rate_hz << " Hz is not supported"; |
459 return -1; | 447 return -1; |
460 } | 448 } |
461 } | 449 } |
462 | 450 |
451 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder, | |
452 int sample_rate_hz) { | |
hlundin-webrtc
2015/11/16 12:28:06
I'd argue that the name should be rtp_timestamp_ra
| |
453 auto cng_config = | |
454 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{ | |
455 CngPayloadType(sample_rate_hz), vad_mode_}) | |
456 : rtc::Optional<RentACodec::CngConfig>(); | |
457 auto red_pt = red_enabled_ | |
458 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz)) | |
459 : rtc::Optional<int>(); | |
460 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt); | |
461 } | |
462 | |
463 } // namespace acm2 | 463 } // namespace acm2 |
464 } // namespace webrtc | 464 } // namespace webrtc |
OLD | NEW |