Removed SSRC knowledge from ViEEncoder.

SSRC knowledge is contained withing VideoSendStream. That also means that debug recording is moved to VideoSendStream.
I think that make sence since that allows debug recording with external encoder implementations one day.

BUG=webrtc:5687

Review-Url: https://codereview.webrtc.org/1936503002
Cr-Commit-Position: refs/heads/master@{#12632}
diff --git a/webrtc/modules/video_coding/include/video_coding.h b/webrtc/modules/video_coding/include/video_coding.h
index 295911d..7d2bdb6 100644
--- a/webrtc/modules/video_coding/include/video_coding.h
+++ b/webrtc/modules/video_coding/include/video_coding.h
@@ -230,7 +230,7 @@
   //
   // Return value      : VCM_OK, on success.
   //                     < 0,    on error.
-  virtual int32_t IntraFrameRequest(int stream_index) = 0;
+  virtual int32_t IntraFrameRequest(size_t stream_index) = 0;
 
   // Frame Dropper enable. Can be used to disable the frame dropping when the
   // encoder
diff --git a/webrtc/modules/video_coding/video_coding_impl.cc b/webrtc/modules/video_coding/video_coding_impl.cc
index 219f668..970236d 100644
--- a/webrtc/modules/video_coding/video_coding_impl.cc
+++ b/webrtc/modules/video_coding/video_coding_impl.cc
@@ -152,7 +152,7 @@
     return sender_.AddVideoFrame(videoFrame, contentMetrics, codecSpecificInfo);
   }
 
-  int32_t IntraFrameRequest(int stream_index) override {
+  int32_t IntraFrameRequest(size_t stream_index) override {
     return sender_.IntraFrameRequest(stream_index);
   }
 
diff --git a/webrtc/modules/video_coding/video_coding_impl.h b/webrtc/modules/video_coding/video_coding_impl.h
index a4f74eb..9e99ab4 100644
--- a/webrtc/modules/video_coding/video_coding_impl.h
+++ b/webrtc/modules/video_coding/video_coding_impl.h
@@ -88,7 +88,7 @@
                         const VideoContentMetrics* _contentMetrics,
                         const CodecSpecificInfo* codecSpecificInfo);
 
-  int32_t IntraFrameRequest(int stream_index);
+  int32_t IntraFrameRequest(size_t stream_index);
   int32_t EnableFrameDropper(bool enable);
 
   void SuspendBelowMinBitrate();
diff --git a/webrtc/modules/video_coding/video_sender.cc b/webrtc/modules/video_coding/video_sender.cc
index a407c9e..4d544ae 100644
--- a/webrtc/modules/video_coding/video_sender.cc
+++ b/webrtc/modules/video_coding/video_sender.cc
@@ -335,11 +335,10 @@
   return VCM_OK;
 }
 
