xref: /aosp_15_r20/external/openscreen/cast/streaming/rtcp_common_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "cast/streaming/rtcp_common.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <chrono>
8*3f982cf4SFabien Sanglard #include <limits>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "absl/types/span.h"
11*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
12*3f982cf4SFabien Sanglard #include "platform/api/time.h"
13*3f982cf4SFabien Sanglard #include "util/chrono_helpers.h"
14*3f982cf4SFabien Sanglard 
15*3f982cf4SFabien Sanglard namespace openscreen {
16*3f982cf4SFabien Sanglard namespace cast {
17*3f982cf4SFabien Sanglard namespace {
18*3f982cf4SFabien Sanglard 
19*3f982cf4SFabien Sanglard template <typename T>
SerializeAndExpectPointerAdvanced(const T & source,int num_bytes,uint8_t * buffer)20*3f982cf4SFabien Sanglard void SerializeAndExpectPointerAdvanced(const T& source,
21*3f982cf4SFabien Sanglard                                        int num_bytes,
22*3f982cf4SFabien Sanglard                                        uint8_t* buffer) {
23*3f982cf4SFabien Sanglard   absl::Span<uint8_t> buffer_span(buffer, num_bytes);
24*3f982cf4SFabien Sanglard   source.AppendFields(&buffer_span);
25*3f982cf4SFabien Sanglard   EXPECT_EQ(buffer + num_bytes, buffer_span.data());
26*3f982cf4SFabien Sanglard }
27*3f982cf4SFabien Sanglard 
28*3f982cf4SFabien Sanglard // Tests that the RTCP Common Header for a packet type that includes an Item
29*3f982cf4SFabien Sanglard // Count is successfully serialized and re-parsed.
TEST(RtcpCommonTest,SerializesAndParsesHeaderForSenderReports)30*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, SerializesAndParsesHeaderForSenderReports) {
31*3f982cf4SFabien Sanglard   RtcpCommonHeader original;
32*3f982cf4SFabien Sanglard   original.packet_type = RtcpPacketType::kSenderReport;
33*3f982cf4SFabien Sanglard   original.with.report_count = 31;
34*3f982cf4SFabien Sanglard   original.payload_size = 16;
35*3f982cf4SFabien Sanglard 
36*3f982cf4SFabien Sanglard   uint8_t buffer[kRtcpCommonHeaderSize];
37*3f982cf4SFabien Sanglard   SerializeAndExpectPointerAdvanced(original, kRtcpCommonHeaderSize, buffer);
38*3f982cf4SFabien Sanglard 
39*3f982cf4SFabien Sanglard   const auto parsed = RtcpCommonHeader::Parse(buffer);
40*3f982cf4SFabien Sanglard   ASSERT_TRUE(parsed.has_value());
41*3f982cf4SFabien Sanglard   EXPECT_EQ(original.packet_type, parsed->packet_type);
42*3f982cf4SFabien Sanglard   EXPECT_EQ(original.with.report_count, parsed->with.report_count);
43*3f982cf4SFabien Sanglard   EXPECT_EQ(original.payload_size, parsed->payload_size);
44*3f982cf4SFabien Sanglard }
45*3f982cf4SFabien Sanglard 
46*3f982cf4SFabien Sanglard // Tests that the RTCP Common Header for a packet type that includes a RTCP
47*3f982cf4SFabien Sanglard // Subtype is successfully serialized and re-parsed.
TEST(RtcpCommonTest,SerializesAndParsesHeaderForCastFeedback)48*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, SerializesAndParsesHeaderForCastFeedback) {
49*3f982cf4SFabien Sanglard   RtcpCommonHeader original;
50*3f982cf4SFabien Sanglard   original.packet_type = RtcpPacketType::kPayloadSpecific;
51*3f982cf4SFabien Sanglard   original.with.subtype = RtcpSubtype::kFeedback;
52*3f982cf4SFabien Sanglard   original.payload_size = 99 * sizeof(uint32_t);
53*3f982cf4SFabien Sanglard 
54*3f982cf4SFabien Sanglard   uint8_t buffer[kRtcpCommonHeaderSize];
55*3f982cf4SFabien Sanglard   SerializeAndExpectPointerAdvanced(original, kRtcpCommonHeaderSize, buffer);
56*3f982cf4SFabien Sanglard 
57*3f982cf4SFabien Sanglard   const auto parsed = RtcpCommonHeader::Parse(buffer);
58*3f982cf4SFabien Sanglard   ASSERT_TRUE(parsed.has_value());
59*3f982cf4SFabien Sanglard   EXPECT_EQ(original.packet_type, parsed->packet_type);
60*3f982cf4SFabien Sanglard   EXPECT_EQ(original.with.subtype, parsed->with.subtype);
61*3f982cf4SFabien Sanglard   EXPECT_EQ(original.payload_size, parsed->payload_size);
62*3f982cf4SFabien Sanglard }
63*3f982cf4SFabien Sanglard 
64*3f982cf4SFabien Sanglard // Tests that a RTCP Common Header will not be parsed from an empty buffer.
TEST(RtcpCommonTest,WillNotParseHeaderFromEmptyBuffer)65*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, WillNotParseHeaderFromEmptyBuffer) {
66*3f982cf4SFabien Sanglard   const uint8_t kEmptyPacket[] = {};
67*3f982cf4SFabien Sanglard   EXPECT_FALSE(
68*3f982cf4SFabien Sanglard       RtcpCommonHeader::Parse(absl::Span<const uint8_t>(kEmptyPacket, 0))
69*3f982cf4SFabien Sanglard           .has_value());
70*3f982cf4SFabien Sanglard }
71*3f982cf4SFabien Sanglard 
72*3f982cf4SFabien Sanglard // Tests that a RTCP Common Header will not be parsed from a buffer containing
73*3f982cf4SFabien Sanglard // garbage data.
TEST(RtcpCommonTest,WillNotParseHeaderFromGarbage)74*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, WillNotParseHeaderFromGarbage) {
75*3f982cf4SFabien Sanglard   // clang-format off
76*3f982cf4SFabien Sanglard   const uint8_t kGarbage[] = {
77*3f982cf4SFabien Sanglard     0x4f, 0x27, 0xeb, 0x22, 0x27, 0xeb, 0x22, 0x4f,
78*3f982cf4SFabien Sanglard     0xeb, 0x22, 0x4f, 0x27, 0x22, 0x4f, 0x27, 0xeb,
79*3f982cf4SFabien Sanglard   };
80*3f982cf4SFabien Sanglard   // clang-format on
81*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpCommonHeader::Parse(kGarbage).has_value());
82*3f982cf4SFabien Sanglard }
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard // Tests whether RTCP Common Header validation logic is correct.
TEST(RtcpCommonTest,WillNotParseHeaderWithInvalidData)85*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, WillNotParseHeaderWithInvalidData) {
86*3f982cf4SFabien Sanglard   // clang-format off
87*3f982cf4SFabien Sanglard   const uint8_t kCastFeedbackPacket[] = {
88*3f982cf4SFabien Sanglard     0b10000001,  // Version=2, Padding=no, ItemCount=1 byte.
89*3f982cf4SFabien Sanglard     206,  // RTCP Packet type byte.
90*3f982cf4SFabien Sanglard     0x00, 0x04,  // Length of remainder of packet, in 32-bit words.
91*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // SSRC of receiver.
92*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC of sender.
93*3f982cf4SFabien Sanglard     'C', 'A', 'S', 'T',
94*3f982cf4SFabien Sanglard     0x0a,  // Checkpoint Frame ID (lower 8 bits).
95*3f982cf4SFabien Sanglard     0x00,  // Number of "Loss Fields"
96*3f982cf4SFabien Sanglard     0x00, 0x28,  // Current Playout Delay in milliseconds.
97*3f982cf4SFabien Sanglard   };
98*3f982cf4SFabien Sanglard   // clang-format on
99*3f982cf4SFabien Sanglard 
100*3f982cf4SFabien Sanglard   // Start with a valid packet, and expect the parse to succeed.
101*3f982cf4SFabien Sanglard   uint8_t buffer[sizeof(kCastFeedbackPacket)];
102*3f982cf4SFabien Sanglard   memcpy(buffer, kCastFeedbackPacket, sizeof(buffer));
103*3f982cf4SFabien Sanglard   EXPECT_TRUE(RtcpCommonHeader::Parse(buffer).has_value());
104*3f982cf4SFabien Sanglard 
105*3f982cf4SFabien Sanglard   // Wrong version in first byte: Expect parse failure.
106*3f982cf4SFabien Sanglard   buffer[0] = 0b01000001;
107*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpCommonHeader::Parse(buffer).has_value());
108*3f982cf4SFabien Sanglard   buffer[0] = kCastFeedbackPacket[0];
109*3f982cf4SFabien Sanglard 
110*3f982cf4SFabien Sanglard   // Wrong packet type (not in RTCP range): Expect parse failure.
111*3f982cf4SFabien Sanglard   buffer[1] = 42;
112*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpCommonHeader::Parse(buffer).has_value());
113*3f982cf4SFabien Sanglard   buffer[1] = kCastFeedbackPacket[1];
114*3f982cf4SFabien Sanglard }
115*3f982cf4SFabien Sanglard 
116*3f982cf4SFabien Sanglard // Test that the Report Block optionally included in Sender Reports or Receiver
117*3f982cf4SFabien Sanglard // Reports can be serialized and re-parsed correctly.
TEST(RtcpCommonTest,SerializesAndParsesRtcpReportBlocks)118*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, SerializesAndParsesRtcpReportBlocks) {
119*3f982cf4SFabien Sanglard   constexpr Ssrc kSsrc{0x04050607};
120*3f982cf4SFabien Sanglard 
121*3f982cf4SFabien Sanglard   RtcpReportBlock original;
122*3f982cf4SFabien Sanglard   original.ssrc = kSsrc;
123*3f982cf4SFabien Sanglard   original.packet_fraction_lost_numerator = 0x67;
124*3f982cf4SFabien Sanglard   original.cumulative_packets_lost = 74536;
125*3f982cf4SFabien Sanglard   original.extended_high_sequence_number = 0x0201fedc;
126*3f982cf4SFabien Sanglard   original.jitter = RtpTimeDelta::FromTicks(123);
127*3f982cf4SFabien Sanglard   original.last_status_report_id = 0x0908;
128*3f982cf4SFabien Sanglard   original.delay_since_last_report = RtcpReportBlock::Delay(99999);
129*3f982cf4SFabien Sanglard 
130*3f982cf4SFabien Sanglard   uint8_t buffer[kRtcpReportBlockSize];
131*3f982cf4SFabien Sanglard   SerializeAndExpectPointerAdvanced(original, kRtcpReportBlockSize, buffer);
132*3f982cf4SFabien Sanglard 
133*3f982cf4SFabien Sanglard   // If the number of report blocks is zero, or some other SSRC is specified,
134*3f982cf4SFabien Sanglard   // ParseOne() should not return a result.
135*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpReportBlock::ParseOne(buffer, 0, 0).has_value());
136*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpReportBlock::ParseOne(buffer, 0, kSsrc).has_value());
137*3f982cf4SFabien Sanglard   EXPECT_FALSE(RtcpReportBlock::ParseOne(buffer, 1, 0).has_value());
138*3f982cf4SFabien Sanglard 
139*3f982cf4SFabien Sanglard   // Expect that the report block is parsed correctly.
140*3f982cf4SFabien Sanglard   const auto parsed = RtcpReportBlock::ParseOne(buffer, 1, kSsrc);
141*3f982cf4SFabien Sanglard   ASSERT_TRUE(parsed.has_value());
142*3f982cf4SFabien Sanglard   EXPECT_EQ(original.ssrc, parsed->ssrc);
143*3f982cf4SFabien Sanglard   EXPECT_EQ(original.packet_fraction_lost_numerator,
144*3f982cf4SFabien Sanglard             parsed->packet_fraction_lost_numerator);
145*3f982cf4SFabien Sanglard   EXPECT_EQ(original.cumulative_packets_lost, parsed->cumulative_packets_lost);
146*3f982cf4SFabien Sanglard   EXPECT_EQ(original.extended_high_sequence_number,
147*3f982cf4SFabien Sanglard             parsed->extended_high_sequence_number);
148*3f982cf4SFabien Sanglard   EXPECT_EQ(original.jitter, parsed->jitter);
149*3f982cf4SFabien Sanglard   EXPECT_EQ(original.last_status_report_id, parsed->last_status_report_id);
150*3f982cf4SFabien Sanglard   EXPECT_EQ(original.delay_since_last_report, parsed->delay_since_last_report);
151*3f982cf4SFabien Sanglard }
152*3f982cf4SFabien Sanglard 
153*3f982cf4SFabien Sanglard // Tests that the Report Block parser can, among multiple Report Blocks, find
154*3f982cf4SFabien Sanglard // the one with a matching recipient SSRC.
TEST(RtcpCommonTest,ParsesOneReportBlockFromMultipleBlocks)155*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, ParsesOneReportBlockFromMultipleBlocks) {
156*3f982cf4SFabien Sanglard   constexpr Ssrc kSsrc{0x04050607};
157*3f982cf4SFabien Sanglard   constexpr int kNumBlocks = 5;
158*3f982cf4SFabien Sanglard 
159*3f982cf4SFabien Sanglard   RtcpReportBlock expected;
160*3f982cf4SFabien Sanglard   expected.ssrc = kSsrc;
161*3f982cf4SFabien Sanglard   expected.packet_fraction_lost_numerator = 0x67;
162*3f982cf4SFabien Sanglard   expected.cumulative_packets_lost = 74536;
163*3f982cf4SFabien Sanglard   expected.extended_high_sequence_number = 0x0201fedc;
164*3f982cf4SFabien Sanglard   expected.jitter = RtpTimeDelta::FromTicks(123);
165*3f982cf4SFabien Sanglard   expected.last_status_report_id = 0x0908;
166*3f982cf4SFabien Sanglard   expected.delay_since_last_report = RtcpReportBlock::Delay(99999);
167*3f982cf4SFabien Sanglard 
168*3f982cf4SFabien Sanglard   // Generate multiple report blocks with different recipient SSRCs.
169*3f982cf4SFabien Sanglard   uint8_t buffer[kRtcpReportBlockSize * kNumBlocks];
170*3f982cf4SFabien Sanglard   absl::Span<uint8_t> buffer_span(buffer, kRtcpReportBlockSize * kNumBlocks);
171*3f982cf4SFabien Sanglard   for (int i = 0; i < kNumBlocks; ++i) {
172*3f982cf4SFabien Sanglard     RtcpReportBlock another;
173*3f982cf4SFabien Sanglard     another.ssrc = expected.ssrc + i - 2;
174*3f982cf4SFabien Sanglard     another.packet_fraction_lost_numerator =
175*3f982cf4SFabien Sanglard         expected.packet_fraction_lost_numerator + i - 2;
176*3f982cf4SFabien Sanglard     another.cumulative_packets_lost = expected.cumulative_packets_lost + i - 2;
177*3f982cf4SFabien Sanglard     another.extended_high_sequence_number =
178*3f982cf4SFabien Sanglard         expected.extended_high_sequence_number + i - 2;
179*3f982cf4SFabien Sanglard     another.jitter = expected.jitter + RtpTimeDelta::FromTicks(i - 2);
180*3f982cf4SFabien Sanglard     another.last_status_report_id = expected.last_status_report_id + i - 2;
181*3f982cf4SFabien Sanglard     another.delay_since_last_report =
182*3f982cf4SFabien Sanglard         expected.delay_since_last_report + RtcpReportBlock::Delay(i - 2);
183*3f982cf4SFabien Sanglard 
184*3f982cf4SFabien Sanglard     another.AppendFields(&buffer_span);
185*3f982cf4SFabien Sanglard   }
186*3f982cf4SFabien Sanglard 
187*3f982cf4SFabien Sanglard   // Expect that the desired report block is found and parsed correctly.
188*3f982cf4SFabien Sanglard   const auto parsed = RtcpReportBlock::ParseOne(buffer, kNumBlocks, kSsrc);
189*3f982cf4SFabien Sanglard   ASSERT_TRUE(parsed.has_value());
190*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.ssrc, parsed->ssrc);
191*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.packet_fraction_lost_numerator,
192*3f982cf4SFabien Sanglard             parsed->packet_fraction_lost_numerator);
193*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.cumulative_packets_lost, parsed->cumulative_packets_lost);
194*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.extended_high_sequence_number,
195*3f982cf4SFabien Sanglard             parsed->extended_high_sequence_number);
196*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.jitter, parsed->jitter);
197*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.last_status_report_id, parsed->last_status_report_id);
198*3f982cf4SFabien Sanglard   EXPECT_EQ(expected.delay_since_last_report, parsed->delay_since_last_report);
199*3f982cf4SFabien Sanglard }
200*3f982cf4SFabien Sanglard 
201*3f982cf4SFabien Sanglard // Tests the helper for computing the packet fraction loss numerator, a value
202*3f982cf4SFabien Sanglard // that should always be between 0 and 255, in terms of absolute packet counts.
TEST(RtcpCommonTest,ComputesPacketLossFractionForReportBlocks)203*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, ComputesPacketLossFractionForReportBlocks) {
204*3f982cf4SFabien Sanglard   const auto ComputeFractionLost = [](int64_t num_apparently_sent,
205*3f982cf4SFabien Sanglard                                       int64_t num_received) {
206*3f982cf4SFabien Sanglard     RtcpReportBlock report;
207*3f982cf4SFabien Sanglard     report.SetPacketFractionLostNumerator(num_apparently_sent, num_received);
208*3f982cf4SFabien Sanglard     return report.packet_fraction_lost_numerator;
209*3f982cf4SFabien Sanglard   };
210*3f982cf4SFabien Sanglard 
211*3f982cf4SFabien Sanglard   // If no non-duplicate packets were sent to the Receiver, the packet loss
212*3f982cf4SFabien Sanglard   // fraction should be zero.
213*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(0, 0));
214*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(0, 1));
215*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(0, 999));
216*3f982cf4SFabien Sanglard 
217*3f982cf4SFabien Sanglard   // If the same number or more packets were received than those apparently
218*3f982cf4SFabien Sanglard   // sent, the packet loss fraction should be zero.
219*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(1, 1));
220*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(1, 2));
221*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(1, 4));
222*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(4, 5));
223*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(42, 42));
224*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeFractionLost(60, 999));
225*3f982cf4SFabien Sanglard 
226*3f982cf4SFabien Sanglard   // Test various partial loss scenarios.
227*3f982cf4SFabien Sanglard   EXPECT_EQ(85, ComputeFractionLost(3, 2));
228*3f982cf4SFabien Sanglard   EXPECT_EQ(128, ComputeFractionLost(10, 5));
229*3f982cf4SFabien Sanglard   EXPECT_EQ(174, ComputeFractionLost(22, 7));
230*3f982cf4SFabien Sanglard 
231*3f982cf4SFabien Sanglard   // Test various total-loss/near-total-loss scenarios.
232*3f982cf4SFabien Sanglard   EXPECT_EQ(255, ComputeFractionLost(17, 0));
233*3f982cf4SFabien Sanglard   EXPECT_EQ(255, ComputeFractionLost(100, 0));
234*3f982cf4SFabien Sanglard   EXPECT_EQ(255, ComputeFractionLost(9876, 1));
235*3f982cf4SFabien Sanglard }
236*3f982cf4SFabien Sanglard 
237*3f982cf4SFabien Sanglard // Tests the helper for computing the cumulative packet loss total, a value that
238*3f982cf4SFabien Sanglard // should always be between 0 and 2^24 - 1, in terms of absolute packet counts.
TEST(RtcpCommonTest,ComputesCumulativePacketLossForReportBlocks)239*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, ComputesCumulativePacketLossForReportBlocks) {
240*3f982cf4SFabien Sanglard   const auto ComputeLoss = [](int64_t num_apparently_sent,
241*3f982cf4SFabien Sanglard                               int64_t num_received) {
242*3f982cf4SFabien Sanglard     RtcpReportBlock report;
243*3f982cf4SFabien Sanglard     report.SetCumulativePacketsLost(num_apparently_sent, num_received);
244*3f982cf4SFabien Sanglard     return report.cumulative_packets_lost;
245*3f982cf4SFabien Sanglard   };
246*3f982cf4SFabien Sanglard 
247*3f982cf4SFabien Sanglard   // Test various no-loss scenarios (including duplicate packets).
248*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(0, 0));
249*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(0, 1));
250*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(3, 3));
251*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(56, 56));
252*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(std::numeric_limits<int64_t>::max() - 12,
253*3f982cf4SFabien Sanglard                            std::numeric_limits<int64_t>::max()));
254*3f982cf4SFabien Sanglard   EXPECT_EQ(0, ComputeLoss(std::numeric_limits<int64_t>::max(),
255*3f982cf4SFabien Sanglard                            std::numeric_limits<int64_t>::max()));
256*3f982cf4SFabien Sanglard 
257*3f982cf4SFabien Sanglard   // Test various partial loss scenarios.
258*3f982cf4SFabien Sanglard   EXPECT_EQ(1, ComputeLoss(2, 1));
259*3f982cf4SFabien Sanglard   EXPECT_EQ(2, ComputeLoss(42, 40));
260*3f982cf4SFabien Sanglard   EXPECT_EQ(1025, ComputeLoss(999999, 999999 - 1025));
261*3f982cf4SFabien Sanglard   EXPECT_EQ(1, ComputeLoss(std::numeric_limits<int64_t>::max(),
262*3f982cf4SFabien Sanglard                            std::numeric_limits<int64_t>::max() - 1));
263*3f982cf4SFabien Sanglard 
264*3f982cf4SFabien Sanglard   // Test that a huge cumulative loss saturates to the maximum valid value for
265*3f982cf4SFabien Sanglard   // the field.
266*3f982cf4SFabien Sanglard   EXPECT_EQ((1 << 24) - 1, ComputeLoss(999999999, 1));
267*3f982cf4SFabien Sanglard }
268*3f982cf4SFabien Sanglard 
269*3f982cf4SFabien Sanglard // Tests the helper that converts Clock::durations to the report blocks timebase
270*3f982cf4SFabien Sanglard // (1/65536 sconds), and also that it saturates to to the valid range of values
271*3f982cf4SFabien Sanglard // (0 to 2^32 - 1 ticks).
TEST(RtcpCommonTest,ComputesDelayForReportBlocks)272*3f982cf4SFabien Sanglard TEST(RtcpCommonTest, ComputesDelayForReportBlocks) {
273*3f982cf4SFabien Sanglard   RtcpReportBlock report;
274*3f982cf4SFabien Sanglard   using Delay = RtcpReportBlock::Delay;
275*3f982cf4SFabien Sanglard 
276*3f982cf4SFabien Sanglard   const auto ComputeDelay = [](Clock::duration delay_in_wrong_timebase) {
277*3f982cf4SFabien Sanglard     RtcpReportBlock report;
278*3f982cf4SFabien Sanglard     report.SetDelaySinceLastReport(delay_in_wrong_timebase);
279*3f982cf4SFabien Sanglard     return report.delay_since_last_report;
280*3f982cf4SFabien Sanglard   };
281*3f982cf4SFabien Sanglard 
282*3f982cf4SFabien Sanglard   // A duration less than or equal to zero should clamp to zero.
283*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay::zero(), ComputeDelay(Clock::duration::min()));
284*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay::zero(), ComputeDelay(milliseconds{-1234}));
285*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay::zero(), ComputeDelay(Clock::duration::zero()));
286*3f982cf4SFabien Sanglard 
287*3f982cf4SFabien Sanglard   // Test conversion of various durations that should not clamp.
288*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(32768 /* 1/2 second worth of ticks */),
289*3f982cf4SFabien Sanglard             ComputeDelay(milliseconds(500)));
290*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(65536 /* 1 second worth of ticks */),
291*3f982cf4SFabien Sanglard             ComputeDelay(seconds(1)));
292*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(655360 /* 10 seconds worth of ticks */),
293*3f982cf4SFabien Sanglard             ComputeDelay(seconds(10)));
294*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967294), ComputeDelay(microseconds(65535999983)));
295*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967294), ComputeDelay(microseconds(65535999984)));
296*3f982cf4SFabien Sanglard 
297*3f982cf4SFabien Sanglard   // A too-large duration should clamp to the maximum-possible Delay value.
298*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967295), ComputeDelay(microseconds(65535999985)));
299*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967295), ComputeDelay(microseconds(65535999986)));
300*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967295), ComputeDelay(microseconds(999999000000)));
301*3f982cf4SFabien Sanglard   EXPECT_EQ(Delay(4294967295), ComputeDelay(Clock::duration::max()));
302*3f982cf4SFabien Sanglard }
303*3f982cf4SFabien Sanglard 
304*3f982cf4SFabien Sanglard }  // namespace
305*3f982cf4SFabien Sanglard }  // namespace cast
306*3f982cf4SFabien Sanglard }  // namespace openscreen
307