OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 // The current implementation applies the following values to mono signals, | 76 // The current implementation applies the following values to mono signals, |
77 // and multiplies them by 2 for stereo. | 77 // and multiplies them by 2 for stereo. |
78 const int kOpusBitrateNb = 12000; | 78 const int kOpusBitrateNb = 12000; |
79 const int kOpusBitrateWb = 20000; | 79 const int kOpusBitrateWb = 20000; |
80 const int kOpusBitrateFb = 32000; | 80 const int kOpusBitrateFb = 32000; |
81 | 81 |
82 // Opus bitrate should be in the range between 6000 and 510000. | 82 // Opus bitrate should be in the range between 6000 and 510000. |
83 const int kOpusMinBitrate = 6000; | 83 const int kOpusMinBitrate = 6000; |
84 const int kOpusMaxBitrate = 510000; | 84 const int kOpusMaxBitrate = 510000; |
85 | 85 |
| 86 // iSAC bitrate should be <= 56000. |
| 87 const int kIsacMaxBitrate = 56000; |
| 88 |
86 // Default audio dscp value. | 89 // Default audio dscp value. |
87 // See http://tools.ietf.org/html/rfc2474 for details. | 90 // See http://tools.ietf.org/html/rfc2474 for details. |
88 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 91 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
89 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 92 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
90 | 93 |
91 // Constants from voice_engine_defines.h. | 94 // Constants from voice_engine_defines.h. |
92 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) | 95 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) |
93 const int kMaxTelephoneEventCode = 255; | 96 const int kMaxTelephoneEventCode = 255; |
94 const int kMinTelephoneEventDuration = 100; | 97 const int kMinTelephoneEventDuration = 100; |
95 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16 | 98 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { | 344 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { |
342 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | 345 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { |
343 if (IsCodec(codec, kCodecPrefs[i].name) && | 346 if (IsCodec(codec, kCodecPrefs[i].name) && |
344 kCodecPrefs[i].clockrate == codec.plfreq) { | 347 kCodecPrefs[i].clockrate == codec.plfreq) { |
345 return kCodecPrefs[i].is_multi_rate; | 348 return kCodecPrefs[i].is_multi_rate; |
346 } | 349 } |
347 } | 350 } |
348 return false; | 351 return false; |
349 } | 352 } |
350 | 353 |
| 354 static int MaxBitrateBps(const webrtc::CodecInst& codec) { |
| 355 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { |
| 356 if (IsCodec(codec, kCodecPrefs[i].name) && |
| 357 kCodecPrefs[i].clockrate == codec.plfreq) { |
| 358 return kCodecPrefs[i].max_bitrate_bps; |
| 359 } |
| 360 } |
| 361 return 0; |
| 362 } |
| 363 |
351 // If the AudioCodec param kCodecParamPTime is set, then we will set it to | 364 // If the AudioCodec param kCodecParamPTime is set, then we will set it to |
352 // codec pacsize if it's valid, or we will pick the next smallest value we | 365 // codec pacsize if it's valid, or we will pick the next smallest value we |
353 // support. | 366 // support. |
354 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. | 367 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. |
355 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { | 368 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { |
356 for (const CodecPref& codec_pref : kCodecPrefs) { | 369 for (const CodecPref& codec_pref : kCodecPrefs) { |
357 if ((IsCodec(*codec, codec_pref.name) && | 370 if ((IsCodec(*codec, codec_pref.name) && |
358 codec_pref.clockrate == codec->plfreq) || | 371 codec_pref.clockrate == codec->plfreq) || |
359 IsCodec(*codec, kG722CodecName)) { | 372 IsCodec(*codec, kG722CodecName)) { |
360 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); | 373 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 424 |
412 private: | 425 private: |
413 static const int kMaxNumPacketSize = 6; | 426 static const int kMaxNumPacketSize = 6; |
414 struct CodecPref { | 427 struct CodecPref { |
415 const char* name; | 428 const char* name; |
416 int clockrate; | 429 int clockrate; |
417 size_t channels; | 430 size_t channels; |
418 int payload_type; | 431 int payload_type; |
419 bool is_multi_rate; | 432 bool is_multi_rate; |
420 int packet_sizes_ms[kMaxNumPacketSize]; | 433 int packet_sizes_ms[kMaxNumPacketSize]; |
| 434 int max_bitrate_bps; |
421 }; | 435 }; |
422 // Note: keep the supported packet sizes in ascending order. | 436 // Note: keep the supported packet sizes in ascending order. |
423 static const CodecPref kCodecPrefs[12]; | 437 static const CodecPref kCodecPrefs[12]; |
424 | 438 |
425 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | 439 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
426 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | 440 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
427 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | 441 for (int packet_size_ms : codec_pref.packet_sizes_ms) { |
428 if (packet_size_ms && packet_size_ms <= ptime_ms) { | 442 if (packet_size_ms && packet_size_ms <= ptime_ms) { |
429 selected_packet_size_ms = packet_size_ms; | 443 selected_packet_size_ms = packet_size_ms; |
430 } | 444 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 if (codec.id == red_pt) { | 491 if (codec.id == red_pt) { |
478 return &codec; | 492 return &codec; |
479 } | 493 } |
480 } | 494 } |
481 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; | 495 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; |
482 return nullptr; | 496 return nullptr; |
483 } | 497 } |
484 }; | 498 }; |
485 | 499 |
486 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[12] = { | 500 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[12] = { |
487 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } }, | 501 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrate}, |
488 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } }, | 502 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate}, |
489 { kIsacCodecName, 32000, 1, 104, true, { 30 } }, | 503 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate}, |
490 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 504 // G722 should be advertised as 8000 Hz because of the RFC "bug". |
491 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } }, | 505 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, |
492 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } }, | 506 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, |
493 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } }, | 507 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, |
494 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } }, | 508 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, |
495 { kCnCodecName, 32000, 1, 106, false, { } }, | 509 {kCnCodecName, 32000, 1, 106, false, {}}, |
496 { kCnCodecName, 16000, 1, 105, false, { } }, | 510 {kCnCodecName, 16000, 1, 105, false, {}}, |
497 { kCnCodecName, 8000, 1, 13, false, { } }, | 511 {kCnCodecName, 8000, 1, 13, false, {}}, |
498 { kRedCodecName, 8000, 1, 127, false, { } }, | 512 {kRedCodecName, 8000, 1, 127, false, {}}, |
499 { kDtmfCodecName, 8000, 1, 126, false, { } }, | 513 {kDtmfCodecName, 8000, 1, 126, false, {}}, |
500 }; | 514 }; |
501 } // namespace { | 515 } // namespace { |
502 | 516 |
503 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 517 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
504 webrtc::CodecInst* out) { | 518 webrtc::CodecInst* out) { |
505 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 519 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
506 } | 520 } |
507 | 521 |
508 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm) | 522 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm) |
509 : WebRtcVoiceEngine(adm, new VoEWrapper()) { | 523 : WebRtcVoiceEngine(adm, new VoEWrapper()) { |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 std::vector<webrtc::RtpExtension> filtered_extensions = | 1374 std::vector<webrtc::RtpExtension> filtered_extensions = |
1361 FilterRtpExtensions(params.extensions, | 1375 FilterRtpExtensions(params.extensions, |
1362 webrtc::RtpExtension::IsSupportedForAudio, true); | 1376 webrtc::RtpExtension::IsSupportedForAudio, true); |
1363 if (send_rtp_extensions_ != filtered_extensions) { | 1377 if (send_rtp_extensions_ != filtered_extensions) { |
1364 send_rtp_extensions_.swap(filtered_extensions); | 1378 send_rtp_extensions_.swap(filtered_extensions); |
1365 for (auto& it : send_streams_) { | 1379 for (auto& it : send_streams_) { |
1366 it.second->RecreateAudioSendStream(send_rtp_extensions_); | 1380 it.second->RecreateAudioSendStream(send_rtp_extensions_); |
1367 } | 1381 } |
1368 } | 1382 } |
1369 | 1383 |
1370 if (!SetSendBitrate(params.max_bandwidth_bps)) { | 1384 if (!SetMaxSendBitrate(params.max_bandwidth_bps)) { |
1371 return false; | 1385 return false; |
1372 } | 1386 } |
1373 return SetOptions(params.options); | 1387 return SetOptions(params.options); |
1374 } | 1388 } |
1375 | 1389 |
1376 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1390 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
1377 const AudioRecvParameters& params) { | 1391 const AudioRecvParameters& params) { |
1378 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::SetRecvParameters"); | 1392 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::SetRecvParameters"); |
1379 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1393 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1380 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetRecvParameters: " | 1394 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetRecvParameters: " |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1740 << " Hz on channel " | 1754 << " Hz on channel " |
1741 << channel; | 1755 << channel; |
1742 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate( | 1756 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate( |
1743 channel, send_codec_spec_.opus_max_playback_rate) == -1) { | 1757 channel, send_codec_spec_.opus_max_playback_rate) == -1) { |
1744 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel, | 1758 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel, |
1745 send_codec_spec_.opus_max_playback_rate); | 1759 send_codec_spec_.opus_max_playback_rate); |
1746 return false; | 1760 return false; |
1747 } | 1761 } |
1748 } | 1762 } |
1749 } | 1763 } |
1750 // TODO(solenberg): SetSendBitrate() yields another call to SetSendCodec(). | 1764 // TODO(solenberg): SetMaxSendBitrate() yields another call to SetSendCodec(). |
1751 // Check if it is possible to fuse with the previous call in this function. | 1765 // Check if it is possible to fuse with the previous call in this function. |
1752 SetChannelParameters(channel, rtp_parameters); | 1766 SetChannelParameters(channel, rtp_parameters); |
1753 | 1767 |
1754 // Set the CN payloadtype and the VAD status. | 1768 // Set the CN payloadtype and the VAD status. |
1755 if (send_codec_spec_.cng_payload_type != -1) { | 1769 if (send_codec_spec_.cng_payload_type != -1) { |
1756 // The CN payload type for 8000 Hz clockrate is fixed at 13. | 1770 // The CN payload type for 8000 Hz clockrate is fixed at 13. |
1757 if (send_codec_spec_.cng_plfreq != 8000) { | 1771 if (send_codec_spec_.cng_plfreq != 8000) { |
1758 webrtc::PayloadFrequencies cn_freq; | 1772 webrtc::PayloadFrequencies cn_freq; |
1759 switch (send_codec_spec_.cng_plfreq) { | 1773 switch (send_codec_spec_.cng_plfreq) { |
1760 case 16000: | 1774 case 16000: |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2376 } | 2390 } |
2377 } | 2391 } |
2378 | 2392 |
2379 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2393 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
2380 if (ap) { | 2394 if (ap) { |
2381 ap->set_output_will_be_muted(all_muted); | 2395 ap->set_output_will_be_muted(all_muted); |
2382 } | 2396 } |
2383 return true; | 2397 return true; |
2384 } | 2398 } |
2385 | 2399 |
2386 bool WebRtcVoiceMediaChannel::SetSendBitrate(int bps) { | 2400 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { |
2387 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrate."; | 2401 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; |
2388 send_bitrate_bps_ = bps; | 2402 max_send_bitrate_bps_ = bps; |
2389 | 2403 |
2390 for (const auto& kv : send_streams_) { | 2404 for (const auto& kv : send_streams_) { |
2391 if (!SetChannelParameters(kv.second->channel(), | 2405 if (!SetChannelParameters(kv.second->channel(), |
2392 kv.second->rtp_parameters())) { | 2406 kv.second->rtp_parameters())) { |
2393 return false; | 2407 return false; |
2394 } | 2408 } |
2395 } | 2409 } |
2396 return true; | 2410 return true; |
2397 } | 2411 } |
2398 | 2412 |
2399 bool WebRtcVoiceMediaChannel::SetChannelParameters( | 2413 bool WebRtcVoiceMediaChannel::SetChannelParameters( |
2400 int channel, | 2414 int channel, |
2401 const webrtc::RtpParameters& parameters) { | 2415 const webrtc::RtpParameters& parameters) { |
2402 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | 2416 RTC_CHECK_EQ(1UL, parameters.encodings.size()); |
2403 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | 2417 // TODO(deadbeef): Handle setting parameters with a list of codecs in a |
2404 // different order (which should change the send codec). | 2418 // different order (which should change the send codec). |
2405 return SetSendBitrate( | 2419 return SetMaxSendBitrate( |
2406 channel, | 2420 channel, MinPositive(max_send_bitrate_bps_, |
2407 MinPositive(send_bitrate_bps_, parameters.encodings[0].max_bitrate_bps)); | 2421 parameters.encodings[0].max_bitrate_bps)); |
2408 } | 2422 } |
2409 | 2423 |
2410 bool WebRtcVoiceMediaChannel::SetSendBitrate(int channel, int bps) { | 2424 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int channel, int bps) { |
2411 // Bitrate is auto by default. | 2425 // Bitrate is auto by default. |
2412 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | 2426 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by |
2413 // SetMaxSendBandwith(0), the second call removes the previous limit. | 2427 // SetMaxSendBandwith(0), the second call removes the previous limit. |
2414 if (bps <= 0) | 2428 if (bps <= 0) { |
2415 return true; | 2429 return true; |
| 2430 } |
2416 | 2431 |
2417 if (!HasSendCodec()) { | 2432 if (!HasSendCodec()) { |
2418 LOG(LS_INFO) << "The send codec has not been set up yet. " | 2433 LOG(LS_INFO) << "The send codec has not been set up yet. " |
2419 << "The send bitrate setting will be applied later."; | 2434 << "The send bitrate setting will be applied later."; |
2420 return true; | 2435 return true; |
2421 } | 2436 } |
2422 | 2437 |
2423 webrtc::CodecInst codec = send_codec_spec_.codec_inst; | 2438 webrtc::CodecInst codec = send_codec_spec_.codec_inst; |
2424 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); | 2439 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); |
2425 | 2440 |
2426 if (is_multi_rate) { | 2441 if (is_multi_rate) { |
2427 // If codec is multi-rate then just set the bitrate. | 2442 // If codec is multi-rate then just set the bitrate. |
2428 codec.rate = bps; | 2443 int max_bitrate_bps = WebRtcVoiceCodecs::MaxBitrateBps(codec); |
| 2444 codec.rate = std::min(bps, max_bitrate_bps); |
| 2445 LOG(LS_INFO) << "Setting codec " << codec.plname << " to bitrate " << bps |
| 2446 << " bps."; |
2429 if (!SetSendCodec(channel, codec)) { | 2447 if (!SetSendCodec(channel, codec)) { |
2430 LOG(LS_INFO) << "Failed to set codec " << codec.plname << " to bitrate " | 2448 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " |
2431 << bps << " bps."; | 2449 << bps << " bps."; |
2432 return false; | 2450 return false; |
2433 } | 2451 } |
2434 return true; | 2452 return true; |
2435 } else { | 2453 } else { |
2436 // If codec is not multi-rate and |bps| is less than the fixed bitrate | 2454 // If codec is not multi-rate and |bps| is less than the fixed bitrate |
2437 // then fail. If codec is not multi-rate and |bps| exceeds or equal the | 2455 // then fail. If codec is not multi-rate and |bps| exceeds or equal the |
2438 // fixed bitrate then ignore. | 2456 // fixed bitrate then ignore. |
2439 if (bps < codec.rate) { | 2457 if (bps < codec.rate) { |
2440 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2458 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " |
2441 << " to bitrate " << bps << " bps" | 2459 << bps << " bps" |
2442 << ", requires at least " << codec.rate << " bps."; | 2460 << ", requires at least " << codec.rate << " bps."; |
2443 return false; | 2461 return false; |
2444 } | 2462 } |
2445 return true; | 2463 return true; |
2446 } | 2464 } |
2447 } | 2465 } |
2448 | 2466 |
2449 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { | 2467 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { |
2450 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2468 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2451 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 2469 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); |
2452 call_->SignalChannelNetworkState( | 2470 call_->SignalChannelNetworkState( |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 } | 2593 } |
2576 } else { | 2594 } else { |
2577 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2595 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2578 engine()->voe()->base()->StopPlayout(channel); | 2596 engine()->voe()->base()->StopPlayout(channel); |
2579 } | 2597 } |
2580 return true; | 2598 return true; |
2581 } | 2599 } |
2582 } // namespace cricket | 2600 } // namespace cricket |
2583 | 2601 |
2584 #endif // HAVE_WEBRTC_VOICE | 2602 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |