blob: c586b3dc4de39f4a09c6f8be29b346854f31dfba [file] [log] [blame]
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg84be5112016-04-27 01:19:58 -070011#include <memory>
Danil Chapovalovd1996b72018-01-16 11:07:18 +010012#include <vector>
kwiberg84be5112016-04-27 01:19:58 -070013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "modules/rtp_rtcp/include/receive_statistics.h"
15#include "system_wrappers/include/clock.h"
16#include "test/gmock.h"
17#include "test/gtest.h"
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000018
19namespace webrtc {
Danil Chapovalovd1996b72018-01-16 11:07:18 +010020namespace {
21
22using ::testing::SizeIs;
23using ::testing::UnorderedElementsAre;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000024
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000025const size_t kPacketSize1 = 100;
26const size_t kPacketSize2 = 300;
Danil Chapovalovd1996b72018-01-16 11:07:18 +010027const uint32_t kSsrc1 = 101;
28const uint32_t kSsrc2 = 202;
29const uint32_t kSsrc3 = 203;
30const uint32_t kSsrc4 = 304;
31
32RTPHeader CreateRtpHeader(uint32_t ssrc) {
33 RTPHeader header;
34 memset(&header, 0, sizeof(header));
35 header.ssrc = ssrc;
36 header.sequenceNumber = 100;
37 return header;
38}
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000039
40class ReceiveStatisticsTest : public ::testing::Test {
41 public:
42 ReceiveStatisticsTest() :
43 clock_(0),
44 receive_statistics_(ReceiveStatistics::Create(&clock_)) {
Danil Chapovalovd1996b72018-01-16 11:07:18 +010045 header1_ = CreateRtpHeader(kSsrc1);
46 header2_ = CreateRtpHeader(kSsrc2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000047 }
48
49 protected:
50 SimulatedClock clock_;
kwiberg84be5112016-04-27 01:19:58 -070051 std::unique_ptr<ReceiveStatistics> receive_statistics_;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000052 RTPHeader header1_;
53 RTPHeader header2_;
54};
55
56TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000057 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000058 ++header1_.sequenceNumber;
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000059 receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000060 ++header2_.sequenceNumber;
61 clock_.AdvanceTimeMilliseconds(100);
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000062 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000063 ++header1_.sequenceNumber;
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000064 receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000065 ++header2_.sequenceNumber;
66
67 StreamStatistician* statistician =
68 receive_statistics_->GetStatistician(kSsrc1);
69 ASSERT_TRUE(statistician != NULL);
70 EXPECT_GT(statistician->BitrateReceived(), 0u);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000071 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000072 uint32_t packets_received = 0;
73 statistician->GetDataCounters(&bytes_received, &packets_received);
74 EXPECT_EQ(200u, bytes_received);
75 EXPECT_EQ(2u, packets_received);
76
77 statistician =
78 receive_statistics_->GetStatistician(kSsrc2);
79 ASSERT_TRUE(statistician != NULL);
80 EXPECT_GT(statistician->BitrateReceived(), 0u);
81 statistician->GetDataCounters(&bytes_received, &packets_received);
82 EXPECT_EQ(600u, bytes_received);
83 EXPECT_EQ(2u, packets_received);
84
Danil Chapovalovc5267d22017-09-18 13:57:19 +020085 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000086 // Add more incoming packets and verify that they are registered in both
87 // access methods.
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000088 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000089 ++header1_.sequenceNumber;
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000090 receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000091 ++header2_.sequenceNumber;
92
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000093 receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
94 &bytes_received, &packets_received);
95 EXPECT_EQ(300u, bytes_received);
96 EXPECT_EQ(3u, packets_received);
97 receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
98 &bytes_received, &packets_received);
99 EXPECT_EQ(900u, bytes_received);
100 EXPECT_EQ(3u, packets_received);
101}
102
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100103TEST_F(ReceiveStatisticsTest,
104 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
105 RTPHeader header1 = CreateRtpHeader(kSsrc1);
106 RTPHeader header2 = CreateRtpHeader(kSsrc2);
107 RTPHeader header3 = CreateRtpHeader(kSsrc3);
108 receive_statistics_->IncomingPacket(header1, kPacketSize1, false);
109 receive_statistics_->IncomingPacket(header2, kPacketSize1, false);
110 receive_statistics_->IncomingPacket(header3, kPacketSize1, false);
111
112 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
113 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
114 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
115}
116
117TEST_F(ReceiveStatisticsTest,
118 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
119 RTPHeader header1 = CreateRtpHeader(kSsrc1);
120 RTPHeader header2 = CreateRtpHeader(kSsrc2);
121 RTPHeader header3 = CreateRtpHeader(kSsrc3);
122 RTPHeader header4 = CreateRtpHeader(kSsrc4);
123 receive_statistics_->IncomingPacket(header1, kPacketSize1, false);
124 receive_statistics_->IncomingPacket(header2, kPacketSize1, false);
125 receive_statistics_->IncomingPacket(header3, kPacketSize1, false);
126 receive_statistics_->IncomingPacket(header4, kPacketSize1, false);
127
128 std::vector<uint32_t> observed_ssrcs;
129 std::vector<rtcp::ReportBlock> report_blocks =
130 receive_statistics_->RtcpReportBlocks(2);
131 ASSERT_THAT(report_blocks, SizeIs(2));
132 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
133 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
134
135 report_blocks = receive_statistics_->RtcpReportBlocks(2);
136 ASSERT_THAT(report_blocks, SizeIs(2));
137 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
138 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
139
140 EXPECT_THAT(observed_ssrcs,
141 UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4));
142}
143
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000144TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +0000145 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000146 ++header1_.sequenceNumber;
147 clock_.AdvanceTimeMilliseconds(1000);
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +0000148 receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000149 ++header2_.sequenceNumber;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000150 // Nothing should time out since only 1000 ms has passed since the first
151 // packet came in.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200152 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000153
154 clock_.AdvanceTimeMilliseconds(7000);
155 // kSsrc1 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200156 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000157
158 clock_.AdvanceTimeMilliseconds(1000);
159 // kSsrc2 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200160 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000161
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +0000162 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000163 ++header1_.sequenceNumber;
164 // kSsrc1 should be active again and the data counters should have survived.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200165 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000166 StreamStatistician* statistician =
167 receive_statistics_->GetStatistician(kSsrc1);
168 ASSERT_TRUE(statistician != NULL);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000169 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000170 uint32_t packets_received = 0;
171 statistician->GetDataCounters(&bytes_received, &packets_received);
172 EXPECT_EQ(200u, bytes_received);
173 EXPECT_EQ(2u, packets_received);
174}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000175
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000176TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
177 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
178 StreamStatistician* statistician =
179 receive_statistics_->GetStatistician(kSsrc1);
180 ASSERT_TRUE(statistician != NULL);
181
182 StreamDataCounters counters;
183 statistician->GetReceiveStreamDataCounters(&counters);
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000184 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000185 EXPECT_EQ(1u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000186
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000187 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
188 statistician->GetReceiveStreamDataCounters(&counters);
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000189 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000190 EXPECT_EQ(2u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000191}
192
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000193TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000194 class TestCallback : public RtcpStatisticsCallback {
195 public:
196 TestCallback()
197 : RtcpStatisticsCallback(), num_calls_(0), ssrc_(0), stats_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000198 ~TestCallback() override {}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000199
nisseef8b61e2016-04-29 06:09:15 -0700200 void StatisticsUpdated(const RtcpStatistics& statistics,
201 uint32_t ssrc) override {
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000202 ssrc_ = ssrc;
203 stats_ = statistics;
204 ++num_calls_;
205 }
206
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000207 void CNameChanged(const char* cname, uint32_t ssrc) override {}
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000208
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000209 uint32_t num_calls_;
210 uint32_t ssrc_;
211 RtcpStatistics stats_;
212 } callback;
213
214 receive_statistics_->RegisterRtcpStatisticsCallback(&callback);
215
216 // Add some arbitrary data, with loss and jitter.
217 header1_.sequenceNumber = 1;
218 clock_.AdvanceTimeMilliseconds(7);
219 header1_.timestamp += 3;
220 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
221 header1_.sequenceNumber += 2;
222 clock_.AdvanceTimeMilliseconds(9);
223 header1_.timestamp += 9;
224 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
225 --header1_.sequenceNumber;
226 clock_.AdvanceTimeMilliseconds(13);
227 header1_.timestamp += 47;
228 receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
229 header1_.sequenceNumber += 3;
230 clock_.AdvanceTimeMilliseconds(11);
231 header1_.timestamp += 17;
232 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
233 ++header1_.sequenceNumber;
234
235 EXPECT_EQ(0u, callback.num_calls_);
236
237 // Call GetStatistics, simulating a timed rtcp sender thread.
238 RtcpStatistics statistics;
239 receive_statistics_->GetStatistician(kSsrc1)
240 ->GetStatistics(&statistics, true);
241
242 EXPECT_EQ(1u, callback.num_calls_);
243 EXPECT_EQ(callback.ssrc_, kSsrc1);
srte186d9c32017-08-04 05:03:53 -0700244 EXPECT_EQ(statistics.packets_lost, callback.stats_.packets_lost);
245 EXPECT_EQ(statistics.extended_highest_sequence_number,
246 callback.stats_.extended_highest_sequence_number);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000247 EXPECT_EQ(statistics.fraction_lost, callback.stats_.fraction_lost);
248 EXPECT_EQ(statistics.jitter, callback.stats_.jitter);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000249 EXPECT_EQ(51, statistics.fraction_lost);
Harald Alvestrandc7c41912017-12-08 09:59:34 +0100250 EXPECT_EQ(1, statistics.packets_lost);
srte186d9c32017-08-04 05:03:53 -0700251 EXPECT_EQ(5u, statistics.extended_highest_sequence_number);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000252 EXPECT_EQ(4u, statistics.jitter);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000253
254 receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
255
256 // Add some more data.
257 header1_.sequenceNumber = 1;
258 clock_.AdvanceTimeMilliseconds(7);
259 header1_.timestamp += 3;
260 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
261 header1_.sequenceNumber += 2;
262 clock_.AdvanceTimeMilliseconds(9);
263 header1_.timestamp += 9;
264 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
265 --header1_.sequenceNumber;
266 clock_.AdvanceTimeMilliseconds(13);
267 header1_.timestamp += 47;
268 receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
269 header1_.sequenceNumber += 3;
270 clock_.AdvanceTimeMilliseconds(11);
271 header1_.timestamp += 17;
272 receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
273 ++header1_.sequenceNumber;
274
275 receive_statistics_->GetStatistician(kSsrc1)
276 ->GetStatistics(&statistics, true);
277
278 // Should not have been called after deregister.
279 EXPECT_EQ(1u, callback.num_calls_);
280}
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000281
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000282class RtpTestCallback : public StreamDataCountersCallback {
283 public:
284 RtpTestCallback()
285 : StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000286 ~RtpTestCallback() override = default;
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000287
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000288 void DataCountersUpdated(const StreamDataCounters& counters,
289 uint32_t ssrc) override {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000290 ssrc_ = ssrc;
291 stats_ = counters;
292 ++num_calls_;
293 }
294
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000295 void MatchPacketCounter(const RtpPacketCounter& expected,
296 const RtpPacketCounter& actual) {
297 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
298 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
299 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
300 EXPECT_EQ(expected.packets, actual.packets);
301 }
302
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000303 void Matches(uint32_t num_calls,
304 uint32_t ssrc,
305 const StreamDataCounters& expected) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000306 EXPECT_EQ(num_calls, num_calls_);
307 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000308 MatchPacketCounter(expected.transmitted, stats_.transmitted);
309 MatchPacketCounter(expected.retransmitted, stats_.retransmitted);
310 MatchPacketCounter(expected.fec, stats_.fec);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000311 }
312
313 uint32_t num_calls_;
314 uint32_t ssrc_;
315 StreamDataCounters stats_;
316};
317
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000318TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000319 RtpTestCallback callback;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000320 receive_statistics_->RegisterRtpStatisticsCallback(&callback);
321
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000322 const size_t kHeaderLength = 20;
323 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000324
325 // One packet of size kPacketSize1.
326 header1_.headerLength = kHeaderLength;
327 receive_statistics_->IncomingPacket(
328 header1_, kPacketSize1 + kHeaderLength, false);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000329 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000330 expected.transmitted.payload_bytes = kPacketSize1;
331 expected.transmitted.header_bytes = kHeaderLength;
332 expected.transmitted.padding_bytes = 0;
333 expected.transmitted.packets = 1;
334 expected.retransmitted.payload_bytes = 0;
335 expected.retransmitted.header_bytes = 0;
336 expected.retransmitted.padding_bytes = 0;
337 expected.retransmitted.packets = 0;
338 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000339 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000340
341 ++header1_.sequenceNumber;
342 clock_.AdvanceTimeMilliseconds(5);
343 header1_.paddingLength = 9;
344 // Another packet of size kPacketSize1 with 9 bytes padding.
345 receive_statistics_->IncomingPacket(
346 header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000347 expected.transmitted.payload_bytes = kPacketSize1 * 2;
348 expected.transmitted.header_bytes = kHeaderLength * 2;
349 expected.transmitted.padding_bytes = kPaddingLength;
350 expected.transmitted.packets = 2;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000351 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000352
353 clock_.AdvanceTimeMilliseconds(5);
354 // Retransmit last packet.
355 receive_statistics_->IncomingPacket(
356 header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000357 expected.transmitted.payload_bytes = kPacketSize1 * 3;
358 expected.transmitted.header_bytes = kHeaderLength * 3;
359 expected.transmitted.padding_bytes = kPaddingLength * 2;
360 expected.transmitted.packets = 3;
361 expected.retransmitted.payload_bytes = kPacketSize1;
362 expected.retransmitted.header_bytes = kHeaderLength;
363 expected.retransmitted.padding_bytes = kPaddingLength;
364 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000365 callback.Matches(3, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000366
367 header1_.paddingLength = 0;
368 ++header1_.sequenceNumber;
369 clock_.AdvanceTimeMilliseconds(5);
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000370 // One FEC packet.
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000371 receive_statistics_->IncomingPacket(
372 header1_, kPacketSize1 + kHeaderLength, false);
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000373 receive_statistics_->FecPacketReceived(header1_,
374 kPacketSize1 + kHeaderLength);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000375 expected.transmitted.payload_bytes = kPacketSize1 * 4;
376 expected.transmitted.header_bytes = kHeaderLength * 4;
377 expected.transmitted.packets = 4;
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000378 expected.fec.payload_bytes = kPacketSize1;
379 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000380 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000381 callback.Matches(5, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000382
383 receive_statistics_->RegisterRtpStatisticsCallback(NULL);
384
385 // New stats, but callback should not be called.
386 ++header1_.sequenceNumber;
387 clock_.AdvanceTimeMilliseconds(5);
388 receive_statistics_->IncomingPacket(
389 header1_, kPacketSize1 + kHeaderLength, true);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000390 callback.Matches(5, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000391}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000392
393TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
394 RtpTestCallback callback;
395 receive_statistics_->RegisterRtpStatisticsCallback(&callback);
396
397 const uint32_t kHeaderLength = 20;
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000398 header1_.headerLength = kHeaderLength;
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000399
400 // If first packet is FEC, ignore it.
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000401 receive_statistics_->FecPacketReceived(header1_,
402 kPacketSize1 + kHeaderLength);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000403 EXPECT_EQ(0u, callback.num_calls_);
404
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000405 receive_statistics_->IncomingPacket(
406 header1_, kPacketSize1 + kHeaderLength, false);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000407 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000408 expected.transmitted.payload_bytes = kPacketSize1;
409 expected.transmitted.header_bytes = kHeaderLength;
410 expected.transmitted.padding_bytes = 0;
411 expected.transmitted.packets = 1;
412 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000413 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000414
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000415 receive_statistics_->FecPacketReceived(header1_,
416 kPacketSize1 + kHeaderLength);
417 expected.fec.payload_bytes = kPacketSize1;
418 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000419 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000420 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000421}
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100422
423} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000424} // namespace webrtc