| 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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 return false; | 389 return false; |
| 390 } | 390 } |
| 391 | 391 |
| 392 static const AudioCodec* GetPreferredCodec( | 392 static const AudioCodec* GetPreferredCodec( |
| 393 const std::vector<AudioCodec>& codecs, | 393 const std::vector<AudioCodec>& codecs, |
| 394 webrtc::CodecInst* out) { | 394 webrtc::CodecInst* out) { |
| 395 RTC_DCHECK(out); | 395 RTC_DCHECK(out); |
| 396 // Select the preferred send codec (the first non-telephone-event/CN codec). | 396 // Select the preferred send codec (the first non-telephone-event/CN codec). |
| 397 for (const AudioCodec& codec : codecs) { | 397 for (const AudioCodec& codec : codecs) { |
| 398 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { | 398 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { |
| 399 // Skip telephone-event/CN codec, which will be handled later. | 399 // Skip telephone-event/CN codecs - they will be handled later. |
| 400 continue; | 400 continue; |
| 401 } | 401 } |
| 402 | 402 |
| 403 // We'll use the first codec in the list to actually send audio data. | 403 // We'll use the first codec in the list to actually send audio data. |
| 404 // Be sure to use the payload type requested by the remote side. | 404 // Be sure to use the payload type requested by the remote side. |
| 405 // Ignore codecs we don't know about. The negotiation step should prevent | 405 // Ignore codecs we don't know about. The negotiation step should prevent |
| 406 // this, but double-check to be sure. | 406 // this, but double-check to be sure. |
| 407 if (!ToCodecInst(codec, out)) { | 407 if (!ToCodecInst(codec, out)) { |
| 408 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 408 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 409 continue; | 409 continue; |
| 410 } | 410 } |
| 411 return &codec; | 411 return &codec; |
| 412 } | 412 } |
| 413 return nullptr; | 413 return nullptr; |
| 414 } | 414 } |
| 415 | 415 |
| 416 private: | 416 private: |
| 417 static const int kMaxNumPacketSize = 6; | 417 static const int kMaxNumPacketSize = 6; |
| 418 struct CodecPref { | 418 struct CodecPref { |
| 419 const char* name; | 419 const char* name; |
| 420 int clockrate; | 420 int clockrate; |
| 421 size_t channels; | 421 size_t channels; |
| 422 int payload_type; | 422 int payload_type; |
| 423 bool is_multi_rate; | 423 bool is_multi_rate; |
| 424 int packet_sizes_ms[kMaxNumPacketSize]; | 424 int packet_sizes_ms[kMaxNumPacketSize]; |
| 425 int max_bitrate_bps; | 425 int max_bitrate_bps; |
| 426 }; | 426 }; |
| 427 // Note: keep the supported packet sizes in ascending order. | 427 // Note: keep the supported packet sizes in ascending order. |
| 428 static const CodecPref kCodecPrefs[11]; | 428 static const CodecPref kCodecPrefs[14]; |
| 429 | 429 |
| 430 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | 430 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
| 431 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | 431 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
| 432 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | 432 for (int packet_size_ms : codec_pref.packet_sizes_ms) { |
| 433 if (packet_size_ms && packet_size_ms <= ptime_ms) { | 433 if (packet_size_ms && packet_size_ms <= ptime_ms) { |
| 434 selected_packet_size_ms = packet_size_ms; | 434 selected_packet_size_ms = packet_size_ms; |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 return selected_packet_size_ms; | 437 return selected_packet_size_ms; |
| 438 } | 438 } |
| 439 | 439 |
| 440 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC | 440 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC |
| 441 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz | 441 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz |
| 442 // codec. | 442 // codec. |
| 443 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | 443 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { |
| 444 if (IsCodec(*voe_codec, kG722CodecName)) { | 444 if (IsCodec(*voe_codec, kG722CodecName)) { |
| 445 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine | 445 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine |
| 446 // has changed, and this special case is no longer needed. | 446 // has changed, and this special case is no longer needed. |
| 447 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | 447 RTC_DCHECK(voe_codec->plfreq != new_plfreq); |
| 448 voe_codec->plfreq = new_plfreq; | 448 voe_codec->plfreq = new_plfreq; |
| 449 } | 449 } |
| 450 } | 450 } |
| 451 }; | 451 }; |
| 452 | 452 |
| 453 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[11] = { | 453 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[14] = { |
| 454 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrate}, | 454 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrate}, |
| 455 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate}, | 455 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate}, |
| 456 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate}, | 456 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate}, |
| 457 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 457 // G722 should be advertised as 8000 Hz because of the RFC "bug". |
| 458 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | 458 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, |
| 459 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | 459 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, |
| 460 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 460 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, |
| 461 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 461 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, |
| 462 {kCnCodecName, 32000, 1, 106, false, {}}, | 462 {kCnCodecName, 32000, 1, 106, false, {}}, |
| 463 {kCnCodecName, 16000, 1, 105, false, {}}, | 463 {kCnCodecName, 16000, 1, 105, false, {}}, |
| 464 {kCnCodecName, 8000, 1, 13, false, {}}, | 464 {kCnCodecName, 8000, 1, 13, false, {}}, |
| 465 {kDtmfCodecName, 48000, 1, 123, false, {}}, |
| 466 {kDtmfCodecName, 32000, 1, 124, false, {}}, |
| 467 {kDtmfCodecName, 16000, 1, 125, false, {}}, |
| 465 {kDtmfCodecName, 8000, 1, 126, false, {}} | 468 {kDtmfCodecName, 8000, 1, 126, false, {}} |
| 466 }; | 469 }; |
| 467 } // namespace { | 470 } // namespace { |
| 468 | 471 |
| 469 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { | 472 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { |
| 470 if (nack_enabled != rhs.nack_enabled) { | 473 if (nack_enabled != rhs.nack_enabled) { |
| 471 return false; | 474 return false; |
| 472 } | 475 } |
| 473 if (transport_cc_enabled != rhs.transport_cc_enabled) { | 476 if (transport_cc_enabled != rhs.transport_cc_enabled) { |
| 474 return false; | 477 return false; |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 RTC_DCHECK(adm_); | 1086 RTC_DCHECK(adm_); |
| 1084 return adm_; | 1087 return adm_; |
| 1085 } | 1088 } |
| 1086 | 1089 |
| 1087 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { | 1090 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { |
| 1088 PayloadTypeMapper mapper; | 1091 PayloadTypeMapper mapper; |
| 1089 AudioCodecs out; | 1092 AudioCodecs out; |
| 1090 const std::vector<webrtc::AudioCodecSpec>& specs = | 1093 const std::vector<webrtc::AudioCodecSpec>& specs = |
| 1091 decoder_factory_->GetSupportedDecoders(); | 1094 decoder_factory_->GetSupportedDecoders(); |
| 1092 | 1095 |
| 1093 // Only generate CN payload types for these clockrates | 1096 // Only generate CN payload types for these clockrates: |
| 1094 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, | 1097 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
| 1095 { 16000, false }, | 1098 { 16000, false }, |
| 1096 { 32000, false }}; | 1099 { 32000, false }}; |
| 1100 // Only generate telephone-event payload types for these clockrates: |
| 1101 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, |
| 1102 { 16000, false }, |
| 1103 { 32000, false }, |
| 1104 { 48000, false }}; |
| 1097 | 1105 |
| 1098 auto map_format = [&mapper, &out] (const webrtc::SdpAudioFormat& format) { | 1106 auto map_format = [&mapper, &out] (const webrtc::SdpAudioFormat& format) { |
| 1099 rtc::Optional<AudioCodec> opt_codec = mapper.ToAudioCodec(format); | 1107 rtc::Optional<AudioCodec> opt_codec = mapper.ToAudioCodec(format); |
| 1100 if (!opt_codec) { | 1108 if (!opt_codec) { |
| 1101 LOG(LS_ERROR) << "Unable to assign payload type to format: " << format; | 1109 LOG(LS_ERROR) << "Unable to assign payload type to format: " << format; |
| 1102 return false; | 1110 return false; |
| 1103 } | 1111 } |
| 1104 | 1112 |
| 1105 auto& codec = *opt_codec; | 1113 auto& codec = *opt_codec; |
| 1106 if (IsCodec(codec, kOpusCodecName)) { | 1114 if (IsCodec(codec, kOpusCodecName)) { |
| 1107 // TODO(ossu): Set this specifically for Opus for now, until we have a | 1115 // TODO(ossu): Set this specifically for Opus for now, until we have a |
| 1108 // better way of dealing with rtcp-fb parameters. | 1116 // better way of dealing with rtcp-fb parameters. |
| 1109 codec.AddFeedbackParam( | 1117 codec.AddFeedbackParam( |
| 1110 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | 1118 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); |
| 1111 } | 1119 } |
| 1112 out.push_back(codec); | 1120 out.push_back(codec); |
| 1113 return true; | 1121 return true; |
| 1114 }; | 1122 }; |
| 1115 | 1123 |
| 1116 for (const auto& spec : specs) { | 1124 for (const auto& spec : specs) { |
| 1117 if (map_format(spec.format) && spec.allow_comfort_noise) { | 1125 if (map_format(spec.format)) { |
| 1118 // Generate a CN entry if the decoder allows it and we support the | 1126 if (spec.allow_comfort_noise) { |
| 1119 // clockrate. | 1127 // Generate a CN entry if the decoder allows it and we support the |
| 1120 auto cn = generate_cn.find(spec.format.clockrate_hz); | 1128 // clockrate. |
| 1121 if (cn != generate_cn.end()) { | 1129 auto cn = generate_cn.find(spec.format.clockrate_hz); |
| 1122 cn->second = true; | 1130 if (cn != generate_cn.end()) { |
| 1131 cn->second = true; |
| 1132 } |
| 1133 } |
| 1134 |
| 1135 // Generate a telephone-event entry if we support the clockrate. |
| 1136 auto dtmf = generate_dtmf.find(spec.format.clockrate_hz); |
| 1137 if (dtmf != generate_dtmf.end()) { |
| 1138 dtmf->second = true; |
| 1123 } | 1139 } |
| 1124 } | 1140 } |
| 1125 } | 1141 } |
| 1126 | 1142 |
| 1127 // Add CN codecs after "proper" audio codecs | 1143 // Add CN codecs after "proper" audio codecs. |
| 1128 for (const auto& cn : generate_cn) { | 1144 for (const auto& cn : generate_cn) { |
| 1129 if (cn.second) { | 1145 if (cn.second) { |
| 1130 map_format({kCnCodecName, cn.first, 1}); | 1146 map_format({kCnCodecName, cn.first, 1}); |
| 1131 } | 1147 } |
| 1132 } | 1148 } |
| 1133 | 1149 |
| 1134 // Add telephone-event codec last | 1150 // Add telephone-event codecs last. |
| 1135 map_format({kDtmfCodecName, 8000, 1}); | 1151 for (const auto& dtmf : generate_dtmf) { |
| 1152 if (dtmf.second) { |
| 1153 map_format({kDtmfCodecName, dtmf.first, 1}); |
| 1154 } |
| 1155 } |
| 1136 | 1156 |
| 1137 return out; | 1157 return out; |
| 1138 } | 1158 } |
| 1139 | 1159 |
| 1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1160 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
| 1141 : public AudioSource::Sink { | 1161 : public AudioSource::Sink { |
| 1142 public: | 1162 public: |
| 1143 WebRtcAudioSendStream(int ch, | 1163 WebRtcAudioSendStream(int ch, |
| 1144 webrtc::AudioTransport* voe_audio_transport, | 1164 webrtc::AudioTransport* voe_audio_transport, |
| 1145 uint32_t ssrc, | 1165 uint32_t ssrc, |
| (...skipping 1515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2661 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2681 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2662 const auto it = send_streams_.find(ssrc); | 2682 const auto it = send_streams_.find(ssrc); |
| 2663 if (it != send_streams_.end()) { | 2683 if (it != send_streams_.end()) { |
| 2664 return it->second->channel(); | 2684 return it->second->channel(); |
| 2665 } | 2685 } |
| 2666 return -1; | 2686 return -1; |
| 2667 } | 2687 } |
| 2668 } // namespace cricket | 2688 } // namespace cricket |
| 2669 | 2689 |
| 2670 #endif // HAVE_WEBRTC_VOICE | 2690 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |