| Index: webrtc/media/engine/webrtcvideoengine2.cc
 | 
| diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
 | 
| index 82d32b0e1865dff74586b16030a8731a6634a5ec..42f6a3789f734c2556866fa97b8e7ca6072b0393 100644
 | 
| --- a/webrtc/media/engine/webrtcvideoengine2.cc
 | 
| +++ b/webrtc/media/engine/webrtcvideoengine2.cc
 | 
| @@ -396,7 +396,8 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams(
 | 
|      const VideoCodec& codec,
 | 
|      const VideoOptions& options,
 | 
|      int max_bitrate_bps,
 | 
| -    size_t num_streams) {
 | 
| +    size_t num_streams,
 | 
| +    bool encode_from_texture) {
 | 
|    int codec_max_bitrate_kbps;
 | 
|    if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) {
 | 
|      max_bitrate_bps = codec_max_bitrate_kbps * 1000;
 | 
| @@ -424,6 +425,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams(
 | 
|    int max_qp = kDefaultQpMax;
 | 
|    codec.GetParam(kCodecParamMaxQuantization, &max_qp);
 | 
|    stream.max_qp = max_qp;
 | 
| +  stream.encode_from_texture = encode_from_texture;
 | 
|    std::vector<webrtc::VideoStream> streams;
 | 
|    streams.push_back(stream);
 | 
|    return streams;
 | 
| @@ -748,7 +750,7 @@ bool WebRtcVideoChannel2::GetChangedSendParameters(
 | 
|    // Handle RTP header extensions.
 | 
|    std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(
 | 
|        params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true);
 | 
| -  if (send_rtp_extensions_ != filtered_extensions) {
 | 
| +  if (!send_rtp_extensions_ || (*send_rtp_extensions_ != filtered_extensions)) {
 | 
|      changed_params->rtp_header_extensions =
 | 
|          rtc::Optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);
 | 
|    }
 | 
| @@ -796,7 +798,7 @@ bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) {
 | 
|    }
 | 
|  
 | 
|    if (changed_params.rtp_header_extensions) {
 | 
| -    send_rtp_extensions_ = *changed_params.rtp_header_extensions;
 | 
| +    send_rtp_extensions_ = changed_params.rtp_header_extensions;
 | 
|    }
 | 
|  
 | 
|    if (changed_params.codec || changed_params.max_bandwidth_bps) {
 | 
| @@ -1520,7 +1522,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
 | 
|      bool enable_cpu_overuse_detection,
 | 
|      int max_bitrate_bps,
 | 
|      const rtc::Optional<VideoCodecSettings>& codec_settings,
 | 
| -    const std::vector<webrtc::RtpExtension>& rtp_extensions,
 | 
| +    const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
 | 
|      // TODO(deadbeef): Don't duplicate information between send_params,
 | 
|      // rtp_extensions, options, etc.
 | 
|      const VideoSendParameters& send_params)
 | 
| @@ -1546,15 +1548,19 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream(
 | 
|    sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
 | 
|                   ¶meters_.config.rtp.rtx.ssrcs);
 | 
|    parameters_.config.rtp.c_name = sp.cname;
 | 
| -  parameters_.config.rtp.extensions = rtp_extensions;
 | 
| +  if (rtp_extensions) {
 | 
| +    parameters_.config.rtp.extensions = *rtp_extensions;
 | 
| +  }
 | 
|    parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
 | 
|                                           ? webrtc::RtcpMode::kReducedSize
 | 
|                                           : webrtc::RtcpMode::kCompound;
 | 
|    parameters_.config.overuse_callback =
 | 
|        enable_cpu_overuse_detection ? this : nullptr;
 | 
|  
 | 
| -  sink_wants_.rotation_applied = !ContainsHeaderExtension(
 | 
| -      rtp_extensions, webrtc::RtpExtension::kVideoRotationUri);
 | 
| +  sink_wants_.rotation_applied =
 | 
| +      rtp_extensions &&
 | 
| +      !ContainsHeaderExtension(*rtp_extensions,
 | 
| +                               webrtc::RtpExtension::kVideoRotationUri);
 | 
|  
 | 
|    if (codec_settings) {
 | 
|      SetCodec(*codec_settings);
 | 
| @@ -1593,6 +1599,20 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame(
 | 
|    webrtc::VideoFrame video_frame(frame.video_frame_buffer(), 0, 0,
 | 
|                                   frame.rotation());
 | 
|    rtc::CritScope cs(&lock_);
 | 
| +
 | 
| +  last_rotation_ = video_frame.rotation();
 | 
| +  last_frame_in_texture_ =
 | 
| +      video_frame.video_frame_buffer()->native_handle() != NULL;
 | 
| +  if (video_frame.width() != last_dimensions_.width ||
 | 
| +      video_frame.height() != last_dimensions_.height) {
 | 
| +    last_dimensions_.width = video_frame.width();
 | 
| +    last_dimensions_.height = video_frame.height();
 | 
| +    pending_encoder_reconfiguration_ = true;
 | 
| +    LOG(LS_INFO) << "Caching frame dimensions: " << last_dimensions_.width
 | 
| +                 << "x" << last_dimensions_.height << ", r=" << last_rotation_
 | 
| +                 << ", texture=" << last_frame_in_texture_;
 | 
| +  }
 | 
| +
 | 
|    if (stream_ == NULL) {
 | 
|      // Frame input before send codecs are configured, dropping frame.
 | 
|      return;
 | 
| @@ -1609,9 +1629,8 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame(
 | 
|    last_frame_timestamp_ms_ = *first_frame_timestamp_ms_ + frame_delta_ms;
 | 
|  
 | 
|    video_frame.set_render_time_ms(last_frame_timestamp_ms_);
 | 
| -  // Reconfigure codec if necessary.
 | 
| -  SetDimensions(video_frame.width(), video_frame.height());
 | 
| -  last_rotation_ = video_frame.rotation();
 | 
| +
 | 
| +  ReconfigureEncoderIfNecessary();
 | 
|  
 | 
|    // Not sending, abort after reconfiguration. Reconfiguration should still
 | 
|    // occur to permit sending this input as quickly as possible once we start
 | 
| @@ -1758,8 +1777,8 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder(
 | 
|  
 | 
|  void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec(
 | 
|      const VideoCodecSettings& codec_settings) {
 | 
| -  parameters_.encoder_config =
 | 
| -      CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec);
 | 
| +  parameters_.encoder_config = CreateVideoEncoderConfig(
 | 
| +      last_dimensions_, last_frame_in_texture_, codec_settings.codec);
 | 
|    RTC_DCHECK(!parameters_.encoder_config.streams.empty());
 | 
|  
 | 
|    AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec);
 | 
| @@ -1899,6 +1918,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateSendState() {
 | 
|  webrtc::VideoEncoderConfig
 | 
|  WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig(
 | 
|      const Dimensions& dimensions,
 | 
| +    bool encode_from_texture,
 | 
|      const VideoCodec& codec) const {
 | 
|    webrtc::VideoEncoderConfig encoder_config;
 | 
|    bool is_screencast = parameters_.options.is_screencast.value_or(false);
 | 
| @@ -1938,8 +1958,9 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig(
 | 
|    int stream_max_bitrate =
 | 
|        MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps,
 | 
|                    parameters_.max_bitrate_bps);
 | 
| -  encoder_config.streams = CreateVideoStreams(
 | 
| -      clamped_codec, parameters_.options, stream_max_bitrate, stream_count);
 | 
| +  encoder_config.streams =
 | 
| +      CreateVideoStreams(clamped_codec, parameters_.options, stream_max_bitrate,
 | 
| +                         stream_count, encode_from_texture);
 | 
|  
 | 
|    // Conference mode screencast uses 2 temporal layers split at 100kbit.
 | 
|    if (parameters_.conference_mode && is_screencast &&
 | 
| @@ -1964,25 +1985,20 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig(
 | 
|    return encoder_config;
 | 
|  }
 | 
|  
 | 
| -void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(
 | 
| -    int width,
 | 
| -    int height) {
 | 
| -  if (last_dimensions_.width == width && last_dimensions_.height == height &&
 | 
| -      !pending_encoder_reconfiguration_) {
 | 
| +void WebRtcVideoChannel2::WebRtcVideoSendStream::
 | 
| +    ReconfigureEncoderIfNecessary() {
 | 
| +  if (!pending_encoder_reconfiguration_) {
 | 
|      // Configured using the same parameters, do not reconfigure.
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  last_dimensions_.width = width;
 | 
| -  last_dimensions_.height = height;
 | 
| -
 | 
|    RTC_DCHECK(!parameters_.encoder_config.streams.empty());
 | 
|  
 | 
|    RTC_CHECK(parameters_.codec_settings);
 | 
|    VideoCodecSettings codec_settings = *parameters_.codec_settings;
 | 
|  
 | 
| -  webrtc::VideoEncoderConfig encoder_config =
 | 
| -      CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec);
 | 
| +  webrtc::VideoEncoderConfig encoder_config = CreateVideoEncoderConfig(
 | 
| +      last_dimensions_, last_frame_in_texture_, codec_settings.codec);
 | 
|  
 | 
|    encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings(
 | 
|        codec_settings.codec);
 | 
| 
 |