Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc

Issue 2080553003: Style updates for ForwardErrorCorrection and related classes (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 /* 11 /*
12 * Test application for core FEC algorithm. Calls encoding and decoding 12 * Test application for core FEC algorithm. Calls encoding and decoding
13 * functions in ForwardErrorCorrection directly. 13 * functions in ForwardErrorCorrection directly.
14 */ 14 */
15 15
16 #include <assert.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h> 16 #include <string.h>
20 #include <time.h> 17 #include <time.h>
21 18
22 #include <list> 19 #include <list>
23 20
24 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
25 #include "webrtc/base/random.h" 22 #include "webrtc/base/random.h"
26 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 23 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
27 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" 24 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
28 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" 25 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
29 #include "webrtc/test/testsupport/fileutils.h" 26 #include "webrtc/test/testsupport/fileutils.h"
30 27
31 // #define VERBOSE_OUTPUT 28 // #define VERBOSE_OUTPUT
32 29
33 namespace webrtc { 30 namespace webrtc {
34 namespace fec_private_tables { 31 namespace fec_private_tables {
35 extern const uint8_t** kPacketMaskBurstyTbl[12]; 32 extern const uint8_t** kPacketMaskBurstyTbl[12];
36 } 33 }
37 namespace test { 34 namespace test {
38 using fec_private_tables::kPacketMaskBurstyTbl; 35 using fec_private_tables::kPacketMaskBurstyTbl;
39 36
40 void ReceivePackets( 37 void ReceivePackets(
41 ForwardErrorCorrection::ReceivedPacketList* toDecodeList, 38 ForwardErrorCorrection::ReceivedPacketList* to_decode_list,
42 ForwardErrorCorrection::ReceivedPacketList* receivedPacketList, 39 ForwardErrorCorrection::ReceivedPacketList* received_packet_list,
43 size_t numPacketsToDecode, 40 size_t num_packets_to_decode,
44 float reorderRate, 41 float reorder_rate,
45 float duplicateRate, 42 float duplicate_rate,
46 Random* random) { 43 Random* random) {
47 assert(toDecodeList->empty()); 44 RTC_DCHECK(to_decode_list->empty());
48 assert(numPacketsToDecode <= receivedPacketList->size()); 45 RTC_DCHECK_LE(num_packets_to_decode, received_packet_list->size());
49 46
50 ForwardErrorCorrection::ReceivedPacketList::iterator it; 47 for (size_t i = 0; i < num_packets_to_decode; i++) {
51 for (size_t i = 0; i < numPacketsToDecode; i++) { 48 auto it = received_packet_list->begin();
52 it = receivedPacketList->begin();
53 // Reorder packets. 49 // Reorder packets.
54 float randomVariable = random->Rand<float>(); 50 float random_variable = random->Rand<float>();
55 while (randomVariable < reorderRate) { 51 while (random_variable < reorder_rate) {
56 ++it; 52 ++it;
57 if (it == receivedPacketList->end()) { 53 if (it == received_packet_list->end()) {
58 --it; 54 --it;
59 break; 55 break;
60 } 56 }
61 randomVariable = random->Rand<float>(); 57 random_variable = random->Rand<float>();
62 } 58 }
63 ForwardErrorCorrection::ReceivedPacket* receivedPacket = *it; 59 ForwardErrorCorrection::ReceivedPacket* received_packet = *it;
64 toDecodeList->push_back(receivedPacket); 60 to_decode_list->push_back(received_packet);
65 61
66 // Duplicate packets. 62 // Duplicate packets.
67 randomVariable = random->Rand<float>(); 63 random_variable = random->Rand<float>();
68 while (randomVariable < duplicateRate) { 64 while (random_variable < duplicate_rate) {
69 ForwardErrorCorrection::ReceivedPacket* duplicatePacket = 65 ForwardErrorCorrection::ReceivedPacket* duplicate_packet =
70 new ForwardErrorCorrection::ReceivedPacket; 66 new ForwardErrorCorrection::ReceivedPacket();
71 *duplicatePacket = *receivedPacket; 67 *duplicate_packet = *received_packet;
72 duplicatePacket->pkt = new ForwardErrorCorrection::Packet; 68 duplicate_packet->pkt = new ForwardErrorCorrection::Packet();
73 memcpy(duplicatePacket->pkt->data, receivedPacket->pkt->data, 69 memcpy(duplicate_packet->pkt->data, received_packet->pkt->data,
74 receivedPacket->pkt->length); 70 received_packet->pkt->length);
75 duplicatePacket->pkt->length = receivedPacket->pkt->length; 71 duplicate_packet->pkt->length = received_packet->pkt->length;
76 72
77 toDecodeList->push_back(duplicatePacket); 73 to_decode_list->push_back(duplicate_packet);
78 randomVariable = random->Rand<float>(); 74 random_variable = random->Rand<float>();
79 } 75 }
80 receivedPacketList->erase(it); 76 received_packet_list->erase(it);
81 } 77 }
82 } 78 }
83 79
84 // Too slow to finish before timeout on iOS. See webrtc:4755. 80 // Too slow to finish before timeout on iOS. See webrtc:4755.
85 #if defined(WEBRTC_IOS) 81 #if defined(WEBRTC_IOS)
86 #define MAYBE_FecTest DISABLED_FecTest 82 #define MAYBE_FecTest DISABLED_FecTest
87 #else 83 #else
88 #define MAYBE_FecTest FecTest 84 #define MAYBE_FecTest FecTest
89 #endif 85 #endif
90 TEST(FecTest, MAYBE_FecTest) { 86 TEST(FecTest, MAYBE_FecTest) {
(...skipping 13 matching lines...) Expand all
104 100
105 // Maximum number of media packets allowed for the mask type. 101 // Maximum number of media packets allowed for the mask type.
106 const uint16_t kMaxMediaPackets[] = { 102 const uint16_t kMaxMediaPackets[] = {
107 kMaxNumberMediaPackets, 103 kMaxNumberMediaPackets,
108 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)}; 104 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)};
109 105
110 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not " 106 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not "
111 << "equal to 12."; 107 << "equal to 12.";
112 108
113 ForwardErrorCorrection fec; 109 ForwardErrorCorrection fec;
114 ForwardErrorCorrection::PacketList mediaPacketList; 110 ForwardErrorCorrection::PacketList media_packet_list;
115 ForwardErrorCorrection::PacketList fecPacketList; 111 ForwardErrorCorrection::PacketList fec_packet_list;
116 ForwardErrorCorrection::ReceivedPacketList toDecodeList; 112 ForwardErrorCorrection::ReceivedPacketList to_decode_list;
117 ForwardErrorCorrection::ReceivedPacketList receivedPacketList; 113 ForwardErrorCorrection::ReceivedPacketList received_packet_list;
118 ForwardErrorCorrection::RecoveredPacketList recoveredPacketList; 114 ForwardErrorCorrection::RecoveredPacketList recovered_packet_list;
119 std::list<uint8_t*> fecMaskList; 115 std::list<uint8_t*> fec_mask_list;
120 116
121 ForwardErrorCorrection::Packet* mediaPacket = NULL; 117 ForwardErrorCorrection::Packet* media_packet = nullptr;
122 // Running over only one loss rate to limit execution time. 118 // Running over only one loss rate to limit execution time.
123 const float lossRate[] = {0.5f}; 119 const float loss_rate[] = {0.5f};
124 const uint32_t lossRateSize = sizeof(lossRate) / sizeof(*lossRate); 120 const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate);
125 const float reorderRate = 0.1f; 121 const float reorder_rate = 0.1f;
126 const float duplicateRate = 0.1f; 122 const float duplicate_rate = 0.1f;
127 123
128 uint8_t mediaLossMask[kMaxNumberMediaPackets]; 124 uint8_t media_loss_mask[kMaxNumberMediaPackets];
129 uint8_t fecLossMask[kMaxNumberFecPackets]; 125 uint8_t fec_loss_mask[kMaxNumberFecPackets];
130 uint8_t fecPacketMasks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; 126 uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets];
131 127
132 // Seed the random number generator, storing the seed to file in order to 128 // Seed the random number generator, storing the seed to file in order to
133 // reproduce past results. 129 // reproduce past results.
134 const unsigned int randomSeed = static_cast<unsigned int>(time(NULL)); 130 const unsigned int random_seed = static_cast<unsigned int>(time(nullptr));
135 Random random(randomSeed); 131 Random random(random_seed);
136 std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt"; 132 std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt";
137 FILE* randomSeedFile = fopen(filename.c_str(), "a"); 133 FILE* random_seed_file = fopen(filename.c_str(), "a");
138 fprintf(randomSeedFile, "%u\n", randomSeed); 134 fprintf(random_seed_file, "%u\n", random_seed);
139 fclose(randomSeedFile); 135 fclose(random_seed_file);
140 randomSeedFile = NULL; 136 random_seed_file = nullptr;
141 137
142 uint16_t seqNum = 0; 138 uint16_t seq_num = 0;
143 uint32_t timeStamp = random.Rand<uint32_t>(); 139 uint32_t timestamp = random.Rand<uint32_t>();
144 const uint32_t ssrc = random.Rand(1u, 0xfffffffe); 140 const uint32_t ssrc = random.Rand(1u, 0xfffffffe);
145 141
146 // Loop over the mask types: random and bursty. 142 // Loop over the mask types: random and bursty.
147 for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes; 143 for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes;
148 ++mask_type_idx) { 144 ++mask_type_idx) {
149 for (uint32_t lossRateIdx = 0; lossRateIdx < lossRateSize; ++lossRateIdx) { 145 for (uint32_t loss_rate_idx = 0; loss_rate_idx < loss_rate_size;
150 printf("Loss rate: %.2f, Mask type %d \n", lossRate[lossRateIdx], 146 ++loss_rate_idx) {
147 printf("Loss rate: %.2f, Mask type %d \n", loss_rate[loss_rate_idx],
151 mask_type_idx); 148 mask_type_idx);
152 149
153 const uint32_t packetMaskMax = kMaxMediaPackets[mask_type_idx]; 150 const uint32_t packet_mask_max = kMaxMediaPackets[mask_type_idx];
154 uint8_t* packetMask = new uint8_t[packetMaskMax * kNumMaskBytesL1]; 151 std::unique_ptr<uint8_t[]> packet_mask(
152 new uint8_t[packet_mask_max * kNumMaskBytesL1]);
155 153
156 FecMaskType fec_mask_type = kMaskTypes[mask_type_idx]; 154 FecMaskType fec_mask_type = kMaskTypes[mask_type_idx];
157 155
158 for (uint32_t numMediaPackets = 1; numMediaPackets <= packetMaskMax; 156 for (uint32_t num_media_packets = 1; num_media_packets <= packet_mask_max;
159 numMediaPackets++) { 157 num_media_packets++) {
160 internal::PacketMaskTable mask_table(fec_mask_type, numMediaPackets); 158 internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets);
161 159
162 for (uint32_t numFecPackets = 1; 160 for (uint32_t num_fec_packets = 1;
163 numFecPackets <= numMediaPackets && numFecPackets <= packetMaskMax; 161 num_fec_packets <= num_media_packets &&
164 numFecPackets++) { 162 num_fec_packets <= packet_mask_max;
165 // Loop over numImpPackets: usually <= (0.3*numMediaPackets). 163 num_fec_packets++) {
166 // For this test we check up to ~ (numMediaPackets / 4). 164 // Loop over num_imp_packets: usually <= (0.3*num_media_packets).
167 uint32_t maxNumImpPackets = numMediaPackets / 4 + 1; 165 // For this test we check up to ~ (num_media_packets / 4).
168 for (uint32_t numImpPackets = 0; numImpPackets <= maxNumImpPackets && 166 uint32_t max_num_imp_packets = num_media_packets / 4 + 1;
169 numImpPackets <= packetMaskMax; 167 for (uint32_t num_imp_packets = 0;
170 numImpPackets++) { 168 num_imp_packets <= max_num_imp_packets &&
171 uint8_t protectionFactor = 169 num_imp_packets <= packet_mask_max;
172 static_cast<uint8_t>(numFecPackets * 255 / numMediaPackets); 170 num_imp_packets++) {
171 uint8_t protection_factor =
172 static_cast<uint8_t>(num_fec_packets * 255 / num_media_packets);
173 173
174 const uint32_t maskBytesPerFecPacket = 174 const uint32_t mask_bytes_per_fec_packet =
175 (numMediaPackets > 16) ? kNumMaskBytesL1 : kNumMaskBytesL0; 175 (num_media_packets > 16) ? kNumMaskBytesL1 : kNumMaskBytesL0;
176 176
177 memset(packetMask, 0, numMediaPackets * maskBytesPerFecPacket); 177 memset(packet_mask.get(), 0,
178 num_media_packets * mask_bytes_per_fec_packet);
178 179
179 // Transfer packet masks from bit-mask to byte-mask. 180 // Transfer packet masks from bit-mask to byte-mask.
180 internal::GeneratePacketMasks(numMediaPackets, numFecPackets, 181 internal::GeneratePacketMasks(num_media_packets, num_fec_packets,
181 numImpPackets, kUseUnequalProtection, 182 num_imp_packets,
182 mask_table, packetMask); 183 kUseUnequalProtection,
184 mask_table, packet_mask.get());
183 185
184 #ifdef VERBOSE_OUTPUT 186 #ifdef VERBOSE_OUTPUT
185 printf( 187 printf(
186 "%u media packets, %u FEC packets, %u numImpPackets, " 188 "%u media packets, %u FEC packets, %u num_imp_packets, "
187 "loss rate = %.2f \n", 189 "loss rate = %.2f \n",
188 numMediaPackets, numFecPackets, numImpPackets, 190 num_media_packets, num_fec_packets, num_imp_packets,
189 lossRate[lossRateIdx]); 191 loss_rate[loss_rate_idx]);
190 printf("Packet mask matrix \n"); 192 printf("Packet mask matrix \n");
191 #endif 193 #endif
192 194
193 for (uint32_t i = 0; i < numFecPackets; i++) { 195 for (uint32_t i = 0; i < num_fec_packets; i++) {
194 for (uint32_t j = 0; j < numMediaPackets; j++) { 196 for (uint32_t j = 0; j < num_media_packets; j++) {
195 const uint8_t byteMask = 197 const uint8_t byte_mask =
196 packetMask[i * maskBytesPerFecPacket + j / 8]; 198 packet_mask[i * mask_bytes_per_fec_packet + j / 8];
197 const uint32_t bitPosition = (7 - j % 8); 199 const uint32_t bit_position = (7 - j % 8);
198 fecPacketMasks[i][j] = 200 fec_packet_masks[i][j] =
199 (byteMask & (1 << bitPosition)) >> bitPosition; 201 (byte_mask & (1 << bit_position)) >> bit_position;
200 #ifdef VERBOSE_OUTPUT 202 #ifdef VERBOSE_OUTPUT
201 printf("%u ", fecPacketMasks[i][j]); 203 printf("%u ", fec_packet_masks[i][j]);
202 #endif 204 #endif
203 } 205 }
204 #ifdef VERBOSE_OUTPUT 206 #ifdef VERBOSE_OUTPUT
205 printf("\n"); 207 printf("\n");
206 #endif 208 #endif
207 } 209 }
208 #ifdef VERBOSE_OUTPUT 210 #ifdef VERBOSE_OUTPUT
209 printf("\n"); 211 printf("\n");
210 #endif 212 #endif
211 // Check for all zero rows or columns: indicates incorrect mask. 213 // Check for all zero rows or columns: indicates incorrect mask.
212 uint32_t rowLimit = numMediaPackets; 214 uint32_t row_limit = num_media_packets;
213 for (uint32_t i = 0; i < numFecPackets; ++i) { 215 for (uint32_t i = 0; i < num_fec_packets; ++i) {
214 uint32_t rowSum = 0; 216 uint32_t row_sum = 0;
215 for (uint32_t j = 0; j < rowLimit; ++j) { 217 for (uint32_t j = 0; j < row_limit; ++j) {
216 rowSum += fecPacketMasks[i][j]; 218 row_sum += fec_packet_masks[i][j];
217 } 219 }
218 ASSERT_NE(0u, rowSum) << "Row is all zero " << i; 220 ASSERT_NE(0u, row_sum) << "Row is all zero " << i;
219 } 221 }
220 for (uint32_t j = 0; j < rowLimit; ++j) { 222 for (uint32_t j = 0; j < row_limit; ++j) {
221 uint32_t columnSum = 0; 223 uint32_t column_sum = 0;
222 for (uint32_t i = 0; i < numFecPackets; ++i) { 224 for (uint32_t i = 0; i < num_fec_packets; ++i) {
223 columnSum += fecPacketMasks[i][j]; 225 column_sum += fec_packet_masks[i][j];
224 } 226 }
225 ASSERT_NE(0u, columnSum) << "Column is all zero " << j; 227 ASSERT_NE(0u, column_sum) << "Column is all zero " << j;
226 } 228 }
227 229
228 // Construct media packets. 230 // Construct media packets.
229 // Reset the sequence number here for each FEC code/mask tested 231 // Reset the sequence number here for each FEC code/mask tested
230 // below, to avoid sequence number wrap-around. In actual decoding, 232 // below, to avoid sequence number wrap-around. In actual decoding,
231 // old FEC packets in list are dropped if sequence number wrap 233 // old FEC packets in list are dropped if sequence number wrap
232 // around is detected. This case is currently not handled below. 234 // around is detected. This case is currently not handled below.
233 seqNum = 0; 235 seq_num = 0;
234 for (uint32_t i = 0; i < numMediaPackets; ++i) { 236 for (uint32_t i = 0; i < num_media_packets; ++i) {
235 mediaPacket = new ForwardErrorCorrection::Packet; 237 media_packet = new ForwardErrorCorrection::Packet();
236 mediaPacketList.push_back(mediaPacket); 238 media_packet_list.push_back(media_packet);
237 const uint32_t kMinPacketSize = 12; 239 const uint32_t kMinPacketSize = 12;
238 const uint32_t kMaxPacketSize = static_cast<uint32_t>( 240 const uint32_t kMaxPacketSize = static_cast<uint32_t>(
239 IP_PACKET_SIZE - 12 - 28 - 241 IP_PACKET_SIZE - 12 - 28 -
240 ForwardErrorCorrection::PacketOverhead()); 242 ForwardErrorCorrection::PacketOverhead());
241 mediaPacket->length = random.Rand(kMinPacketSize, kMaxPacketSize); 243 media_packet->length = random.Rand(kMinPacketSize,
244 kMaxPacketSize);
242 245
243 // Generate random values for the first 2 bytes. 246 // Generate random values for the first 2 bytes.
244 mediaPacket->data[0] = random.Rand<uint8_t>(); 247 media_packet->data[0] = random.Rand<uint8_t>();
245 mediaPacket->data[1] = random.Rand<uint8_t>(); 248 media_packet->data[1] = random.Rand<uint8_t>();
246 249
247 // The first two bits are assumed to be 10 by the 250 // The first two bits are assumed to be 10 by the
248 // FEC encoder. In fact the FEC decoder will set the 251 // FEC encoder. In fact the FEC decoder will set the
249 // two first bits to 10 regardless of what they 252 // two first bits to 10 regardless of what they
250 // actually were. Set the first two bits to 10 253 // actually were. Set the first two bits to 10
251 // so that a memcmp can be performed for the 254 // so that a memcmp can be performed for the
252 // whole restored packet. 255 // whole restored packet.
253 mediaPacket->data[0] |= 0x80; 256 media_packet->data[0] |= 0x80;
254 mediaPacket->data[0] &= 0xbf; 257 media_packet->data[0] &= 0xbf;
255 258
256 // FEC is applied to a whole frame. 259 // FEC is applied to a whole frame.
257 // A frame is signaled by multiple packets without 260 // A frame is signaled by multiple packets without
258 // the marker bit set followed by the last packet of 261 // the marker bit set followed by the last packet of
259 // the frame for which the marker bit is set. 262 // the frame for which the marker bit is set.
260 // Only push one (fake) frame to the FEC. 263 // Only push one (fake) frame to the FEC.
261 mediaPacket->data[1] &= 0x7f; 264 media_packet->data[1] &= 0x7f;
262 265
263 ByteWriter<uint16_t>::WriteBigEndian(&mediaPacket->data[2], 266 ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2],
264 seqNum); 267 seq_num);
265 ByteWriter<uint32_t>::WriteBigEndian(&mediaPacket->data[4], 268 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4],
266 timeStamp); 269 timestamp);
267 ByteWriter<uint32_t>::WriteBigEndian(&mediaPacket->data[8], ssrc); 270 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8],
271 ssrc);
268 // Generate random values for payload 272 // Generate random values for payload
269 for (size_t j = 12; j < mediaPacket->length; ++j) { 273 for (size_t j = 12; j < media_packet->length; ++j) {
270 mediaPacket->data[j] = random.Rand<uint8_t>(); 274 media_packet->data[j] = random.Rand<uint8_t>();
271 } 275 }
272 seqNum++; 276 seq_num++;
273 } 277 }
274 mediaPacket->data[1] |= 0x80; 278 media_packet->data[1] |= 0x80;
275 279
276 ASSERT_EQ(0, fec.GenerateFEC(mediaPacketList, protectionFactor, 280 ASSERT_EQ(0, fec.GenerateFec(media_packet_list, protection_factor,
277 numImpPackets, kUseUnequalProtection, 281 num_imp_packets, kUseUnequalProtection,
278 fec_mask_type, &fecPacketList)) 282 fec_mask_type, &fec_packet_list))
279 << "GenerateFEC() failed"; 283 << "GenerateFec() failed";
280 284
281 ASSERT_EQ(numFecPackets, fecPacketList.size()) 285 ASSERT_EQ(num_fec_packets, fec_packet_list.size())
282 << "We requested " << numFecPackets << " FEC packets, but " 286 << "We requested " << num_fec_packets << " FEC packets, but "
283 << "GenerateFEC() produced " << fecPacketList.size(); 287 << "GenerateFec() produced " << fec_packet_list.size();
284 memset(mediaLossMask, 0, sizeof(mediaLossMask)); 288
285 ForwardErrorCorrection::PacketList::iterator mediaPacketListItem = 289 memset(media_loss_mask, 0, sizeof(media_loss_mask));
286 mediaPacketList.begin(); 290 uint32_t media_packet_idx = 0;
287 ForwardErrorCorrection::ReceivedPacket* receivedPacket; 291 for (auto* media_packet : media_packet_list) {
288 uint32_t mediaPacketIdx = 0;
289
290 while (mediaPacketListItem != mediaPacketList.end()) {
291 mediaPacket = *mediaPacketListItem;
292 // We want a value between 0 and 1. 292 // We want a value between 0 and 1.
293 const float lossRandomVariable = random.Rand<float>(); 293 const float loss_random_variable = random.Rand<float>();
294 294
295 if (lossRandomVariable >= lossRate[lossRateIdx]) { 295 if (loss_random_variable >= loss_rate[loss_rate_idx]) {
296 mediaLossMask[mediaPacketIdx] = 1; 296 media_loss_mask[media_packet_idx] = 1;
297 receivedPacket = new ForwardErrorCorrection::ReceivedPacket; 297 auto received_packet =
298 receivedPacket->pkt = new ForwardErrorCorrection::Packet; 298 new ForwardErrorCorrection::ReceivedPacket();
299 receivedPacketList.push_back(receivedPacket); 299 received_packet->pkt = new ForwardErrorCorrection::Packet();
300 300 received_packet_list.push_back(received_packet);
301 receivedPacket->pkt->length = mediaPacket->length; 301
302 memcpy(receivedPacket->pkt->data, mediaPacket->data, 302 received_packet->pkt->length = media_packet->length;
303 mediaPacket->length); 303 memcpy(received_packet->pkt->data, media_packet->data,
304 receivedPacket->seq_num = 304 media_packet->length);
305 ByteReader<uint16_t>::ReadBigEndian(&mediaPacket->data[2]); 305 received_packet->seq_num =
306 receivedPacket->is_fec = false; 306 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]);
307 } 307 received_packet->is_fec = false;
308 mediaPacketIdx++; 308 }
309 ++mediaPacketListItem; 309 media_packet_idx++;
310 } 310 }
311 memset(fecLossMask, 0, sizeof(fecLossMask)); 311
312 ForwardErrorCorrection::PacketList::iterator fecPacketListItem = 312 memset(fec_loss_mask, 0, sizeof(fec_loss_mask));
313 fecPacketList.begin(); 313 uint32_t fec_packet_idx = 0;
314 ForwardErrorCorrection::Packet* fecPacket; 314 for (auto* fec_packet : fec_packet_list) {
315 uint32_t fecPacketIdx = 0; 315 const float loss_random_variable = random.Rand<float>();
316 while (fecPacketListItem != fecPacketList.end()) { 316 if (loss_random_variable >= loss_rate[loss_rate_idx]) {
317 fecPacket = *fecPacketListItem; 317 fec_loss_mask[fec_packet_idx] = 1;
318 const float lossRandomVariable = random.Rand<float>(); 318 auto received_packet =
319 if (lossRandomVariable >= lossRate[lossRateIdx]) { 319 new ForwardErrorCorrection::ReceivedPacket();
320 fecLossMask[fecPacketIdx] = 1; 320 received_packet->pkt = new ForwardErrorCorrection::Packet();
321 receivedPacket = new ForwardErrorCorrection::ReceivedPacket; 321
322 receivedPacket->pkt = new ForwardErrorCorrection::Packet; 322 received_packet_list.push_back(received_packet);
323 323
324 receivedPacketList.push_back(receivedPacket); 324 received_packet->pkt->length = fec_packet->length;
325 325 memcpy(received_packet->pkt->data, fec_packet->data,
326 receivedPacket->pkt->length = fecPacket->length; 326 fec_packet->length);
327 memcpy(receivedPacket->pkt->data, fecPacket->data, 327
328 fecPacket->length); 328 received_packet->seq_num = seq_num;
329 329 received_packet->is_fec = true;
330 receivedPacket->seq_num = seqNum; 330 received_packet->ssrc = ssrc;
331 receivedPacket->is_fec = true; 331
332 receivedPacket->ssrc = ssrc; 332 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]);
333 333 }
334 fecMaskList.push_back(fecPacketMasks[fecPacketIdx]); 334 ++fec_packet_idx;
335 } 335 ++seq_num;
336 ++fecPacketIdx;
337 ++seqNum;
338 ++fecPacketListItem;
339 } 336 }
340 337
341 #ifdef VERBOSE_OUTPUT 338 #ifdef VERBOSE_OUTPUT
342 printf("Media loss mask:\n"); 339 printf("Media loss mask:\n");
343 for (uint32_t i = 0; i < numMediaPackets; i++) { 340 for (uint32_t i = 0; i < num_media_packets; i++) {
344 printf("%u ", mediaLossMask[i]); 341 printf("%u ", media_loss_mask[i]);
345 } 342 }
346 printf("\n\n"); 343 printf("\n\n");
347 344
348 printf("FEC loss mask:\n"); 345 printf("FEC loss mask:\n");
349 for (uint32_t i = 0; i < numFecPackets; i++) { 346 for (uint32_t i = 0; i < num_fec_packets; i++) {
350 printf("%u ", fecLossMask[i]); 347 printf("%u ", fec_loss_mask[i]);
351 } 348 }
352 printf("\n\n"); 349 printf("\n\n");
353 #endif 350 #endif
354 351
355 std::list<uint8_t*>::iterator fecMaskIt = fecMaskList.begin(); 352 auto fec_mask_it = fec_mask_list.begin();
356 uint8_t* fecMask; 353 while (fec_mask_it != fec_mask_list.end()) {
357 while (fecMaskIt != fecMaskList.end()) { 354 uint32_t hamming_dist = 0;
358 fecMask = *fecMaskIt; 355 uint32_t recovery_position = 0;
359 uint32_t hammingDist = 0; 356 for (uint32_t i = 0; i < num_media_packets; i++) {
360 uint32_t recoveryPosition = 0; 357 if (media_loss_mask[i] == 0 && (*fec_mask_it)[i] == 1) {
361 for (uint32_t i = 0; i < numMediaPackets; i++) { 358 recovery_position = i;
362 if (mediaLossMask[i] == 0 && fecMask[i] == 1) { 359 ++hamming_dist;
363 recoveryPosition = i;
364 ++hammingDist;
365 } 360 }
366 } 361 }
367 std::list<uint8_t*>::iterator itemToDelete = fecMaskIt; 362 auto item_to_delete = fec_mask_it;
368 ++fecMaskIt; 363 ++fec_mask_it;
369 364
370 if (hammingDist == 1) { 365 if (hamming_dist == 1) {
371 // Recovery possible. Restart search. 366 // Recovery possible. Restart search.
372 mediaLossMask[recoveryPosition] = 1; 367 media_loss_mask[recovery_position] = 1;
373 fecMaskIt = fecMaskList.begin(); 368 fec_mask_it = fec_mask_list.begin();
374 } else if (hammingDist == 0) { 369 } else if (hamming_dist == 0) {
375 // FEC packet cannot provide further recovery. 370 // FEC packet cannot provide further recovery.
376 fecMaskList.erase(itemToDelete); 371 fec_mask_list.erase(item_to_delete);
377 } 372 }
378 } 373 }
379 #ifdef VERBOSE_OUTPUT 374 #ifdef VERBOSE_OUTPUT
380 printf("Recovery mask:\n"); 375 printf("Recovery mask:\n");
381 for (uint32_t i = 0; i < numMediaPackets; ++i) { 376 for (uint32_t i = 0; i < num_media_packets; ++i) {
382 printf("%u ", mediaLossMask[i]); 377 printf("%u ", media_loss_mask[i]);
383 } 378 }
384 printf("\n\n"); 379 printf("\n\n");
385 #endif 380 #endif
386 // For error-checking frame completion. 381 // For error-checking frame completion.
387 bool fecPacketReceived = false; 382 bool fec_packet_received = false;
388 while (!receivedPacketList.empty()) { 383 while (!received_packet_list.empty()) {
389 size_t numPacketsToDecode = random.Rand( 384 size_t num_packets_to_decode = random.Rand(
390 1u, static_cast<uint32_t>(receivedPacketList.size())); 385 1u, static_cast<uint32_t>(received_packet_list.size()));
391 ReceivePackets(&toDecodeList, &receivedPacketList, 386 ReceivePackets(&to_decode_list, &received_packet_list,
392 numPacketsToDecode, reorderRate, duplicateRate, 387 num_packets_to_decode, reorder_rate,
393 &random); 388 duplicate_rate, &random);
394 389
395 if (fecPacketReceived == false) { 390 if (fec_packet_received == false) {
396 ForwardErrorCorrection::ReceivedPacketList::iterator 391 for (auto* received_packet : to_decode_list) {
397 toDecodeIt = toDecodeList.begin(); 392 if (received_packet->is_fec) {
398 while (toDecodeIt != toDecodeList.end()) { 393 fec_packet_received = true;
399 receivedPacket = *toDecodeIt;
400 if (receivedPacket->is_fec) {
401 fecPacketReceived = true;
402 } 394 }
403 ++toDecodeIt;
404 } 395 }
405 } 396 }
406 ASSERT_EQ(0, fec.DecodeFEC(&toDecodeList, &recoveredPacketList)) 397 ASSERT_EQ(0, fec.DecodeFec(&to_decode_list,
407 << "DecodeFEC() failed"; 398 &recovered_packet_list))
408 ASSERT_TRUE(toDecodeList.empty()) 399 << "DecodeFec() failed";
400 ASSERT_TRUE(to_decode_list.empty())
409 << "Received packet list is not empty."; 401 << "Received packet list is not empty.";
410 } 402 }
411 mediaPacketListItem = mediaPacketList.begin(); 403 media_packet_idx = 0;
412 mediaPacketIdx = 0; 404 for (auto* media_packet : media_packet_list) {
413 while (mediaPacketListItem != mediaPacketList.end()) { 405 if (media_loss_mask[media_packet_idx] == 1) {
414 if (mediaLossMask[mediaPacketIdx] == 1) {
415 // Should have recovered this packet. 406 // Should have recovered this packet.
416 ForwardErrorCorrection::RecoveredPacketList::iterator 407 auto recovered_packet_list_it = recovered_packet_list.cbegin();
417 recoveredPacketListItem = recoveredPacketList.begin(); 408
418 409 ASSERT_FALSE(recovered_packet_list_it ==
419 ASSERT_FALSE(recoveredPacketListItem == 410 recovered_packet_list.end())
420 recoveredPacketList.end())
421 << "Insufficient number of recovered packets."; 411 << "Insufficient number of recovered packets.";
422 mediaPacket = *mediaPacketListItem; 412 ForwardErrorCorrection::RecoveredPacket* recovered_packet =
423 ForwardErrorCorrection::RecoveredPacket* recoveredPacket = 413 *recovered_packet_list_it;
424 *recoveredPacketListItem; 414
425 415 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length)
426 ASSERT_EQ(recoveredPacket->pkt->length, mediaPacket->length)
427 << "Recovered packet length not identical to original " 416 << "Recovered packet length not identical to original "
428 << "media packet"; 417 << "media packet";
429 ASSERT_EQ(0, memcmp(recoveredPacket->pkt->data, 418 ASSERT_EQ(0, memcmp(recovered_packet->pkt->data,
430 mediaPacket->data, mediaPacket->length)) 419 media_packet->data, media_packet->length))
431 << "Recovered packet payload not identical to original " 420 << "Recovered packet payload not identical to original "
432 << "media packet"; 421 << "media packet";
433 delete recoveredPacket; 422 delete recovered_packet;
434 recoveredPacketList.pop_front(); 423 recovered_packet_list.pop_front();
435 } 424 }
436 ++mediaPacketIdx; 425 ++media_packet_idx;
437 ++mediaPacketListItem; 426 }
438 } 427 fec.ResetState(&recovered_packet_list);
439 fec.ResetState(&recoveredPacketList); 428 ASSERT_TRUE(recovered_packet_list.empty())
440 ASSERT_TRUE(recoveredPacketList.empty())
441 << "Excessive number of recovered packets.\t size is: " 429 << "Excessive number of recovered packets.\t size is: "
442 << recoveredPacketList.size(); 430 << recovered_packet_list.size();
443 // -- Teardown -- 431 // -- Teardown --
444 mediaPacketListItem = mediaPacketList.begin(); 432 auto media_packet_list_it = media_packet_list.begin();
445 while (mediaPacketListItem != mediaPacketList.end()) { 433 while (media_packet_list_it != media_packet_list.end()) {
446 delete *mediaPacketListItem; 434 delete *media_packet_list_it;
447 ++mediaPacketListItem; 435 ++media_packet_list_it;
448 mediaPacketList.pop_front(); 436 media_packet_list.pop_front();
449 } 437 }
450 assert(mediaPacketList.empty()); 438 RTC_DCHECK(media_packet_list.empty());
451 439
452 fecPacketListItem = fecPacketList.begin(); 440 // Clear FEC packet list, so we don't pass in a non-empty
453 while (fecPacketListItem != fecPacketList.end()) { 441 // list in the next call to DecodeFec().
454 ++fecPacketListItem; 442 fec_packet_list.clear();
455 fecPacketList.pop_front(); 443
456 } 444 // Delete received packets we didn't pass to DecodeFec(), due to
457
458 // Delete received packets we didn't pass to DecodeFEC(), due to
459 // early frame completion. 445 // early frame completion.
460 ForwardErrorCorrection::ReceivedPacketList::iterator 446 auto received_packet_it = received_packet_list.cbegin();
461 receivedPacketIt = receivedPacketList.begin(); 447 while (received_packet_it != received_packet_list.end()) {
462 while (receivedPacketIt != receivedPacketList.end()) { 448 delete *received_packet_it;
463 receivedPacket = *receivedPacketIt; 449 ++received_packet_it;
464 delete receivedPacket; 450 received_packet_list.pop_front();
465 ++receivedPacketIt; 451 }
466 receivedPacketList.pop_front(); 452 RTC_DCHECK(received_packet_list.empty());
467 } 453
468 assert(receivedPacketList.empty()); 454 while (!fec_mask_list.empty()) {
469 455 fec_mask_list.pop_front();
470 while (!fecMaskList.empty()) { 456 }
471 fecMaskList.pop_front(); 457 timestamp += 90000 / 30;
472 } 458 } // loop over num_imp_packets
473 timeStamp += 90000 / 30;
474 } // loop over numImpPackets
475 } // loop over FecPackets 459 } // loop over FecPackets
476 } // loop over numMediaPackets 460 } // loop over num_media_packets
477 delete[] packetMask;
478 } // loop over loss rates 461 } // loop over loss rates
479 } // loop over mask types 462 } // loop over mask types
480 463
481 // Have DecodeFEC free allocated memory. 464 // Have DecodeFec free allocated memory.
482 fec.ResetState(&recoveredPacketList); 465 fec.ResetState(&recovered_packet_list);
483 ASSERT_TRUE(recoveredPacketList.empty()) 466 ASSERT_TRUE(recovered_packet_list.empty())
484 << "Recovered packet list is not empty"; 467 << "Recovered packet list is not empty";
485 } 468 }
486 469
487 } // namespace test 470 } // namespace test
488 } // namespace webrtc 471 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698