-int32_t VideoSender::IntraFrameRequest(int stream_index) {
+int32_t VideoSender::IntraFrameRequest(size_t stream_index) {
   {
     rtc::CritScope lock(&params_crit_);
-    if (stream_index < 0 ||
-        static_cast<size_t>(stream_index) >= next_frame_types_.size()) {
+    if (stream_index >= next_frame_types_.size()) {
       return -1;
     }
     next_frame_types_[stream_index] = kVideoFrameKey;
@@ -353,7 +352,7 @@
   // encoder_crit_.
   rtc::CritScope lock(&encoder_crit_);
   rtc::CritScope params_lock(&params_crit_);
-  if (static_cast<size_t>(stream_index) >= next_frame_types_.size())
+  if (stream_index >= next_frame_types_.size())
     return -1;
   if (_encoder != nullptr && _encoder->InternalSource()) {
     // Try to request the frame if we have an external encoder with
diff --git a/webrtc/modules/video_coding/video_sender_unittest.cc b/webrtc/modules/video_coding/video_sender_unittest.cc
index 7d4d066..3a779ba 100644
--- a/webrtc/modules/video_coding/video_sender_unittest.cc
+++ b/webrtc/modules/video_coding/video_sender_unittest.cc
@@ -290,10 +290,6 @@
   EXPECT_EQ(-1, sender_->IntraFrameRequest(3));
   ExpectIntraRequest(-1);
   AddFrame();
-
-  EXPECT_EQ(-1, sender_->IntraFrameRequest(-1));
-  ExpectIntraRequest(-1);
-  AddFrame();
 }
 
 TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequestsInternalCapture) {
@@ -313,7 +309,6 @@
   EXPECT_EQ(0, sender_->IntraFrameRequest(2));
   // No requests expected since these indices are out of bounds.
   EXPECT_EQ(-1, sender_->IntraFrameRequest(3));
-  EXPECT_EQ(-1, sender_->IntraFrameRequest(-1));
 }
 
 TEST_F(TestVideoSenderWithMockEncoder, TestEncoderParametersForInternalSource) {
diff --git a/webrtc/video/encoder_state_feedback.cc b/webrtc/video/encoder_state_feedback.cc
index 52f5111..28508d0 100644
--- a/webrtc/video/encoder_state_feedback.cc
+++ b/webrtc/video/encoder_state_feedback.cc
@@ -13,16 +13,18 @@
 #include "webrtc/base/checks.h"
 #include "webrtc/video/vie_encoder.h"
 
+static const int kMinKeyFrameRequestIntervalMs = 300;
+
 namespace webrtc {
 
-EncoderStateFeedback::EncoderStateFeedback() : vie_encoder_(nullptr) {}
-
-void EncoderStateFeedback::Init(const std::vector<uint32_t>& ssrcs,
-                                ViEEncoder* encoder) {
+EncoderStateFeedback::EncoderStateFeedback(Clock* clock,
+                                           const std::vector<uint32_t>& ssrcs,
+                                           ViEEncoder* encoder)
+    : clock_(clock),
+      ssrcs_(ssrcs),
+      vie_encoder_(encoder),
+      time_last_intra_request_ms_(ssrcs.size(), -1) {
   RTC_DCHECK(!ssrcs.empty());
-  rtc::CritScope lock(&crit_);
-  ssrcs_ = ssrcs;
-  vie_encoder_ = encoder;
 }
 
 bool EncoderStateFeedback::HasSsrc(uint32_t ssrc) {
@@ -33,41 +35,59 @@
   return false;
 }
 
+size_t EncoderStateFeedback::GetStreamIndex(uint32_t ssrc) {
+  for (size_t i = 0; i < ssrcs_.size(); ++i) {
+    if (ssrcs_[i] == ssrc)
+      return i;
+  }
+  RTC_NOTREACHED() << "Unknown ssrc " << ssrc;
+  return 0;
+}
+
 void EncoderStateFeedback::OnReceivedIntraFrameRequest(uint32_t ssrc) {
-  rtc::CritScope lock(&crit_);
   if (!HasSsrc(ssrc))
     return;
-  RTC_DCHECK(vie_encoder_);
 
-  vie_encoder_->OnReceivedIntraFrameRequest(ssrc);
+  size_t index = GetStreamIndex(ssrc);
+  {
+    int64_t now_ms = clock_->TimeInMilliseconds();
+    rtc::CritScope lock(&crit_);
+    if (time_last_intra_request_ms_[index] + kMinKeyFrameRequestIntervalMs >
+        now_ms) {
+      return;
+    }
+    time_last_intra_request_ms_[index] = now_ms;
+  }
+
+  vie_encoder_->OnReceivedIntraFrameRequest(index);
 }
 
 void EncoderStateFeedback::OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
-  rtc::CritScope lock(&crit_);
   if (!HasSsrc(ssrc))
     return;
-  RTC_DCHECK(vie_encoder_);
 
-  vie_encoder_->OnReceivedSLI(ssrc, picture_id);
+  vie_encoder_->OnReceivedSLI(picture_id);
 }
 
 void EncoderStateFeedback::OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
-  rtc::CritScope lock(&crit_);
   if (!HasSsrc(ssrc))
     return;
-  RTC_DCHECK(vie_encoder_);
 
-  vie_encoder_->OnReceivedRPSI(ssrc, picture_id);
+  vie_encoder_->OnReceivedRPSI(picture_id);
 }
 
 // Sending SSRCs for this encoder should never change since they are configured
-// once and not reconfigured.
+// once and not reconfigured, however, OnLocalSsrcChanged is called when the
+// RtpModules are created with a different SSRC than what will be used in the
+// end.
+// TODO(perkj): Can we make sure the RTP module is created with the right SSRC
+// from the beginning so this method is not triggered during creation ?
 void EncoderStateFeedback::OnLocalSsrcChanged(uint32_t old_ssrc,
                                               uint32_t new_ssrc) {
   if (!RTC_DCHECK_IS_ON)
     return;
-  rtc::CritScope lock(&crit_);
-  if (ssrcs_.empty())  // Encoder not yet attached (or detached for teardown).
+
+  if (old_ssrc == 0)  // old_ssrc == 0 during creation.
     return;
   // SSRC shouldn't change to something we haven't already registered with the
   // encoder.
diff --git a/webrtc/video/encoder_state_feedback.h b/webrtc/video/encoder_state_feedback.h
index 57595a0..c9fb9cc 100644
--- a/webrtc/video/encoder_state_feedback.h
+++ b/webrtc/video/encoder_state_feedback.h
@@ -7,10 +7,6 @@
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
-
-// TODO(mflodman) ViEEncoder has a time check to not send key frames too often,
-// move the logic to this class.
-
 #ifndef WEBRTC_VIDEO_ENCODER_STATE_FEEDBACK_H_
 #define WEBRTC_VIDEO_ENCODER_STATE_FEEDBACK_H_
 
@@ -18,6 +14,7 @@
 
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
@@ -26,22 +23,24 @@
 
 class EncoderStateFeedback : public RtcpIntraFrameObserver {
  public:
-  EncoderStateFeedback();
-
-  // Adds an encoder to receive feedback for a set of SSRCs.
-  void Init(const std::vector<uint32_t>& ssrc, ViEEncoder* encoder);
-
+  EncoderStateFeedback(Clock* clock,
+                       const std::vector<uint32_t>& ssrcs,
+                       ViEEncoder* encoder);
   void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
   void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) override;
   void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) override;
   void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) override;
 
  private:
-  bool HasSsrc(uint32_t ssrc) EXCLUSIVE_LOCKS_REQUIRED(crit_);
-  rtc::CriticalSection crit_;
+  bool HasSsrc(uint32_t ssrc);
+  size_t GetStreamIndex(uint32_t ssrc);
 
-  std::vector<uint32_t> ssrcs_ GUARDED_BY(crit_);
-  ViEEncoder* vie_encoder_ GUARDED_BY(crit_);
+  Clock* const clock_;
+  const std::vector<uint32_t> ssrcs_;
+  ViEEncoder* const vie_encoder_;
+
+  rtc::CriticalSection crit_;
+  std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(crit_);
 };
 
 }  // namespace webrtc
diff --git a/webrtc/video/encoder_state_feedback_unittest.cc b/webrtc/video/encoder_state_feedback_unittest.cc
index 7dda826..b9f27d5 100644
--- a/webrtc/video/encoder_state_feedback_unittest.cc
+++ b/webrtc/video/encoder_state_feedback_unittest.cc
@@ -12,10 +12,6 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-
-#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
-#include "webrtc/modules/pacing/paced_sender.h"
-#include "webrtc/modules/pacing/packet_router.h"
 #include "webrtc/modules/utility/include/mock/mock_process_thread.h"
 #include "webrtc/video/vie_encoder.h"
 
@@ -27,42 +23,59 @@
  public:
   explicit MockVieEncoder(ProcessThread* process_thread)
       : ViEEncoder(1,
-                   std::vector<uint32_t>(),
                    process_thread,
                    nullptr,
                    nullptr) {}
   ~MockVieEncoder() {}
 
-  MOCK_METHOD1(OnReceivedIntraFrameRequest,
-               void(uint32_t));
-  MOCK_METHOD2(OnReceivedSLI,
-               void(uint32_t ssrc, uint8_t picture_id));
-  MOCK_METHOD2(OnReceivedRPSI,
-               void(uint32_t ssrc, uint64_t picture_id));
+  MOCK_METHOD1(OnReceivedIntraFrameRequest, void(size_t));
+  MOCK_METHOD1(OnReceivedSLI, void(uint8_t picture_id));
+  MOCK_METHOD1(OnReceivedRPSI, void(uint64_t picture_id));
 };
 
