blob: 578d81fc3d4000e9612d7f01a20725d79e439dbd [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"
Niels Möller1f3206c2018-09-14 08:26:32 +020015#include "modules/rtp_rtcp/source/rtp_packet_received.h"
16#include "rtc_base/random.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "system_wrappers/include/clock.h"
18#include "test/gmock.h"
19#include "test/gtest.h"
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000020
21namespace webrtc {
Danil Chapovalovd1996b72018-01-16 11:07:18 +010022namespace {
23
24using ::testing::SizeIs;
25using ::testing::UnorderedElementsAre;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000026
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000027const size_t kPacketSize1 = 100;
28const size_t kPacketSize2 = 300;
Danil Chapovalovd1996b72018-01-16 11:07:18 +010029const uint32_t kSsrc1 = 101;
30const uint32_t kSsrc2 = 202;
31const uint32_t kSsrc3 = 203;
32const uint32_t kSsrc4 = 304;
33
Niels Möller1f3206c2018-09-14 08:26:32 +020034RtpPacketReceived CreateRtpPacket(uint32_t ssrc,
35 size_t header_size,
36 size_t payload_size,
37 size_t padding_size) {
38 RtpPacketReceived packet;
39 packet.SetSsrc(ssrc);
40 packet.SetSequenceNumber(100);
41 packet.set_payload_type_frequency(90000);
42 RTC_CHECK_GE(header_size, 12);
43 RTC_CHECK_EQ(header_size % 4, 0);
44 if (header_size > 12) {
45 // Insert csrcs to increase header size.
46 const int num_csrcs = (header_size - 12) / 4;
47 std::vector<uint32_t> csrcs(num_csrcs);
48 packet.SetCsrcs(csrcs);
49 }
50 packet.SetPayloadSize(payload_size);
Danil Chapovalovf7fcaf02018-10-10 14:56:01 +020051 packet.SetPadding(padding_size);
Niels Möller1f3206c2018-09-14 08:26:32 +020052 return packet;
53}
54
55RtpPacketReceived CreateRtpPacket(uint32_t ssrc, size_t packet_size) {
56 return CreateRtpPacket(ssrc, 12, packet_size - 12, 0);
57}
58
59void IncrementSequenceNumber(RtpPacketReceived* packet, uint16_t incr) {
60 packet->SetSequenceNumber(packet->SequenceNumber() + incr);
61}
62
63void IncrementSequenceNumber(RtpPacketReceived* packet) {
64 IncrementSequenceNumber(packet, 1);
65}
66
67void IncrementTimestamp(RtpPacketReceived* packet, uint32_t incr) {
68 packet->SetTimestamp(packet->Timestamp() + incr);
Danil Chapovalovd1996b72018-01-16 11:07:18 +010069}
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000070
71class ReceiveStatisticsTest : public ::testing::Test {
72 public:
Yves Gerey665174f2018-06-19 15:03:05 +020073 ReceiveStatisticsTest()
74 : clock_(0), receive_statistics_(ReceiveStatistics::Create(&clock_)) {
Niels Möller1f3206c2018-09-14 08:26:32 +020075 packet1_ = CreateRtpPacket(kSsrc1, kPacketSize1);
76 packet2_ = CreateRtpPacket(kSsrc2, kPacketSize2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000077 }
78
79 protected:
80 SimulatedClock clock_;
kwiberg84be5112016-04-27 01:19:58 -070081 std::unique_ptr<ReceiveStatistics> receive_statistics_;
Niels Möller1f3206c2018-09-14 08:26:32 +020082 RtpPacketReceived packet1_;
83 RtpPacketReceived packet2_;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000084};
85
86TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
Niels Möller1f3206c2018-09-14 08:26:32 +020087 receive_statistics_->OnRtpPacket(packet1_);
88 IncrementSequenceNumber(&packet1_);
89 receive_statistics_->OnRtpPacket(packet2_);
90 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000091 clock_.AdvanceTimeMilliseconds(100);
Niels Möller1f3206c2018-09-14 08:26:32 +020092 receive_statistics_->OnRtpPacket(packet1_);
93 IncrementSequenceNumber(&packet1_);
94 receive_statistics_->OnRtpPacket(packet2_);
95 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +000096
97 StreamStatistician* statistician =
98 receive_statistics_->GetStatistician(kSsrc1);
99 ASSERT_TRUE(statistician != NULL);
100 EXPECT_GT(statistician->BitrateReceived(), 0u);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000101 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000102 uint32_t packets_received = 0;
103 statistician->GetDataCounters(&bytes_received, &packets_received);
104 EXPECT_EQ(200u, bytes_received);
105 EXPECT_EQ(2u, packets_received);
106
Yves Gerey665174f2018-06-19 15:03:05 +0200107 statistician = receive_statistics_->GetStatistician(kSsrc2);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000108 ASSERT_TRUE(statistician != NULL);
109 EXPECT_GT(statistician->BitrateReceived(), 0u);
110 statistician->GetDataCounters(&bytes_received, &packets_received);
111 EXPECT_EQ(600u, bytes_received);
112 EXPECT_EQ(2u, packets_received);
113
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200114 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000115 // Add more incoming packets and verify that they are registered in both
116 // access methods.
Niels Möller1f3206c2018-09-14 08:26:32 +0200117 receive_statistics_->OnRtpPacket(packet1_);
118 IncrementSequenceNumber(&packet1_);
119 receive_statistics_->OnRtpPacket(packet2_);
120 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000121
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000122 receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
123 &bytes_received, &packets_received);
124 EXPECT_EQ(300u, bytes_received);
125 EXPECT_EQ(3u, packets_received);
126 receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
127 &bytes_received, &packets_received);
128 EXPECT_EQ(900u, bytes_received);
129 EXPECT_EQ(3u, packets_received);
130}
131
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100132TEST_F(ReceiveStatisticsTest,
133 RtcpReportBlocksReturnsMaxBlocksWhenThereAreMoreStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200134 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
135 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
136 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
137 receive_statistics_->OnRtpPacket(packet1);
138 receive_statistics_->OnRtpPacket(packet2);
139 receive_statistics_->OnRtpPacket(packet3);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100140
141 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
142 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
143 EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
144}
145
146TEST_F(ReceiveStatisticsTest,
147 RtcpReportBlocksReturnsAllObservedSsrcsWithMultipleCalls) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200148 RtpPacketReceived packet1 = CreateRtpPacket(kSsrc1, kPacketSize1);
149 RtpPacketReceived packet2 = CreateRtpPacket(kSsrc2, kPacketSize1);
150 RtpPacketReceived packet3 = CreateRtpPacket(kSsrc3, kPacketSize1);
151 RtpPacketReceived packet4 = CreateRtpPacket(kSsrc4, kPacketSize1);
152 receive_statistics_->OnRtpPacket(packet1);
153 receive_statistics_->OnRtpPacket(packet2);
154 receive_statistics_->OnRtpPacket(packet3);
155 receive_statistics_->OnRtpPacket(packet4);
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100156
157 std::vector<uint32_t> observed_ssrcs;
158 std::vector<rtcp::ReportBlock> report_blocks =
159 receive_statistics_->RtcpReportBlocks(2);
160 ASSERT_THAT(report_blocks, SizeIs(2));
161 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
162 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
163
164 report_blocks = receive_statistics_->RtcpReportBlocks(2);
165 ASSERT_THAT(report_blocks, SizeIs(2));
166 observed_ssrcs.push_back(report_blocks[0].source_ssrc());
167 observed_ssrcs.push_back(report_blocks[1].source_ssrc());
168
169 EXPECT_THAT(observed_ssrcs,
170 UnorderedElementsAre(kSsrc1, kSsrc2, kSsrc3, kSsrc4));
171}
172
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000173TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200174 receive_statistics_->OnRtpPacket(packet1_);
175 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000176 clock_.AdvanceTimeMilliseconds(1000);
Niels Möller1f3206c2018-09-14 08:26:32 +0200177 receive_statistics_->OnRtpPacket(packet2_);
178 IncrementSequenceNumber(&packet2_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000179 // Nothing should time out since only 1000 ms has passed since the first
180 // packet came in.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200181 EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000182
183 clock_.AdvanceTimeMilliseconds(7000);
184 // kSsrc1 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200185 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000186
187 clock_.AdvanceTimeMilliseconds(1000);
188 // kSsrc2 should have timed out.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200189 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000190
Niels Möller1f3206c2018-09-14 08:26:32 +0200191 receive_statistics_->OnRtpPacket(packet1_);
192 IncrementSequenceNumber(&packet1_);
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000193 // kSsrc1 should be active again and the data counters should have survived.
Danil Chapovalovc5267d22017-09-18 13:57:19 +0200194 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000195 StreamStatistician* statistician =
196 receive_statistics_->GetStatistician(kSsrc1);
197 ASSERT_TRUE(statistician != NULL);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000198 size_t bytes_received = 0;
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000199 uint32_t packets_received = 0;
200 statistician->GetDataCounters(&bytes_received, &packets_received);
201 EXPECT_EQ(200u, bytes_received);
202 EXPECT_EQ(2u, packets_received);
203}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000204
Niels Möller5304a322018-08-27 13:27:05 +0200205TEST_F(ReceiveStatisticsTest,
206 DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) {
207 // Creates a statistician object for the ssrc.
208 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
209 EXPECT_TRUE(receive_statistics_->GetStatistician(kSsrc1) != nullptr);
210 EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
211 // Receive first packet
Niels Möller1f3206c2018-09-14 08:26:32 +0200212 receive_statistics_->OnRtpPacket(packet1_);
Niels Möller5304a322018-08-27 13:27:05 +0200213 EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
214}
215
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000216TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
Niels Möller1f3206c2018-09-14 08:26:32 +0200217 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000218 StreamStatistician* statistician =
219 receive_statistics_->GetStatistician(kSsrc1);
220 ASSERT_TRUE(statistician != NULL);
221
222 StreamDataCounters counters;
223 statistician->GetReceiveStreamDataCounters(&counters);
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000224 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000225 EXPECT_EQ(1u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000226
Niels Möller1f3206c2018-09-14 08:26:32 +0200227 receive_statistics_->OnRtpPacket(packet1_);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000228 statistician->GetReceiveStreamDataCounters(&counters);
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000229 EXPECT_GT(counters.first_packet_time_ms, -1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000230 EXPECT_EQ(2u, counters.transmitted.packets);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000231}
232
Qingsi Wang2370b082018-08-21 14:24:26 -0700233TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
234 class TestCallback : public RtcpStatisticsCallback {
235 public:
236 TestCallback()
237 : RtcpStatisticsCallback(), num_calls_(0), ssrc_(0), stats_() {}
238 ~TestCallback() override {}
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000239
Qingsi Wang2370b082018-08-21 14:24:26 -0700240 void StatisticsUpdated(const RtcpStatistics& statistics,
241 uint32_t ssrc) override {
242 ssrc_ = ssrc;
243 stats_ = statistics;
244 ++num_calls_;
245 }
246
247 void CNameChanged(const char* cname, uint32_t ssrc) override {}
248
249 uint32_t num_calls_;
250 uint32_t ssrc_;
251 RtcpStatistics stats_;
252 } callback;
253
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000254 receive_statistics_->RegisterRtcpStatisticsCallback(&callback);
Niels Möller5304a322018-08-27 13:27:05 +0200255 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000256
257 // Add some arbitrary data, with loss and jitter.
Niels Möller1f3206c2018-09-14 08:26:32 +0200258 packet1_.SetSequenceNumber(1);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000259 clock_.AdvanceTimeMilliseconds(7);
Niels Möller1f3206c2018-09-14 08:26:32 +0200260 IncrementTimestamp(&packet1_, 3);
261 receive_statistics_->OnRtpPacket(packet1_);
262 IncrementSequenceNumber(&packet1_, 2);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000263 clock_.AdvanceTimeMilliseconds(9);
Niels Möller1f3206c2018-09-14 08:26:32 +0200264 IncrementTimestamp(&packet1_, 9);
265 receive_statistics_->OnRtpPacket(packet1_);
266 IncrementSequenceNumber(&packet1_, -1);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000267 clock_.AdvanceTimeMilliseconds(13);
Niels Möller1f3206c2018-09-14 08:26:32 +0200268 IncrementTimestamp(&packet1_, 47);
269 receive_statistics_->OnRtpPacket(packet1_);
270 IncrementSequenceNumber(&packet1_, 3);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000271 clock_.AdvanceTimeMilliseconds(11);
Niels Möller1f3206c2018-09-14 08:26:32 +0200272 IncrementTimestamp(&packet1_, 17);
273 receive_statistics_->OnRtpPacket(packet1_);
274 IncrementSequenceNumber(&packet1_);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000275
Qingsi Wang2370b082018-08-21 14:24:26 -0700276 EXPECT_EQ(0u, callback.num_calls_);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000277
Qingsi Wang2370b082018-08-21 14:24:26 -0700278 // Call GetStatistics, simulating a timed rtcp sender thread.
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000279 RtcpStatistics statistics;
Qingsi Wang2370b082018-08-21 14:24:26 -0700280 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
281 true);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000282
Qingsi Wang2370b082018-08-21 14:24:26 -0700283 EXPECT_EQ(1u, callback.num_calls_);
284 EXPECT_EQ(callback.ssrc_, kSsrc1);
285 EXPECT_EQ(statistics.packets_lost, callback.stats_.packets_lost);
286 EXPECT_EQ(statistics.extended_highest_sequence_number,
287 callback.stats_.extended_highest_sequence_number);
288 EXPECT_EQ(statistics.fraction_lost, callback.stats_.fraction_lost);
289 EXPECT_EQ(statistics.jitter, callback.stats_.jitter);
290 EXPECT_EQ(51, statistics.fraction_lost);
Harald Alvestrandc7c41912017-12-08 09:59:34 +0100291 EXPECT_EQ(1, statistics.packets_lost);
Qingsi Wang2370b082018-08-21 14:24:26 -0700292 EXPECT_EQ(5u, statistics.extended_highest_sequence_number);
Niels Möller5304a322018-08-27 13:27:05 +0200293 EXPECT_EQ(177u, statistics.jitter);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000294
Qingsi Wang2370b082018-08-21 14:24:26 -0700295 receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000296
Qingsi Wang2370b082018-08-21 14:24:26 -0700297 // Add some more data.
Niels Möller1f3206c2018-09-14 08:26:32 +0200298 packet1_.SetSequenceNumber(1);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000299 clock_.AdvanceTimeMilliseconds(7);
Niels Möller1f3206c2018-09-14 08:26:32 +0200300 IncrementTimestamp(&packet1_, 3);
301 receive_statistics_->OnRtpPacket(packet1_);
302 IncrementSequenceNumber(&packet1_, 2);
Qingsi Wang2370b082018-08-21 14:24:26 -0700303 clock_.AdvanceTimeMilliseconds(9);
Niels Möller1f3206c2018-09-14 08:26:32 +0200304 IncrementTimestamp(&packet1_, 9);
305 receive_statistics_->OnRtpPacket(packet1_);
306 IncrementSequenceNumber(&packet1_, -1);
Qingsi Wang2370b082018-08-21 14:24:26 -0700307 clock_.AdvanceTimeMilliseconds(13);
Niels Möller1f3206c2018-09-14 08:26:32 +0200308 IncrementTimestamp(&packet1_, 47);
309 receive_statistics_->OnRtpPacket(packet1_);
310 IncrementSequenceNumber(&packet1_, 3);
Qingsi Wang2370b082018-08-21 14:24:26 -0700311 clock_.AdvanceTimeMilliseconds(11);
Niels Möller1f3206c2018-09-14 08:26:32 +0200312 IncrementTimestamp(&packet1_, 17);
313 receive_statistics_->OnRtpPacket(packet1_);
314 IncrementSequenceNumber(&packet1_);
Taylor Brandstetter84916932018-06-25 15:50:26 -0700315
Qingsi Wang2370b082018-08-21 14:24:26 -0700316 receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
317 true);
Taylor Brandstetter84916932018-06-25 15:50:26 -0700318
Qingsi Wang2370b082018-08-21 14:24:26 -0700319 // Should not have been called after deregister.
320 EXPECT_EQ(1u, callback.num_calls_);
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000321}
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000322
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000323class RtpTestCallback : public StreamDataCountersCallback {
324 public:
325 RtpTestCallback()
326 : StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000327 ~RtpTestCallback() override = default;
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000328
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000329 void DataCountersUpdated(const StreamDataCounters& counters,
330 uint32_t ssrc) override {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000331 ssrc_ = ssrc;
332 stats_ = counters;
333 ++num_calls_;
334 }
335
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000336 void MatchPacketCounter(const RtpPacketCounter& expected,
337 const RtpPacketCounter& actual) {
338 EXPECT_EQ(expected.payload_bytes, actual.payload_bytes);
339 EXPECT_EQ(expected.header_bytes, actual.header_bytes);
340 EXPECT_EQ(expected.padding_bytes, actual.padding_bytes);
341 EXPECT_EQ(expected.packets, actual.packets);
342 }
343
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000344 void Matches(uint32_t num_calls,
345 uint32_t ssrc,
346 const StreamDataCounters& expected) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000347 EXPECT_EQ(num_calls, num_calls_);
348 EXPECT_EQ(ssrc, ssrc_);
asapersson@webrtc.org44149392015-02-04 08:34:47 +0000349 MatchPacketCounter(expected.transmitted, stats_.transmitted);
350 MatchPacketCounter(expected.retransmitted, stats_.retransmitted);
351 MatchPacketCounter(expected.fec, stats_.fec);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000352 }
353
354 uint32_t num_calls_;
355 uint32_t ssrc_;
356 StreamDataCounters stats_;
357};
358
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000359TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000360 RtpTestCallback callback;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000361 receive_statistics_->RegisterRtpStatisticsCallback(&callback);
Niels Möller5304a322018-08-27 13:27:05 +0200362 receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000363
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000364 const size_t kHeaderLength = 20;
365 const size_t kPaddingLength = 9;
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000366
Niels Möller1f3206c2018-09-14 08:26:32 +0200367 // One packet with payload size kPacketSize1.
368 RtpPacketReceived packet1 =
369 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
370 receive_statistics_->OnRtpPacket(packet1);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000371 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000372 expected.transmitted.payload_bytes = kPacketSize1;
373 expected.transmitted.header_bytes = kHeaderLength;
374 expected.transmitted.padding_bytes = 0;
375 expected.transmitted.packets = 1;
376 expected.retransmitted.payload_bytes = 0;
377 expected.retransmitted.header_bytes = 0;
378 expected.retransmitted.padding_bytes = 0;
379 expected.retransmitted.packets = 0;
380 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000381 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000382
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000383 // Another packet of size kPacketSize1 with 9 bytes padding.
Niels Möller1f3206c2018-09-14 08:26:32 +0200384 RtpPacketReceived packet2 =
385 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 9);
386 packet2.SetSequenceNumber(packet1.SequenceNumber() + 1);
387 clock_.AdvanceTimeMilliseconds(5);
388 receive_statistics_->OnRtpPacket(packet2);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000389 expected.transmitted.payload_bytes = kPacketSize1 * 2;
390 expected.transmitted.header_bytes = kHeaderLength * 2;
391 expected.transmitted.padding_bytes = kPaddingLength;
392 expected.transmitted.packets = 2;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000393 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000394
395 clock_.AdvanceTimeMilliseconds(5);
396 // Retransmit last packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200397 receive_statistics_->OnRtpPacket(packet2);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000398 expected.transmitted.payload_bytes = kPacketSize1 * 3;
399 expected.transmitted.header_bytes = kHeaderLength * 3;
400 expected.transmitted.padding_bytes = kPaddingLength * 2;
401 expected.transmitted.packets = 3;
402 expected.retransmitted.payload_bytes = kPacketSize1;
403 expected.retransmitted.header_bytes = kHeaderLength;
404 expected.retransmitted.padding_bytes = kPaddingLength;
405 expected.retransmitted.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000406 callback.Matches(3, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000407
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000408 // One FEC packet.
Niels Möller1f3206c2018-09-14 08:26:32 +0200409 packet1.SetSequenceNumber(packet2.SequenceNumber() + 1);
410 clock_.AdvanceTimeMilliseconds(5);
411 receive_statistics_->OnRtpPacket(packet1);
412 receive_statistics_->FecPacketReceived(packet1);
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000413 expected.transmitted.payload_bytes = kPacketSize1 * 4;
414 expected.transmitted.header_bytes = kHeaderLength * 4;
415 expected.transmitted.packets = 4;
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000416 expected.fec.payload_bytes = kPacketSize1;
417 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000418 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000419 callback.Matches(5, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000420
421 receive_statistics_->RegisterRtpStatisticsCallback(NULL);
422
423 // New stats, but callback should not be called.
Niels Möller1f3206c2018-09-14 08:26:32 +0200424 IncrementSequenceNumber(&packet1);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000425 clock_.AdvanceTimeMilliseconds(5);
Niels Möller1f3206c2018-09-14 08:26:32 +0200426 receive_statistics_->OnRtpPacket(packet1);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000427 callback.Matches(5, kSsrc1, expected);
sprang@webrtc.org0e932572014-01-23 10:00:39 +0000428}
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000429
430TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
431 RtpTestCallback callback;
432 receive_statistics_->RegisterRtpStatisticsCallback(&callback);
433
434 const uint32_t kHeaderLength = 20;
Niels Möller1f3206c2018-09-14 08:26:32 +0200435 RtpPacketReceived packet =
436 CreateRtpPacket(kSsrc1, kHeaderLength, kPacketSize1, 0);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000437 // If first packet is FEC, ignore it.
Niels Möller1f3206c2018-09-14 08:26:32 +0200438 receive_statistics_->FecPacketReceived(packet);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000439 EXPECT_EQ(0u, callback.num_calls_);
440
Niels Möller1f3206c2018-09-14 08:26:32 +0200441 receive_statistics_->OnRtpPacket(packet);
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000442 StreamDataCounters expected;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000443 expected.transmitted.payload_bytes = kPacketSize1;
444 expected.transmitted.header_bytes = kHeaderLength;
445 expected.transmitted.padding_bytes = 0;
446 expected.transmitted.packets = 1;
447 expected.fec.packets = 0;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000448 callback.Matches(1, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000449
Niels Möller1f3206c2018-09-14 08:26:32 +0200450 receive_statistics_->FecPacketReceived(packet);
asapersson@webrtc.org273fbbb2015-01-27 12:17:29 +0000451 expected.fec.payload_bytes = kPacketSize1;
452 expected.fec.header_bytes = kHeaderLength;
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +0000453 expected.fec.packets = 1;
asapersson@webrtc.org97d04892014-12-09 09:47:53 +0000454 callback.Matches(2, kSsrc1, expected);
sprang@webrtc.orgc30e9e22014-09-08 08:20:18 +0000455}
Danil Chapovalovd1996b72018-01-16 11:07:18 +0100456
457} // namespace
stefan@webrtc.org286fe0b2013-08-21 20:58:21 +0000458} // namespace webrtc