Index: webrtc/media/engine/webrtcvideoengine2.cc |
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc |
index d4360b8f00523094e2ce9fa0d9c7212a817097e3..d81c849234ecf9c6b1955f6504915c982dfd0274 100644 |
--- a/webrtc/media/engine/webrtcvideoengine2.cc |
+++ b/webrtc/media/engine/webrtcvideoengine2.cc |
@@ -263,39 +263,6 @@ inline bool ContainsHeaderExtension( |
return false; |
} |
-// Merges two fec configs and logs an error if a conflict arises |
-// such that merging in different order would trigger a different output. |
-static void MergeFecConfig(const webrtc::FecConfig& other, |
- webrtc::FecConfig* output) { |
- if (other.ulpfec_payload_type != -1) { |
- if (output->ulpfec_payload_type != -1 && |
- output->ulpfec_payload_type != other.ulpfec_payload_type) { |
- LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " |
- << output->ulpfec_payload_type << " and " |
- << other.ulpfec_payload_type; |
- } |
- output->ulpfec_payload_type = other.ulpfec_payload_type; |
- } |
- if (other.red_payload_type != -1) { |
- if (output->red_payload_type != -1 && |
- output->red_payload_type != other.red_payload_type) { |
- LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " |
- << output->red_payload_type << " and " |
- << other.red_payload_type; |
- } |
- output->red_payload_type = other.red_payload_type; |
- } |
- if (other.red_rtx_payload_type != -1) { |
- if (output->red_rtx_payload_type != -1 && |
- output->red_rtx_payload_type != other.red_rtx_payload_type) { |
- LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " |
- << output->red_rtx_payload_type << " and " |
- << other.red_rtx_payload_type; |
- } |
- output->red_rtx_payload_type = other.red_rtx_payload_type; |
- } |
-} |
- |
// Returns true if the given codec is disallowed from doing simulcast. |
bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { |
return CodecNamesEq(codec_name, kH264CodecName) || |
@@ -682,7 +649,8 @@ WebRtcVideoChannel2::WebRtcVideoChannel2( |
video_config_(config.video), |
external_encoder_factory_(external_encoder_factory), |
external_decoder_factory_(external_decoder_factory), |
- default_send_options_(options) { |
+ default_send_options_(options), |
+ red_disabled_by_remote_side_(false) { |
RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; |
@@ -872,6 +840,19 @@ bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { |
: webrtc::RtcpMode::kCompound); |
} |
} |
+ if (changed_params.codec) { |
+ bool red_was_disabled = red_disabled_by_remote_side_; |
+ red_disabled_by_remote_side_ = |
+ changed_params.codec->fec.red_payload_type == -1; |
+ if (red_was_disabled != red_disabled_by_remote_side_) { |
+ for (auto& kv : receive_streams_) { |
+ // In practice VideoChannel::SetRemoteContent appears to most of the |
+ // time also call UpdateRemoteStreams, which recreates the receive |
+ // streams. If that's always true this call isn't needed. |
+ kv.second->SetFecDisabledRemotely(red_disabled_by_remote_side_); |
+ } |
+ } |
+ } |
} |
send_params_ = params; |
return true; |
@@ -1237,7 +1218,7 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, |
receive_streams_[ssrc] = new WebRtcVideoReceiveStream( |
call_, sp, config, external_decoder_factory_, default_stream, |
- recv_codecs_); |
+ recv_codecs_, red_disabled_by_remote_side_); |
return true; |
} |
@@ -1273,10 +1254,6 @@ void WebRtcVideoChannel2::ConfigureReceiverRtp( |
} |
for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
- MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); |
- } |
- |
- for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
uint32_t rtx_ssrc; |
if (recv_codecs_[i].rtx_payload_type != -1 && |
sp.GetFidSsrc(ssrc, &rtx_ssrc)) { |
@@ -2239,13 +2216,15 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( |
const webrtc::VideoReceiveStream::Config& config, |
WebRtcVideoDecoderFactory* external_decoder_factory, |
bool default_stream, |
- const std::vector<VideoCodecSettings>& recv_codecs) |
+ const std::vector<VideoCodecSettings>& recv_codecs, |
+ bool red_disabled_by_remote_side) |
: call_(call), |
ssrcs_(sp.ssrcs), |
ssrc_groups_(sp.ssrc_groups), |
stream_(NULL), |
default_stream_(default_stream), |
config_(config), |
+ red_disabled_by_remote_side_(red_disabled_by_remote_side), |
external_decoder_factory_(external_decoder_factory), |
sink_(NULL), |
last_width_(-1), |
@@ -2421,7 +2400,13 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { |
if (stream_ != NULL) { |
call_->DestroyVideoReceiveStream(stream_); |
} |
- stream_ = call_->CreateVideoReceiveStream(config_); |
+ webrtc::VideoReceiveStream::Config config = config_; |
+ if (red_disabled_by_remote_side_) { |
+ config.rtp.fec.red_payload_type = -1; |
+ config.rtp.fec.ulpfec_payload_type = -1; |
+ config.rtp.fec.red_rtx_payload_type = -1; |
+ } |
+ stream_ = call_->CreateVideoReceiveStream(config); |
stream_->Start(); |
} |
@@ -2529,6 +2514,12 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { |
return info; |
} |
+void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetFecDisabledRemotely( |
+ bool disable) { |
+ red_disabled_by_remote_side_ = disable; |
+ RecreateWebRtcStream(); |
+} |
+ |
WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() |
: rtx_payload_type(-1) {} |