-TEST(VieKeyRequestTest, CreateAndTriggerRequests) {
-  static const uint32_t kSsrc = 1234;
-  NiceMock<MockProcessThread> process_thread;
-  PacketRouter router;
-  MockVieEncoder encoder(&process_thread);
+class VieKeyRequestTest : public ::testing::Test {
+ public:
+  VieKeyRequestTest()
+      : encoder_(&process_thread_),
+        simulated_clock_(123456789),
+        encoder_state_feedback_(
+            &simulated_clock_,
+            std::vector<uint32_t>(1, VieKeyRequestTest::kSsrc),
+            &encoder_) {}
 
-  EncoderStateFeedback encoder_state_feedback;
-  encoder_state_feedback.Init(std::vector<uint32_t>(1, kSsrc), &encoder);
+ protected:
+  const uint32_t kSsrc = 1234;
+  NiceMock<MockProcessThread> process_thread_;
+  MockVieEncoder encoder_;
+  SimulatedClock simulated_clock_;
+  EncoderStateFeedback encoder_state_feedback_;
+};
 
-  EXPECT_CALL(encoder, OnReceivedIntraFrameRequest(kSsrc))
-      .Times(1);
-  encoder_state_feedback.OnReceivedIntraFrameRequest(kSsrc);
+TEST_F(VieKeyRequestTest, CreateAndTriggerRequests) {
+  EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
 
   const uint8_t sli_picture_id = 3;
-  EXPECT_CALL(encoder, OnReceivedSLI(kSsrc, sli_picture_id))
-      .Times(1);
-  encoder_state_feedback.OnReceivedSLI(kSsrc, sli_picture_id);
+  EXPECT_CALL(encoder_, OnReceivedSLI(sli_picture_id)).Times(1);
+  encoder_state_feedback_.OnReceivedSLI(kSsrc, sli_picture_id);
 
   const uint64_t rpsi_picture_id = 9;
-  EXPECT_CALL(encoder, OnReceivedRPSI(kSsrc, rpsi_picture_id))
-      .Times(1);
-  encoder_state_feedback.OnReceivedRPSI(kSsrc, rpsi_picture_id);
+  EXPECT_CALL(encoder_, OnReceivedRPSI(rpsi_picture_id)).Times(1);
+  encoder_state_feedback_.OnReceivedRPSI(kSsrc, rpsi_picture_id);
+}
+
+TEST_F(VieKeyRequestTest, TooManyOnReceivedIntraFrameRequest) {
+  EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
+  simulated_clock_.AdvanceTimeMilliseconds(10);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
+
+  EXPECT_CALL(encoder_, OnReceivedIntraFrameRequest(0)).Times(1);
+  simulated_clock_.AdvanceTimeMilliseconds(300);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
+  encoder_state_feedback_.OnReceivedIntraFrameRequest(kSsrc);
 }
 
 }  // namespace webrtc
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 9ffe8a3..840991b 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -24,6 +24,7 @@
 #include "webrtc/modules/pacing/packet_router.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
 #include "webrtc/modules/utility/include/process_thread.h"
