OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified | 141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified |
142 // below. | 142 // below. |
143 #if defined(CHROMEOS) | 143 #if defined(CHROMEOS) |
144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; | 144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; |
145 #elif defined(ANDROID) | 145 #elif defined(ANDROID) |
146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; | 146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; |
147 #else | 147 #else |
148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; | 148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; |
149 #endif | 149 #endif |
150 | 150 |
| 151 bool ValidateStreamParams(const StreamParams& sp) { |
| 152 if (sp.ssrcs.empty()) { |
| 153 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); |
| 154 return false; |
| 155 } |
| 156 if (sp.ssrcs.size() > 1) { |
| 157 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
| 158 return false; |
| 159 } |
| 160 return true; |
| 161 } |
| 162 |
151 // Dumps an AudioCodec in RFC 2327-ish format. | 163 // Dumps an AudioCodec in RFC 2327-ish format. |
152 std::string ToString(const AudioCodec& codec) { | 164 std::string ToString(const AudioCodec& codec) { |
153 std::stringstream ss; | 165 std::stringstream ss; |
154 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 166 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels |
155 << " (" << codec.id << ")"; | 167 << " (" << codec.id << ")"; |
156 return ss.str(); | 168 return ss.str(); |
157 } | 169 } |
158 | 170 |
159 std::string ToString(const webrtc::CodecInst& codec) { | 171 std::string ToString(const webrtc::CodecInst& codec) { |
160 std::stringstream ss; | 172 std::stringstream ss; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 if (c.Matches(codec)) { | 226 if (c.Matches(codec)) { |
215 if (found_codec != NULL) { | 227 if (found_codec != NULL) { |
216 *found_codec = c; | 228 *found_codec = c; |
217 } | 229 } |
218 return true; | 230 return true; |
219 } | 231 } |
220 } | 232 } |
221 return false; | 233 return false; |
222 } | 234 } |
223 | 235 |
| 236 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) { |
| 237 if (codecs.empty()) { |
| 238 return true; |
| 239 } |
| 240 std::vector<int> payload_types; |
| 241 for (const AudioCodec& codec : codecs) { |
| 242 payload_types.push_back(codec.id); |
| 243 } |
| 244 std::sort(payload_types.begin(), payload_types.end()); |
| 245 auto it = std::unique(payload_types.begin(), payload_types.end()); |
| 246 return it == payload_types.end(); |
| 247 } |
| 248 |
224 bool IsNackEnabled(const AudioCodec& codec) { | 249 bool IsNackEnabled(const AudioCodec& codec) { |
225 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, | 250 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, |
226 kParamValueEmpty)); | 251 kParamValueEmpty)); |
227 } | 252 } |
228 | 253 |
229 int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | 254 int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
230 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | 255 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
231 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | 256 for (int packet_size_ms : codec_pref.packet_sizes_ms) { |
232 if (packet_size_ms && packet_size_ms <= ptime_ms) { | 257 if (packet_size_ms && packet_size_ms <= ptime_ms) { |
233 selected_packet_size_ms = packet_size_ms; | 258 selected_packet_size_ms = packet_size_ms; |
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 } | 1463 } |
1439 | 1464 |
1440 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1465 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { |
1441 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1466 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1442 LOG(LS_INFO) << "Setting voice channel options: " | 1467 LOG(LS_INFO) << "Setting voice channel options: " |
1443 << options.ToString(); | 1468 << options.ToString(); |
1444 | 1469 |
1445 // Check if DSCP value is changed from previous. | 1470 // Check if DSCP value is changed from previous. |
1446 bool dscp_option_changed = (options_.dscp != options.dscp); | 1471 bool dscp_option_changed = (options_.dscp != options.dscp); |
1447 | 1472 |
1448 // TODO(xians): Add support to set different options for different send | |
1449 // streams after we support multiple APMs. | |
1450 | |
1451 // We retain all of the existing options, and apply the given ones | 1473 // We retain all of the existing options, and apply the given ones |
1452 // on top. This means there is no way to "clear" options such that | 1474 // on top. This means there is no way to "clear" options such that |
1453 // they go back to the engine default. | 1475 // they go back to the engine default. |
1454 options_.SetAll(options); | 1476 options_.SetAll(options); |
1455 | 1477 |
1456 if (send_ != SEND_NOTHING) { | 1478 if (send_ != SEND_NOTHING) { |
1457 if (!engine()->ApplyOptions(options_)) { | 1479 if (!engine()->ApplyOptions(options_)) { |
1458 LOG(LS_WARNING) << | 1480 LOG(LS_WARNING) << |
1459 "Failed to apply engine options during channel SetOptions."; | 1481 "Failed to apply engine options during channel SetOptions."; |
1460 return false; | 1482 return false; |
1461 } | 1483 } |
1462 } | 1484 } |
1463 | 1485 |
1464 // Receiver-side auto gain control happens per channel, so set it here from | |
1465 // options. Note that, like conference mode, setting it on the engine won't | |
1466 // have the desired effect, since voice channels don't inherit options from | |
1467 // the media engine when those options are applied per-channel. | |
1468 bool rx_auto_gain_control; | |
1469 if (options.rx_auto_gain_control.Get(&rx_auto_gain_control)) { | |
1470 if (engine()->voe()->processing()->SetRxAgcStatus( | |
1471 voe_channel(), rx_auto_gain_control, | |
1472 webrtc::kAgcFixedDigital) == -1) { | |
1473 LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control); | |
1474 return false; | |
1475 } else { | |
1476 LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control | |
1477 << " with mode " << webrtc::kAgcFixedDigital; | |
1478 } | |
1479 } | |
1480 if (options.rx_agc_target_dbov.IsSet() || | |
1481 options.rx_agc_digital_compression_gain.IsSet() || | |
1482 options.rx_agc_limiter.IsSet()) { | |
1483 webrtc::AgcConfig config; | |
1484 // If only some of the options are being overridden, get the current | |
1485 // settings for the channel and bail if they aren't available. | |
1486 if (!options.rx_agc_target_dbov.IsSet() || | |
1487 !options.rx_agc_digital_compression_gain.IsSet() || | |
1488 !options.rx_agc_limiter.IsSet()) { | |
1489 if (engine()->voe()->processing()->GetRxAgcConfig( | |
1490 voe_channel(), config) != 0) { | |
1491 LOG(LS_ERROR) << "Failed to get default rx agc configuration for " | |
1492 << "channel " << voe_channel() << ". Since not all rx " | |
1493 << "agc options are specified, unable to safely set rx " | |
1494 << "agc options."; | |
1495 return false; | |
1496 } | |
1497 } | |
1498 config.targetLeveldBOv = | |
1499 options.rx_agc_target_dbov.GetWithDefaultIfUnset( | |
1500 config.targetLeveldBOv); | |
1501 config.digitalCompressionGaindB = | |
1502 options.rx_agc_digital_compression_gain.GetWithDefaultIfUnset( | |
1503 config.digitalCompressionGaindB); | |
1504 config.limiterEnable = options.rx_agc_limiter.GetWithDefaultIfUnset( | |
1505 config.limiterEnable); | |
1506 if (engine()->voe()->processing()->SetRxAgcConfig( | |
1507 voe_channel(), config) == -1) { | |
1508 LOG_RTCERR4(SetRxAgcConfig, voe_channel(), config.targetLeveldBOv, | |
1509 config.digitalCompressionGaindB, config.limiterEnable); | |
1510 return false; | |
1511 } | |
1512 } | |
1513 if (dscp_option_changed) { | 1486 if (dscp_option_changed) { |
1514 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; | 1487 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; |
1515 if (options_.dscp.GetWithDefaultIfUnset(false)) | 1488 if (options_.dscp.GetWithDefaultIfUnset(false)) |
1516 dscp = kAudioDscpValue; | 1489 dscp = kAudioDscpValue; |
1517 if (MediaChannel::SetDscp(dscp) != 0) { | 1490 if (MediaChannel::SetDscp(dscp) != 0) { |
1518 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; | 1491 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; |
1519 } | 1492 } |
1520 } | 1493 } |
1521 | |
1522 RecreateAudioReceiveStreams(); | 1494 RecreateAudioReceiveStreams(); |
1523 | |
1524 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1495 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1525 << options_.ToString(); | 1496 << options_.ToString(); |
1526 return true; | 1497 return true; |
1527 } | 1498 } |
1528 | 1499 |
1529 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1500 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1530 const std::vector<AudioCodec>& codecs) { | 1501 const std::vector<AudioCodec>& codecs) { |
| 1502 // Set the payload types to be used for incoming media. |
| 1503 LOG(LS_INFO) << "Setting receive voice codecs."; |
1531 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1504 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1532 // Set the payload types to be used for incoming media. | 1505 |
1533 LOG(LS_INFO) << "Setting receive voice codecs:"; | 1506 if (!VerifyUniquePayloadTypes(codecs)) { |
| 1507 LOG(LS_ERROR) << "Codec payload types overlap."; |
| 1508 return false; |
| 1509 } |
1534 | 1510 |
1535 std::vector<AudioCodec> new_codecs; | 1511 std::vector<AudioCodec> new_codecs; |
1536 // Find all new codecs. We allow adding new codecs but don't allow changing | 1512 // Find all new codecs. We allow adding new codecs but don't allow changing |
1537 // the payload type of codecs that is already configured since we might | 1513 // the payload type of codecs that is already configured since we might |
1538 // already be receiving packets with that payload type. | 1514 // already be receiving packets with that payload type. |
1539 for (const AudioCodec& codec : codecs) { | 1515 for (const AudioCodec& codec : codecs) { |
1540 AudioCodec old_codec; | 1516 AudioCodec old_codec; |
1541 if (FindCodec(recv_codecs_, codec, &old_codec)) { | 1517 if (FindCodec(recv_codecs_, codec, &old_codec)) { |
1542 if (old_codec.id != codec.id) { | 1518 if (old_codec.id != codec.id) { |
1543 LOG(LS_ERROR) << codec.name << " payload type changed."; | 1519 LOG(LS_ERROR) << codec.name << " payload type changed."; |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 if (send_channels_.empty()) | 2198 if (send_channels_.empty()) |
2223 ChangeSend(SEND_NOTHING); | 2199 ChangeSend(SEND_NOTHING); |
2224 | 2200 |
2225 return true; | 2201 return true; |
2226 } | 2202 } |
2227 | 2203 |
2228 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2204 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2229 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2205 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2230 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); | 2206 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
2231 | 2207 |
2232 rtc::CritScope lock(&receive_channels_cs_); | 2208 if (!ValidateStreamParams(sp)) { |
2233 | |
2234 if (!VERIFY(sp.ssrcs.size() == 1)) | |
2235 return false; | |
2236 uint32_t ssrc = sp.first_ssrc(); | |
2237 | |
2238 if (ssrc == 0) { | |
2239 LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; | |
2240 return false; | 2209 return false; |
2241 } | 2210 } |
2242 | 2211 |
| 2212 uint32_t ssrc = sp.first_ssrc(); |
| 2213 if (ssrc == 0) { |
| 2214 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; |
| 2215 return false; |
| 2216 } |
| 2217 |
| 2218 rtc::CritScope lock(&receive_channels_cs_); |
| 2219 |
2243 if (receive_channels_.find(ssrc) != receive_channels_.end()) { | 2220 if (receive_channels_.find(ssrc) != receive_channels_.end()) { |
2244 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2221 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2245 return false; | 2222 return false; |
2246 } | 2223 } |
2247 | 2224 |
2248 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); | 2225 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); |
2249 | 2226 |
2250 // Reuse default channel for recv stream in non-conference mode call | 2227 // Reuse default channel for recv stream in non-conference mode call |
2251 // when the default channel is not being used. | 2228 // when the default channel is not being used. |
2252 webrtc::AudioTransport* audio_transport = | 2229 webrtc::AudioTransport* audio_transport = |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2660 // Sending channels need all RTCP packets with feedback information. | 2637 // Sending channels need all RTCP packets with feedback information. |
2661 // Even sender reports can contain attached report blocks. | 2638 // Even sender reports can contain attached report blocks. |
2662 // Receiving channels need sender reports in order to create | 2639 // Receiving channels need sender reports in order to create |
2663 // correct receiver reports. | 2640 // correct receiver reports. |
2664 int type = 0; | 2641 int type = 0; |
2665 if (!GetRtcpType(packet->data(), packet->size(), &type)) { | 2642 if (!GetRtcpType(packet->data(), packet->size(), &type)) { |
2666 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; | 2643 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; |
2667 return; | 2644 return; |
2668 } | 2645 } |
2669 | 2646 |
2670 // If it is a sender report, find the channel that is listening. | 2647 // If it is a sender report, find the receive channel that is listening. |
2671 bool has_sent_to_default_channel = false; | 2648 bool has_sent_to_default_channel = false; |
2672 if (type == kRtcpTypeSR) { | 2649 if (type == kRtcpTypeSR) { |
2673 int which_channel = | 2650 uint32_t ssrc = 0; |
2674 GetReceiveChannelId(ParseSsrc(packet->data(), packet->size(), true)); | 2651 if (!GetRtcpSsrc(packet->data(), packet->size(), &ssrc)) { |
2675 if (which_channel != -1) { | 2652 return; |
| 2653 } |
| 2654 int recv_channel_id = GetReceiveChannelId(ssrc); |
| 2655 if (recv_channel_id != -1) { |
2676 engine()->voe()->network()->ReceivedRTCPPacket( | 2656 engine()->voe()->network()->ReceivedRTCPPacket( |
2677 which_channel, packet->data(), packet->size()); | 2657 recv_channel_id, packet->data(), packet->size()); |
2678 | 2658 |
2679 if (IsDefaultChannel(which_channel)) | 2659 if (IsDefaultChannel(recv_channel_id)) |
2680 has_sent_to_default_channel = true; | 2660 has_sent_to_default_channel = true; |
2681 } | 2661 } |
2682 } | 2662 } |
2683 | 2663 |
2684 // SR may continue RR and any RR entry may correspond to any one of the send | 2664 // SR may continue RR and any RR entry may correspond to any one of the send |
2685 // channels. So all RTCP packets must be forwarded all send channels. VoE | 2665 // channels. So all RTCP packets must be forwarded all send channels. VoE |
2686 // will filter out RR internally. | 2666 // will filter out RR internally. |
2687 for (const auto& ch : send_channels_) { | 2667 for (const auto& ch : send_channels_) { |
2688 // Make sure not sending the same packet to default channel more than once. | 2668 // Make sure not sending the same packet to default channel more than once. |
2689 if (IsDefaultChannel(ch.second->channel()) && | 2669 if (IsDefaultChannel(ch.second->channel()) && |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 3200 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
3221 return false; | 3201 return false; |
3222 } | 3202 } |
3223 } | 3203 } |
3224 return true; | 3204 return true; |
3225 } | 3205 } |
3226 | 3206 |
3227 } // namespace cricket | 3207 } // namespace cricket |
3228 | 3208 |
3229 #endif // HAVE_WEBRTC_VOICE | 3209 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |