blob: 7cc9a48ee60f7618deac49fcecefe31901e120a0 [file] [log] [blame]
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_coding/neteq/tools/packet.h"
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000014
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "test/gtest.h"
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000016
17namespace webrtc {
18namespace test {
19
20namespace {
21const int kHeaderLengthBytes = 12;
22
23void 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;
pkasting@chromium.orgd3245462015-02-23 21:28:22 +000029 rtp_data[1] = static_cast<uint8_t>(payload_type);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000030 rtp_data[2] = (seq_number >> 8) & 0xFF;
Yves Gerey665174f2018-06-19 15:03:05 +020031 rtp_data[3] = (seq_number)&0xFF;
pkasting@chromium.orgd3245462015-02-23 21:28:22 +000032 rtp_data[4] = timestamp >> 24;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000033 rtp_data[5] = (timestamp >> 16) & 0xFF;
34 rtp_data[6] = (timestamp >> 8) & 0xFF;
35 rtp_data[7] = timestamp & 0xFF;
pkasting@chromium.orgd3245462015-02-23 21:28:22 +000036 rtp_data[8] = ssrc >> 24;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000037 rtp_data[9] = (ssrc >> 16) & 0xFF;
38 rtp_data[10] = (ssrc >> 8) & 0xFF;
39 rtp_data[11] = ssrc & 0xFF;
40}
41} // namespace
42
43TEST(TestPacket, RegularPacket) {
44 const size_t kPacketLengthBytes = 100;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020045 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000046 const uint8_t kPayloadType = 17;
47 const uint16_t kSequenceNumber = 4711;
48 const uint32_t kTimestamp = 47114711;
49 const uint32_t kSsrc = 0x12345678;
Yves Gerey665174f2018-06-19 15:03:05 +020050 MakeRtpHeader(kPayloadType, kSequenceNumber, kTimestamp, kSsrc,
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020051 packet_memory.MutableData());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000052 const double kPacketTime = 1.0;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020053 Packet packet(std::move(packet_memory), kPacketTime);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000054 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
69TEST(TestPacket, DummyPacket) {
70 const size_t kPacketLengthBytes = kHeaderLengthBytes; // Only RTP header.
71 const size_t kVirtualPacketLengthBytes = 100;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020072 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000073 const uint8_t kPayloadType = 17;
74 const uint16_t kSequenceNumber = 4711;
75 const uint32_t kTimestamp = 47114711;
76 const uint32_t kSsrc = 0x12345678;
Yves Gerey665174f2018-06-19 15:03:05 +020077 MakeRtpHeader(kPayloadType, kSequenceNumber, kTimestamp, kSsrc,
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020078 packet_memory.MutableData());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000079 const double kPacketTime = 1.0;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +020080 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
97TEST(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,
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000110 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
126namespace {
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
143int 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
161TEST(TestPacket, RED) {
162 const size_t kPacketLengthBytes = 100;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +0200163 rtc::CopyOnWriteBuffer packet_memory(kPacketLengthBytes);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000164 const uint8_t kRedPayloadType = 17;
165 const uint16_t kSequenceNumber = 4711;
166 const uint32_t kTimestamp = 47114711;
167 const uint32_t kSsrc = 0x12345678;
Yves Gerey665174f2018-06-19 15:03:05 +0200168 MakeRtpHeader(kRedPayloadType, kSequenceNumber, kTimestamp, kSsrc,
Danil Chapovalovb4100ad2021-06-16 14:23:22 +0200169 packet_memory.MutableData());
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000170 // 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;
Danil Chapovalovb4100ad2021-06-16 14:23:22 +0200174 uint8_t* payload_ptr = packet_memory.MutableData() +
175 kHeaderLengthBytes; // First byte after header.
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000176 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;
Yves Gerey665174f2018-06-19 15:03:05 +0200182 payload_ptr += MakeRedHeader(payload_type, timestamp_offset, block_length,
183 last_block, payload_ptr);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000184 }
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();
Yves Gerey665174f2018-06-19 15:03:05 +0200206 it != red_headers.rend(); ++it) {
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000207 // 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