+#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
 #include "webrtc/video/call_stats.h"
 #include "webrtc/video/video_capture_input.h"
 #include "webrtc/video/vie_remb.h"
@@ -376,10 +377,12 @@
           config.post_encode_callback,
           &stats_proxy_),
       vie_encoder_(num_cpu_cores,
-                   config_.rtp.ssrcs,
                    module_process_thread_,
                    &stats_proxy_,
                    &overuse_detector_),
+      encoder_feedback_(Clock::GetRealTimeClock(),
+                        config.rtp.ssrcs,
+                        &vie_encoder_),
       video_sender_(vie_encoder_.video_sender()),
       bandwidth_observer_(congestion_controller_->GetBitrateController()
                               ->CreateRtcpBandwidthObserver()),
@@ -407,7 +410,6 @@
   RTC_DCHECK(congestion_controller_);
   RTC_DCHECK(remb_);
 
-  encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_);
 
   // RTP/RTCP initialization.
   for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
@@ -567,6 +569,13 @@
       vie_encoder_.SetEncoder(encoder_settings->video_codec,
                               encoder_settings->min_transmit_bitrate_bps,
                               payload_router_.MaxPayloadLength(), this);
+
+      // Clear stats for disabled layers.
+      for (size_t i = encoder_settings->streams.size();
+           i < config_.rtp.ssrcs.size(); ++i) {
+        stats_proxy_.OnInactiveSsrc(config_.rtp.ssrcs[i]);
+      }
+
       if (config_.suspend_below_min_bitrate) {
         video_sender_->SuspendBelowMinBitrate();
         bitrate_allocator_->EnforceMinBitrate(false);
@@ -627,8 +636,33 @@
   // |encoded_frame_proxy_| forwards frames to |config_.post_encode_callback|;
   encoded_frame_proxy_.Encoded(encoded_image, codec_specific_info,
                                fragmentation);
-  return payload_router_.Encoded(encoded_image, codec_specific_info,
-                                 fragmentation);
+  int32_t return_value = payload_router_.Encoded(
+      encoded_image, codec_specific_info, fragmentation);
+
+  if (kEnableFrameRecording) {
+    int layer = codec_specific_info->codecType == kVideoCodecVP8
+                    ? codec_specific_info->codecSpecific.VP8.simulcastIdx
+                    : 0;
+    IvfFileWriter* file_writer;
+    {
+      if (file_writers_[layer] == nullptr) {
+        std::ostringstream oss;
+        oss << "send_bitstream_ssrc";
+        for (uint32_t ssrc : config_.rtp.ssrcs)
+          oss << "_" << ssrc;
+        oss << "_layer" << layer << ".ivf";
+        file_writers_[layer] =
+            IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
+      }
+      file_writer = file_writers_[layer].get();
+    }
+    if (file_writer) {
+      bool ok = file_writer->WriteFrame(encoded_image);
+      RTC_DCHECK(ok);
+    }
+  }
+
+  return return_value;
 }
 
 void VideoSendStream::ConfigureProtection() {
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index b67e9e5..fa6a7a7 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -34,6 +34,7 @@
 class BitrateAllocator;
 class CallStats;
 class CongestionController;
+class IvfFileWriter;
 class ProcessThread;
 class RtpRtcp;
 class ViEEncoder;
@@ -126,6 +127,10 @@
   BitrateAllocator* const bitrate_allocator_;
   VieRemb* const remb_;
 
+  static const bool kEnableFrameRecording = false;
+  static const int kMaxLayers = 3;
+  std::unique_ptr<IvfFileWriter> file_writers_[kMaxLayers];
+
   rtc::PlatformThread encoder_thread_;
   rtc::Event encoder_wakeup_event_;
   volatile int stop_encoder_thread_;
@@ -134,8 +139,8 @@
       GUARDED_BY(encoder_settings_crit_);
 
   OveruseFrameDetector overuse_detector_;
-  EncoderStateFeedback encoder_feedback_;
   ViEEncoder vie_encoder_;
+  EncoderStateFeedback encoder_feedback_;
   vcm::VideoSender* const video_sender_;
 
   const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
index 91fc1f0..ec20ad9 100644
--- a/webrtc/video/vie_encoder.cc
+++ b/webrtc/video/vie_encoder.cc
@@ -17,26 +17,18 @@
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
 #include "webrtc/base/trace_event.h"
-#include "webrtc/common_video/include/frame_callback.h"
-#include "webrtc/common_video/include/video_image.h"
-#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/pacing/paced_sender.h"
-#include "webrtc/modules/utility/include/process_thread.h"
-#include "webrtc/modules/video_coding/include/video_codec_interface.h"
 #include "webrtc/modules/video_coding/include/video_coding.h"
 #include "webrtc/modules/video_coding/include/video_coding_defines.h"
-#include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/system_wrappers/include/metrics.h"
 #include "webrtc/system_wrappers/include/tick_util.h"
 #include "webrtc/video/overuse_frame_detector.h"
-#include "webrtc/video/payload_router.h"
 #include "webrtc/video/send_statistics_proxy.h"
 #include "webrtc/video_frame.h"
 
 namespace webrtc {
 
 static const float kStopPaddingThresholdMs = 2000;
-static const int kMinKeyFrameRequestIntervalMs = 300;
 
 class QMVideoSettingsCallback : public VCMQMSettingsCallback {
  public:
@@ -54,12 +46,10 @@
 };
 
 ViEEncoder::ViEEncoder(uint32_t number_of_cores,
-                       const std::vector<uint32_t>& ssrcs,
                        ProcessThread* module_process_thread,
                        SendStatisticsProxy* stats_proxy,
                        OveruseFrameDetector* overuse_detector)
     : number_of_cores_(number_of_cores),
-      ssrcs_(ssrcs),
       vp_(VideoProcessing::Create()),
       qm_callback_(new QMVideoSettingsCallback(vp_.get())),
       video_sender_(Clock::GetRealTimeClock(),
@@ -76,7 +66,6 @@
       network_is_transmitting_(true),
       encoder_paused_(true),
       encoder_paused_and_dropped_frame_(false),
-      time_last_intra_request_ms_(ssrcs.size(), -1),
       module_process_thread_(module_process_thread),
       has_received_sli_(false),
       picture_id_sli_(0),
@@ -156,11 +145,6 @@
   }
 
   if (stats_proxy_) {
-    // Clear stats for disabled layers.
-    for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size();
-         ++i) {
-      stats_proxy_->OnInactiveSsrc(ssrcs_[i]);
-    }
     VideoEncoderConfig::ContentType content_type =
         VideoEncoderConfig::ContentType::kRealtimeVideo;
     switch (video_codec.mode) {
@@ -353,30 +337,6 @@
   }
 
   overuse_detector_->FrameSent(encoded_image._timeStamp);
-  if (kEnableFrameRecording) {
-    int layer = codec_specific_info->codecType == kVideoCodecVP8
-                    ? codec_specific_info->codecSpecific.VP8.simulcastIdx
-                    : 0;
-    IvfFileWriter* file_writer;
-    {
-      rtc::CritScope lock(&data_cs_);
-      if (file_writers_[layer] == nullptr) {
-        std::ostringstream oss;
-        oss << "send_bitstream_ssrc";
-        for (uint32_t ssrc : ssrcs_)
-          oss << "_" << ssrc;
-        oss << "_layer" << layer << ".ivf";
-        file_writers_[layer] =
-            IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
-      }
-      file_writer = file_writers_[layer].get();
-    }
-    if (file_writer) {
-      bool ok = file_writer->WriteFrame(encoded_image);
-      RTC_DCHECK(ok);
-    }
-  }
-
   return success;
 }
 
@@ -387,40 +347,22 @@
     stats_proxy_->OnEncoderStatsUpdate(frame_rate, bit_rate, encoder_name);
 }
 
