1 /*
2 * Copyright (c) 2014 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
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 #include "webrtc/base/checks.h"
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
15 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
16
17 namespace webrtc {
18
19 using RTCPUtility::RtcpCommonHeader;
20
21 namespace rtcp {
22
TEST(RtcpUtilityTest,MidNtp)23 TEST(RtcpUtilityTest, MidNtp) {
24 const uint32_t kNtpSec = 0x12345678;
25 const uint32_t kNtpFrac = 0x23456789;
26 const uint32_t kNtpMid = 0x56782345;
27 EXPECT_EQ(kNtpMid, RTCPUtility::MidNtp(kNtpSec, kNtpFrac));
28 }
29
TEST(RtcpUtilityTest,NackRequests)30 TEST(RtcpUtilityTest, NackRequests) {
31 RTCPUtility::NackStats stats;
32 EXPECT_EQ(0U, stats.unique_requests());
33 EXPECT_EQ(0U, stats.requests());
34 stats.ReportRequest(10);
35 EXPECT_EQ(1U, stats.unique_requests());
36 EXPECT_EQ(1U, stats.requests());
37
38 stats.ReportRequest(10);
39 EXPECT_EQ(1U, stats.unique_requests());
40 stats.ReportRequest(11);
41 EXPECT_EQ(2U, stats.unique_requests());
42
43 stats.ReportRequest(11);
44 EXPECT_EQ(2U, stats.unique_requests());
45 stats.ReportRequest(13);
46 EXPECT_EQ(3U, stats.unique_requests());
47
48 stats.ReportRequest(11);
49 EXPECT_EQ(3U, stats.unique_requests());
50 EXPECT_EQ(6U, stats.requests());
51 }
52
TEST(RtcpUtilityTest,NackRequestsWithWrap)53 TEST(RtcpUtilityTest, NackRequestsWithWrap) {
54 RTCPUtility::NackStats stats;
55 stats.ReportRequest(65534);
56 EXPECT_EQ(1U, stats.unique_requests());
57
58 stats.ReportRequest(65534);
59 EXPECT_EQ(1U, stats.unique_requests());
60 stats.ReportRequest(65535);
61 EXPECT_EQ(2U, stats.unique_requests());
62
63 stats.ReportRequest(65535);
64 EXPECT_EQ(2U, stats.unique_requests());
65 stats.ReportRequest(0);
66 EXPECT_EQ(3U, stats.unique_requests());
67
68 stats.ReportRequest(65535);
69 EXPECT_EQ(3U, stats.unique_requests());
70 stats.ReportRequest(0);
71 EXPECT_EQ(3U, stats.unique_requests());
72 stats.ReportRequest(1);
73 EXPECT_EQ(4U, stats.unique_requests());
74 EXPECT_EQ(8U, stats.requests());
75 }
76
77 class RtcpParseCommonHeaderTest : public ::testing::Test {
78 public:
RtcpParseCommonHeaderTest()79 RtcpParseCommonHeaderTest() { memset(buffer, 0, kBufferCapacityBytes); }
~RtcpParseCommonHeaderTest()80 virtual ~RtcpParseCommonHeaderTest() {}
81
82 protected:
83 static const size_t kBufferCapacityBytes = 40;
84 uint8_t buffer[kBufferCapacityBytes];
85 RtcpCommonHeader header;
86 };
87
TEST_F(RtcpParseCommonHeaderTest,TooSmallBuffer)88 TEST_F(RtcpParseCommonHeaderTest, TooSmallBuffer) {
89 // Buffer needs to be able to hold the header.
90 for (size_t i = 0; i < RtcpCommonHeader::kHeaderSizeBytes; ++i)
91 EXPECT_FALSE(RtcpParseCommonHeader(buffer, i, &header));
92 }
93
TEST_F(RtcpParseCommonHeaderTest,Version)94 TEST_F(RtcpParseCommonHeaderTest, Version) {
95 // Version 2 is the only allowed for now.
96 for (int v = 0; v < 4; ++v) {
97 buffer[0] = v << 6;
98 EXPECT_EQ(v == 2, RtcpParseCommonHeader(
99 buffer, RtcpCommonHeader::kHeaderSizeBytes, &header));
100 }
101 }
102
TEST_F(RtcpParseCommonHeaderTest,PacketSize)103 TEST_F(RtcpParseCommonHeaderTest, PacketSize) {
104 // Set v = 2, leave p, fmt, pt as 0.
105 buffer[0] = 2 << 6;
106
107 const size_t kBlockSize = 3;
108 ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], kBlockSize);
109 const size_t kSizeInBytes = (kBlockSize + 1) * 4;
110
111 EXPECT_FALSE(RtcpParseCommonHeader(buffer, kSizeInBytes - 1, &header));
112 EXPECT_TRUE(RtcpParseCommonHeader(buffer, kSizeInBytes, &header));
113 }
114
TEST_F(RtcpParseCommonHeaderTest,PayloadSize)115 TEST_F(RtcpParseCommonHeaderTest, PayloadSize) {
116 // Set v = 2, p = 1, but leave fmt, pt as 0.
117 buffer[0] = (2 << 6) | (1 << 5);
118
119 // Padding bit set, but no byte for padding (can't specify padding length).
120 EXPECT_FALSE(RtcpParseCommonHeader(buffer, 4, &header));
121
122 const size_t kBlockSize = 3;
123 ByteWriter<uint16_t>::WriteBigEndian(&buffer[2], kBlockSize);
124 const size_t kSizeInBytes = (kBlockSize + 1) * 4;
125 const size_t kPayloadSizeBytes =
126 kSizeInBytes - RtcpCommonHeader::kHeaderSizeBytes;
127
128 // Padding one byte larger than possible.
129 buffer[kSizeInBytes - 1] = kPayloadSizeBytes + 1;
130 EXPECT_FALSE(RtcpParseCommonHeader(buffer, kSizeInBytes, &header));
131
132 // Pure padding packet?
133 buffer[kSizeInBytes - 1] = kPayloadSizeBytes;
134 EXPECT_TRUE(RtcpParseCommonHeader(buffer, kSizeInBytes, &header));
135 EXPECT_EQ(kPayloadSizeBytes, header.padding_bytes);
136 EXPECT_EQ(0u, header.payload_size_bytes);
137
138 // Single byte of actual data.
139 buffer[kSizeInBytes - 1] = kPayloadSizeBytes - 1;
140 EXPECT_TRUE(RtcpParseCommonHeader(buffer, kSizeInBytes, &header));
141 EXPECT_EQ(kPayloadSizeBytes - 1, header.padding_bytes);
142 EXPECT_EQ(1u, header.payload_size_bytes);
143 }
144
TEST_F(RtcpParseCommonHeaderTest,FormatAndPayloadType)145 TEST_F(RtcpParseCommonHeaderTest, FormatAndPayloadType) {
146 // Format/count and packet type both set to max values.
147 const uint8_t kCountOrFormat = 0x1F;
148 const uint8_t kPacketType = 0xFF;
149 buffer[0] = 2 << 6; // V = 2.
150 buffer[0] |= kCountOrFormat;
151 buffer[1] = kPacketType;
152
153 EXPECT_TRUE(RtcpParseCommonHeader(buffer, RtcpCommonHeader::kHeaderSizeBytes,
154 &header));
155 EXPECT_EQ(kCountOrFormat, header.count_or_format);
156 EXPECT_EQ(kPacketType, header.packet_type);
157 }
158
159 } // namespace rtcp
160 } // namespace webrtc
161
162