| Index: webrtc/call/call.cc
 | 
| diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc
 | 
| index c7e49dee1a2ef587052eadd88edd406ba74bd218..aa888fb6520a1f6f23308af49fdbb4d8d08ef090 100644
 | 
| --- a/webrtc/call/call.cc
 | 
| +++ b/webrtc/call/call.cc
 | 
| @@ -63,11 +63,7 @@ const int Call::Config::kDefaultStartBitrateBps = 300000;
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| -// TODO(nisse): This really begs for a shared context struct.
 | 
| -bool UseSendSideBwe(const std::vector<RtpExtension>& extensions,
 | 
| -                    bool transport_cc) {
 | 
| -  if (!transport_cc)
 | 
| -    return false;
 | 
| +bool UseTransportSeqno(const std::vector<RtpExtension>& extensions) {
 | 
|    for (const auto& extension : extensions) {
 | 
|      if (extension.uri == RtpExtension::kTransportSequenceNumberUri)
 | 
|        return true;
 | 
| @@ -75,18 +71,16 @@ bool UseSendSideBwe(const std::vector<RtpExtension>& extensions,
 | 
|    return false;
 | 
|  }
 | 
|  
 | 
| -bool UseSendSideBwe(const VideoReceiveStream::Config& config) {
 | 
| -  return UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc);
 | 
| +// TODO(nisse): This really begs for a shared context struct.
 | 
| +bool UseSendSideBwe(const std::vector<RtpExtension>& extensions,
 | 
| +                    bool transport_cc) {
 | 
| +  return transport_cc && UseTransportSeqno(extensions);
 | 
|  }
 | 
|  
 | 
|  bool UseSendSideBwe(const AudioReceiveStream::Config& config) {
 | 
|    return UseSendSideBwe(config.rtp.extensions, config.rtp.transport_cc);
 | 
|  }
 | 
|  
 | 
| -bool UseSendSideBwe(const FlexfecReceiveStream::Config& config) {
 | 
| -  return UseSendSideBwe(config.rtp_header_extensions, config.transport_cc);
 | 
| -}
 | 
| -
 | 
|  class RtpTransportControllerSend : public RtpTransportControllerSendInterface {
 | 
|   public:
 | 
|    RtpTransportControllerSend(Clock* clock, webrtc::RtcEventLog* event_log);
 | 
| @@ -138,6 +132,9 @@ class Call : public webrtc::Call,
 | 
|    // Implements webrtc::Call.
 | 
|    PacketReceiver* Receiver() override;
 | 
|  
 | 
| +  void SetVideoReceiveRtpHeaderExtensions(
 | 
| +      const std::vector<RtpExtension>& extensions) override;
 | 
| +
 | 
|    webrtc::AudioSendStream* CreateAudioSendStream(
 | 
|        const webrtc::AudioSendStream::Config& config) override;
 | 
|    void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override;
 | 
| @@ -255,6 +252,9 @@ class Call : public webrtc::Call,
 | 
|    std::map<std::string, AudioReceiveStream*> sync_stream_mapping_
 | 
|        GUARDED_BY(receive_crit_);
 | 
|  
 | 
| +  std::vector<RtpExtension> video_rtp_header_extensions_
 | 
| +      GUARDED_BY(receive_crit_);
 | 
| +
 | 
|    // This extra map is used for receive processing which is
 | 
|    // independent of media type.
 | 
|  
 | 
| @@ -533,6 +533,12 @@ PacketReceiver* Call::Receiver() {
 | 
|    return this;
 | 
|  }
 | 
|  
 | 
| +void Call::SetVideoReceiveRtpHeaderExtensions(
 | 
| +    const std::vector<RtpExtension>& extensions) {
 | 
| +  WriteLockScoped write_lock(*receive_crit_);
 | 
| +  video_rtp_header_extensions_ = extensions;
 | 
| +}
 | 
| +
 | 
|  webrtc::AudioSendStream* Call::CreateAudioSendStream(
 | 
|      const webrtc::AudioSendStream::Config& config) {
 | 
|    TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
 | 
| @@ -724,12 +730,15 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream(
 | 
|                               module_process_thread_.get(), call_stats_.get());
 | 
|  
 | 
|    const webrtc::VideoReceiveStream::Config& config = receive_stream->config();
 | 
| -  ReceiveRtpConfig receive_config(config.rtp.extensions,
 | 
| -                                  UseSendSideBwe(config));
 | 
|    {
 | 
|      WriteLockScoped write_lock(*receive_crit_);
 | 
|      RTC_DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
 | 
|                 video_receive_ssrcs_.end());
 | 
| +    ReceiveRtpConfig receive_config(
 | 
| +        video_rtp_header_extensions_,
 | 
| +        config.rtp.transport_cc &&
 | 
| +        UseTransportSeqno(video_rtp_header_extensions_));
 | 
| +
 | 
|      video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
 | 
|      if (config.rtp.rtx_ssrc) {
 | 
|        video_receive_ssrcs_[config.rtp.rtx_ssrc] = receive_stream;
 | 
| @@ -755,6 +764,7 @@ void Call::DestroyVideoReceiveStream(
 | 
|    RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
 | 
|    RTC_DCHECK(receive_stream != nullptr);
 | 
|    VideoReceiveStream* receive_stream_impl = nullptr;
 | 
| +  bool use_send_side_bwe = false;
 | 
|    {
 | 
|      WriteLockScoped write_lock(*receive_crit_);
 | 
|      // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a
 | 
| @@ -762,8 +772,10 @@ void Call::DestroyVideoReceiveStream(
 | 
|      auto it = video_receive_ssrcs_.begin();
 | 
|      while (it != video_receive_ssrcs_.end()) {
 | 
|        if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) {
 | 
| -        if (receive_stream_impl != nullptr)
 | 
| +        if (receive_stream_impl != nullptr) {
 | 
|            RTC_DCHECK(receive_stream_impl == it->second);
 | 
| +          use_send_side_bwe = receive_rtp_config_[it->first].use_send_side_bwe;
 | 
| +        }
 | 
|          receive_stream_impl = it->second;
 | 
|          receive_rtp_config_.erase(it->first);
 | 
|          it = video_receive_ssrcs_.erase(it);
 | 
| @@ -771,13 +783,13 @@ void Call::DestroyVideoReceiveStream(
 | 
|          ++it;
 | 
|        }
 | 
|      }
 | 
| -    video_receive_streams_.erase(receive_stream_impl);
 | 
|      RTC_CHECK(receive_stream_impl != nullptr);
 | 
| +    video_receive_streams_.erase(receive_stream_impl);
 | 
|      ConfigureSync(receive_stream_impl->config().sync_group);
 | 
|    }
 | 
|    const VideoReceiveStream::Config& config = receive_stream_impl->config();
 | 
|  
 | 
| -  receive_side_cc_.GetRemoteBitrateEstimator(UseSendSideBwe(config))
 | 
| +  receive_side_cc_.GetRemoteBitrateEstimator(use_send_side_bwe)
 | 
|        ->RemoveStream(config.rtp.remote_ssrc);
 | 
|  
 | 
|    UpdateAggregateNetworkState();
 | 
| @@ -811,7 +823,9 @@ FlexfecReceiveStream* Call::CreateFlexfecReceiveStream(
 | 
|      RTC_DCHECK(receive_rtp_config_.find(config.remote_ssrc) ==
 | 
|                 receive_rtp_config_.end());
 | 
|      receive_rtp_config_[config.remote_ssrc] =
 | 
| -        ReceiveRtpConfig(config.rtp_header_extensions, UseSendSideBwe(config));
 | 
| +        ReceiveRtpConfig(video_rtp_header_extensions_,
 | 
| +                         config.transport_cc &&
 | 
| +                         UseTransportSeqno(video_rtp_header_extensions_));
 | 
|    }
 | 
|  
 | 
|    // TODO(brandtr): Store config in RtcEventLog here.
 | 
| @@ -834,6 +848,9 @@ void Call::DestroyFlexfecReceiveStream(FlexfecReceiveStream* receive_stream) {
 | 
|      const FlexfecReceiveStream::Config& config =
 | 
|          receive_stream_impl->GetConfig();
 | 
|      uint32_t ssrc = config.remote_ssrc;
 | 
| +    receive_side_cc_.GetRemoteBitrateEstimator(
 | 
| +        receive_rtp_config_[ssrc].use_send_side_bwe)
 | 
| +        ->RemoveStream(ssrc);
 | 
|      receive_rtp_config_.erase(ssrc);
 | 
|  
 | 
|      // Remove all SSRCs pointing to the FlexfecReceiveStreamImpl to be
 | 
| @@ -853,9 +870,6 @@ void Call::DestroyFlexfecReceiveStream(FlexfecReceiveStream* receive_stream) {
 | 
|          ++media_it;
 | 
|      }
 | 
|  
 | 
| -    receive_side_cc_.GetRemoteBitrateEstimator(UseSendSideBwe(config))
 | 
| -        ->RemoveStream(ssrc);
 | 
| -
 | 
|      flexfec_receive_streams_.erase(receive_stream_impl);
 | 
|    }
 | 
|  
 | 
| 
 |