-void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/,
-                               uint8_t picture_id) {
+void ViEEncoder::OnReceivedSLI(uint8_t picture_id) {
   rtc::CritScope lock(&data_cs_);
   picture_id_sli_ = picture_id;
   has_received_sli_ = true;
 }
 
-void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/,
-                                uint64_t picture_id) {
+void ViEEncoder::OnReceivedRPSI(uint64_t picture_id) {
   rtc::CritScope lock(&data_cs_);
   picture_id_rpsi_ = picture_id;
   has_received_rpsi_ = true;
 }
 
-void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t ssrc) {
+void ViEEncoder::OnReceivedIntraFrameRequest(size_t stream_index) {
   // Key frame request from remote side, signal to VCM.
   TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
-
-  for (size_t i = 0; i < ssrcs_.size(); ++i) {
-    if (ssrcs_[i] != ssrc)
-      continue;
-    int64_t now_ms = TickTime::MillisecondTimestamp();
-    {
-      rtc::CritScope lock(&data_cs_);
-      if (time_last_intra_request_ms_[i] + kMinKeyFrameRequestIntervalMs >
-          now_ms) {
-        return;
-      }
-      time_last_intra_request_ms_[i] = now_ms;
-    }
-    video_sender_.IntraFrameRequest(static_cast<int>(i));
-    return;
-  }
-  RTC_NOTREACHED() << "Should not receive keyframe requests on unknown SSRCs.";
+  video_sender_.IntraFrameRequest(stream_index);
 }
 
 void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
@@ -443,8 +385,8 @@
   if (!video_suspension_changed)
     return;
   // Video suspend-state changed, inform codec observer.
-  LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended
-               << " for ssrc " << ssrcs_[0];
+  LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended;
+
   if (stats_proxy_)
     stats_proxy_->OnSuspendChange(video_is_suspended);
 }
