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 // Unit tests for test Packet class.
12
13 #include "modules/audio_coding/neteq/tools/packet.h"
14
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 namespace test {
19
20 namespace {
21 const int kHeaderLengthBytes = 12;
22
MakeRtpHeader(int payload_type,int seq_number,uint32_t timestamp,uint32_t ssrc,uint8_t * rtp_data)23 void MakeRtpHeader(int payload_type,
24 int seq_number,
25 uint32_t timestamp,
26 uint32_t ssrc,
27 uint8_t* rtp_data) {
28 rtp_data[0] = 0x80;
29 rtp_data[1] = static_cast<uint8_t>(payload_type);
30 rtp_data[2] = (seq_number >> 8) & 0xFF;
31 rtp_data[3] = (seq_number)&0xFF;
32 rtp_data[4] = timestamp >> 24;
33 rtp_data[5] = (timestamp >> 16) & 0xFF;
34 rtp_data[6] = (timestamp >> 8) & 0xFF;
35 rtp_data[7] = timestamp & 0xFF;
36 rtp_data[8] = ssrc >> 24;
37 rtp_data[9] = (ssrc >> 16) & 0xFF;
38 rtp_data[10] = (ssrc >> 8) & 0xFF;
39 rtp_data[11] = ssrc & 0xFF;
40 }
41 } // namespace
42
TEST(TestPacket,RegularPacket)43 TEST(TestPacket, RegularPacket) {
44 const size_t kPacketLengthBytes = 100;
45 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
46 const uint8_t kPayloadType = 17;
47 const uint16_t kSequenceNumber = 4711;
48 const uint32_t kTimestamp = 47114711;
49 const uint32_t kSsrc = 0x12345678;
50 MakeRtpHeader(kPayloadType, kSequenceNumber, kTimestamp, kSsrc,
51 packet_memory.MutableData());
52 const double kPacketTime = 1.0;
53 Packet packet(std::move(packet_memory), kPacketTime);
54 ASSERT_TRUE(packet.valid_header());
55 EXPECT_EQ(kPayloadType, packet.header().payloadType);
56 EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
57 EXPECT_EQ(kTimestamp, packet.header().timestamp);
58 EXPECT_EQ(kSsrc, packet.header().ssrc);
59 EXPECT_EQ(0, packet.header().numCSRCs);
60 EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
61 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
62 packet.payload_length_bytes());
63 EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
64 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
65 packet.virtual_payload_length_bytes());
66 EXPECT_EQ(kPacketTime, packet.time_ms());
67 }
68
TEST(TestPacket,DummyPacket)69 TEST(TestPacket, DummyPacket) {
70 const size_t kPacketLengthBytes = kHeaderLengthBytes; // Only RTP header.
71 const size_t kVirtualPacketLengthBytes = 100;
72 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
73 const uint8_t kPayloadType = 17;
74 const uint16_t kSequenceNumber = 4711;
75 const uint32_t kTimestamp = 47114711;
76 const uint32_t kSsrc = 0x12345678;
77 MakeRtpHeader(kPayloadType, kSequenceNumber, kTimestamp, kSsrc,
78 packet_memory.MutableData());
79 const double kPacketTime = 1.0;
80 Packet packet(std::move(packet_memory), kVirtualPacketLengthBytes,
81 kPacketTime);
82 ASSERT_TRUE(packet.valid_header());
83 EXPECT_EQ(kPayloadType, packet.header().payloadType);
84 EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
85 EXPECT_EQ(kTimestamp, packet.header().timestamp);
86 EXPECT_EQ(kSsrc, packet.header().ssrc);
87 EXPECT_EQ(0, packet.header().numCSRCs);
88 EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
89 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
90 packet.payload_length_bytes());
91 EXPECT_EQ(kVirtualPacketLengthBytes, packet.virtual_packet_length_bytes());
92 EXPECT_EQ(kVirtualPacketLengthBytes - kHeaderLengthBytes,
93 packet.virtual_payload_length_bytes());
94 EXPECT_EQ(kPacketTime, packet.time_ms());
95 }
96
TEST(TestPacket,DummyPaddingPacket)97 TEST(TestPacket, DummyPaddingPacket) {
98 const size_t kPacketLengthBytes = kHeaderLengthBytes; // Only RTP header.
99 const size_t kVirtualPacketLengthBytes = 100;
100 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
101 const uint8_t kPayloadType = 17;
102 const uint16_t kSequenceNumber = 4711;
103 const uint32_t kTimestamp = 47114711;
104 const uint32_t kSsrc = 0x12345678;
105 MakeRtpHeader(kPayloadType, kSequenceNumber, kTimestamp, kSsrc,
106 packet_memory.MutableData());
107 packet_memory.MutableData()[0] |= 0b0010'0000; // Set the padding bit.
108 const double kPacketTime = 1.0;
109 Packet packet(std::move(packet_memory), kVirtualPacketLengthBytes,
110 kPacketTime);
111 ASSERT_TRUE(packet.valid_header());
112 EXPECT_EQ(kPayloadType, packet.header().payloadType);
113 EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
114 EXPECT_EQ(kTimestamp, packet.header().timestamp);
115 EXPECT_EQ(kSsrc, packet.header().ssrc);
116 EXPECT_EQ(0, packet.header().numCSRCs);
117 EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
118 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
119 packet.payload_length_bytes());
120 EXPECT_EQ(kVirtualPacketLengthBytes, packet.virtual_packet_length_bytes());
121 EXPECT_EQ(kVirtualPacketLengthBytes - kHeaderLengthBytes,
122 packet.virtual_payload_length_bytes());
123 EXPECT_EQ(kPacketTime, packet.time_ms());
124 }
125
126 namespace {
127 // Writes one RED block header starting at `rtp_data`, according to RFC 2198.
128 // returns the number of bytes written (1 or 4).
129 //
130 // Format if `last_payoad` is false:
131 // 0 1 2 3
132 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
133 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134 // |1| block PT | timestamp offset | block length |
135 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136 //
137 // Format if `last_payoad` is true:
138 // 0 1 2 3 4 5 6 7
139 // +-+-+-+-+-+-+-+-+
140 // |0| Block PT |
141 // +-+-+-+-+-+-+-+-+
142
MakeRedHeader(int payload_type,uint32_t timestamp_offset,int block_length,bool last_payload,uint8_t * rtp_data)143 int MakeRedHeader(int payload_type,
144 uint32_t timestamp_offset,
145 int block_length,
146 bool last_payload,
147 uint8_t* rtp_data) {
148 rtp_data[0] = 0x80 | (payload_type & 0x7F); // Set the first bit to 1.
149 if (last_payload) {
150 rtp_data[0] &= 0x7F; // Reset the first but to 0 to indicate last block.
151 return 1;
152 }
153 rtp_data[1] = timestamp_offset >> 6;
154 rtp_data[2] = (timestamp_offset & 0x3F) << 2;
155 rtp_data[2] |= block_length >> 8;
156 rtp_data[3] = block_length & 0xFF;
157 return 4;
158 }
159 } // namespace
160
TEST(TestPacket,RED)161 TEST(TestPacket, RED) {
162 const size_t kPacketLengthBytes = 100;
163 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
164 const uint8_t kRedPayloadType = 17;
165 const uint16_t kSequenceNumber = 4711;
166 const uint32_t kTimestamp = 47114711;
167 const uint32_t kSsrc = 0x12345678;
168 MakeRtpHeader(kRedPayloadType, kSequenceNumber, kTimestamp, kSsrc,
169 packet_memory.MutableData());
170 // Create four RED headers.
171 // Payload types are just the same as the block index the offset is 100 times
172 // the block index.
173 const int kRedBlocks = 4;
174 uint8_t* payload_ptr = packet_memory.MutableData() +
175 kHeaderLengthBytes; // First byte after header.
176 for (int i = 0; i < kRedBlocks; ++i) {
177 int payload_type = i;
178 // Offset value is not used for the last block.
179 uint32_t timestamp_offset = 100 * i;
180 int block_length = 10 * i;
181 bool last_block = (i == kRedBlocks - 1) ? true : false;
182 payload_ptr += MakeRedHeader(payload_type, timestamp_offset, block_length,
183 last_block, payload_ptr);
184 }
185 const double kPacketTime = 1.0;
186 // Hand over ownership of `packet_memory` to `packet`.
187 Packet packet(packet_memory, kPacketLengthBytes, kPacketTime);
188 ASSERT_TRUE(packet.valid_header());
189 EXPECT_EQ(kRedPayloadType, packet.header().payloadType);
190 EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
191 EXPECT_EQ(kTimestamp, packet.header().timestamp);
192 EXPECT_EQ(kSsrc, packet.header().ssrc);
193 EXPECT_EQ(0, packet.header().numCSRCs);
194 EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
195 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
196 packet.payload_length_bytes());
197 EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
198 EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
199 packet.virtual_payload_length_bytes());
200 EXPECT_EQ(kPacketTime, packet.time_ms());
201 std::list<RTPHeader*> red_headers;
202 EXPECT_TRUE(packet.ExtractRedHeaders(&red_headers));
203 EXPECT_EQ(kRedBlocks, static_cast<int>(red_headers.size()));
204 int block_index = 0;
205 for (std::list<RTPHeader*>::reverse_iterator it = red_headers.rbegin();
206 it != red_headers.rend(); ++it) {
207 // Reading list from the back, since the extraction puts the main payload
208 // (which is the last one on wire) first.
209 RTPHeader* red_block = *it;
210 EXPECT_EQ(block_index, red_block->payloadType);
211 EXPECT_EQ(kSequenceNumber, red_block->sequenceNumber);
212 if (block_index == kRedBlocks - 1) {
213 // Last block has zero offset per definition.
214 EXPECT_EQ(kTimestamp, red_block->timestamp);
215 } else {
216 EXPECT_EQ(kTimestamp - 100 * block_index, red_block->timestamp);
217 }
218 EXPECT_EQ(kSsrc, red_block->ssrc);
219 EXPECT_EQ(0, red_block->numCSRCs);
220 ++block_index;
221 }
222 Packet::DeleteRedHeaders(&red_headers);
223 }
224
225 } // namespace test
226 } // namespace webrtc
227