1042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org/*
2042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *
4042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  Use of this source code is governed by a BSD-style license
5042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  that can be found in the LICENSE file in the root of the source
6042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  tree. An additional intellectual property rights grant can be found
7042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  in the file PATENTS.  All contributing project authors may
8042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org */
10042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
11b8b6fbb7a5d2f5a14f7f6f81c253747aa28e4c7fdanilchap#include <map>
12b8b6fbb7a5d2f5a14f7f6f81c253747aa28e4c7fdanilchap#include <set>
13b8b6fbb7a5d2f5a14f7f6f81c253747aa28e4c7fdanilchap
14042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org#include "testing/gmock/include/gmock/gmock.h"
15042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
16042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
17042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org#include "webrtc/common_types.h"
18ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
19ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
2084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
21a8890a57a5d03f942924ff61d3c62244f2bdab10danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
22042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
2398f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/scoped_vector.h"
242dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org#include "webrtc/test/rtcp_packet_parser.h"
25a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.org
26a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.orgusing ::testing::_;
272dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.orgusing ::testing::ElementsAre;
28a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.orgusing ::testing::NiceMock;
29a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.orgusing ::testing::Return;
30a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.orgusing ::testing::SaveArg;
31042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
32042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.orgnamespace webrtc {
33042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.orgnamespace {
34871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.orgconst uint32_t kSenderSsrc = 0x12345;
35871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.orgconst uint32_t kReceiverSsrc = 0x23456;
3616825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgconst int64_t kOneWayNetworkDelayMs = 100;
3784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.orgconst uint8_t kBaseLayerTid = 0;
3884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.orgconst uint8_t kHigherLayerTid = 1;
3984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.orgconst uint16_t kSequenceNumber = 100;
40042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
411ae1d0c47145f1036c3844a5cd1b536c22565325asapersson@webrtc.orgclass RtcpRttStatsTestImpl : public RtcpRttStats {
427d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org public:
437d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org  RtcpRttStatsTestImpl() : rtt_ms_(0) {}
447d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org  virtual ~RtcpRttStatsTestImpl() {}
457d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org
4614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  void OnRttUpdate(int64_t rtt_ms) override { rtt_ms_ = rtt_ms; }
4714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org  int64_t LastProcessedRtt() const override { return rtt_ms_; }
4816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t rtt_ms_;
497d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org};
507d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org
51042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.orgclass SendTransport : public Transport,
52042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org                      public NullRtpData {
53042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org public:
5484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendTransport()
5584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org      : receiver_(NULL),
5684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org        clock_(NULL),
5784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org        delay_ms_(0),
5884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org        rtp_packets_sent_(0) {
5984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  }
60042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
61871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  void SetRtpRtcpModule(ModuleRtpRtcpImpl* receiver) {
62871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    receiver_ = receiver;
63042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  }
6416825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  void SimulateNetworkDelay(int64_t delay_ms, SimulatedClock* clock) {
65042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org    clock_ = clock;
66042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org    delay_ms_ = delay_ms;
67042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  }
681d8a506405734d0cef9653704b036ca4f1388960stefan  bool SendRtp(const uint8_t* data,
691d8a506405734d0cef9653704b036ca4f1388960stefan               size_t len,
701d8a506405734d0cef9653704b036ca4f1388960stefan               const PacketOptions& options) override {
7184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    RTPHeader header;
7200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org    rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
734591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org    EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data), len, &header));
7484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    ++rtp_packets_sent_;
7584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    last_rtp_header_ = header;
762d566686a23fe93ada58f1c38a0d4b9a0d68556epbos    return true;
77042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  }
782d566686a23fe93ada58f1c38a0d4b9a0d68556epbos  bool SendRtcp(const uint8_t* data, size_t len) override {
792dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org    test::RtcpPacketParser parser;
802dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org    parser.Parse(static_cast<const uint8_t*>(data), len);
812dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org    last_nack_list_ = parser.nack_item()->last_nack_list();
822dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org
83042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org    if (clock_) {
84042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org      clock_->AdvanceTimeMilliseconds(delay_ms_);
85042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org    }
86871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    EXPECT_TRUE(receiver_ != NULL);
87871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    EXPECT_EQ(0, receiver_->IncomingRtcpPacket(
88042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org        static_cast<const uint8_t*>(data), len));
892d566686a23fe93ada58f1c38a0d4b9a0d68556epbos    return true;
90042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  }
91871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  ModuleRtpRtcpImpl* receiver_;
92042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  SimulatedClock* clock_;
9316825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t delay_ms_;
9484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  int rtp_packets_sent_;
9584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  RTPHeader last_rtp_header_;
962dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  std::vector<uint16_t> last_nack_list_;
97871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org};
98871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org
991d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.orgclass RtpRtcpModule : public RtcpPacketTypeCounterObserver {
100871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org public:
1016db6cdc604f9a866991ecf8454eb7f7aa69918eadanilchap  explicit RtpRtcpModule(SimulatedClock* clock)
102871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org      : receive_statistics_(ReceiveStatistics::Create(clock)) {
103871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    RtpRtcp::Configuration config;
104871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    config.audio = false;
105871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    config.clock = clock;
106871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    config.outgoing_transport = &transport_;
107871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    config.receive_statistics = receive_statistics_.get();
1081d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    config.rtcp_packet_type_counter_observer = this;
109871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    config.rtt_stats = &rtt_stats_;
110871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org
111871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    impl_.reset(new ModuleRtpRtcpImpl(config));
112da903eaabbb6c6830efcafc3c2ade1d36f511e43pbos    impl_->SetRTCPStatus(RtcpMode::kCompound);
113871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org
114871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, clock);
115871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  }
1168098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
1178098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  RtcpPacketTypeCounter packets_sent_;
1188098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  RtcpPacketTypeCounter packets_received_;
11900b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<ReceiveStatistics> receive_statistics_;
120871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  SendTransport transport_;
121871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  RtcpRttStatsTestImpl rtt_stats_;
12200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org  rtc::scoped_ptr<ModuleRtpRtcpImpl> impl_;
1231d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  uint32_t remote_ssrc_;
1241d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org
1251d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  void SetRemoteSsrc(uint32_t ssrc) {
1261d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    remote_ssrc_ = ssrc;
1271d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    impl_->SetRemoteSSRC(ssrc);
1281d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  }
1291d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org
1301d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  void RtcpPacketTypesCounterUpdated(
1311d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org      uint32_t ssrc,
1321d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org      const RtcpPacketTypeCounter& packet_counter) override {
1331d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    counter_map_[ssrc] = packet_counter;
1341d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  }
1358098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
1368098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  RtcpPacketTypeCounter RtcpSent() {
1371d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    // RTCP counters for remote SSRC.
1381d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    return counter_map_[remote_ssrc_];
1398098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  }
1401d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org
1418098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  RtcpPacketTypeCounter RtcpReceived() {
1421d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    // Received RTCP stats for (own) local SSRC.
1431d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    return counter_map_[impl_->SSRC()];
1448098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  }
14584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  int RtpSent() {
14684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    return transport_.rtp_packets_sent_;
14784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  }
14884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  uint16_t LastRtpSequenceNumber() {
14984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    return transport_.last_rtp_header_.sequenceNumber;
15084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  }
1512dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  std::vector<uint16_t> LastNackListSent() {
1522dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org    return transport_.last_nack_list_;
1532dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  }
1541d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org
1551d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org private:
1561d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org  std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
157042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org};
158042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org}  // namespace
159042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
160042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.orgclass RtpRtcpImplTest : public ::testing::Test {
161042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org protected:
162042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  RtpRtcpImplTest()
163ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org      : clock_(133590000000000),
164871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org        sender_(&clock_),
165871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org        receiver_(&clock_) {
166871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    // Send module.
167871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
168d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org    sender_.impl_->SetSendingMediaStatus(true);
169ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org    sender_.impl_->SetSSRC(kSenderSsrc);
1701d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    sender_.SetRemoteSsrc(kReceiverSsrc);
17184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    sender_.impl_->SetSequenceNumber(kSequenceNumber);
17284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    sender_.impl_->SetStorePacketsStatus(true, 100);
17384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
17484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    memset(&codec_, 0, sizeof(VideoCodec));
17584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    codec_.plType = 100;
17684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    strncpy(codec_.plName, "VP8", 3);
17784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    codec_.width = 320;
17884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    codec_.height = 180;
17984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    EXPECT_EQ(0, sender_.impl_->RegisterSendPayload(codec_));
18084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
181871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    // Receive module.
182871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
183d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org    receiver_.impl_->SetSendingMediaStatus(false);
184ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org    receiver_.impl_->SetSSRC(kReceiverSsrc);
1851d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org    receiver_.SetRemoteSsrc(kSenderSsrc);
186871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    // Transport settings.
187871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get());
188871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org    receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());
189042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  }
190042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  SimulatedClock clock_;
191871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  RtpRtcpModule sender_;
192871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  RtpRtcpModule receiver_;
19384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  VideoCodec codec_;
19484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
19584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  void SendFrame(const RtpRtcpModule* module, uint8_t tid) {
19684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    RTPVideoHeaderVP8 vp8_header = {};
19784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    vp8_header.temporalIdx = tid;
1984536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org    RTPVideoHeader rtp_video_header = {codec_.width,
1994536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       codec_.height,
2004536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       kVideoRotation_0,
2014536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       true,
2024536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       0,
2034536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       kRtpVideoVp8,
2044536289353cdcc315cc5e6218893e4843cf528e6guoweis@webrtc.org                                       {vp8_header}};
20584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
20684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    const uint8_t payload[100] = {0};
20784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    EXPECT_EQ(0, module->impl_->SendOutgoingData(kVideoFrameKey,
20884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 codec_.plType,
20984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 0,
21084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 0,
21184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 payload,
21284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 sizeof(payload),
21384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 NULL,
21484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org                                                 &rtp_video_header));
21584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  }
21684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
21784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {
218ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org    bool sender = module->impl_->SSRC() == kSenderSsrc;
21984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    rtcp::Nack nack;
22084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    uint16_t list[1];
22184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    list[0] = sequence_number;
22284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    const uint16_t kListLength = sizeof(list) / sizeof(list[0]);
223ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org    nack.From(sender ? kReceiverSsrc : kSenderSsrc);
224ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org    nack.To(sender ? kSenderSsrc : kReceiverSsrc);
22584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org    nack.WithList(list, kListLength);
226c1b9d4e686c184e4b1779d442d447128477d3b8bErik Språng    rtc::scoped_ptr<rtcp::RawPacket> packet(nack.Build());
227c1b9d4e686c184e4b1779d442d447128477d3b8bErik Språng    EXPECT_EQ(0, module->impl_->IncomingRtcpPacket(packet->Buffer(),
228c1b9d4e686c184e4b1779d442d447128477d3b8bErik Språng                                                   packet->Length()));
22984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  }
230042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org};
231042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
23284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, SetSelectiveRetransmissions_BaseLayer) {
23384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  sender_.impl_->SetSelectiveRetransmissions(kRetransmitBaseLayer);
23484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kRetransmitBaseLayer, sender_.impl_->SelectiveRetransmissions());
23584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
23684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Send frames.
23784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(0, sender_.RtpSent());
23884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kBaseLayerTid);    // kSequenceNumber
23984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kHigherLayerTid);  // kSequenceNumber + 1
24084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kNoTemporalIdx);   // kSequenceNumber + 2
24184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(3, sender_.RtpSent());
24284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
24384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
24443c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org  // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
24543c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
24643c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org
24784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kBaseLayerTid re-sent.
24884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber);
24984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(4, sender_.RtpSent());
25084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
25184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kHigherLayerTid not re-sent.
25284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
25384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(4, sender_.RtpSent());
25484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kNoTemporalIdx re-sent.
25584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
25684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(5, sender_.RtpSent());
25784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
25884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org}
25984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
26084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, SetSelectiveRetransmissions_HigherLayers) {
26184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  const uint8_t kSetting = kRetransmitBaseLayer + kRetransmitHigherLayers;
26284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  sender_.impl_->SetSelectiveRetransmissions(kSetting);
26384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSetting, sender_.impl_->SelectiveRetransmissions());
26484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
26584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Send frames.
26684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(0, sender_.RtpSent());
26784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kBaseLayerTid);    // kSequenceNumber
26884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kHigherLayerTid);  // kSequenceNumber + 1
26984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  SendFrame(&sender_, kNoTemporalIdx);   // kSequenceNumber + 2
27084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(3, sender_.RtpSent());
27184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
27284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
27343c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org  // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
27443c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
27543c883954f5edc84bd8e0e901ef770fead218ed5sprang@webrtc.org
27684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kBaseLayerTid re-sent.
27784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber);
27884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(4, sender_.RtpSent());
27984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
28084b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kHigherLayerTid re-sent.
28184b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber + 1);
28284b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(5, sender_.RtpSent());
28384b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber());
28484b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  // Frame with kNoTemporalIdx re-sent.
28584b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  IncomingRtcpNack(&sender_, kSequenceNumber + 2);
28684b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(6, sender_.RtpSent());
28784b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org  EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
28884b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org}
28984b9e1e9d9407c48ff85a28f0825fe3a23a1f614asapersson@webrtc.org
290042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, Rtt) {
291b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org  RTPHeader header;
292042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  header.timestamp = 1;
293042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  header.sequenceNumber = 123;
294871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  header.ssrc = kSenderSsrc;
295042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  header.headerLength = 12;
296871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  receiver_.receive_statistics_->IncomingPacket(header, 100, false);
297042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
298871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  // Sender module should send a SR.
299871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
300042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
301871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  // Receiver module should send a RR with a response to the last received SR.
302042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  clock_.AdvanceTimeMilliseconds(1000);
303871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
304042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
305042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  // Verify RTT.
30616825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t rtt;
30716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t avg_rtt;
30816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t min_rtt;
30916825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  int64_t max_rtt;
310871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(0,
311871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org      sender_.impl_->RTT(kReceiverSsrc, &rtt, &avg_rtt, &min_rtt, &max_rtt));
312871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, rtt);
313871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, avg_rtt);
314871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, min_rtt);
315871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, max_rtt);
316042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
317042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  // No RTT from other ssrc.
318042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org  EXPECT_EQ(-1,
319871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org      sender_.impl_->RTT(kReceiverSsrc+1, &rtt, &avg_rtt, &min_rtt, &max_rtt));
320e7b1e112833517c334a12aac16be17a27d798944asapersson@webrtc.org
321e7b1e112833517c334a12aac16be17a27d798944asapersson@webrtc.org  // Verify RTT from rtt_stats config.
32216825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
32316825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  EXPECT_EQ(0, sender_.impl_->rtt_ms());
324871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  sender_.impl_->Process();
325871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt());
326871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms());
327042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org}
328042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org
3298d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, SetRtcpXrRrtrStatus) {
330871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_FALSE(receiver_.impl_->RtcpXrRrtrStatus());
331871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  receiver_.impl_->SetRtcpXrRrtrStatus(true);
332871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_TRUE(receiver_.impl_->RtcpXrRrtrStatus());
3338d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.org}
3348d02f5dc7146ebc35c30fc3f7e1cbfa6802486a2asapersson@webrtc.org
3357d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, RttForReceiverOnly) {
336871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  receiver_.impl_->SetRtcpXrRrtrStatus(true);
3377d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org
338871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  // Receiver module should send a Receiver time reference report (RTRR).
339871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
3407d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org
341871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  // Sender module should send a response to the last received RTRR (DLRR).
3427d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org  clock_.AdvanceTimeMilliseconds(1000);
343871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
3447d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org
3457d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org  // Verify RTT.
34616825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
34716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org  EXPECT_EQ(0, receiver_.impl_->rtt_ms());
348871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  receiver_.impl_->Process();
349871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.rtt_stats_.LastProcessedRtt());
350871d949299a4ec27efe9805ad5c2289e7e2f68b3asapersson@webrtc.org  EXPECT_EQ(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms());
3517d6bd2201938e4b6b7e5219c0fc971b0e1ba05b1asapersson@webrtc.org}
3528098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
3530b3d7eec07100a9df006e679408a8e015af643d6mflodmanTEST_F(RtpRtcpImplTest, NoSrBeforeMedia) {
3540b3d7eec07100a9df006e679408a8e015af643d6mflodman  // Ignore fake transport delays in this test.
3550b3d7eec07100a9df006e679408a8e015af643d6mflodman  sender_.transport_.SimulateNetworkDelay(0, &clock_);
3560b3d7eec07100a9df006e679408a8e015af643d6mflodman  receiver_.transport_.SimulateNetworkDelay(0, &clock_);
3570b3d7eec07100a9df006e679408a8e015af643d6mflodman
3580b3d7eec07100a9df006e679408a8e015af643d6mflodman  sender_.impl_->Process();
3590b3d7eec07100a9df006e679408a8e015af643d6mflodman  EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
3600b3d7eec07100a9df006e679408a8e015af643d6mflodman
3610b3d7eec07100a9df006e679408a8e015af643d6mflodman  // Verify no SR is sent before media has been sent, RR should still be sent
3620b3d7eec07100a9df006e679408a8e015af643d6mflodman  // from the receiving module though.
3630b3d7eec07100a9df006e679408a8e015af643d6mflodman  clock_.AdvanceTimeMilliseconds(2000);
3640b3d7eec07100a9df006e679408a8e015af643d6mflodman  int64_t current_time = clock_.TimeInMilliseconds();
3650b3d7eec07100a9df006e679408a8e015af643d6mflodman  sender_.impl_->Process();
3660b3d7eec07100a9df006e679408a8e015af643d6mflodman  receiver_.impl_->Process();
3670b3d7eec07100a9df006e679408a8e015af643d6mflodman  EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
3680b3d7eec07100a9df006e679408a8e015af643d6mflodman  EXPECT_EQ(receiver_.RtcpSent().first_packet_time_ms, current_time);
3690b3d7eec07100a9df006e679408a8e015af643d6mflodman
3700b3d7eec07100a9df006e679408a8e015af643d6mflodman  SendFrame(&sender_, kBaseLayerTid);
3710b3d7eec07100a9df006e679408a8e015af643d6mflodman  EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, current_time);
3720b3d7eec07100a9df006e679408a8e015af643d6mflodman}
3730b3d7eec07100a9df006e679408a8e015af643d6mflodman
3748098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) {
375d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_EQ(-1, receiver_.RtcpSent().first_packet_time_ms);
376d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_EQ(-1, sender_.RtcpReceived().first_packet_time_ms);
3778098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
3788098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
379d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org
3808098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Receive module sends a NACK.
3818098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  const uint16_t kNackLength = 1;
3828098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  uint16_t nack_list[kNackLength] = {123};
3838098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
3848098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
385d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_GT(receiver_.RtcpSent().first_packet_time_ms, -1);
3868098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
3878098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Send module receives the NACK.
3888098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
389d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_GT(sender_.RtcpReceived().first_packet_time_ms, -1);
3908098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org}
3918098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
3928098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.orgTEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_FirAndPli) {
3938098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0U, sender_.RtcpReceived().fir_packets);
3948098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0U, receiver_.RtcpSent().fir_packets);
3958098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Receive module sends a FIR.
3968098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpFir));
3978098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, receiver_.RtcpSent().fir_packets);
3988098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Send module receives the FIR.
3998098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpReceived().fir_packets);
4008098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org
4018098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Receive module sends a FIR and PLI.
402242e22b055940be70b1df3031e2363b0d02397b2Erik Språng  std::set<RTCPPacketType> packet_types;
403242e22b055940be70b1df3031e2363b0d02397b2Erik Språng  packet_types.insert(kRtcpFir);
404242e22b055940be70b1df3031e2363b0d02397b2Erik Språng  packet_types.insert(kRtcpPli);
405242e22b055940be70b1df3031e2363b0d02397b2Erik Språng  EXPECT_EQ(0, receiver_.impl_->SendCompoundRTCP(packet_types));
4068098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(2U, receiver_.RtcpSent().fir_packets);
4078098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, receiver_.RtcpSent().pli_packets);
4088098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  // Send module receives the FIR and PLI.
4098098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(2U, sender_.RtcpReceived().fir_packets);
4108098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpReceived().pli_packets);
4118098e0747879b191335e8de1e16b87cf6adbdf54asapersson@webrtc.org}
412a15fbfdcdee391bd87bb1c2721f0fbb824f5fbfbstefan@webrtc.org
413d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.orgTEST_F(RtpRtcpImplTest, AddStreamDataCounters) {
414d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  StreamDataCounters rtp;
415d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  const int64_t kStartTimeMs = 1;
416d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  rtp.first_packet_time_ms = kStartTimeMs;
417cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp.transmitted.packets = 1;
418cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp.transmitted.payload_bytes = 1;
419cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp.transmitted.header_bytes = 2;
420cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp.transmitted.padding_bytes = 3;
421cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes +
422cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org                                          rtp.transmitted.header_bytes +
423cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org                                          rtp.transmitted.padding_bytes);
424d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org
425d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  StreamDataCounters rtp2;
426d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  rtp2.first_packet_time_ms = -1;
427cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.transmitted.packets = 10;
428cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.transmitted.payload_bytes = 10;
429cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.retransmitted.header_bytes = 4;
430cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.retransmitted.payload_bytes = 5;
431cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.retransmitted.padding_bytes = 6;
432cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.retransmitted.packets = 7;
433cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  rtp2.fec.packets = 8;
434d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org
435d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  StreamDataCounters sum = rtp;
436d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  sum.Add(rtp2);
437d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);
438cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(11U, sum.transmitted.packets);
439cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(11U, sum.transmitted.payload_bytes);
440cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(2U, sum.transmitted.header_bytes);
441cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(3U, sum.transmitted.padding_bytes);
442cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(4U, sum.retransmitted.header_bytes);
443cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(5U, sum.retransmitted.payload_bytes);
444cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(6U, sum.retransmitted.padding_bytes);
445cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(7U, sum.retransmitted.packets);
446cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(8U, sum.fec.packets);
447cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org  EXPECT_EQ(sum.transmitted.TotalBytes(),
448cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org            rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());
449d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org
450d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  StreamDataCounters rtp3;
451d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  rtp3.first_packet_time_ms = kStartTimeMs + 10;
452d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  sum.Add(rtp3);
453d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);  // Holds oldest time.
454d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org}
455d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org
456ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.orgTEST_F(RtpRtcpImplTest, SendsInitialNackList) {
457ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Send module sends a NACK.
458ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  const uint16_t kNackLength = 1;
459ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  uint16_t nack_list[kNackLength] = {123};
460ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
461ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
462ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
463ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
464ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org}
465ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
466ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.orgTEST_F(RtpRtcpImplTest, SendsExtendedNackList) {
467ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Send module sends a NACK.
468ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  const uint16_t kNackLength = 1;
469ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  uint16_t nack_list[kNackLength] = {123};
470ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
471ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
472ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
473ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
474ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
475ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Same list not re-send.
476ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
477ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
478ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
479ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
480ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Only extended list sent.
481ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  const uint16_t kNackExtLength = 2;
482ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  uint16_t nack_list_ext[kNackExtLength] = {123, 124};
483ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list_ext, kNackExtLength));
484ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
485ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(124));
486ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org}
487ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
488ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.orgTEST_F(RtpRtcpImplTest, ReSendsNackListAfterRttMs) {
489ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  sender_.transport_.SimulateNetworkDelay(0, &clock_);
490ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Send module sends a NACK.
491ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  const uint16_t kNackLength = 2;
492ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  uint16_t nack_list[kNackLength] = {123, 125};
493ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
494ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
495ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
496ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
497ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
498ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Same list not re-send, rtt interval has not passed.
499ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  const int kStartupRttMs = 100;
500ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  clock_.AdvanceTimeMilliseconds(kStartupRttMs);
501ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
502ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
503ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
504ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  // Rtt interval passed, full list sent.
505ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  clock_.AdvanceTimeMilliseconds(1);
506ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
507ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
508ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org  EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
509ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org}
510ba8138ba384f72674dad9b91b9a095a0fd1b27ddasapersson@webrtc.org
5112dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.orgTEST_F(RtpRtcpImplTest, UniqueNackRequests) {
5122dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  receiver_.transport_.SimulateNetworkDelay(0, &clock_);
5132dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
5142dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
5152dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
5162dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());
5172dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org
5182dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  // Receive module sends NACK request.
5192dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  const uint16_t kNackLength = 4;
5202dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
5212dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
5222dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
5232dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
5242dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
5252dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));
5262dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org
5272dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  // Send module receives the request.
5282dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
5292dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
5302dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
5312dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
5322dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org
5332dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  // Receive module sends new request with duplicated packets.
5342dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  const int kStartupRttMs = 100;
5352dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1);
5362dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  const uint16_t kNackLength2 = 4;
5372dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
5382dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
5392dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
5402dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
5412dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
5422dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));
5432dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org
5442dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  // Send module receives the request.
5452dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
5462dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
5472dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
5482dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org  EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
5492dd3134e50f884f6a9e16fb643b2a8f2f6920c1dasapersson@webrtc.org}
550042e91c2b24b3bf2acea6e59e0303ff50ff36970asapersson@webrtc.org}  // namespace webrtc
551