diff --git a/webrtc/video/vie_encoder.h b/webrtc/video/vie_encoder.h
index 17ad30b..e309dd5 100644
--- a/webrtc/video/vie_encoder.h
+++ b/webrtc/video/vie_encoder.h
@@ -23,7 +23,6 @@
 #include "webrtc/media/base/videosinkinterface.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "webrtc/modules/video_coding/include/video_coding_defines.h"
-#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
 #include "webrtc/modules/video_coding/video_coding_impl.h"
 #include "webrtc/modules/video_processing/include/video_processing.h"
 #include "webrtc/typedefs.h"
@@ -58,7 +57,6 @@
   friend class ViEBitrateObserver;
 
   ViEEncoder(uint32_t number_of_cores,
-             const std::vector<uint32_t>& ssrcs,
              ProcessThread* module_process_thread,
              SendStatisticsProxy* stats_proxy,
              OveruseFrameDetector* overuse_detector);
@@ -108,9 +106,9 @@
                       const std::string& encoder_name) override;
 
   // virtual to test EncoderStateFeedback with mocks.
-  virtual void OnReceivedIntraFrameRequest(uint32_t ssrc);
-  virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id);
-  virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id);
+  virtual void OnReceivedIntraFrameRequest(size_t stream_index);
+  virtual void OnReceivedSLI(uint8_t picture_id);
+  virtual void OnReceivedRPSI(uint64_t picture_id);
 
   int GetPaddingNeededBps() const;
 
