Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: talk/media/webrtc/webrtcvoiceengine.cc

Issue 1604563002: Add send-side BWE to WebRtcVoiceEngine under a finch experiment. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/media/webrtc/webrtcvoiceengine.cc
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index 6c07ff4154c62c9e2b495536e16f63daaefe043f..e55df96ae3e68024e6cb14231fb04e9c7200ce40 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -194,11 +194,6 @@ bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) {
return it == payload_types.end();
}
-bool IsNackEnabled(const AudioCodec& codec) {
- return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack,
- kParamValueEmpty));
-}
-
// Return true if codec.params[feature] == "1", false otherwise.
bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) {
int value;
@@ -321,6 +316,8 @@ class WebRtcVoiceCodecs final {
rtc::ToString(kPreferredMaxPTime);
}
codec.SetParam(kCodecParamUseInbandFec, 1);
+ codec.AddFeedbackParam(
+ FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));
// TODO(hellner): Add ptime, sprop-stereo, and stereo
// when they can be set to values other than the default.
@@ -933,6 +930,12 @@ RtpCapabilities WebRtcVoiceEngine::GetCapabilities() const {
capabilities.header_extensions.push_back(
RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
+ if (webrtc::field_trial::FindFullName("WebRTC-Audio-SendSideBwe") ==
+ "Enabled") {
+ capabilities.header_extensions.push_back(RtpHeaderExtension(
+ kRtpTransportSequenceNumberHeaderExtension,
+ kRtpTransportSequenceNumberHeaderExtensionDefaultId));
+ }
return capabilities;
}
@@ -1208,19 +1211,22 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
public:
- WebRtcAudioReceiveStream(int ch, uint32_t remote_ssrc, uint32_t local_ssrc,
- bool use_combined_bwe, const std::string& sync_group,
+ WebRtcAudioReceiveStream(int ch,
+ uint32_t remote_ssrc,
+ uint32_t local_ssrc,
+ bool use_combined_bwe,
+ bool use_transport_cc,
+ const std::string& sync_group,
const std::vector<webrtc::RtpExtension>& extensions,
webrtc::Call* call)
- : call_(call),
- config_() {
+ : call_(call), config_() {
RTC_DCHECK_GE(ch, 0);
RTC_DCHECK(call);
config_.rtp.remote_ssrc = remote_ssrc;
config_.rtp.local_ssrc = local_ssrc;
config_.voe_channel_id = ch;
config_.sync_group = sync_group;
- RecreateAudioReceiveStream(use_combined_bwe, extensions);
+ RecreateAudioReceiveStream(use_combined_bwe, use_transport_cc, extensions);
}
~WebRtcAudioReceiveStream() {
@@ -1231,11 +1237,18 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
void RecreateAudioReceiveStream(
const std::vector<webrtc::RtpExtension>& extensions) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- RecreateAudioReceiveStream(config_.combined_audio_video_bwe, extensions);
+ RecreateAudioReceiveStream(config_.combined_audio_video_bwe,
+ config_.rtp.transport_cc, extensions);
}
void RecreateAudioReceiveStream(bool use_combined_bwe) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- RecreateAudioReceiveStream(use_combined_bwe, config_.rtp.extensions);
+ RecreateAudioReceiveStream(use_combined_bwe, config_.rtp.transport_cc,
+ config_.rtp.extensions);
+ }
+ void RecreateAudioReceiveStreamWithTransportCc(bool use_transport_cc) {
+ RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
+ RecreateAudioReceiveStream(config_.combined_audio_video_bwe,
+ use_transport_cc, config_.rtp.extensions);
}
webrtc::AudioReceiveStream::Stats GetStats() const {
@@ -1255,7 +1268,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
}
private:
- void RecreateAudioReceiveStream(bool use_combined_bwe,
+ void RecreateAudioReceiveStream(
+ bool use_combined_bwe,
+ bool use_transport_cc,
const std::vector<webrtc::RtpExtension>& extensions) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
if (stream_) {
@@ -1263,6 +1278,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
stream_ = nullptr;
}
config_.rtp.extensions = extensions;
+ config_.rtp.transport_cc = use_transport_cc;
config_.combined_audio_video_bwe = use_combined_bwe;
RTC_DCHECK(!stream_);
stream_ = call_->CreateAudioReceiveStream(config_);
@@ -1359,7 +1375,6 @@ bool WebRtcVoiceMediaChannel::SetRecvParameters(
it.second->RecreateAudioReceiveStream(recv_rtp_extensions_);
}
}
-
return true;
}
@@ -1481,7 +1496,6 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
// Scan through the list to figure out the codec to use for sending, along
// with the proper configuration for VAD.
- bool found_send_codec = false;
webrtc::CodecInst send_codec;
memset(&send_codec, 0, sizeof(send_codec));
@@ -1489,53 +1503,33 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
bool enable_codec_fec = false;
bool enable_opus_dtx = false;
int opus_max_playback_rate = 0;
+ int red_payload_type = -1;
// Set send codec (the first non-telephone-event/CN codec)
- for (const AudioCodec& codec : codecs) {
- // Ignore codecs we don't know about. The negotiation step should prevent
- // this, but double-check to be sure.
- webrtc::CodecInst voe_codec;
- if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
- LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
- continue;
- }
-
- if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
- // Skip telephone-event/CN codec, which will be handled later.
- continue;
- }
-
- // We'll use the first codec in the list to actually send audio data.
- // Be sure to use the payload type requested by the remote side.
- // "red", for RED audio, is a special case where the actual codec to be
- // used is specified in params.
- if (IsCodec(codec, kRedCodecName)) {
- // Parse out the RED parameters. If we fail, just ignore RED;
- // we don't support all possible params/usage scenarios.
- if (!GetRedSendCodec(codec, codecs, &send_codec)) {
- continue;
- }
-
+ const AudioCodec* codec =
+ GetPreferredCodec(codecs, &send_codec, &red_payload_type);
+ if (codec) {
+ if (red_payload_type != -1) {
// Enable redundant encoding of the specified codec. Treat any
// failure as a fatal internal error.
LOG(LS_INFO) << "Enabling RED on channel " << channel;
- if (engine()->voe()->rtp()->SetREDStatus(channel, true, codec.id) == -1) {
- LOG_RTCERR3(SetREDStatus, channel, true, codec.id);
+ if (engine()->voe()->rtp()->SetREDStatus(channel, true,
+ red_payload_type) == -1) {
+ LOG_RTCERR3(SetREDStatus, channel, true, red_payload_type);
return false;
}
} else {
- send_codec = voe_codec;
- nack_enabled = IsNackEnabled(codec);
+ nack_enabled = HasNack(*codec);
// For Opus as the send codec, we are to determine inband FEC, maximum
// playback rate, and opus internal dtx.
- if (IsCodec(codec, kOpusCodecName)) {
- GetOpusConfig(codec, &send_codec, &enable_codec_fec,
+ if (IsCodec(*codec, kOpusCodecName)) {
+ GetOpusConfig(*codec, &send_codec, &enable_codec_fec,
&opus_max_playback_rate, &enable_opus_dtx);
}
// Set packet size if the AudioCodec param kCodecParamPTime is set.
int ptime_ms = 0;
- if (codec.GetParam(kCodecParamPTime, &ptime_ms)) {
+ if (codec->GetParam(kCodecParamPTime, &ptime_ms)) {
if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(&send_codec, ptime_ms)) {
LOG(LS_WARNING) << "Failed to set packet size for codec "
<< send_codec.plname;
@@ -1543,16 +1537,13 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
}
}
}
- found_send_codec = true;
- break;
}
if (nack_enabled_ != nack_enabled) {
SetNack(channel, nack_enabled);
nack_enabled_ = nack_enabled;
}
-
- if (!found_send_codec) {
+ if (!codec) {
LOG(LS_WARNING) << "Received empty list of codecs.";
return false;
}
@@ -1671,6 +1662,43 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
return true;
}
+const AudioCodec* WebRtcVoiceMediaChannel::GetPreferredCodec(
+ const std::vector<AudioCodec>& codecs,
+ webrtc::CodecInst* voe_codec,
+ int* red_payload_type) const {
+ // Set send codec (the first non-telephone-event/CN codec)
+ for (const AudioCodec& codec : codecs) {
+ *red_payload_type = -1;
+ if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
+ // Skip telephone-event/CN codec, which will be handled later.
+ continue;
+ }
+
+ // We'll use the first codec in the list to actually send audio data.
+ // Be sure to use the payload type requested by the remote side.
+ // "red", for RED audio, is a special case where the actual codec to be
+ // used is specified in params.
+ const AudioCodec* found_codec = &codec;
+ if (IsCodec(*found_codec, kRedCodecName)) {
+ // Parse out the RED parameters. If we fail, just ignore RED;
+ // we don't support all possible params/usage scenarios.
+ *red_payload_type = codec.id;
+ found_codec = GetRedSendCodec(*found_codec, codecs);
+ if (!found_codec) {
+ continue;
+ }
+ }
+ // Ignore codecs we don't know about. The negotiation step should prevent
+ // this, but double-check to be sure.
+ if (!WebRtcVoiceEngine::ToCodecInst(*found_codec, voe_codec)) {
+ LOG(LS_WARNING) << "Unknown codec " << ToString(*found_codec);
+ continue;
+ }
+ return found_codec;
+ }
+ return nullptr;
+}
+
bool WebRtcVoiceMediaChannel::SetSendCodecs(
const std::vector<AudioCodec>& codecs) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
@@ -1700,6 +1728,26 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs(
SetNack(ch.second->channel(), nack_enabled_);
}
+ // Check if the transport cc feedback has changed on the preferred send codec,
+ // and in that case reconfigure all receive streams.
+ webrtc::CodecInst voe_codec;
+ int red_payload_type;
+ const AudioCodec* send_codec =
+ GetPreferredCodec(send_codecs_, &voe_codec, &red_payload_type);
+ if (send_codec) {
+ bool transport_cc = HasTransportCc(*send_codec);
+ if (transport_cc_enabled_ != transport_cc) {
+ LOG(LS_INFO) << "Recreate all the receive streams because the send "
+ "codec has changed.";
+ transport_cc_enabled_ = transport_cc;
+ for (auto& kv : recv_streams_) {
+ RTC_DCHECK(kv.second != nullptr);
+ kv.second->RecreateAudioReceiveStreamWithTransportCc(
+ transport_cc_enabled_);
+ }
+ }
+ }
stefan-webrtc 2016/01/18 15:32:32 I think this should work, as it is what we are doi
+
return true;
}
@@ -2006,10 +2054,15 @@ bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
<< " is associated with channel #" << send_channel << ".";
}
- recv_streams_.insert(std::make_pair(ssrc, new WebRtcAudioReceiveStream(
- channel, ssrc, receiver_reports_ssrc_,
- options_.combined_audio_video_bwe.value_or(false), sp.sync_label,
- recv_rtp_extensions_, call_)));
+ transport_cc_enabled_ =
+ !send_codecs_.empty() ? HasTransportCc(send_codecs_[0]) : false;
+
+ recv_streams_.insert(std::make_pair(
+ ssrc,
+ new WebRtcAudioReceiveStream(
+ channel, ssrc, receiver_reports_ssrc_,
+ options_.combined_audio_video_bwe.value_or(false),
+ transport_cc_enabled_, sp.sync_label, recv_rtp_extensions_, call_)));
SetNack(channel, nack_enabled_);
SetPlayout(channel, playout_);
@@ -2452,8 +2505,9 @@ int WebRtcVoiceMediaChannel::GetSendChannelId(uint32_t ssrc) const {
return -1;
}
-bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
- const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) {
+const AudioCodec* WebRtcVoiceMediaChannel::GetRedSendCodec(
+ const AudioCodec& red_codec,
+ const std::vector<AudioCodec>& all_codecs) const {
// Get the RED encodings from the parameter with no name. This may
// change based on what is discussed on the Jingle list.
// The encoding parameter is of the form "a/b"; we only support where
@@ -2471,7 +2525,7 @@ bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
red_pts[0] != red_pts[1] ||
!rtc::FromString(red_pts[0], &red_pt)) {
LOG(LS_WARNING) << "RED params " << red_params << " not supported.";
- return false;
+ return nullptr;
}
} else if (red_codec.params.empty()) {
LOG(LS_WARNING) << "RED params not present, using defaults";
@@ -2483,17 +2537,11 @@ bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
// Try to find red_pt in |codecs|.
for (const AudioCodec& codec : all_codecs) {
if (codec.id == red_pt) {
- // If we find the right codec, that will be the codec we pass to
- // SetSendCodec, with the desired payload type.
- if (WebRtcVoiceEngine::ToCodecInst(codec, send_codec)) {
- return true;
- } else {
- break;
- }
+ return &codec;
}
}
LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
- return false;
+ return nullptr;
}
bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698