Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / rtp_rtcp_impl_unittest.cc
index 0f28854..24ff227 100644 (file)
 #include "testing/gtest/include/gtest/gtest.h"
 
 #include "webrtc/common_types.h"
+#include "webrtc/modules/pacing/include/mock/mock_paced_sender.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "webrtc/system_wrappers/interface/scoped_vector.h"
+#include "webrtc/test/rtcp_packet_parser.h"
+
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::NiceMock;
+using ::testing::Return;
+using ::testing::SaveArg;
 
 namespace webrtc {
 namespace {
 const uint32_t kSenderSsrc = 0x12345;
 const uint32_t kReceiverSsrc = 0x23456;
+const uint32_t kSenderRtxSsrc = 0x32345;
 const uint32_t kOneWayNetworkDelayMs = 100;
+const uint8_t kBaseLayerTid = 0;
+const uint8_t kHigherLayerTid = 1;
+const uint16_t kSequenceNumber = 100;
 
 class RtcpRttStatsTestImpl : public RtcpRttStats {
  public:
   RtcpRttStatsTestImpl() : rtt_ms_(0) {}
   virtual ~RtcpRttStatsTestImpl() {}
 
-  virtual void OnRttUpdate(uint32_t rtt_ms) {
+  virtual void OnRttUpdate(uint32_t rtt_ms) OVERRIDE {
     rtt_ms_ = rtt_ms;
   }
-  virtual uint32_t LastProcessedRtt() const {
+  virtual uint32_t LastProcessedRtt() const OVERRIDE {
     return rtt_ms_;
   }
   uint32_t rtt_ms_;
@@ -38,7 +53,12 @@ class RtcpRttStatsTestImpl : public RtcpRttStats {
 class SendTransport : public Transport,
                       public NullRtpData {
  public:
-  SendTransport() : receiver_(NULL), clock_(NULL), delay_ms_(0) {}
+  SendTransport()
+      : receiver_(NULL),
+        clock_(NULL),
+        delay_ms_(0),
+        rtp_packets_sent_(0) {
+  }
 
   void SetRtpRtcpModule(ModuleRtpRtcpImpl* receiver) {
     receiver_ = receiver;
@@ -47,10 +67,21 @@ class SendTransport : public Transport,
     clock_ = clock;
     delay_ms_ = delay_ms;
   }
-  virtual int SendPacket(int /*ch*/, const void* /*data*/, int /*len*/) {
-    return -1;
+  virtual int SendPacket(int /*ch*/, const void* data, int len) OVERRIDE {
+    RTPHeader header;
+    scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+    EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data),
+                              static_cast<size_t>(len),
+                              &header));
+    ++rtp_packets_sent_;
+    last_rtp_header_ = header;
+    return len;
   }
-  virtual int SendRTCPPacket(int /*ch*/, const void *data, int len) {
+  virtual int SendRTCPPacket(int /*ch*/, const void *data, int len) OVERRIDE {
+    test::RtcpPacketParser parser;
+    parser.Parse(static_cast<const uint8_t*>(data), len);
+    last_nack_list_ = parser.nack_item()->last_nack_list();
+
     if (clock_) {
       clock_->AdvanceTimeMilliseconds(delay_ms_);
     }
@@ -62,6 +93,9 @@ class SendTransport : public Transport,
   ModuleRtpRtcpImpl* receiver_;
   SimulatedClock* clock_;
   uint32_t delay_ms_;
+  int rtp_packets_sent_;
+  RTPHeader last_rtp_header_;
+  std::vector<uint16_t> last_nack_list_;
 };
 
 class RtpRtcpModule {
@@ -80,10 +114,31 @@ class RtpRtcpModule {
 
     transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, clock);
   }
+
+  RtcpPacketTypeCounter packets_sent_;
+  RtcpPacketTypeCounter packets_received_;
   scoped_ptr<ReceiveStatistics> receive_statistics_;
   SendTransport transport_;
   RtcpRttStatsTestImpl rtt_stats_;
   scoped_ptr<ModuleRtpRtcpImpl> impl_;
+
+  RtcpPacketTypeCounter RtcpSent() {
+    impl_->GetRtcpPacketTypeCounters(&packets_sent_, &packets_received_);
+    return packets_sent_;
+  }
+  RtcpPacketTypeCounter RtcpReceived() {
+    impl_->GetRtcpPacketTypeCounters(&packets_sent_, &packets_received_);
+    return packets_received_;
+  }
+  int RtpSent() {
+    return transport_.rtp_packets_sent_;
+  }
+  uint16_t LastRtpSequenceNumber() {
+    return transport_.last_rtp_header_.sequenceNumber;
+  }
+  std::vector<uint16_t> LastNackListSent() {
+    return transport_.last_nack_list_;
+  }
 };
 }  // namespace
 
@@ -95,11 +150,23 @@ class RtpRtcpImplTest : public ::testing::Test {
         receiver_(&clock_) {
     // Send module.
     EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
-    EXPECT_EQ(0, sender_.impl_->SetSSRC(kSenderSsrc));
+    EXPECT_EQ(0, sender_.impl_->SetSendingMediaStatus(true));
+    sender_.impl_->SetSSRC(kSenderSsrc);
     sender_.impl_->SetRemoteSSRC(kReceiverSsrc);
+    sender_.impl_->SetSequenceNumber(kSequenceNumber);
+    sender_.impl_->SetStorePacketsStatus(true, 100);
+
+    memset(&codec_, 0, sizeof(VideoCodec));
+    codec_.plType = 100;
+    strncpy(codec_.plName, "VP8", 3);
+    codec_.width = 320;
+    codec_.height = 180;
+    EXPECT_EQ(0, sender_.impl_->RegisterSendPayload(codec_));
+
     // Receive module.
     EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
-    EXPECT_EQ(0, receiver_.impl_->SetSSRC(kReceiverSsrc));
+    EXPECT_EQ(0, receiver_.impl_->SetSendingMediaStatus(false));
+    receiver_.impl_->SetSSRC(kReceiverSsrc);
     receiver_.impl_->SetRemoteSSRC(kSenderSsrc);
     // Transport settings.
     sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get());
@@ -108,10 +175,93 @@ class RtpRtcpImplTest : public ::testing::Test {
   SimulatedClock clock_;
   RtpRtcpModule sender_;
   RtpRtcpModule receiver_;
+  VideoCodec codec_;
+
+  void SendFrame(const RtpRtcpModule* module, uint8_t tid) {
+    RTPVideoHeaderVP8 vp8_header = {};
+    vp8_header.temporalIdx = tid;
+    RTPVideoHeader rtp_video_header = {
+        codec_.width, codec_.height, true, 0, kRtpVideoVp8, {vp8_header}};
+
+    const uint8_t payload[100] = {0};
+    EXPECT_EQ(0, module->impl_->SendOutgoingData(kVideoFrameKey,
+                                                 codec_.plType,
+                                                 0,
+                                                 0,
+                                                 payload,
+                                                 sizeof(payload),
+                                                 NULL,
+                                                 &rtp_video_header));
+  }
+
+  void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {
+    rtcp::Nack nack;
+    uint16_t list[1];
+    list[0] = sequence_number;
+    const uint16_t kListLength = sizeof(list) / sizeof(list[0]);
+    nack.From(kReceiverSsrc);
+    nack.To(kSenderSsrc);
+    nack.WithList(list, kListLength);
+    rtcp::RawPacket packet = nack.Build();
+    EXPECT_EQ(0, module->impl_->IncomingRtcpPacket(packet.buffer(),
+                                                   packet.buffer_length()));
+  }
 };
 
+TEST_F(RtpRtcpImplTest, SetSelectiveRetransmissions_BaseLayer) {
+  sender_.impl_->SetSelectiveRetransmissions(kRetransmitBaseLayer);
+  EXPECT_EQ(kRetransmitBaseLayer, sender_.impl_->SelectiveRetransmissions());
+
+  // Send frames.
+  EXPECT_EQ(0, sender_.RtpSent());
+  SendFrame(&sender_, kBaseLayerTid);    // kSequenceNumber
+  SendFrame(&sender_, kHigherLayerTid);  // kSequenceNumber + 1
+  SendFrame(&sender_, kNoTemporalIdx);   // kSequenceNumber + 2
+  EXPECT_EQ(3, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+
+  // Frame with kBaseLayerTid re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber);
+  EXPECT_EQ(4, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
+  // Frame with kHigherLayerTid not re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
+  EXPECT_EQ(4, sender_.RtpSent());
+  // Frame with kNoTemporalIdx re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
+  EXPECT_EQ(5, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+}
+
+TEST_F(RtpRtcpImplTest, SetSelectiveRetransmissions_HigherLayers) {
+  const uint8_t kSetting = kRetransmitBaseLayer + kRetransmitHigherLayers;
+  sender_.impl_->SetSelectiveRetransmissions(kSetting);
+  EXPECT_EQ(kSetting, sender_.impl_->SelectiveRetransmissions());
+
+  // Send frames.
+  EXPECT_EQ(0, sender_.RtpSent());
+  SendFrame(&sender_, kBaseLayerTid);    // kSequenceNumber
+  SendFrame(&sender_, kHigherLayerTid);  // kSequenceNumber + 1
+  SendFrame(&sender_, kNoTemporalIdx);   // kSequenceNumber + 2
+  EXPECT_EQ(3, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+
+  // Frame with kBaseLayerTid re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber);
+  EXPECT_EQ(4, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
+  // Frame with kHigherLayerTid re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
+  EXPECT_EQ(5, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber());
+  // Frame with kNoTemporalIdx re-sent.
+  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
+  EXPECT_EQ(6, sender_.RtpSent());
+  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
+}
+
 TEST_F(RtpRtcpImplTest, Rtt) {
-  RTPHeader header = {};
+  RTPHeader header;
   header.timestamp = 1;
   header.sequenceNumber = 123;
   header.ssrc = kSenderSsrc;
@@ -172,4 +322,323 @@ TEST_F(RtpRtcpImplTest, RttForReceiverOnly) {
   EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.rtt_stats_.LastProcessedRtt());
   EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms());
 }
+
+TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) {
+  EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+  // Receive module sends a NACK.
+  const uint16_t kNackLength = 1;
+  uint16_t nack_list[kNackLength] = {123};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+
+  // Send module receives the NACK.
+  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+}
+
+TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_FirAndPli) {
+  EXPECT_EQ(0U, sender_.RtcpReceived().fir_packets);
+  EXPECT_EQ(0U, receiver_.RtcpSent().fir_packets);
+  // Receive module sends a FIR.
+  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir));
+  EXPECT_EQ(1U, receiver_.RtcpSent().fir_packets);
+  // Send module receives the FIR.
+  EXPECT_EQ(1U, sender_.RtcpReceived().fir_packets);
+
+  // Receive module sends a FIR and PLI.
+  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir | kRtcpPli));
+  EXPECT_EQ(2U, receiver_.RtcpSent().fir_packets);
+  EXPECT_EQ(1U, receiver_.RtcpSent().pli_packets);
+  // Send module receives the FIR and PLI.
+  EXPECT_EQ(2U, sender_.RtcpReceived().fir_packets);
+  EXPECT_EQ(1U, sender_.RtcpReceived().pli_packets);
+}
+
+TEST_F(RtpRtcpImplTest, UniqueNackRequests) {
+  receiver_.transport_.SimulateNetworkDelay(0, &clock_);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());
+
+  // Receive module sends NACK request.
+  const uint16_t kNackLength = 4;
+  uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
+  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));
+
+  // Send module receives the request.
+  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
+  EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
+  EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+
+  // Receive module sends new request with duplicated packets.
+  const int kStartupRttMs = 100;
+  clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1);
+  const uint16_t kNackLength2 = 4;
+  uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
+  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
+  EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
+  EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
+  EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
+  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));
+
+  // Send module receives the request.
+  EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
+  EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
+  EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
+  EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
+}
+
+class RtpSendingTestTransport : public Transport {
+ public:
+  void ResetCounters() { bytes_received_.clear(); }
+
+  virtual int SendPacket(int channel, const void* data, int length) OVERRIDE {
+    RTPHeader header;
+    scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+    EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data),
+                              static_cast<size_t>(length),
+                              &header));
+    bytes_received_[header.ssrc] += length;
+    ++packets_received_[header.ssrc];
+    return length;
+  }
+
+  virtual int SendRTCPPacket(int channel,
+                             const void* data,
+                             int length) OVERRIDE {
+    return length;
+  }
+
+  int GetPacketsReceived(uint32_t ssrc) const {
+    std::map<uint32_t, int>::const_iterator it = packets_received_.find(ssrc);
+    if (it == packets_received_.end())
+      return 0;
+    return it->second;
+  }
+
+  int GetBytesReceived(uint32_t ssrc) const {
+    std::map<uint32_t, int>::const_iterator it = bytes_received_.find(ssrc);
+    if (it == bytes_received_.end())
+      return 0;
+    return it->second;
+  }
+
+  int GetTotalBytesReceived() const {
+    int sum = 0;
+    for (std::map<uint32_t, int>::const_iterator it = bytes_received_.begin();
+         it != bytes_received_.end();
+         ++it) {
+      sum += it->second;
+    }
+    return sum;
+  }
+
+ private:
+  std::map<uint32_t, int> bytes_received_;
+  std::map<uint32_t, int> packets_received_;
+};
+
+class RtpSendingTest : public ::testing::Test {
+ protected:
+  // Map from SSRC to number of received packets and bytes.
+  typedef std::map<uint32_t, std::pair<int, int> > PaddingMap;
+
+  RtpSendingTest() {
+    // Send module.
+    RtpRtcp::Configuration config;
+    config.audio = false;
+    config.clock = Clock::GetRealTimeClock();
+    config.outgoing_transport = &transport_;
+    config.receive_statistics = receive_statistics_.get();
+    config.rtt_stats = &rtt_stats_;
+    config.paced_sender = &pacer_;
+    memset(&codec_, 0, sizeof(VideoCodec));
+    codec_.plType = 100;
+    strncpy(codec_.plName, "VP8", 3);
+    codec_.numberOfSimulcastStreams = 3;
+    codec_.simulcastStream[0].width = 320;
+    codec_.simulcastStream[0].height = 180;
+    codec_.simulcastStream[0].maxBitrate = 300;
+    codec_.simulcastStream[1].width = 640;
+    codec_.simulcastStream[1].height = 360;
+    codec_.simulcastStream[1].maxBitrate = 600;
+    codec_.simulcastStream[2].width = 1280;
+    codec_.simulcastStream[2].height = 720;
+    codec_.simulcastStream[2].maxBitrate = 1200;
+    // We need numberOfSimulcastStreams + 1 RTP modules since we need one
+    // default module.
+    for (int i = 0; i < codec_.numberOfSimulcastStreams + 1; ++i) {
+      RtpRtcp* sender = RtpRtcp::CreateRtpRtcp(config);
+      EXPECT_EQ(0, sender->RegisterSendPayload(codec_));
+      EXPECT_EQ(0, sender->SetSendingStatus(true));
+      EXPECT_EQ(0, sender->SetSendingMediaStatus(true));
+      sender->SetSSRC(kSenderSsrc + i);
+      sender->SetRemoteSSRC(kReceiverSsrc + i);
+      senders_.push_back(sender);
+      config.default_module = senders_[0];
+    }
+    std::vector<uint32_t> bitrates;
+    bitrates.push_back(codec_.simulcastStream[0].maxBitrate);
+    bitrates.push_back(codec_.simulcastStream[1].maxBitrate);
+    bitrates.push_back(codec_.simulcastStream[2].maxBitrate);
+    senders_[0]->SetTargetSendBitrate(bitrates);
+  }
+
+  ~RtpSendingTest() {
+    for (int i = senders_.size() - 1; i >= 0; --i) {
+      delete senders_[i];
+    }
+  }
+
+  void SendFrameOnSender(int sender_index,
+                         const uint8_t* payload,
+                         size_t length) {
+    RTPVideoHeader rtp_video_header = {
+        codec_.simulcastStream[sender_index].width,
+        codec_.simulcastStream[sender_index].height,
+        true,
+        0,
+        kRtpVideoVp8,
+        {}};
+    uint32_t seq_num = 0;
+    uint32_t ssrc = 0;
+    int64_t capture_time_ms = 0;
+    bool retransmission = false;
+    EXPECT_CALL(pacer_, SendPacket(_, _, _, _, _, _))
+        .WillRepeatedly(DoAll(SaveArg<1>(&ssrc),
+                              SaveArg<2>(&seq_num),
+                              SaveArg<3>(&capture_time_ms),
+                              SaveArg<5>(&retransmission),
+                              Return(true)));
+    EXPECT_EQ(0,
+              senders_[sender_index]->SendOutgoingData(kVideoFrameKey,
+                                                       codec_.plType,
+                                                       0,
+                                                       0,
+                                                       payload,
+                                                       length,
+                                                       NULL,
+                                                       &rtp_video_header));
+    EXPECT_TRUE(senders_[sender_index]->TimeToSendPacket(
+        ssrc, seq_num, capture_time_ms, retransmission));
+  }
+
+  void ExpectPadding(const PaddingMap& expected_padding) {
+    int expected_total_bytes = 0;
+    for (PaddingMap::const_iterator it = expected_padding.begin();
+         it != expected_padding.end();
+         ++it) {
+      int packets_received = transport_.GetBytesReceived(it->first);
+      if (it->second.first > 0) {
+        EXPECT_GE(packets_received, it->second.first)
+            << "On SSRC: " << it->first;
+      }
+      int bytes_received = transport_.GetBytesReceived(it->first);
+      expected_total_bytes += bytes_received;
+      if (it->second.second > 0) {
+        EXPECT_GE(bytes_received, it->second.second)
+            << "On SSRC: " << it->first;
+      } else {
+        EXPECT_EQ(0, bytes_received) << "On SSRC: " << it->first;
+      }
+    }
+    EXPECT_EQ(expected_total_bytes, transport_.GetTotalBytesReceived());
+  }
+
+  scoped_ptr<ReceiveStatistics> receive_statistics_;
+  RtcpRttStatsTestImpl rtt_stats_;
+  std::vector<RtpRtcp*> senders_;
+  RtpSendingTestTransport transport_;
+  NiceMock<MockPacedSender> pacer_;
+  VideoCodec codec_;
+};
+
+TEST_F(RtpSendingTest, DISABLED_RoundRobinPadding) {
+  // We have to send on an SSRC to be allowed to pad, since a marker bit must
+  // be sent prior to padding packets.
+  const uint8_t payload[200] = {0};
+  for (int i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
+    SendFrameOnSender(i + 1, payload, sizeof(payload));
+  }
+  transport_.ResetCounters();
+  senders_[0]->TimeToSendPadding(500);
+  PaddingMap expected_padding;
+  expected_padding[kSenderSsrc + 1] = std::make_pair(2, 500);
+  expected_padding[kSenderSsrc + 2] = std::make_pair(0, 0);
+  expected_padding[kSenderSsrc + 3] = std::make_pair(0, 0);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1000);
+  expected_padding[kSenderSsrc + 2] = std::make_pair(4, 1000);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1500);
+  expected_padding[kSenderSsrc + 3] = std::make_pair(6, 1500);
+  ExpectPadding(expected_padding);
+}
+
+TEST_F(RtpSendingTest, DISABLED_RoundRobinPaddingRtx) {
+  // Enable RTX to allow padding to be sent prior to media.
+  for (int i = 1; i < codec_.numberOfSimulcastStreams + 1; ++i) {
+    // Abs-send-time is needed to be allowed to send padding prior to media,
+    // as otherwise the timestmap used for BWE will be broken.
+    senders_[i]->RegisterSendRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
+                                                1);
+    senders_[i]->SetRtxSendPayloadType(96);
+    senders_[i]->SetRtxSsrc(kSenderRtxSsrc + i);
+    senders_[i]->SetRTXSendStatus(kRtxRetransmitted);
+  }
+  transport_.ResetCounters();
+  senders_[0]->TimeToSendPadding(500);
+  PaddingMap expected_padding;
+  expected_padding[kSenderSsrc + 1] = std::make_pair(0, 0);
+  expected_padding[kSenderSsrc + 2] = std::make_pair(0, 0);
+  expected_padding[kSenderSsrc + 3] = std::make_pair(0, 0);
+  expected_padding[kSenderRtxSsrc + 1] = std::make_pair(2, 500);
+  expected_padding[kSenderRtxSsrc + 2] = std::make_pair(0, 0);
+  expected_padding[kSenderRtxSsrc + 3] = std::make_pair(0, 0);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1000);
+  expected_padding[kSenderRtxSsrc + 2] = std::make_pair(4, 500);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1500);
+
+  expected_padding[kSenderRtxSsrc + 3] = std::make_pair(6, 500);
+  ExpectPadding(expected_padding);
+}
+
+TEST_F(RtpSendingTest, DISABLED_RoundRobinPaddingRtxRedundantPayloads) {
+  for (int i = 1; i < codec_.numberOfSimulcastStreams + 1; ++i) {
+    senders_[i]->SetRtxSendPayloadType(96);
+    senders_[i]->SetRtxSsrc(kSenderRtxSsrc + i);
+    senders_[i]->SetRTXSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
+    senders_[i]->SetStorePacketsStatus(true, 100);
+  }
+  // First send payloads so that we have something to retransmit.
+  const size_t kPayloadSize = 500;
+  const uint8_t payload[kPayloadSize] = {0};
+  for (int i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
+    SendFrameOnSender(i + 1, payload, sizeof(payload));
+  }
+  transport_.ResetCounters();
+  senders_[0]->TimeToSendPadding(500);
+  PaddingMap expected_padding;
+  expected_padding[kSenderSsrc + 1] = std::make_pair<int, int>(0, 0);
+  expected_padding[kSenderSsrc + 2] = std::make_pair<int, int>(0, 0);
+  expected_padding[kSenderSsrc + 3] = std::make_pair<int, int>(0, 0);
+  expected_padding[kSenderRtxSsrc + 1] = std::make_pair<int, int>(1, 500);
+  expected_padding[kSenderRtxSsrc + 2] = std::make_pair<int, int>(0, 0);
+  expected_padding[kSenderRtxSsrc + 3] = std::make_pair<int, int>(0, 0);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1000);
+  expected_padding[kSenderRtxSsrc + 2] = std::make_pair<int, int>(2, 1000);
+  ExpectPadding(expected_padding);
+  senders_[0]->TimeToSendPadding(1500);
+  expected_padding[kSenderRtxSsrc + 3] = std::make_pair<int, int>(3, 1500);
+  ExpectPadding(expected_padding);
+}
 }  // namespace webrtc