@@ -119,15 +117,11 @@
                         int64_t round_trip_time_ms);
 
  private:
-  static const bool kEnableFrameRecording = false;
-  static const int kMaxLayers = 3;
-
   bool EncoderPaused() const EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
   void TraceFrameDropStart() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
   void TraceFrameDropEnd() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
 
   const uint32_t number_of_cores_;
-  const std::vector<uint32_t> ssrcs_;
 
   const std::unique_ptr<VideoProcessing> vp_;
   const std::unique_ptr<QMVideoSettingsCallback> qm_callback_;
@@ -148,7 +142,6 @@
   bool network_is_transmitting_ GUARDED_BY(data_cs_);
   bool encoder_paused_ GUARDED_BY(data_cs_);
   bool encoder_paused_and_dropped_frame_ GUARDED_BY(data_cs_);
-  std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(data_cs_);
 
   rtc::CriticalSection sink_cs_;
   EncodedImageCallback* sink_ GUARDED_BY(sink_cs_);
@@ -161,8 +154,6 @@
   uint64_t picture_id_rpsi_ GUARDED_BY(data_cs_);
 
   bool video_suspended_ GUARDED_BY(data_cs_);
-
-  std::unique_ptr<IvfFileWriter> file_writers_[kMaxLayers] GUARDED_BY(data_cs_);
 };
 
 }  // namespace webrtc