1233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang/*
2233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *
4233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  Use of this source code is governed by a BSD-style license
5233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  that can be found in the LICENSE file in the root of the source
6233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  tree. An additional intellectual property rights grant can be found
7233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  in the file PATENTS.  All contributing project authors may
8233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang *  be found in the AUTHORS file in the root of the source tree.
9233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang */
10233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
11233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang#include "testing/gmock/include/gmock/gmock.h"
12233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang#include "testing/gtest/include/gtest/gtest.h"
13233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
140b9e29c87da2d9c1a3792d2c87197b0688b68e4eHenrik Kjellander#include "webrtc/modules/pacing/packet_router.h"
15233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang#include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
16233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
1798f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/clock.h"
18233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
19233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangusing ::testing::_;
20233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangusing ::testing::InSequence;
21233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangusing ::testing::Invoke;
22233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
23233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangnamespace webrtc {
24233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
25233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangclass MockPacketRouter : public PacketRouter {
26233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang public:
27233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  MOCK_METHOD1(SendFeedback, bool(rtcp::TransportFeedback* packet));
28233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang};
29233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
30233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangclass RemoteEstimatorProxyTest : public ::testing::Test {
31233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang public:
32233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  RemoteEstimatorProxyTest() : clock_(0), proxy_(&clock_, &router_) {}
33233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
34233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang protected:
35233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  void IncomingPacket(uint16_t seq, int64_t time_ms) {
36233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    RTPHeader header;
37233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    header.extension.hasTransportSequenceNumber = true;
38233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    header.extension.transportSequenceNumber = seq;
39233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    header.ssrc = kMediaSsrc;
40233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    proxy_.IncomingPacket(time_ms, kDefaultPacketSize, header, true);
41233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  }
42233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
43233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  void Process() {
44233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    clock_.AdvanceTimeMilliseconds(
45233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        RemoteEstimatorProxy::kDefaultProcessIntervalMs);
46233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang    proxy_.Process();
47233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  }
48233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
49233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  SimulatedClock clock_;
50233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  MockPacketRouter router_;
51233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  RemoteEstimatorProxy proxy_;
52233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
53233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const size_t kDefaultPacketSize = 100;
54233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const uint32_t kMediaSsrc = 456;
55233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const uint16_t kBaseSeq = 10;
56233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const int64_t kBaseTimeMs = 123;
57233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const int64_t kMaxSmallDeltaMs =
58233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      (rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) / 1000;
59233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang};
60233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
61233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangTEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
62233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq, kBaseTimeMs);
63233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
64233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
65233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
66233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
67233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
68233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
69233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
70233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
71233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
72233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang            packet->GetStatusVector();
73233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, status_vec.size());
74233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
75233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[0]);
76233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
77233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, delta_vec.size());
78233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
79233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
80233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
81233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
82233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
83233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}
84233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
85233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangTEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
86233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq, kBaseTimeMs);
87233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
88233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1);
89233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
90233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
91233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
92233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
93233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
94233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
95233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
96233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
97233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
98233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang            packet->GetStatusVector();
99233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(3u, status_vec.size());
100233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
101233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[0]);
102233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
103233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[1]);
104233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedLargeDelta,
105233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[2]);
106233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
107233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
108233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(3u, delta_vec.size());
109233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
110233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMaxSmallDeltaMs, delta_vec[1] / 1000);
111233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMaxSmallDeltaMs + 1, delta_vec[2] / 1000);
112233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
113233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
114233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
115233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
116233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}
117233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
118233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangTEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
119233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const int64_t kTooLargeDelta =
120233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 16);
121233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
122233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq, kBaseTimeMs);
123233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta);
124233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
125233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  InSequence s;
126233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
127233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
128233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) {
129233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
130233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
131233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
132233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
133233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
134233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang            packet->GetStatusVector();
135233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, status_vec.size());
136233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
137233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[0]);
138233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
139233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, delta_vec.size());
140233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
141233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
142233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }))
143233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .RetiresOnSaturation();
144233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
145233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
146233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
147233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) {
148233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
149233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence());
150233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
151233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
152233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
153233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang            packet->GetStatusVector();
154233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, status_vec.size());
155233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
156233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  status_vec[0]);
157233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
158233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, delta_vec.size());
159233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs + kTooLargeDelta,
160233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
161233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
162233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }))
163233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .RetiresOnSaturation();
164233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
165233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
166233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}
167233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
168233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangTEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
169233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq, kBaseTimeMs);
170233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2);
171233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
172233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
173233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
174233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
175233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
176233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
177233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
178233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
179233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
180233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(2u, delta_vec.size());
181233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
182233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(2, delta_vec[1] / 1000);
183233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
184233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
185233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
186233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
187233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
188233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1);
189233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
190233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
191233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
192233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
193233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
194233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence());
195233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kMediaSsrc, packet->GetMediaSourceSsrc());
196233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
197233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
198233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(2u, delta_vec.size());
199233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs + 1,
200233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
201233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1, delta_vec[1] / 1000);
202233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
203233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
204233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
205233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
206233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}
207233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
208233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprangTEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
209233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  const int64_t kTimeoutTimeMs =
210233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      kBaseTimeMs + RemoteEstimatorProxy::kBackWindowMs;
211233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
212233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 2, kBaseTimeMs);
213233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
214233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
215233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
216233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
217233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
218233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq + 2, packet->GetBaseSequence());
219233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
220233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
221233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, delta_vec.size());
222233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
223233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
224233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
225233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
226233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
227233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
228233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs);  // kBaseSeq + 2 times out here.
229233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
230233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
231233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
232233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
233233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
234233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq + 3, packet->GetBaseSequence());
235233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
236233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
237233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1u, delta_vec.size());
238233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kTimeoutTimeMs,
239233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
240233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
241233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
242233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
243233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
244233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
245233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  // New group, with sequence starting below the first so that they may be
246233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  // retransmitted.
247233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq, kBaseTimeMs - 1);
248233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1);
249233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
250233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  EXPECT_CALL(router_, SendFeedback(_))
251233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .Times(1)
252233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
253233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        packet->Build();
254233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
255233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
256233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        // Four status entries (kBaseSeq + 3 missing).
257233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(4u, packet->GetStatusVector().size());
258233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
259233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        // Only three actual timestamps.
260233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
261233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(3u, delta_vec.size());
262233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kBaseTimeMs - 1,
263233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang                  (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
264233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(kTimeoutTimeMs - kBaseTimeMs, delta_vec[1] / 1000);
265233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        EXPECT_EQ(1, delta_vec[2] / 1000);
266233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang        return true;
267233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang      }));
268233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
269233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang  Process();
270233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}
271233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang
272233bd87d45bbeeec50d7687e7d98c1cfc7f65562sprang}  // namespace webrtc
273