OLD | NEW |
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 #include <algorithm> |
11 #include <list> | 12 #include <list> |
12 | 13 |
13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "webrtc/base/random.h" | 15 #include "webrtc/base/random.h" |
15 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
16 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | 17 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" |
17 | 18 |
18 using webrtc::ForwardErrorCorrection; | 19 using webrtc::ForwardErrorCorrection; |
19 | 20 |
20 // Minimum RTP header size in bytes. | 21 // Minimum RTP header size in bytes. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 }; | 93 }; |
93 | 94 |
94 TEST_F(RtpFecTest, FecRecoveryNoLoss) { | 95 TEST_F(RtpFecTest, FecRecoveryNoLoss) { |
95 const int kNumImportantPackets = 0; | 96 const int kNumImportantPackets = 0; |
96 const bool kUseUnequalProtection = false; | 97 const bool kUseUnequalProtection = false; |
97 const int kNumMediaPackets = 4; | 98 const int kNumMediaPackets = 4; |
98 uint8_t kProtectionFactor = 60; | 99 uint8_t kProtectionFactor = 60; |
99 | 100 |
100 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 101 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
101 | 102 |
102 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 103 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
103 kNumImportantPackets, kUseUnequalProtection, | 104 kNumImportantPackets, kUseUnequalProtection, |
104 webrtc::kFecMaskBursty, &fec_packet_list_)); | 105 webrtc::kFecMaskBursty, &fec_packet_list_)); |
105 | 106 |
106 // Expect 1 FEC packet. | 107 // Expect 1 FEC packet. |
107 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 108 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
108 | 109 |
109 // No packets lost. | 110 // No packets lost. |
110 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 111 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
111 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 112 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
112 NetworkReceivedPackets(); | 113 NetworkReceivedPackets(); |
113 | 114 |
114 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 115 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
115 &recovered_packet_list_)); | 116 &recovered_packet_list_)); |
116 | 117 |
117 // No packets lost, expect complete recovery. | 118 // No packets lost, expect complete recovery. |
118 EXPECT_TRUE(IsRecoveryComplete()); | 119 EXPECT_TRUE(IsRecoveryComplete()); |
119 } | 120 } |
120 | 121 |
121 TEST_F(RtpFecTest, FecRecoveryWithLoss) { | 122 TEST_F(RtpFecTest, FecRecoveryWithLoss) { |
122 const int kNumImportantPackets = 0; | 123 const int kNumImportantPackets = 0; |
123 const bool kUseUnequalProtection = false; | 124 const bool kUseUnequalProtection = false; |
124 const int kNumMediaPackets = 4; | 125 const int kNumMediaPackets = 4; |
125 uint8_t kProtectionFactor = 60; | 126 uint8_t kProtectionFactor = 60; |
126 | 127 |
127 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 128 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
128 | 129 |
129 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 130 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
130 kNumImportantPackets, kUseUnequalProtection, | 131 kNumImportantPackets, kUseUnequalProtection, |
131 webrtc::kFecMaskBursty, &fec_packet_list_)); | 132 webrtc::kFecMaskBursty, &fec_packet_list_)); |
132 | 133 |
133 // Expect 1 FEC packet. | 134 // Expect 1 FEC packet. |
134 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 135 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
135 | 136 |
136 // 1 media packet lost | 137 // 1 media packet lost |
137 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 138 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
138 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 139 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
139 media_loss_mask_[3] = 1; | 140 media_loss_mask_[3] = 1; |
140 NetworkReceivedPackets(); | 141 NetworkReceivedPackets(); |
141 | 142 |
142 EXPECT_EQ(0, | 143 EXPECT_EQ(0, |
143 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 144 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
144 | 145 |
145 // One packet lost, one FEC packet, expect complete recovery. | 146 // One packet lost, one FEC packet, expect complete recovery. |
146 EXPECT_TRUE(IsRecoveryComplete()); | 147 EXPECT_TRUE(IsRecoveryComplete()); |
147 FreeRecoveredPacketList(); | 148 FreeRecoveredPacketList(); |
148 | 149 |
149 // 2 media packets lost. | 150 // 2 media packets lost. |
150 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 151 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
151 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 152 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
152 media_loss_mask_[1] = 1; | 153 media_loss_mask_[1] = 1; |
153 media_loss_mask_[3] = 1; | 154 media_loss_mask_[3] = 1; |
154 NetworkReceivedPackets(); | 155 NetworkReceivedPackets(); |
155 | 156 |
156 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 157 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
157 &recovered_packet_list_)); | 158 &recovered_packet_list_)); |
158 | 159 |
159 // 2 packets lost, one FEC packet, cannot get complete recovery. | 160 // 2 packets lost, one FEC packet, cannot get complete recovery. |
160 EXPECT_FALSE(IsRecoveryComplete()); | 161 EXPECT_FALSE(IsRecoveryComplete()); |
161 } | 162 } |
162 | 163 |
163 // Verify that we don't use an old FEC packet for FEC decoding. | 164 // Verify that we don't use an old FEC packet for FEC decoding. |
164 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { | 165 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { |
165 const int kNumImportantPackets = 0; | 166 const int kNumImportantPackets = 0; |
166 const bool kUseUnequalProtection = false; | 167 const bool kUseUnequalProtection = false; |
167 uint8_t kProtectionFactor = 20; | 168 uint8_t kProtectionFactor = 20; |
168 | 169 |
169 // Two frames: first frame (old) with two media packets and 1 FEC packet. | 170 // Two frames: first frame (old) with two media packets and 1 FEC packet. |
170 // Second frame (new) with 3 media packets, and no FEC packets. | 171 // Second frame (new) with 3 media packets, and no FEC packets. |
171 // ---Frame 1---- ----Frame 2------ | 172 // ---Frame 1---- ----Frame 2------ |
172 // #0(media) #1(media) #2(FEC) #65535(media) #0(media) #1(media). | 173 // #0(media) #1(media) #2(FEC) #65535(media) #0(media) #1(media). |
173 // If we lose either packet 0 or 1 of second frame, FEC decoding should not | 174 // If we lose either packet 0 or 1 of second frame, FEC decoding should not |
174 // try to decode using "old" FEC packet #2. | 175 // try to decode using "old" FEC packet #2. |
175 | 176 |
176 // Construct media packets for first frame, starting at sequence number 0. | 177 // Construct media packets for first frame, starting at sequence number 0. |
177 fec_seq_num_ = ConstructMediaPacketsSeqNum(2, 0); | 178 fec_seq_num_ = ConstructMediaPacketsSeqNum(2, 0); |
178 | 179 |
179 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 180 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
180 kNumImportantPackets, kUseUnequalProtection, | 181 kNumImportantPackets, kUseUnequalProtection, |
181 webrtc::kFecMaskBursty, &fec_packet_list_)); | 182 webrtc::kFecMaskBursty, &fec_packet_list_)); |
182 // Expect 1 FEC packet. | 183 // Expect 1 FEC packet. |
183 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 184 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
184 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume | 185 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume |
185 // the two media packet were lost). | 186 // the two media packet were lost). |
186 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 187 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
187 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 188 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
188 | 189 |
189 // Construct media packets for second frame, with sequence number wrap. | 190 // Construct media packets for second frame, with sequence number wrap. |
190 ClearList(&media_packet_list_); | 191 ClearList(&media_packet_list_); |
191 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); | 192 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); |
192 | 193 |
193 // Expect 3 media packets for this frame. | 194 // Expect 3 media packets for this frame. |
194 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); | 195 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); |
195 | 196 |
196 // Second media packet lost (seq#0). | 197 // Second media packet lost (seq#0). |
197 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 198 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
198 media_loss_mask_[1] = 1; | 199 media_loss_mask_[1] = 1; |
199 // Add packets #65535, and #1 to received list. | 200 // Add packets #65535, and #1 to received list. |
200 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 201 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
201 | 202 |
202 EXPECT_EQ(0, | 203 EXPECT_EQ(0, |
203 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 204 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
204 | 205 |
205 // Expect that no decoding is done to get missing packet (seq#0) of second | 206 // Expect that no decoding is done to get missing packet (seq#0) of second |
206 // frame, using old FEC packet (seq#2) from first (old) frame. So number of | 207 // frame, using old FEC packet (seq#2) from first (old) frame. So number of |
207 // recovered packets is 2, and not equal to number of media packets (=3). | 208 // recovered packets is 2, and not equal to number of media packets (=3). |
208 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 209 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
209 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 210 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
210 FreeRecoveredPacketList(); | 211 FreeRecoveredPacketList(); |
211 } | 212 } |
212 | 213 |
213 // Verify we can still recovery frame if sequence number wrap occurs within | 214 // Verify we can still recovery frame if sequence number wrap occurs within |
214 // the frame and FEC packet following wrap is received after media packets. | 215 // the frame and FEC packet following wrap is received after media packets. |
215 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { | 216 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { |
216 const int kNumImportantPackets = 0; | 217 const int kNumImportantPackets = 0; |
217 const bool kUseUnequalProtection = false; | 218 const bool kUseUnequalProtection = false; |
218 uint8_t kProtectionFactor = 20; | 219 uint8_t kProtectionFactor = 20; |
219 | 220 |
220 // One frame, with sequence number wrap in media packets. | 221 // One frame, with sequence number wrap in media packets. |
221 // -----Frame 1---- | 222 // -----Frame 1---- |
222 // #65534(media) #65535(media) #0(media) #1(FEC). | 223 // #65534(media) #65535(media) #0(media) #1(FEC). |
223 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65534); | 224 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65534); |
224 | 225 |
225 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 226 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
226 kNumImportantPackets, kUseUnequalProtection, | 227 kNumImportantPackets, kUseUnequalProtection, |
227 webrtc::kFecMaskBursty, &fec_packet_list_)); | 228 webrtc::kFecMaskBursty, &fec_packet_list_)); |
228 | 229 |
229 // Expect 1 FEC packet. | 230 // Expect 1 FEC packet. |
230 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 231 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
231 | 232 |
232 // Lose one media packet (seq# 65535). | 233 // Lose one media packet (seq# 65535). |
233 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 234 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
234 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 235 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
235 media_loss_mask_[1] = 1; | 236 media_loss_mask_[1] = 1; |
236 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 237 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
237 // Add FEC packet to received list following the media packets. | 238 // Add FEC packet to received list following the media packets. |
238 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 239 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
239 | 240 |
240 EXPECT_EQ(0, | 241 EXPECT_EQ(0, |
241 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 242 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
242 | 243 |
243 // Expect 3 media packets in recovered list, and complete recovery. | 244 // Expect 3 media packets in recovered list, and complete recovery. |
244 // Wrap-around won't remove FEC packet, as it follows the wrap. | 245 // Wrap-around won't remove FEC packet, as it follows the wrap. |
245 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 246 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
246 EXPECT_TRUE(IsRecoveryComplete()); | 247 EXPECT_TRUE(IsRecoveryComplete()); |
247 FreeRecoveredPacketList(); | 248 FreeRecoveredPacketList(); |
248 } | 249 } |
249 | 250 |
250 // Sequence number wrap occurs within the FEC packets for the frame. | 251 // Sequence number wrap occurs within the FEC packets for the frame. |
251 // In this case we will discard FEC packet and full recovery is not expected. | 252 // In this case we will discard FEC packet and full recovery is not expected. |
252 // Same problem will occur if wrap is within media packets but FEC packet is | 253 // Same problem will occur if wrap is within media packets but FEC packet is |
253 // received before the media packets. This may be improved if timing information | 254 // received before the media packets. This may be improved if timing information |
254 // is used to detect old FEC packets. | 255 // is used to detect old FEC packets. |
255 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. | 256 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. |
256 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { | 257 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { |
257 const int kNumImportantPackets = 0; | 258 const int kNumImportantPackets = 0; |
258 const bool kUseUnequalProtection = false; | 259 const bool kUseUnequalProtection = false; |
259 uint8_t kProtectionFactor = 200; | 260 uint8_t kProtectionFactor = 200; |
260 | 261 |
261 // 1 frame: 3 media packets and 2 FEC packets. | 262 // 1 frame: 3 media packets and 2 FEC packets. |
262 // Sequence number wrap in FEC packets. | 263 // Sequence number wrap in FEC packets. |
263 // -----Frame 1---- | 264 // -----Frame 1---- |
264 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). | 265 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). |
265 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65532); | 266 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65532); |
266 | 267 |
267 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 268 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
268 kNumImportantPackets, kUseUnequalProtection, | 269 kNumImportantPackets, kUseUnequalProtection, |
269 webrtc::kFecMaskBursty, &fec_packet_list_)); | 270 webrtc::kFecMaskBursty, &fec_packet_list_)); |
270 | 271 |
271 // Expect 2 FEC packets. | 272 // Expect 2 FEC packets. |
272 EXPECT_EQ(2, static_cast<int>(fec_packet_list_.size())); | 273 EXPECT_EQ(2, static_cast<int>(fec_packet_list_.size())); |
273 | 274 |
274 // Lose the last two media packets (seq# 65533, 65534). | 275 // Lose the last two media packets (seq# 65533, 65534). |
275 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 276 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
276 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 277 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
277 media_loss_mask_[1] = 1; | 278 media_loss_mask_[1] = 1; |
278 media_loss_mask_[2] = 1; | 279 media_loss_mask_[2] = 1; |
279 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 280 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
280 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 281 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
281 | 282 |
282 EXPECT_EQ(0, | 283 EXPECT_EQ(0, |
283 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 284 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
284 | 285 |
285 // The two FEC packets are received and should allow for complete recovery, | 286 // The two FEC packets are received and should allow for complete recovery, |
286 // but because of the wrap the second FEC packet will be discarded, and only | 287 // but because of the wrap the second FEC packet will be discarded, and only |
287 // one media packet is recoverable. So exepct 2 media packets on recovered | 288 // one media packet is recoverable. So exepct 2 media packets on recovered |
288 // list and no complete recovery. | 289 // list and no complete recovery. |
289 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 290 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
290 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 291 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
291 EXPECT_FALSE(IsRecoveryComplete()); | 292 EXPECT_FALSE(IsRecoveryComplete()); |
292 FreeRecoveredPacketList(); | 293 FreeRecoveredPacketList(); |
293 } | 294 } |
294 | 295 |
295 // Verify we can still recovery frame if FEC is received before media packets. | 296 // Verify we can still recovery frame if FEC is received before media packets. |
296 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { | 297 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { |
297 const int kNumImportantPackets = 0; | 298 const int kNumImportantPackets = 0; |
298 const bool kUseUnequalProtection = false; | 299 const bool kUseUnequalProtection = false; |
299 uint8_t kProtectionFactor = 20; | 300 uint8_t kProtectionFactor = 20; |
300 | 301 |
301 // One frame: 3 media packets, 1 FEC packet. | 302 // One frame: 3 media packets, 1 FEC packet. |
302 // -----Frame 1---- | 303 // -----Frame 1---- |
303 // #0(media) #1(media) #2(media) #3(FEC). | 304 // #0(media) #1(media) #2(media) #3(FEC). |
304 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); | 305 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); |
305 | 306 |
306 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 307 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
307 kNumImportantPackets, kUseUnequalProtection, | 308 kNumImportantPackets, kUseUnequalProtection, |
308 webrtc::kFecMaskBursty, &fec_packet_list_)); | 309 webrtc::kFecMaskBursty, &fec_packet_list_)); |
309 | 310 |
310 // Expect 1 FEC packet. | 311 // Expect 1 FEC packet. |
311 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 312 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
312 | 313 |
313 // Lose one media packet (seq# 1). | 314 // Lose one media packet (seq# 1). |
314 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 315 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
315 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 316 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
316 media_loss_mask_[1] = 1; | 317 media_loss_mask_[1] = 1; |
317 // Add FEC packet to received list before the media packets. | 318 // Add FEC packet to received list before the media packets. |
318 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 319 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
319 // Add media packets to received list. | 320 // Add media packets to received list. |
320 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 321 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
321 | 322 |
322 EXPECT_EQ(0, | 323 EXPECT_EQ(0, |
323 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 324 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
324 | 325 |
325 // Expect 3 media packets in recovered list, and complete recovery. | 326 // Expect 3 media packets in recovered list, and complete recovery. |
326 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 327 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
327 EXPECT_TRUE(IsRecoveryComplete()); | 328 EXPECT_TRUE(IsRecoveryComplete()); |
328 FreeRecoveredPacketList(); | 329 FreeRecoveredPacketList(); |
329 } | 330 } |
330 | 331 |
331 // Test 50% protection with random mask type: Two cases are considered: | 332 // Test 50% protection with random mask type: Two cases are considered: |
332 // a 50% non-consecutive loss which can be fully recovered, and a 50% | 333 // a 50% non-consecutive loss which can be fully recovered, and a 50% |
333 // consecutive loss which cannot be fully recovered. | 334 // consecutive loss which cannot be fully recovered. |
334 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { | 335 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { |
335 const int kNumImportantPackets = 0; | 336 const int kNumImportantPackets = 0; |
336 const bool kUseUnequalProtection = false; | 337 const bool kUseUnequalProtection = false; |
337 const int kNumMediaPackets = 4; | 338 const int kNumMediaPackets = 4; |
338 const uint8_t kProtectionFactor = 255; | 339 const uint8_t kProtectionFactor = 255; |
339 | 340 |
340 // Packet Mask for (4,4,0) code, from random mask table. | 341 // Packet Mask for (4,4,0) code, from random mask table. |
341 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) | 342 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) |
342 | 343 |
343 // media#0 media#1 media#2 media#3 | 344 // media#0 media#1 media#2 media#3 |
344 // fec#0: 1 1 0 0 | 345 // fec#0: 1 1 0 0 |
345 // fec#1: 1 0 1 0 | 346 // fec#1: 1 0 1 0 |
346 // fec#2: 0 0 1 1 | 347 // fec#2: 0 0 1 1 |
347 // fec#3: 0 1 0 1 | 348 // fec#3: 0 1 0 1 |
348 // | 349 // |
349 | 350 |
350 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 351 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
351 | 352 |
352 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 353 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
353 kNumImportantPackets, kUseUnequalProtection, | 354 kNumImportantPackets, kUseUnequalProtection, |
354 webrtc::kFecMaskRandom, &fec_packet_list_)); | 355 webrtc::kFecMaskRandom, &fec_packet_list_)); |
355 | 356 |
356 // Expect 4 FEC packets. | 357 // Expect 4 FEC packets. |
357 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 358 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); |
358 | 359 |
359 // 4 packets lost: 3 media packets (0, 2, 3), and one FEC packet (0) lost. | 360 // 4 packets lost: 3 media packets (0, 2, 3), and one FEC packet (0) lost. |
360 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 361 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
361 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 362 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
362 fec_loss_mask_[0] = 1; | 363 fec_loss_mask_[0] = 1; |
363 media_loss_mask_[0] = 1; | 364 media_loss_mask_[0] = 1; |
364 media_loss_mask_[2] = 1; | 365 media_loss_mask_[2] = 1; |
365 media_loss_mask_[3] = 1; | 366 media_loss_mask_[3] = 1; |
366 NetworkReceivedPackets(); | 367 NetworkReceivedPackets(); |
367 | 368 |
368 EXPECT_EQ(0, | 369 EXPECT_EQ(0, |
369 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 370 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
370 | 371 |
371 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. | 372 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. |
372 EXPECT_TRUE(IsRecoveryComplete()); | 373 EXPECT_TRUE(IsRecoveryComplete()); |
373 FreeRecoveredPacketList(); | 374 FreeRecoveredPacketList(); |
374 | 375 |
375 // 4 consecutive packets lost: media packets 0, 1, 2, 3. | 376 // 4 consecutive packets lost: media packets 0, 1, 2, 3. |
376 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 377 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
377 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 378 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
378 media_loss_mask_[0] = 1; | 379 media_loss_mask_[0] = 1; |
379 media_loss_mask_[1] = 1; | 380 media_loss_mask_[1] = 1; |
380 media_loss_mask_[2] = 1; | 381 media_loss_mask_[2] = 1; |
381 media_loss_mask_[3] = 1; | 382 media_loss_mask_[3] = 1; |
382 NetworkReceivedPackets(); | 383 NetworkReceivedPackets(); |
383 | 384 |
384 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 385 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
385 &recovered_packet_list_)); | 386 &recovered_packet_list_)); |
386 | 387 |
387 // Cannot get complete recovery for this loss configuration with random mask. | 388 // Cannot get complete recovery for this loss configuration with random mask. |
388 EXPECT_FALSE(IsRecoveryComplete()); | 389 EXPECT_FALSE(IsRecoveryComplete()); |
389 } | 390 } |
390 | 391 |
391 // Test 50% protection with bursty type: Three cases are considered: | 392 // Test 50% protection with bursty type: Three cases are considered: |
392 // two 50% consecutive losses which can be fully recovered, and one | 393 // two 50% consecutive losses which can be fully recovered, and one |
393 // non-consecutive which cannot be fully recovered. | 394 // non-consecutive which cannot be fully recovered. |
394 TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { | 395 TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { |
395 const int kNumImportantPackets = 0; | 396 const int kNumImportantPackets = 0; |
396 const bool kUseUnequalProtection = false; | 397 const bool kUseUnequalProtection = false; |
397 const int kNumMediaPackets = 4; | 398 const int kNumMediaPackets = 4; |
398 const uint8_t kProtectionFactor = 255; | 399 const uint8_t kProtectionFactor = 255; |
399 | 400 |
400 // Packet Mask for (4,4,0) code, from bursty mask table. | 401 // Packet Mask for (4,4,0) code, from bursty mask table. |
401 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) | 402 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) |
402 | 403 |
403 // media#0 media#1 media#2 media#3 | 404 // media#0 media#1 media#2 media#3 |
404 // fec#0: 1 0 0 0 | 405 // fec#0: 1 0 0 0 |
405 // fec#1: 1 1 0 0 | 406 // fec#1: 1 1 0 0 |
406 // fec#2: 0 1 1 0 | 407 // fec#2: 0 1 1 0 |
407 // fec#3: 0 0 1 1 | 408 // fec#3: 0 0 1 1 |
408 // | 409 // |
409 | 410 |
410 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 411 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
411 | 412 |
412 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 413 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
413 kNumImportantPackets, kUseUnequalProtection, | 414 kNumImportantPackets, kUseUnequalProtection, |
414 webrtc::kFecMaskBursty, &fec_packet_list_)); | 415 webrtc::kFecMaskBursty, &fec_packet_list_)); |
415 | 416 |
416 // Expect 4 FEC packets. | 417 // Expect 4 FEC packets. |
417 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 418 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); |
418 | 419 |
419 // 4 consecutive packets lost: media packets 0,1,2,3. | 420 // 4 consecutive packets lost: media packets 0,1,2,3. |
420 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 421 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
421 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 422 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
422 media_loss_mask_[0] = 1; | 423 media_loss_mask_[0] = 1; |
423 media_loss_mask_[1] = 1; | 424 media_loss_mask_[1] = 1; |
424 media_loss_mask_[2] = 1; | 425 media_loss_mask_[2] = 1; |
425 media_loss_mask_[3] = 1; | 426 media_loss_mask_[3] = 1; |
426 NetworkReceivedPackets(); | 427 NetworkReceivedPackets(); |
427 | 428 |
428 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 429 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
429 &recovered_packet_list_)); | 430 &recovered_packet_list_)); |
430 | 431 |
431 // Expect complete recovery for consecutive packet loss <= 50%. | 432 // Expect complete recovery for consecutive packet loss <= 50%. |
432 EXPECT_TRUE(IsRecoveryComplete()); | 433 EXPECT_TRUE(IsRecoveryComplete()); |
433 FreeRecoveredPacketList(); | 434 FreeRecoveredPacketList(); |
434 | 435 |
435 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. | 436 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. |
436 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 437 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
437 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 438 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
438 fec_loss_mask_[0] = 1; | 439 fec_loss_mask_[0] = 1; |
439 media_loss_mask_[1] = 1; | 440 media_loss_mask_[1] = 1; |
440 media_loss_mask_[2] = 1; | 441 media_loss_mask_[2] = 1; |
441 media_loss_mask_[3] = 1; | 442 media_loss_mask_[3] = 1; |
442 NetworkReceivedPackets(); | 443 NetworkReceivedPackets(); |
443 | 444 |
444 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 445 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
445 &recovered_packet_list_)); | 446 &recovered_packet_list_)); |
446 | 447 |
447 // Expect complete recovery for consecutive packet loss <= 50%. | 448 // Expect complete recovery for consecutive packet loss <= 50%. |
448 EXPECT_TRUE(IsRecoveryComplete()); | 449 EXPECT_TRUE(IsRecoveryComplete()); |
449 FreeRecoveredPacketList(); | 450 FreeRecoveredPacketList(); |
450 | 451 |
451 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. | 452 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. |
452 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 453 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
453 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 454 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
454 fec_loss_mask_[0] = 1; | 455 fec_loss_mask_[0] = 1; |
455 fec_loss_mask_[3] = 1; | 456 fec_loss_mask_[3] = 1; |
456 media_loss_mask_[0] = 1; | 457 media_loss_mask_[0] = 1; |
457 media_loss_mask_[3] = 1; | 458 media_loss_mask_[3] = 1; |
458 NetworkReceivedPackets(); | 459 NetworkReceivedPackets(); |
459 | 460 |
460 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 461 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
461 &recovered_packet_list_)); | 462 &recovered_packet_list_)); |
462 | 463 |
463 // Cannot get complete recovery for this loss configuration. | 464 // Cannot get complete recovery for this loss configuration. |
464 EXPECT_FALSE(IsRecoveryComplete()); | 465 EXPECT_FALSE(IsRecoveryComplete()); |
465 } | 466 } |
466 | 467 |
467 TEST_F(RtpFecTest, FecRecoveryNoLossUep) { | 468 TEST_F(RtpFecTest, FecRecoveryNoLossUep) { |
468 const int kNumImportantPackets = 2; | 469 const int kNumImportantPackets = 2; |
469 const bool kUseUnequalProtection = true; | 470 const bool kUseUnequalProtection = true; |
470 const int kNumMediaPackets = 4; | 471 const int kNumMediaPackets = 4; |
471 const uint8_t kProtectionFactor = 60; | 472 const uint8_t kProtectionFactor = 60; |
472 | 473 |
473 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 474 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
474 | 475 |
475 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 476 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
476 kNumImportantPackets, kUseUnequalProtection, | 477 kNumImportantPackets, kUseUnequalProtection, |
477 webrtc::kFecMaskBursty, &fec_packet_list_)); | 478 webrtc::kFecMaskBursty, &fec_packet_list_)); |
478 | 479 |
479 // Expect 1 FEC packet. | 480 // Expect 1 FEC packet. |
480 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 481 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
481 | 482 |
482 // No packets lost. | 483 // No packets lost. |
483 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 484 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
484 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 485 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
485 NetworkReceivedPackets(); | 486 NetworkReceivedPackets(); |
486 | 487 |
487 EXPECT_EQ(0, | 488 EXPECT_EQ(0, |
488 fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); | 489 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
489 | 490 |
490 // No packets lost, expect complete recovery. | 491 // No packets lost, expect complete recovery. |
491 EXPECT_TRUE(IsRecoveryComplete()); | 492 EXPECT_TRUE(IsRecoveryComplete()); |
492 } | 493 } |
493 | 494 |
494 TEST_F(RtpFecTest, FecRecoveryWithLossUep) { | 495 TEST_F(RtpFecTest, FecRecoveryWithLossUep) { |
495 const int kNumImportantPackets = 2; | 496 const int kNumImportantPackets = 2; |
496 const bool kUseUnequalProtection = true; | 497 const bool kUseUnequalProtection = true; |
497 const int kNumMediaPackets = 4; | 498 const int kNumMediaPackets = 4; |
498 const uint8_t kProtectionFactor = 60; | 499 const uint8_t kProtectionFactor = 60; |
499 | 500 |
500 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 501 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
501 | 502 |
502 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 503 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
503 kNumImportantPackets, kUseUnequalProtection, | 504 kNumImportantPackets, kUseUnequalProtection, |
504 webrtc::kFecMaskBursty, &fec_packet_list_)); | 505 webrtc::kFecMaskBursty, &fec_packet_list_)); |
505 | 506 |
506 // Expect 1 FEC packet. | 507 // Expect 1 FEC packet. |
507 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 508 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
508 | 509 |
509 // 1 media packet lost. | 510 // 1 media packet lost. |
510 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
511 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
512 media_loss_mask_[3] = 1; | 513 media_loss_mask_[3] = 1; |
513 NetworkReceivedPackets(); | 514 NetworkReceivedPackets(); |
514 | 515 |
515 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 516 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
516 &recovered_packet_list_)); | 517 &recovered_packet_list_)); |
517 | 518 |
518 // One packet lost, one FEC packet, expect complete recovery. | 519 // One packet lost, one FEC packet, expect complete recovery. |
519 EXPECT_TRUE(IsRecoveryComplete()); | 520 EXPECT_TRUE(IsRecoveryComplete()); |
520 FreeRecoveredPacketList(); | 521 FreeRecoveredPacketList(); |
521 | 522 |
522 // 2 media packets lost. | 523 // 2 media packets lost. |
523 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 524 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
524 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 525 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
525 media_loss_mask_[1] = 1; | 526 media_loss_mask_[1] = 1; |
526 media_loss_mask_[3] = 1; | 527 media_loss_mask_[3] = 1; |
527 NetworkReceivedPackets(); | 528 NetworkReceivedPackets(); |
528 | 529 |
529 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 530 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
530 &recovered_packet_list_)); | 531 &recovered_packet_list_)); |
531 | 532 |
532 // 2 packets lost, one FEC packet, cannot get complete recovery. | 533 // 2 packets lost, one FEC packet, cannot get complete recovery. |
533 EXPECT_FALSE(IsRecoveryComplete()); | 534 EXPECT_FALSE(IsRecoveryComplete()); |
534 } | 535 } |
535 | 536 |
536 // Test 50% protection with random mask type for UEP on. | 537 // Test 50% protection with random mask type for UEP on. |
537 TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { | 538 TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { |
538 const int kNumImportantPackets = 1; | 539 const int kNumImportantPackets = 1; |
539 const bool kUseUnequalProtection = true; | 540 const bool kUseUnequalProtection = true; |
540 const int kNumMediaPackets = 4; | 541 const int kNumMediaPackets = 4; |
541 const uint8_t kProtectionFactor = 255; | 542 const uint8_t kProtectionFactor = 255; |
542 | 543 |
543 // Packet Mask for (4,4,1) code, from random mask table. | 544 // Packet Mask for (4,4,1) code, from random mask table. |
544 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 1) | 545 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 1) |
545 | 546 |
546 // media#0 media#1 media#2 media#3 | 547 // media#0 media#1 media#2 media#3 |
547 // fec#0: 1 0 0 0 | 548 // fec#0: 1 0 0 0 |
548 // fec#1: 1 1 0 0 | 549 // fec#1: 1 1 0 0 |
549 // fec#2: 1 0 1 1 | 550 // fec#2: 1 0 1 1 |
550 // fec#3: 0 1 1 0 | 551 // fec#3: 0 1 1 0 |
551 // | 552 // |
552 | 553 |
553 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 554 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
554 | 555 |
555 EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, | 556 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, |
556 kNumImportantPackets, kUseUnequalProtection, | 557 kNumImportantPackets, kUseUnequalProtection, |
557 webrtc::kFecMaskRandom, &fec_packet_list_)); | 558 webrtc::kFecMaskRandom, &fec_packet_list_)); |
558 | 559 |
559 // Expect 4 FEC packets. | 560 // Expect 4 FEC packets. |
560 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 561 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); |
561 | 562 |
562 // 4 packets lost: 3 media packets and FEC packet#1 lost. | 563 // 4 packets lost: 3 media packets and FEC packet#1 lost. |
563 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 564 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
564 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 565 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
565 fec_loss_mask_[1] = 1; | 566 fec_loss_mask_[1] = 1; |
566 media_loss_mask_[0] = 1; | 567 media_loss_mask_[0] = 1; |
567 media_loss_mask_[2] = 1; | 568 media_loss_mask_[2] = 1; |
568 media_loss_mask_[3] = 1; | 569 media_loss_mask_[3] = 1; |
569 NetworkReceivedPackets(); | 570 NetworkReceivedPackets(); |
570 | 571 |
571 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 572 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
572 &recovered_packet_list_)); | 573 &recovered_packet_list_)); |
573 | 574 |
574 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. | 575 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. |
575 EXPECT_TRUE(IsRecoveryComplete()); | 576 EXPECT_TRUE(IsRecoveryComplete()); |
576 FreeRecoveredPacketList(); | 577 FreeRecoveredPacketList(); |
577 | 578 |
578 // 5 packets lost: 4 media packets and one FEC packet#2 lost. | 579 // 5 packets lost: 4 media packets and one FEC packet#2 lost. |
579 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 580 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
580 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 581 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
581 fec_loss_mask_[2] = 1; | 582 fec_loss_mask_[2] = 1; |
582 media_loss_mask_[0] = 1; | 583 media_loss_mask_[0] = 1; |
583 media_loss_mask_[1] = 1; | 584 media_loss_mask_[1] = 1; |
584 media_loss_mask_[2] = 1; | 585 media_loss_mask_[2] = 1; |
585 media_loss_mask_[3] = 1; | 586 media_loss_mask_[3] = 1; |
586 NetworkReceivedPackets(); | 587 NetworkReceivedPackets(); |
587 | 588 |
588 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 589 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
589 &recovered_packet_list_)); | 590 &recovered_packet_list_)); |
590 | 591 |
591 // Cannot get complete recovery for this loss configuration. | 592 // Cannot get complete recovery for this loss configuration. |
592 EXPECT_FALSE(IsRecoveryComplete()); | 593 EXPECT_FALSE(IsRecoveryComplete()); |
593 } | 594 } |
594 | 595 |
595 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { | 596 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { |
596 const int kNumImportantPackets = 0; | 597 const int kNumImportantPackets = 0; |
597 const bool kUseUnequalProtection = false; | 598 const bool kUseUnequalProtection = false; |
598 const int kNumMediaPackets = 5; | 599 const int kNumMediaPackets = 5; |
599 uint8_t kProtectionFactor = 60; | 600 uint8_t kProtectionFactor = 60; |
600 | 601 |
601 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 602 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
602 | 603 |
603 // Create a new temporary packet list for generating FEC packets. | 604 // Create a new temporary packet list for generating FEC packets. |
604 // This list should have every other packet removed. | 605 // This list should have every other packet removed. |
605 PacketList protected_media_packets; | 606 PacketList protected_media_packets; |
606 int i = 0; | 607 int i = 0; |
607 for (PacketList::iterator it = media_packet_list_.begin(); | 608 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
608 it != media_packet_list_.end(); ++it, ++i) { | 609 ++it, ++i) { |
609 if (i % 2 == 0) protected_media_packets.push_back(*it); | 610 if (i % 2 == 0) protected_media_packets.push_back(*it); |
610 } | 611 } |
611 | 612 |
612 EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, | 613 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
613 kNumImportantPackets, kUseUnequalProtection, | 614 kNumImportantPackets, kUseUnequalProtection, |
614 webrtc::kFecMaskBursty, &fec_packet_list_)); | 615 webrtc::kFecMaskBursty, &fec_packet_list_)); |
615 | 616 |
616 // Expect 1 FEC packet. | 617 // Expect 1 FEC packet. |
617 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 618 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
618 | 619 |
619 // 1 protected media packet lost | 620 // 1 protected media packet lost |
620 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 621 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
621 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 622 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
622 media_loss_mask_[2] = 1; | 623 media_loss_mask_[2] = 1; |
623 NetworkReceivedPackets(); | 624 NetworkReceivedPackets(); |
624 | 625 |
625 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 626 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
626 &recovered_packet_list_)); | 627 &recovered_packet_list_)); |
627 | 628 |
628 // One packet lost, one FEC packet, expect complete recovery. | 629 // One packet lost, one FEC packet, expect complete recovery. |
629 EXPECT_TRUE(IsRecoveryComplete()); | 630 EXPECT_TRUE(IsRecoveryComplete()); |
630 FreeRecoveredPacketList(); | 631 FreeRecoveredPacketList(); |
631 | 632 |
632 // Unprotected packet lost. | 633 // Unprotected packet lost. |
633 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 634 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
634 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 635 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
635 media_loss_mask_[1] = 1; | 636 media_loss_mask_[1] = 1; |
636 NetworkReceivedPackets(); | 637 NetworkReceivedPackets(); |
637 | 638 |
638 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 639 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
639 &recovered_packet_list_)); | 640 &recovered_packet_list_)); |
640 | 641 |
641 // Unprotected packet lost. Recovery not possible. | 642 // Unprotected packet lost. Recovery not possible. |
642 EXPECT_FALSE(IsRecoveryComplete()); | 643 EXPECT_FALSE(IsRecoveryComplete()); |
643 FreeRecoveredPacketList(); | 644 FreeRecoveredPacketList(); |
644 | 645 |
645 // 2 media packets lost. | 646 // 2 media packets lost. |
646 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 647 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
647 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 648 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
648 media_loss_mask_[0] = 1; | 649 media_loss_mask_[0] = 1; |
649 media_loss_mask_[2] = 1; | 650 media_loss_mask_[2] = 1; |
650 NetworkReceivedPackets(); | 651 NetworkReceivedPackets(); |
651 | 652 |
652 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 653 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
653 &recovered_packet_list_)); | 654 &recovered_packet_list_)); |
654 | 655 |
655 // 2 protected packets lost, one FEC packet, cannot get complete recovery. | 656 // 2 protected packets lost, one FEC packet, cannot get complete recovery. |
656 EXPECT_FALSE(IsRecoveryComplete()); | 657 EXPECT_FALSE(IsRecoveryComplete()); |
657 } | 658 } |
658 | 659 |
659 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { | 660 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { |
660 const int kNumImportantPackets = 0; | 661 const int kNumImportantPackets = 0; |
661 const bool kUseUnequalProtection = false; | 662 const bool kUseUnequalProtection = false; |
662 const int kNumMediaPackets = 21; | 663 const int kNumMediaPackets = 21; |
663 uint8_t kProtectionFactor = 127; | 664 uint8_t kProtectionFactor = 127; |
664 | 665 |
665 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 666 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
666 | 667 |
667 // Create a new temporary packet list for generating FEC packets. | 668 // Create a new temporary packet list for generating FEC packets. |
668 // This list should have every other packet removed. | 669 // This list should have every other packet removed. |
669 PacketList protected_media_packets; | 670 PacketList protected_media_packets; |
670 int i = 0; | 671 int i = 0; |
671 for (PacketList::iterator it = media_packet_list_.begin(); | 672 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
672 it != media_packet_list_.end(); ++it, ++i) { | 673 ++it, ++i) { |
673 if (i % 2 == 0) protected_media_packets.push_back(*it); | 674 if (i % 2 == 0) protected_media_packets.push_back(*it); |
674 } | 675 } |
675 | 676 |
676 // Zero column insertion will have to extend the size of the packet | 677 // Zero column insertion will have to extend the size of the packet |
677 // mask since the number of actual packets are 21, while the number | 678 // mask since the number of actual packets are 21, while the number |
678 // of protected packets are 11. | 679 // of protected packets are 11. |
679 EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, | 680 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
680 kNumImportantPackets, kUseUnequalProtection, | 681 kNumImportantPackets, kUseUnequalProtection, |
681 webrtc::kFecMaskBursty, &fec_packet_list_)); | 682 webrtc::kFecMaskBursty, &fec_packet_list_)); |
682 | 683 |
683 // Expect 5 FEC packet. | 684 // Expect 5 FEC packet. |
684 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 685 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
685 | 686 |
686 // Last protected media packet lost | 687 // Last protected media packet lost |
687 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 688 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
688 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 689 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
689 media_loss_mask_[kNumMediaPackets - 1] = 1; | 690 media_loss_mask_[kNumMediaPackets - 1] = 1; |
690 NetworkReceivedPackets(); | 691 NetworkReceivedPackets(); |
691 | 692 |
692 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 693 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
693 &recovered_packet_list_)); | 694 &recovered_packet_list_)); |
694 | 695 |
695 // One packet lost, one FEC packet, expect complete recovery. | 696 // One packet lost, one FEC packet, expect complete recovery. |
696 EXPECT_TRUE(IsRecoveryComplete()); | 697 EXPECT_TRUE(IsRecoveryComplete()); |
697 FreeRecoveredPacketList(); | 698 FreeRecoveredPacketList(); |
698 | 699 |
699 // Last unprotected packet lost. | 700 // Last unprotected packet lost. |
700 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 701 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
701 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 702 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
702 media_loss_mask_[kNumMediaPackets - 2] = 1; | 703 media_loss_mask_[kNumMediaPackets - 2] = 1; |
703 NetworkReceivedPackets(); | 704 NetworkReceivedPackets(); |
704 | 705 |
705 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 706 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
706 &recovered_packet_list_)); | 707 &recovered_packet_list_)); |
707 | 708 |
708 // Unprotected packet lost. Recovery not possible. | 709 // Unprotected packet lost. Recovery not possible. |
709 EXPECT_FALSE(IsRecoveryComplete()); | 710 EXPECT_FALSE(IsRecoveryComplete()); |
710 FreeRecoveredPacketList(); | 711 FreeRecoveredPacketList(); |
711 | 712 |
712 // 6 media packets lost. | 713 // 6 media packets lost. |
713 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 714 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
714 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 715 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
715 media_loss_mask_[kNumMediaPackets - 11] = 1; | 716 media_loss_mask_[kNumMediaPackets - 11] = 1; |
716 media_loss_mask_[kNumMediaPackets - 9] = 1; | 717 media_loss_mask_[kNumMediaPackets - 9] = 1; |
717 media_loss_mask_[kNumMediaPackets - 7] = 1; | 718 media_loss_mask_[kNumMediaPackets - 7] = 1; |
718 media_loss_mask_[kNumMediaPackets - 5] = 1; | 719 media_loss_mask_[kNumMediaPackets - 5] = 1; |
719 media_loss_mask_[kNumMediaPackets - 3] = 1; | 720 media_loss_mask_[kNumMediaPackets - 3] = 1; |
720 media_loss_mask_[kNumMediaPackets - 1] = 1; | 721 media_loss_mask_[kNumMediaPackets - 1] = 1; |
721 NetworkReceivedPackets(); | 722 NetworkReceivedPackets(); |
722 | 723 |
723 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 724 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
724 &recovered_packet_list_)); | 725 &recovered_packet_list_)); |
725 | 726 |
726 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 727 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
727 EXPECT_FALSE(IsRecoveryComplete()); | 728 EXPECT_FALSE(IsRecoveryComplete()); |
728 } | 729 } |
729 | 730 |
730 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { | 731 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { |
731 const int kNumImportantPackets = 0; | 732 const int kNumImportantPackets = 0; |
732 const bool kUseUnequalProtection = false; | 733 const bool kUseUnequalProtection = false; |
733 const int kNumMediaPackets = 21; | 734 const int kNumMediaPackets = 21; |
734 uint8_t kProtectionFactor = 127; | 735 uint8_t kProtectionFactor = 127; |
735 | 736 |
736 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); | 737 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); |
737 | 738 |
738 // Create a new temporary packet list for generating FEC packets. | 739 // Create a new temporary packet list for generating FEC packets. |
739 // This list should have every other packet removed. | 740 // This list should have every other packet removed. |
740 PacketList protected_media_packets; | 741 PacketList protected_media_packets; |
741 int i = 0; | 742 int i = 0; |
742 for (PacketList::iterator it = media_packet_list_.begin(); | 743 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
743 it != media_packet_list_.end(); ++it, ++i) { | 744 ++it, ++i) { |
744 if (i % 2 == 0) protected_media_packets.push_back(*it); | 745 if (i % 2 == 0) protected_media_packets.push_back(*it); |
745 } | 746 } |
746 | 747 |
747 // Zero column insertion will have to extend the size of the packet | 748 // Zero column insertion will have to extend the size of the packet |
748 // mask since the number of actual packets are 21, while the number | 749 // mask since the number of actual packets are 21, while the number |
749 // of protected packets are 11. | 750 // of protected packets are 11. |
750 EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, | 751 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
751 kNumImportantPackets, kUseUnequalProtection, | 752 kNumImportantPackets, kUseUnequalProtection, |
752 webrtc::kFecMaskBursty, &fec_packet_list_)); | 753 webrtc::kFecMaskBursty, &fec_packet_list_)); |
753 | 754 |
754 // Expect 5 FEC packet. | 755 // Expect 5 FEC packet. |
755 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 756 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
756 | 757 |
757 // Last protected media packet lost | 758 // Last protected media packet lost |
758 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 759 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
759 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 760 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
760 media_loss_mask_[kNumMediaPackets - 1] = 1; | 761 media_loss_mask_[kNumMediaPackets - 1] = 1; |
761 NetworkReceivedPackets(); | 762 NetworkReceivedPackets(); |
762 | 763 |
763 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 764 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
764 &recovered_packet_list_)); | 765 &recovered_packet_list_)); |
765 | 766 |
766 // One packet lost, one FEC packet, expect complete recovery. | 767 // One packet lost, one FEC packet, expect complete recovery. |
767 EXPECT_TRUE(IsRecoveryComplete()); | 768 EXPECT_TRUE(IsRecoveryComplete()); |
768 FreeRecoveredPacketList(); | 769 FreeRecoveredPacketList(); |
769 | 770 |
770 // Last unprotected packet lost. | 771 // Last unprotected packet lost. |
771 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 772 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
772 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 773 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
773 media_loss_mask_[kNumMediaPackets - 2] = 1; | 774 media_loss_mask_[kNumMediaPackets - 2] = 1; |
774 NetworkReceivedPackets(); | 775 NetworkReceivedPackets(); |
775 | 776 |
776 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 777 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
777 &recovered_packet_list_)); | 778 &recovered_packet_list_)); |
778 | 779 |
779 // Unprotected packet lost. Recovery not possible. | 780 // Unprotected packet lost. Recovery not possible. |
780 EXPECT_FALSE(IsRecoveryComplete()); | 781 EXPECT_FALSE(IsRecoveryComplete()); |
781 FreeRecoveredPacketList(); | 782 FreeRecoveredPacketList(); |
782 | 783 |
783 // 6 media packets lost. | 784 // 6 media packets lost. |
784 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 785 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
785 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 786 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
786 media_loss_mask_[kNumMediaPackets - 11] = 1; | 787 media_loss_mask_[kNumMediaPackets - 11] = 1; |
787 media_loss_mask_[kNumMediaPackets - 9] = 1; | 788 media_loss_mask_[kNumMediaPackets - 9] = 1; |
788 media_loss_mask_[kNumMediaPackets - 7] = 1; | 789 media_loss_mask_[kNumMediaPackets - 7] = 1; |
789 media_loss_mask_[kNumMediaPackets - 5] = 1; | 790 media_loss_mask_[kNumMediaPackets - 5] = 1; |
790 media_loss_mask_[kNumMediaPackets - 3] = 1; | 791 media_loss_mask_[kNumMediaPackets - 3] = 1; |
791 media_loss_mask_[kNumMediaPackets - 1] = 1; | 792 media_loss_mask_[kNumMediaPackets - 1] = 1; |
792 NetworkReceivedPackets(); | 793 NetworkReceivedPackets(); |
793 | 794 |
794 EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, | 795 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
795 &recovered_packet_list_)); | 796 &recovered_packet_list_)); |
796 | 797 |
797 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 798 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
798 EXPECT_FALSE(IsRecoveryComplete()); | 799 EXPECT_FALSE(IsRecoveryComplete()); |
799 } | 800 } |
800 | 801 |
801 void RtpFecTest::TearDown() { | 802 void RtpFecTest::TearDown() { |
802 fec_->ResetState(&recovered_packet_list_); | 803 fec_->ResetState(&recovered_packet_list_); |
803 delete fec_; | 804 delete fec_; |
804 FreeRecoveredPacketList(); | 805 FreeRecoveredPacketList(); |
805 ClearList(&media_packet_list_); | 806 ClearList(&media_packet_list_); |
806 EXPECT_TRUE(media_packet_list_.empty()); | 807 EXPECT_TRUE(media_packet_list_.empty()); |
807 } | 808 } |
808 | 809 |
809 void RtpFecTest::FreeRecoveredPacketList() { | 810 void RtpFecTest::FreeRecoveredPacketList() { |
810 ClearList(&recovered_packet_list_); | 811 ClearList(&recovered_packet_list_); |
811 } | 812 } |
812 | 813 |
813 bool RtpFecTest::IsRecoveryComplete() { | 814 bool RtpFecTest::IsRecoveryComplete() { |
814 // Check that the number of media and recovered packets are equal. | 815 // We must have equally many recovered packets as original packets. |
815 if (media_packet_list_.size() != recovered_packet_list_.size()) { | 816 if (recovered_packet_list_.size() != media_packet_list_.size()) { |
816 return false; | 817 return false; |
817 } | 818 } |
818 | 819 |
819 ForwardErrorCorrection::Packet* media_packet; | 820 // All recovered packets must be identical to the corresponding |
820 ForwardErrorCorrection::RecoveredPacket* recovered_packet; | 821 // original packets. |
821 | 822 auto cmp = [](ForwardErrorCorrection::Packet* media_packet, |
822 bool recovery = true; | 823 ForwardErrorCorrection::RecoveredPacket* recovered_packet) { |
823 | 824 if (media_packet->length != recovered_packet->pkt->length) { |
824 PacketList::iterator media_packet_list_item = media_packet_list_.begin(); | |
825 RecoveredPacketList::iterator recovered_packet_list_item = | |
826 recovered_packet_list_.begin(); | |
827 while (media_packet_list_item != media_packet_list_.end()) { | |
828 if (recovered_packet_list_item == recovered_packet_list_.end()) { | |
829 return false; | 825 return false; |
830 } | 826 } |
831 media_packet = *media_packet_list_item; | 827 if (memcmp(media_packet->data, |
832 recovered_packet = *recovered_packet_list_item; | 828 recovered_packet->pkt->data, |
833 if (recovered_packet->pkt->length != media_packet->length) { | |
834 return false; | |
835 } | |
836 if (memcmp(recovered_packet->pkt->data, media_packet->data, | |
837 media_packet->length) != 0) { | 829 media_packet->length) != 0) { |
838 return false; | 830 return false; |
839 } | 831 } |
840 media_packet_list_item++; | 832 return true; |
841 recovered_packet_list_item++; | 833 }; |
842 } | 834 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), |
843 return recovery; | 835 recovered_packet_list_.cbegin(), cmp); |
844 } | 836 } |
845 | 837 |
846 void RtpFecTest::NetworkReceivedPackets() { | 838 void RtpFecTest::NetworkReceivedPackets() { |
847 const bool kFecPacket = true; | 839 const bool kFecPacket = true; |
848 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); | 840 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); |
849 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); | 841 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); |
850 } | 842 } |
851 | 843 |
852 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 844 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, |
853 bool is_fec) { | 845 bool is_fec) { |
854 ForwardErrorCorrection::Packet* packet; | |
855 ForwardErrorCorrection::ReceivedPacket* received_packet; | |
856 int seq_num = fec_seq_num_; | 846 int seq_num = fec_seq_num_; |
857 int packet_idx = 0; | 847 int packet_idx = 0; |
858 | 848 |
859 PacketList::const_iterator packet_list_item = packet_list.begin(); | 849 for (const auto* packet : packet_list) { |
860 | |
861 while (packet_list_item != packet_list.end()) { | |
862 packet = *packet_list_item; | |
863 if (loss_mask[packet_idx] == 0) { | 850 if (loss_mask[packet_idx] == 0) { |
864 received_packet = new ForwardErrorCorrection::ReceivedPacket; | 851 auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); |
865 received_packet->pkt = new ForwardErrorCorrection::Packet; | 852 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
866 received_packet_list_.push_back(received_packet); | 853 received_packet_list_.push_back(received_packet); |
867 received_packet->pkt->length = packet->length; | 854 received_packet->pkt->length = packet->length; |
868 memcpy(received_packet->pkt->data, packet->data, packet->length); | 855 memcpy(received_packet->pkt->data, packet->data, packet->length); |
869 received_packet->is_fec = is_fec; | 856 received_packet->is_fec = is_fec; |
870 if (!is_fec) { | 857 if (!is_fec) { |
871 // For media packets, the sequence number and marker bit is | 858 // For media packets, the sequence number and marker bit is |
872 // obtained from RTP header. These were set in ConstructMediaPackets(). | 859 // obtained from RTP header. These were set in ConstructMediaPackets(). |
873 received_packet->seq_num = | 860 received_packet->seq_num = |
874 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); | 861 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); |
875 } else { | 862 } else { |
876 // The sequence number, marker bit, and ssrc number are defined in the | 863 // The sequence number, marker bit, and ssrc number are defined in the |
877 // RTP header of the FEC packet, which is not constructed in this test. | 864 // RTP header of the FEC packet, which is not constructed in this test. |
878 // So we set these values below based on the values generated in | 865 // So we set these values below based on the values generated in |
879 // ConstructMediaPackets(). | 866 // ConstructMediaPackets(). |
880 received_packet->seq_num = seq_num; | 867 received_packet->seq_num = seq_num; |
881 // The ssrc value for FEC packets is set to the one used for the | 868 // The ssrc value for FEC packets is set to the one used for the |
882 // media packets in ConstructMediaPackets(). | 869 // media packets in ConstructMediaPackets(). |
883 received_packet->ssrc = ssrc_; | 870 received_packet->ssrc = ssrc_; |
884 } | 871 } |
885 } | 872 } |
886 packet_idx++; | 873 packet_idx++; |
887 packet_list_item++; | |
888 // Sequence number of FEC packets are defined as increment by 1 from | 874 // Sequence number of FEC packets are defined as increment by 1 from |
889 // last media packet in frame. | 875 // last media packet in frame. |
890 if (is_fec) seq_num++; | 876 if (is_fec) seq_num++; |
891 } | 877 } |
892 } | 878 } |
893 | 879 |
894 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, | 880 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, |
895 int start_seq_num) { | 881 int start_seq_num) { |
896 assert(num_media_packets > 0); | 882 RTC_DCHECK_GT(num_media_packets, 0); |
897 ForwardErrorCorrection::Packet* media_packet = NULL; | 883 ForwardErrorCorrection::Packet* media_packet = NULL; |
898 int sequence_number = start_seq_num; | 884 int sequence_number = start_seq_num; |
899 int time_stamp = random_.Rand<int>(); | 885 int time_stamp = random_.Rand<int>(); |
900 | 886 |
901 for (int i = 0; i < num_media_packets; ++i) { | 887 for (int i = 0; i < num_media_packets; ++i) { |
902 media_packet = new ForwardErrorCorrection::Packet; | 888 media_packet = new ForwardErrorCorrection::Packet(); |
903 media_packet_list_.push_back(media_packet); | 889 media_packet_list_.push_back(media_packet); |
904 const uint32_t kMinPacketSize = kRtpHeaderSize; | 890 const uint32_t kMinPacketSize = kRtpHeaderSize; |
905 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - | 891 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - |
906 kTransportOverhead - | 892 kTransportOverhead - |
907 ForwardErrorCorrection::PacketOverhead(); | 893 ForwardErrorCorrection::PacketOverhead(); |
908 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); | 894 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); |
909 | 895 |
910 // Generate random values for the first 2 bytes | 896 // Generate random values for the first 2 bytes |
911 media_packet->data[0] = random_.Rand<uint8_t>(); | 897 media_packet->data[0] = random_.Rand<uint8_t>(); |
912 media_packet->data[1] = random_.Rand<uint8_t>(); | 898 media_packet->data[1] = random_.Rand<uint8_t>(); |
(...skipping 17 matching lines...) Expand all Loading... |
930 time_stamp); | 916 time_stamp); |
931 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); | 917 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); |
932 | 918 |
933 // Generate random values for payload. | 919 // Generate random values for payload. |
934 for (size_t j = 12; j < media_packet->length; ++j) { | 920 for (size_t j = 12; j < media_packet->length; ++j) { |
935 media_packet->data[j] = random_.Rand<uint8_t>(); | 921 media_packet->data[j] = random_.Rand<uint8_t>(); |
936 } | 922 } |
937 sequence_number++; | 923 sequence_number++; |
938 } | 924 } |
939 // Last packet, set marker bit. | 925 // Last packet, set marker bit. |
940 assert(media_packet != NULL); | 926 RTC_DCHECK(media_packet); |
941 media_packet->data[1] |= 0x80; | 927 media_packet->data[1] |= 0x80; |
942 return sequence_number; | 928 return sequence_number; |
943 } | 929 } |
944 | 930 |
945 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { | 931 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { |
946 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); | 932 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); |
947 } | 933 } |
OLD | NEW |