 Chromium Code Reviews
 Chromium Code Reviews Issue 1788583004:
  Enable setting the maximum bitrate limit in RtpSender.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1788583004:
  Enable setting the maximum bitrate limit in RtpSender.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| 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 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 } | 1131 } | 
| 1132 | 1132 | 
| 1133 int WebRtcVoiceEngine::CreateVoEChannel() { | 1133 int WebRtcVoiceEngine::CreateVoEChannel() { | 
| 1134 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1134 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1135 return voe_wrapper_->base()->CreateChannel(voe_config_); | 1135 return voe_wrapper_->base()->CreateChannel(voe_config_); | 
| 1136 } | 1136 } | 
| 1137 | 1137 | 
| 1138 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1138 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 
| 1139 : public AudioRenderer::Sink { | 1139 : public AudioRenderer::Sink { | 
| 1140 public: | 1140 public: | 
| 1141 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, | 1141 WebRtcAudioSendStream(int ch, | 
| 1142 uint32_t ssrc, const std::string& c_name, | 1142 webrtc::AudioTransport* voe_audio_transport, | 
| 1143 uint32_t ssrc, | |
| 1144 const std::string& c_name, | |
| 1143 const std::vector<webrtc::RtpExtension>& extensions, | 1145 const std::vector<webrtc::RtpExtension>& extensions, | 
| 1144 webrtc::Call* call) | 1146 webrtc::Call* call) | 
| 1145 : voe_audio_transport_(voe_audio_transport), | 1147 : voe_audio_transport_(voe_audio_transport), | 
| 1146 call_(call), | 1148 call_(call), | 
| 1147 config_(nullptr) { | 1149 config_(nullptr), | 
| 1150 rtp_parameters_(webrtc::RTCRtpParameters::CreateDefault()) { | |
| 1148 RTC_DCHECK_GE(ch, 0); | 1151 RTC_DCHECK_GE(ch, 0); | 
| 1149 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1152 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 
| 1150 // RTC_DCHECK(voe_audio_transport); | 1153 // RTC_DCHECK(voe_audio_transport); | 
| 1151 RTC_DCHECK(call); | 1154 RTC_DCHECK(call); | 
| 1152 audio_capture_thread_checker_.DetachFromThread(); | 1155 audio_capture_thread_checker_.DetachFromThread(); | 
| 1153 config_.rtp.ssrc = ssrc; | 1156 config_.rtp.ssrc = ssrc; | 
| 1154 config_.rtp.c_name = c_name; | 1157 config_.rtp.c_name = c_name; | 
| 1155 config_.voe_channel_id = ch; | 1158 config_.voe_channel_id = ch; | 
| 1156 RecreateAudioSendStream(extensions); | 1159 RecreateAudioSendStream(extensions); | 
| 1157 } | 1160 } | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1240 // the renderer. | 1243 // the renderer. | 
| 1241 renderer_ = nullptr; | 1244 renderer_ = nullptr; | 
| 1242 } | 1245 } | 
| 1243 | 1246 | 
| 1244 // Accessor to the VoE channel ID. | 1247 // Accessor to the VoE channel ID. | 
| 1245 int channel() const { | 1248 int channel() const { | 
| 1246 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1249 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1247 return config_.voe_channel_id; | 1250 return config_.voe_channel_id; | 
| 1248 } | 1251 } | 
| 1249 | 1252 | 
| 1253 webrtc::RTCRtpParameters rtp_parameters() const { return rtp_parameters_; } | |
| 1254 | |
| 1255 void set_rtp_parameters(const webrtc::RTCRtpParameters& parameters) { | |
| 1256 rtp_parameters_ = parameters; | |
| 1257 } | |
| 1258 | |
| 1250 private: | 1259 private: | 
| 1251 rtc::ThreadChecker worker_thread_checker_; | 1260 rtc::ThreadChecker worker_thread_checker_; | 
| 1252 rtc::ThreadChecker audio_capture_thread_checker_; | 1261 rtc::ThreadChecker audio_capture_thread_checker_; | 
| 1253 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1262 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 
| 1254 webrtc::Call* call_ = nullptr; | 1263 webrtc::Call* call_ = nullptr; | 
| 1255 webrtc::AudioSendStream::Config config_; | 1264 webrtc::AudioSendStream::Config config_; | 
| 1256 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1265 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 
| 1257 // configuration changes. | 1266 // configuration changes. | 
| 1258 webrtc::AudioSendStream* stream_ = nullptr; | 1267 webrtc::AudioSendStream* stream_ = nullptr; | 
| 1259 | 1268 | 
| 1260 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. | 1269 // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. | 
| 1261 // PeerConnection will make sure invalidating the pointer before the object | 1270 // PeerConnection will make sure invalidating the pointer before the object | 
| 1262 // goes away. | 1271 // goes away. | 
| 1263 AudioRenderer* renderer_ = nullptr; | 1272 AudioRenderer* renderer_ = nullptr; | 
| 1273 webrtc::RTCRtpParameters rtp_parameters_; | |
| 1264 | 1274 | 
| 1265 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1275 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 
| 1266 }; | 1276 }; | 
| 1267 | 1277 | 
| 1268 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1278 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 
| 1269 public: | 1279 public: | 
| 1270 WebRtcAudioReceiveStream(int ch, | 1280 WebRtcAudioReceiveStream(int ch, | 
| 1271 uint32_t remote_ssrc, | 1281 uint32_t remote_ssrc, | 
| 1272 uint32_t local_ssrc, | 1282 uint32_t local_ssrc, | 
| 1273 bool use_transport_cc, | 1283 bool use_transport_cc, | 
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1422 webrtc::RtpExtension::IsSupportedForAudio, false); | 1432 webrtc::RtpExtension::IsSupportedForAudio, false); | 
| 1423 if (recv_rtp_extensions_ != filtered_extensions) { | 1433 if (recv_rtp_extensions_ != filtered_extensions) { | 
| 1424 recv_rtp_extensions_.swap(filtered_extensions); | 1434 recv_rtp_extensions_.swap(filtered_extensions); | 
| 1425 for (auto& it : recv_streams_) { | 1435 for (auto& it : recv_streams_) { | 
| 1426 it.second->RecreateAudioReceiveStream(recv_rtp_extensions_); | 1436 it.second->RecreateAudioReceiveStream(recv_rtp_extensions_); | 
| 1427 } | 1437 } | 
| 1428 } | 1438 } | 
| 1429 return true; | 1439 return true; | 
| 1430 } | 1440 } | 
| 1431 | 1441 | 
| 1442 webrtc::RTCRtpParameters WebRtcVoiceMediaChannel::GetRtpParameters( | |
| 
pthatcher1
2016/03/12 01:21:04
Can you split this into a CL for video and a secon
 | |
| 1443 uint32_t ssrc) { | |
| 1444 auto it = send_streams_.find(ssrc); | |
| 1445 if (it == send_streams_.end()) { | |
| 1446 LOG(LS_WARNING) << "Attempting to get RTP parameters for stream with ssrc " | |
| 1447 << ssrc << " which doesn't exist."; | |
| 1448 return webrtc::RTCRtpParameters(); | |
| 1449 } | |
| 1450 return it->second->rtp_parameters(); | |
| 1451 } | |
| 1452 | |
| 1453 bool WebRtcVoiceMediaChannel::SetRtpParameters( | |
| 1454 uint32_t ssrc, | |
| 1455 const webrtc::RTCRtpParameters& parameters) { | |
| 1456 auto it = send_streams_.find(ssrc); | |
| 1457 if (it == send_streams_.end()) { | |
| 1458 LOG(LS_WARNING) << "Trying to set RTP parameters for stream with ssrc " | |
| 1459 << ssrc << " which doesn't exist."; | |
| 1460 return false; | |
| 1461 } | |
| 1462 | |
| 1463 if (parameters.encodings.size() != 1) { | |
| 1464 LOG(LS_WARNING) | |
| 1465 << "Attempting to set RTP parameters without exactly 1 encoding"; | |
| 1466 return false; | |
| 1467 } | |
| 1468 if (ApplyBitrateLimits(it->second->channel(), send_bitrate_bps_, | |
| 1469 parameters.encodings[0].max_bitrate_bps)) { | |
| 1470 it->second->set_rtp_parameters(parameters); | |
| 1471 return true; | |
| 1472 } | |
| 
pthatcher1
2016/03/12 01:21:04
It feels like we should move the ApplyBitrateLimit
 | |
| 1473 return false; | |
| 1474 } | |
| 1475 | |
| 1432 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1476 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 
| 1433 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1477 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1434 LOG(LS_INFO) << "Setting voice channel options: " | 1478 LOG(LS_INFO) << "Setting voice channel options: " | 
| 1435 << options.ToString(); | 1479 << options.ToString(); | 
| 1436 | 1480 | 
| 1437 // We retain all of the existing options, and apply the given ones | 1481 // We retain all of the existing options, and apply the given ones | 
| 1438 // on top. This means there is no way to "clear" options such that | 1482 // on top. This means there is no way to "clear" options such that | 
| 1439 // they go back to the engine default. | 1483 // they go back to the engine default. | 
| 1440 options_.SetAll(options); | 1484 options_.SetAll(options); | 
| 1441 if (!engine()->ApplyOptions(options_)) { | 1485 if (!engine()->ApplyOptions(options_)) { | 
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2349 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to | 2393 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to | 
| 2350 // SetMaxSendBitrate() in future. | 2394 // SetMaxSendBitrate() in future. | 
| 2351 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { | 2395 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { | 
| 2352 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; | 2396 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; | 
| 2353 return SetSendBitrateInternal(bps); | 2397 return SetSendBitrateInternal(bps); | 
| 2354 } | 2398 } | 
| 2355 | 2399 | 
| 2356 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { | 2400 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { | 
| 2357 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; | 2401 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; | 
| 2358 | 2402 | 
| 2403 for (const auto& ch : send_streams_) { | |
| 2404 if (!ApplyBitrateLimits( | |
| 2405 ch.second->channel(), bps, | |
| 2406 ch.second->rtp_parameters().encodings[0].max_bitrate_bps)) { | |
| 2407 LOG(LS_INFO) << "Failed to limit max bitrate of a stream"; | |
| 2408 return false; | |
| 2409 } | |
| 2410 } | |
| 2411 | |
| 2412 if (send_streams_.size() == 0) { | |
| 2413 LOG(LS_ERROR) << "send_streams_ empty!"; | |
| 2414 } | |
| 2415 | |
| 2359 send_bitrate_setting_ = true; | 2416 send_bitrate_setting_ = true; | 
| 2360 send_bitrate_bps_ = bps; | 2417 send_bitrate_bps_ = bps; | 
| 2418 return true; | |
| 2419 } | |
| 2361 | 2420 | 
| 2421 bool WebRtcVoiceMediaChannel::ApplyBitrateLimits(int channel, | |
| 2422 int global_limit, | |
| 2423 int local_limit) { | |
| 
pthatcher1
2016/03/12 01:21:04
Why not just pass in one value and do the min() be
 | |
| 2362 if (!send_codec_) { | 2424 if (!send_codec_) { | 
| 2363 LOG(LS_INFO) << "The send codec has not been set up yet. " | 2425 LOG(LS_INFO) << "The send codec has not been set up yet. " | 
| 2364 << "The send bitrate setting will be applied later."; | 2426 << "The send bitrate setting will be applied later."; | 
| 2365 return true; | 2427 return true; | 
| 2366 } | 2428 } | 
| 2367 | 2429 | 
| 2430 int bps = MinPositive(global_limit, local_limit); | |
| 2431 | |
| 2432 LOG(LS_INFO) << "Applying bandwidth limit to channel " << channel | |
| 2433 << ": global_limit=" << global_limit | |
| 2434 << " local_limit=" << local_limit << " result=" << bps; | |
| 2435 | |
| 2368 // Bitrate is auto by default. | 2436 // Bitrate is auto by default. | 
| 2369 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | 2437 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | 
| 2370 // SetMaxSendBandwith(0), the second call removes the previous limit. | 2438 // SetMaxSendBandwith(0), the second call removes the previous limit. | 
| 2371 if (bps <= 0) | 2439 if (bps <= 0) | 
| 2372 return true; | 2440 return true; | 
| 2373 | 2441 | 
| 2374 webrtc::CodecInst codec = *send_codec_; | 2442 webrtc::CodecInst codec = *send_codec_; | 
| 2375 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); | 2443 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); | 
| 2376 | 2444 | 
| 2377 if (is_multi_rate) { | 2445 if (is_multi_rate) { | 
| 2378 // If codec is multi-rate then just set the bitrate. | 2446 // If codec is multi-rate then just set the bitrate. | 
| 2379 codec.rate = bps; | 2447 codec.rate = bps; | 
| 2380 for (const auto& ch : send_streams_) { | 2448 if (!SetSendCodec(channel, codec)) { | 
| 2381 if (!SetSendCodec(ch.second->channel(), codec)) { | 2449 LOG(LS_INFO) << "Failed to set codec " << codec.plname << " to bitrate " | 
| 2382 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2450 << bps << " bps."; | 
| 2383 << " to bitrate " << bps << " bps."; | 2451 return false; | 
| 2384 return false; | |
| 2385 } | |
| 2386 } | 2452 } | 
| 2387 return true; | 2453 return true; | 
| 2388 } else { | 2454 } else { | 
| 2389 // If codec is not multi-rate and |bps| is less than the fixed bitrate | 2455 // If codec is not multi-rate and |bps| is less than the fixed bitrate | 
| 2390 // then fail. If codec is not multi-rate and |bps| exceeds or equal the | 2456 // then fail. If codec is not multi-rate and |bps| exceeds or equal the | 
| 2391 // fixed bitrate then ignore. | 2457 // fixed bitrate then ignore. | 
| 2392 if (bps < codec.rate) { | 2458 if (bps < codec.rate) { | 
| 2393 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2459 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 
| 2394 << " to bitrate " << bps << " bps" | 2460 << " to bitrate " << bps << " bps" | 
| 2395 << ", requires at least " << codec.rate << " bps."; | 2461 << ", requires at least " << codec.rate << " bps."; | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2520 } | 2586 } | 
| 2521 } else { | 2587 } else { | 
| 2522 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2588 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 
| 2523 engine()->voe()->base()->StopPlayout(channel); | 2589 engine()->voe()->base()->StopPlayout(channel); | 
| 2524 } | 2590 } | 
| 2525 return true; | 2591 return true; | 
| 2526 } | 2592 } | 
| 2527 } // namespace cricket | 2593 } // namespace cricket | 
| 2528 | 2594 | 
| 2529 #endif // HAVE_WEBRTC_VOICE | 2595 #endif // HAVE_WEBRTC_VOICE | 
| OLD | NEW |