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 |
(...skipping 27 matching lines...) Expand all Loading... |
38 constexpr uint32_t kMediaSsrc = 835424; | 38 constexpr uint32_t kMediaSsrc = 835424; |
39 } // namespace | 39 } // namespace |
40 | 40 |
41 class ReceiverFecTest : public ::testing::Test { | 41 class ReceiverFecTest : public ::testing::Test { |
42 protected: | 42 protected: |
43 ReceiverFecTest() | 43 ReceiverFecTest() |
44 : fec_(ForwardErrorCorrection::CreateUlpfec()), | 44 : fec_(ForwardErrorCorrection::CreateUlpfec()), |
45 receiver_fec_(FecReceiver::Create(&rtp_data_callback_)), | 45 receiver_fec_(FecReceiver::Create(&rtp_data_callback_)), |
46 packet_generator_(kMediaSsrc) {} | 46 packet_generator_(kMediaSsrc) {} |
47 | 47 |
| 48 // Generates |num_fec_packets| FEC packets, given |media_packets|. |
48 void EncodeFec(const ForwardErrorCorrection::PacketList& media_packets, | 49 void EncodeFec(const ForwardErrorCorrection::PacketList& media_packets, |
49 size_t num_fec_packets, | 50 size_t num_fec_packets, |
50 std::list<ForwardErrorCorrection::Packet*>* fec_packets) { | 51 std::list<ForwardErrorCorrection::Packet*>* fec_packets); |
51 uint8_t protection_factor = num_fec_packets * 255 / media_packets.size(); | |
52 EXPECT_EQ(0, fec_->EncodeFec(media_packets, protection_factor, 0, false, | |
53 kFecMaskBursty, fec_packets)); | |
54 ASSERT_EQ(num_fec_packets, fec_packets->size()); | |
55 } | |
56 | 52 |
57 void GenerateFrame(size_t num_media_packets, | 53 // Generates |num_media_packets| corresponding to a single frame. |
58 size_t frame_offset, | 54 void PacketizeFrame(size_t num_media_packets, |
59 std::list<AugmentedPacket*>* augmented_packets, | 55 size_t frame_offset, |
60 ForwardErrorCorrection::PacketList* media_packets) { | 56 std::list<AugmentedPacket*>* augmented_packets, |
61 packet_generator_.NewFrame(num_media_packets); | 57 ForwardErrorCorrection::PacketList* packets); |
62 for (size_t i = 0; i < num_media_packets; ++i) { | |
63 std::unique_ptr<AugmentedPacket> next_packet( | |
64 packet_generator_.NextPacket(frame_offset + i, kRtpHeaderSize + 10)); | |
65 augmented_packets->push_back(next_packet.get()); | |
66 media_packets->push_back(std::move(next_packet)); | |
67 } | |
68 } | |
69 | 58 |
| 59 // Build a media packet using |packet_generator_| and add it |
| 60 // to the receiver. |
| 61 void BuildAndAddRedMediaPacket(AugmentedPacket* packet); |
| 62 |
| 63 // Build a FEC packet using |packet_generator_| and add it |
| 64 // to the receiver. |
| 65 void BuildAndAddRedFecPacket(Packet* packet); |
| 66 |
| 67 // Ensure that |rtp_data_callback_| will be called correctly |
| 68 // and that the recovered packet will be identical to the lost packet. |
70 void VerifyReconstructedMediaPacket(const AugmentedPacket& packet, | 69 void VerifyReconstructedMediaPacket(const AugmentedPacket& packet, |
71 size_t times) { | 70 size_t times); |
72 // Verify that the content of the reconstructed packet is equal to the | |
73 // content of |packet|, and that the same content is received |times| number | |
74 // of times in a row. | |
75 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet.length)) | |
76 .With(Args<0, 1>(ElementsAreArray(packet.data, packet.length))) | |
77 .Times(times) | |
78 .WillRepeatedly(Return(true)); | |
79 } | |
80 | |
81 void BuildAndAddRedMediaPacket(AugmentedPacket* packet) { | |
82 std::unique_ptr<AugmentedPacket> red_packet( | |
83 UlpfecPacketGenerator::BuildMediaRedPacket(*packet)); | |
84 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | |
85 red_packet->header.header, red_packet->data, | |
86 red_packet->length, kFecPayloadType)); | |
87 } | |
88 | |
89 void BuildAndAddRedFecPacket(Packet* packet) { | |
90 std::unique_ptr<AugmentedPacket> red_packet( | |
91 packet_generator_.BuildUlpfecRedPacket(*packet)); | |
92 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | |
93 red_packet->header.header, red_packet->data, | |
94 red_packet->length, kFecPayloadType)); | |
95 } | |
96 | 71 |
97 void InjectGarbagePacketLength(size_t fec_garbage_offset); | 72 void InjectGarbagePacketLength(size_t fec_garbage_offset); |
| 73 |
98 static void SurvivesMaliciousPacket(const uint8_t* data, | 74 static void SurvivesMaliciousPacket(const uint8_t* data, |
99 size_t length, | 75 size_t length, |
100 uint8_t ulpfec_payload_type); | 76 uint8_t ulpfec_payload_type); |
101 | 77 |
102 MockRtpData rtp_data_callback_; | 78 MockRtpData rtp_data_callback_; |
103 std::unique_ptr<ForwardErrorCorrection> fec_; | 79 std::unique_ptr<ForwardErrorCorrection> fec_; |
104 std::unique_ptr<FecReceiver> receiver_fec_; | 80 std::unique_ptr<FecReceiver> receiver_fec_; |
105 UlpfecPacketGenerator packet_generator_; | 81 UlpfecPacketGenerator packet_generator_; |
106 }; | 82 }; |
107 | 83 |
108 TEST_F(ReceiverFecTest, TwoMediaOneFec) { | 84 void ReceiverFecTest::EncodeFec( |
109 const size_t kNumFecPackets = 1; | 85 const ForwardErrorCorrection::PacketList& media_packets, |
110 std::list<AugmentedPacket*> augmented_media_packets; | 86 size_t num_fec_packets, |
111 ForwardErrorCorrection::PacketList media_packets; | 87 std::list<ForwardErrorCorrection::Packet*>* fec_packets) { |
112 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 88 const uint8_t protection_factor = |
113 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 89 num_fec_packets * 255 / media_packets.size(); |
114 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 90 // Unequal protection is turned off, and the number of important |
| 91 // packets is thus irrelevant. |
| 92 constexpr int kNumImportantPackets = 0; |
| 93 constexpr bool kUseUnequalProtection = false; |
| 94 constexpr FecMaskType kFecMaskType = kFecMaskBursty; |
| 95 EXPECT_EQ( |
| 96 0, fec_->EncodeFec(media_packets, protection_factor, kNumImportantPackets, |
| 97 kUseUnequalProtection, kFecMaskType, fec_packets)); |
| 98 ASSERT_EQ(num_fec_packets, fec_packets->size()); |
| 99 } |
115 | 100 |
116 // Recovery | 101 void ReceiverFecTest::PacketizeFrame( |
117 auto it = augmented_media_packets.begin(); | 102 size_t num_media_packets, |
118 BuildAndAddRedMediaPacket(*it); | 103 size_t frame_offset, |
119 VerifyReconstructedMediaPacket(**it, 1); | 104 std::list<AugmentedPacket*>* augmented_packets, |
120 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 105 ForwardErrorCorrection::PacketList* packets) { |
121 // Drop one media packet. | 106 packet_generator_.NewFrame(num_media_packets); |
122 auto fec_it = fec_packets.begin(); | 107 for (size_t i = 0; i < num_media_packets; ++i) { |
123 BuildAndAddRedFecPacket(*fec_it); | 108 std::unique_ptr<AugmentedPacket> next_packet( |
124 ++it; | 109 packet_generator_.NextPacket(frame_offset + i, kRtpHeaderSize + 10)); |
125 VerifyReconstructedMediaPacket(**it, 1); | 110 augmented_packets->push_back(next_packet.get()); |
126 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 111 packets->push_back(std::move(next_packet)); |
| 112 } |
| 113 } |
127 | 114 |
128 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 115 void ReceiverFecTest::BuildAndAddRedMediaPacket(AugmentedPacket* packet) { |
129 EXPECT_EQ(2U, counter.num_packets); | 116 std::unique_ptr<AugmentedPacket> red_packet( |
130 EXPECT_EQ(1U, counter.num_fec_packets); | 117 packet_generator_.BuildMediaRedPacket(*packet)); |
131 EXPECT_EQ(1U, counter.num_recovered_packets); | 118 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( |
| 119 red_packet->header.header, red_packet->data, |
| 120 red_packet->length, kFecPayloadType)); |
| 121 } |
| 122 |
| 123 void ReceiverFecTest::BuildAndAddRedFecPacket(Packet* packet) { |
| 124 std::unique_ptr<AugmentedPacket> red_packet( |
| 125 packet_generator_.BuildUlpfecRedPacket(*packet)); |
| 126 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( |
| 127 red_packet->header.header, red_packet->data, |
| 128 red_packet->length, kFecPayloadType)); |
| 129 } |
| 130 |
| 131 void ReceiverFecTest::VerifyReconstructedMediaPacket( |
| 132 const AugmentedPacket& packet, |
| 133 size_t times) { |
| 134 // Verify that the content of the reconstructed packet is equal to the |
| 135 // content of |packet|, and that the same content is received |times| number |
| 136 // of times in a row. |
| 137 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet.length)) |
| 138 .With(Args<0, 1>(ElementsAreArray(packet.data, packet.length))) |
| 139 .Times(times) |
| 140 .WillRepeatedly(Return(true)); |
132 } | 141 } |
133 | 142 |
134 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { | 143 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { |
135 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 144 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
136 .WillRepeatedly(Return(true)); | 145 .WillRepeatedly(Return(true)); |
137 | 146 |
138 const size_t kNumFecPackets = 1; | 147 const size_t kNumFecPackets = 1; |
139 std::list<AugmentedPacket*> augmented_media_packets; | 148 std::list<AugmentedPacket*> augmented_media_packets; |
140 ForwardErrorCorrection::PacketList media_packets; | 149 ForwardErrorCorrection::PacketList media_packets; |
141 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 150 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); |
142 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 151 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
143 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 152 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
144 ByteWriter<uint16_t>::WriteBigEndian( | 153 ByteWriter<uint16_t>::WriteBigEndian( |
145 &fec_packets.front()->data[fec_garbage_offset], 0x4711); | 154 &fec_packets.front()->data[fec_garbage_offset], 0x4711); |
146 | 155 |
147 // Inject first media packet, then first FEC packet, skipping the second media | 156 // Inject first media packet, then first FEC packet, skipping the second media |
148 // packet to cause a recovery from the FEC packet. | 157 // packet to cause a recovery from the FEC packet. |
149 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 158 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
150 BuildAndAddRedFecPacket(fec_packets.front()); | 159 BuildAndAddRedFecPacket(fec_packets.front()); |
151 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 160 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
152 | 161 |
153 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 162 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
154 EXPECT_EQ(2U, counter.num_packets); | 163 EXPECT_EQ(2U, counter.num_packets); |
155 EXPECT_EQ(1U, counter.num_fec_packets); | 164 EXPECT_EQ(1U, counter.num_fec_packets); |
156 EXPECT_EQ(0U, counter.num_recovered_packets); | 165 EXPECT_EQ(0U, counter.num_recovered_packets); |
157 } | 166 } |
158 | 167 |
| 168 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, |
| 169 size_t length, |
| 170 uint8_t ulpfec_payload_type) { |
| 171 webrtc::RTPHeader header; |
| 172 std::unique_ptr<webrtc::RtpHeaderParser> parser( |
| 173 webrtc::RtpHeaderParser::Create()); |
| 174 ASSERT_TRUE(parser->Parse(data, length, &header)); |
| 175 |
| 176 webrtc::NullRtpData null_callback; |
| 177 std::unique_ptr<webrtc::FecReceiver> receiver_fec( |
| 178 webrtc::FecReceiver::Create(&null_callback)); |
| 179 |
| 180 receiver_fec->AddReceivedRedPacket(header, data, length, ulpfec_payload_type); |
| 181 } |
| 182 |
| 183 TEST_F(ReceiverFecTest, TwoMediaOneFec) { |
| 184 constexpr size_t kNumFecPackets = 1u; |
| 185 std::list<AugmentedPacket*> augmented_media_packets; |
| 186 ForwardErrorCorrection::PacketList media_packets; |
| 187 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); |
| 188 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 189 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
| 190 |
| 191 // Recovery |
| 192 auto it = augmented_media_packets.begin(); |
| 193 BuildAndAddRedMediaPacket(*it); |
| 194 VerifyReconstructedMediaPacket(**it, 1); |
| 195 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 196 // Drop one media packet. |
| 197 auto fec_it = fec_packets.begin(); |
| 198 BuildAndAddRedFecPacket(*fec_it); |
| 199 ++it; |
| 200 VerifyReconstructedMediaPacket(**it, 1); |
| 201 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 202 |
| 203 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
| 204 EXPECT_EQ(2u, counter.num_packets); |
| 205 EXPECT_EQ(1u, counter.num_fec_packets); |
| 206 EXPECT_EQ(1u, counter.num_recovered_packets); |
| 207 } |
| 208 |
159 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { | 209 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { |
160 // Byte offset 8 is the 'length recovery' field of the FEC header. | 210 // Byte offset 8 is the 'length recovery' field of the FEC header. |
161 InjectGarbagePacketLength(8); | 211 InjectGarbagePacketLength(8); |
162 } | 212 } |
163 | 213 |
164 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { | 214 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { |
165 // Byte offset 10 is the 'protection length' field in the first FEC level | 215 // Byte offset 10 is the 'protection length' field in the first FEC level |
166 // header. | 216 // header. |
167 InjectGarbagePacketLength(10); | 217 InjectGarbagePacketLength(10); |
168 } | 218 } |
169 | 219 |
170 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { | 220 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { |
171 const size_t kNumFecPackets = 2; | 221 const size_t kNumFecPackets = 2; |
172 std::list<AugmentedPacket*> augmented_media_packets; | 222 std::list<AugmentedPacket*> augmented_media_packets; |
173 ForwardErrorCorrection::PacketList media_packets; | 223 ForwardErrorCorrection::PacketList media_packets; |
174 GenerateFrame(2, 0, &augmented_media_packets, &media_packets); | 224 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); |
175 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 225 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
176 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 226 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
177 | 227 |
178 // Recovery | 228 // Recovery |
179 // Drop both media packets. | 229 // Drop both media packets. |
180 auto it = augmented_media_packets.begin(); | 230 auto it = augmented_media_packets.begin(); |
181 auto fec_it = fec_packets.begin(); | 231 auto fec_it = fec_packets.begin(); |
182 BuildAndAddRedFecPacket(*fec_it); | 232 BuildAndAddRedFecPacket(*fec_it); |
183 VerifyReconstructedMediaPacket(**it, 1); | 233 VerifyReconstructedMediaPacket(**it, 1); |
184 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 234 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
185 ++fec_it; | 235 ++fec_it; |
186 BuildAndAddRedFecPacket(*fec_it); | 236 BuildAndAddRedFecPacket(*fec_it); |
187 ++it; | 237 ++it; |
188 VerifyReconstructedMediaPacket(**it, 1); | 238 VerifyReconstructedMediaPacket(**it, 1); |
189 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 239 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
190 } | 240 } |
191 | 241 |
192 TEST_F(ReceiverFecTest, TwoFramesOneFec) { | 242 TEST_F(ReceiverFecTest, TwoFramesOneFec) { |
193 const size_t kNumFecPackets = 1; | 243 const size_t kNumFecPackets = 1; |
194 std::list<AugmentedPacket*> augmented_media_packets; | 244 std::list<AugmentedPacket*> augmented_media_packets; |
195 ForwardErrorCorrection::PacketList media_packets; | 245 ForwardErrorCorrection::PacketList media_packets; |
196 GenerateFrame(1, 0, &augmented_media_packets, &media_packets); | 246 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); |
197 GenerateFrame(1, 1, &augmented_media_packets, &media_packets); | 247 PacketizeFrame(1, 1, &augmented_media_packets, &media_packets); |
198 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 248 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
199 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 249 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
200 | 250 |
201 // Recovery | 251 // Recovery |
202 auto it = augmented_media_packets.begin(); | 252 auto it = augmented_media_packets.begin(); |
203 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 253 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
204 VerifyReconstructedMediaPacket(**it, 1); | 254 VerifyReconstructedMediaPacket(**it, 1); |
205 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 255 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
206 // Drop one media packet. | 256 // Drop one media packet. |
207 BuildAndAddRedFecPacket(fec_packets.front()); | 257 BuildAndAddRedFecPacket(fec_packets.front()); |
208 ++it; | 258 ++it; |
209 VerifyReconstructedMediaPacket(**it, 1); | 259 VerifyReconstructedMediaPacket(**it, 1); |
210 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 260 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
211 } | 261 } |
212 | 262 |
213 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { | 263 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { |
214 const size_t kNumFecPackets = 1; | 264 const size_t kNumFecPackets = 1; |
215 std::list<AugmentedPacket*> augmented_media_packets; | 265 std::list<AugmentedPacket*> augmented_media_packets; |
216 ForwardErrorCorrection::PacketList media_packets; | 266 ForwardErrorCorrection::PacketList media_packets; |
217 GenerateFrame(1, 0, &augmented_media_packets, &media_packets); | 267 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); |
218 GenerateFrame(2, 1, &augmented_media_packets, &media_packets); | 268 PacketizeFrame(2, 1, &augmented_media_packets, &media_packets); |
219 | 269 |
220 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 270 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
221 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 271 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
222 | 272 |
223 // Recovery | 273 // Recovery |
224 auto it = augmented_media_packets.begin(); | 274 auto it = augmented_media_packets.begin(); |
225 BuildAndAddRedMediaPacket(*it); // First frame: one packet. | 275 BuildAndAddRedMediaPacket(*it); // First frame: one packet. |
226 VerifyReconstructedMediaPacket(**it, 1); | 276 VerifyReconstructedMediaPacket(**it, 1); |
227 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 277 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
228 ++it; | 278 ++it; |
229 BuildAndAddRedMediaPacket(*it); // First packet of second frame. | 279 BuildAndAddRedMediaPacket(*it); // First packet of second frame. |
230 VerifyReconstructedMediaPacket(**it, 1); | 280 VerifyReconstructedMediaPacket(**it, 1); |
231 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 281 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
232 } | 282 } |
233 | 283 |
234 TEST_F(ReceiverFecTest, MaxFramesOneFec) { | 284 TEST_F(ReceiverFecTest, MaxFramesOneFec) { |
235 const size_t kNumFecPackets = 1; | 285 const size_t kNumFecPackets = 1; |
236 const size_t kNumMediaPackets = 48; | 286 const size_t kNumMediaPackets = 48; |
237 std::list<AugmentedPacket*> augmented_media_packets; | 287 std::list<AugmentedPacket*> augmented_media_packets; |
238 ForwardErrorCorrection::PacketList media_packets; | 288 ForwardErrorCorrection::PacketList media_packets; |
239 for (size_t i = 0; i < kNumMediaPackets; ++i) { | 289 for (size_t i = 0; i < kNumMediaPackets; ++i) { |
240 GenerateFrame(1, i, &augmented_media_packets, &media_packets); | 290 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); |
241 } | 291 } |
242 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 292 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
243 EncodeFec(media_packets, kNumFecPackets, &fec_packets); | 293 EncodeFec(media_packets, kNumFecPackets, &fec_packets); |
244 | 294 |
245 // Recovery | 295 // Recovery |
246 auto it = augmented_media_packets.begin(); | 296 auto it = augmented_media_packets.begin(); |
247 ++it; // Drop first packet. | 297 ++it; // Drop first packet. |
248 for (; it != augmented_media_packets.end(); ++it) { | 298 for (; it != augmented_media_packets.end(); ++it) { |
249 BuildAndAddRedMediaPacket(*it); | 299 BuildAndAddRedMediaPacket(*it); |
250 VerifyReconstructedMediaPacket(**it, 1); | 300 VerifyReconstructedMediaPacket(**it, 1); |
251 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 301 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
252 } | 302 } |
253 BuildAndAddRedFecPacket(fec_packets.front()); | 303 BuildAndAddRedFecPacket(fec_packets.front()); |
254 it = augmented_media_packets.begin(); | 304 it = augmented_media_packets.begin(); |
255 VerifyReconstructedMediaPacket(**it, 1); | 305 VerifyReconstructedMediaPacket(**it, 1); |
256 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 306 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
257 } | 307 } |
258 | 308 |
259 TEST_F(ReceiverFecTest, TooManyFrames) { | 309 TEST_F(ReceiverFecTest, TooManyFrames) { |
260 const size_t kNumFecPackets = 1; | 310 const size_t kNumFecPackets = 1; |
261 const size_t kNumMediaPackets = 49; | 311 const size_t kNumMediaPackets = 49; |
262 std::list<AugmentedPacket*> augmented_media_packets; | 312 std::list<AugmentedPacket*> augmented_media_packets; |
263 ForwardErrorCorrection::PacketList media_packets; | 313 ForwardErrorCorrection::PacketList media_packets; |
264 for (size_t i = 0; i < kNumMediaPackets; ++i) { | 314 for (size_t i = 0; i < kNumMediaPackets; ++i) { |
265 GenerateFrame(1, i, &augmented_media_packets, &media_packets); | 315 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); |
266 } | 316 } |
267 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 317 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
268 EXPECT_EQ(-1, fec_->EncodeFec(media_packets, | 318 EXPECT_EQ(-1, fec_->EncodeFec(media_packets, |
269 kNumFecPackets * 255 / kNumMediaPackets, 0, | 319 kNumFecPackets * 255 / kNumMediaPackets, 0, |
270 false, kFecMaskBursty, &fec_packets)); | 320 false, kFecMaskBursty, &fec_packets)); |
271 } | 321 } |
272 | 322 |
273 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { | 323 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { |
274 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 324 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
275 // Delay the FEC packet. | 325 // Delay the FEC packet. |
276 Packet* delayed_fec = nullptr; | 326 Packet* delayed_fec = nullptr; |
277 const size_t kNumFecPacketsBatch1 = 1; | 327 const size_t kNumFecPacketsBatch1 = 1; |
278 const size_t kNumMediaPacketsBatch1 = 2; | 328 const size_t kNumMediaPacketsBatch1 = 2; |
279 std::list<AugmentedPacket*> augmented_media_packets_batch1; | 329 std::list<AugmentedPacket*> augmented_media_packets_batch1; |
280 ForwardErrorCorrection::PacketList media_packets_batch1; | 330 ForwardErrorCorrection::PacketList media_packets_batch1; |
281 GenerateFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, | 331 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, |
282 &media_packets_batch1); | 332 &media_packets_batch1); |
283 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 333 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
284 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); | 334 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); |
285 | 335 |
286 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); | 336 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); |
287 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 337 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
288 .Times(1).WillRepeatedly(Return(true)); | 338 .Times(1).WillRepeatedly(Return(true)); |
289 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 339 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
290 delayed_fec = fec_packets.front(); | 340 delayed_fec = fec_packets.front(); |
291 | 341 |
292 // Fill the FEC decoder. No packets should be dropped. | 342 // Fill the FEC decoder. No packets should be dropped. |
293 const size_t kNumMediaPacketsBatch2 = 46; | 343 const size_t kNumMediaPacketsBatch2 = 46; |
294 std::list<AugmentedPacket*> augmented_media_packets_batch2; | 344 std::list<AugmentedPacket*> augmented_media_packets_batch2; |
295 ForwardErrorCorrection::PacketList media_packets_batch2; | 345 ForwardErrorCorrection::PacketList media_packets_batch2; |
296 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { | 346 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { |
297 GenerateFrame(1, i, &augmented_media_packets_batch2, &media_packets_batch2); | 347 PacketizeFrame(1, i, &augmented_media_packets_batch2, |
| 348 &media_packets_batch2); |
298 } | 349 } |
299 for (auto it = augmented_media_packets_batch2.begin(); | 350 for (auto it = augmented_media_packets_batch2.begin(); |
300 it != augmented_media_packets_batch2.end(); ++it) { | 351 it != augmented_media_packets_batch2.end(); ++it) { |
301 BuildAndAddRedMediaPacket(*it); | 352 BuildAndAddRedMediaPacket(*it); |
302 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 353 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
303 .Times(1).WillRepeatedly(Return(true)); | 354 .Times(1).WillRepeatedly(Return(true)); |
304 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 355 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
305 } | 356 } |
306 | 357 |
307 // Add the delayed FEC packet. One packet should be reconstructed. | 358 // Add the delayed FEC packet. One packet should be reconstructed. |
308 BuildAndAddRedFecPacket(delayed_fec); | 359 BuildAndAddRedFecPacket(delayed_fec); |
309 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 360 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
310 .Times(1).WillRepeatedly(Return(true)); | 361 .Times(1).WillRepeatedly(Return(true)); |
311 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 362 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
312 } | 363 } |
313 | 364 |
314 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { | 365 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { |
315 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 366 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
316 // Delay the FEC packet. | 367 // Delay the FEC packet. |
317 Packet* delayed_fec = nullptr; | 368 Packet* delayed_fec = nullptr; |
318 const size_t kNumFecPacketsBatch1 = 1; | 369 const size_t kNumFecPacketsBatch1 = 1; |
319 const size_t kNumMediaPacketsBatch1 = 2; | 370 const size_t kNumMediaPacketsBatch1 = 2; |
320 std::list<AugmentedPacket*> augmented_media_packets_batch1; | 371 std::list<AugmentedPacket*> augmented_media_packets_batch1; |
321 ForwardErrorCorrection::PacketList media_packets_batch1; | 372 ForwardErrorCorrection::PacketList media_packets_batch1; |
322 GenerateFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, | 373 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, |
323 &media_packets_batch1); | 374 &media_packets_batch1); |
324 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 375 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
325 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); | 376 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); |
326 | 377 |
327 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); | 378 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); |
328 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 379 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
329 .Times(1).WillRepeatedly(Return(true)); | 380 .Times(1).WillRepeatedly(Return(true)); |
330 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 381 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
331 delayed_fec = fec_packets.front(); | 382 delayed_fec = fec_packets.front(); |
332 | 383 |
333 // Fill the FEC decoder and force the last packet to be dropped. | 384 // Fill the FEC decoder and force the last packet to be dropped. |
334 const size_t kNumMediaPacketsBatch2 = 48; | 385 const size_t kNumMediaPacketsBatch2 = 48; |
335 std::list<AugmentedPacket*> augmented_media_packets_batch2; | 386 std::list<AugmentedPacket*> augmented_media_packets_batch2; |
336 ForwardErrorCorrection::PacketList media_packets_batch2; | 387 ForwardErrorCorrection::PacketList media_packets_batch2; |
337 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { | 388 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { |
338 GenerateFrame(1, i, &augmented_media_packets_batch2, &media_packets_batch2); | 389 PacketizeFrame(1, i, &augmented_media_packets_batch2, |
| 390 &media_packets_batch2); |
339 } | 391 } |
340 for (auto it = augmented_media_packets_batch2.begin(); | 392 for (auto it = augmented_media_packets_batch2.begin(); |
341 it != augmented_media_packets_batch2.end(); ++it) { | 393 it != augmented_media_packets_batch2.end(); ++it) { |
342 BuildAndAddRedMediaPacket(*it); | 394 BuildAndAddRedMediaPacket(*it); |
343 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 395 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
344 .Times(1).WillRepeatedly(Return(true)); | 396 .Times(1).WillRepeatedly(Return(true)); |
345 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 397 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
346 } | 398 } |
347 | 399 |
348 // Add the delayed FEC packet. No packet should be reconstructed since the | 400 // Add the delayed FEC packet. No packet should be reconstructed since the |
349 // first media packet of that frame has been dropped due to being too old. | 401 // first media packet of that frame has been dropped due to being too old. |
350 BuildAndAddRedFecPacket(delayed_fec); | 402 BuildAndAddRedFecPacket(delayed_fec); |
351 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 403 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
352 .Times(0); | 404 .Times(0); |
353 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 405 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
354 } | 406 } |
355 | 407 |
356 TEST_F(ReceiverFecTest, OldFecPacketDropped) { | 408 TEST_F(ReceiverFecTest, OldFecPacketDropped) { |
357 // 49 frames with 2 media packets and one FEC packet. All media packets | 409 // 49 frames with 2 media packets and one FEC packet. All media packets |
358 // missing. | 410 // missing. |
359 const size_t kNumMediaPackets = 49 * 2; | 411 const size_t kNumMediaPackets = 49 * 2; |
360 std::list<AugmentedPacket*> augmented_media_packets; | 412 std::list<AugmentedPacket*> augmented_media_packets; |
361 ForwardErrorCorrection::PacketList media_packets; | 413 ForwardErrorCorrection::PacketList media_packets; |
362 for (size_t i = 0; i < kNumMediaPackets / 2; ++i) { | 414 for (size_t i = 0; i < kNumMediaPackets / 2; ++i) { |
363 std::list<AugmentedPacket*> frame_augmented_media_packets; | 415 std::list<AugmentedPacket*> frame_augmented_media_packets; |
364 ForwardErrorCorrection::PacketList frame_media_packets; | 416 ForwardErrorCorrection::PacketList frame_media_packets; |
365 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 417 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
366 GenerateFrame(2, 0, &frame_augmented_media_packets, &frame_media_packets); | 418 PacketizeFrame(2, 0, &frame_augmented_media_packets, &frame_media_packets); |
367 EncodeFec(frame_media_packets, 1, &fec_packets); | 419 EncodeFec(frame_media_packets, 1, &fec_packets); |
368 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { | 420 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { |
369 // Only FEC packets inserted. No packets recoverable at this time. | 421 // Only FEC packets inserted. No packets recoverable at this time. |
370 BuildAndAddRedFecPacket(*it); | 422 BuildAndAddRedFecPacket(*it); |
371 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 423 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
372 .Times(0); | 424 .Times(0); |
373 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 425 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
374 } | 426 } |
375 // Move unique_ptr's to media_packets for lifetime management. | 427 // Move unique_ptr's to media_packets for lifetime management. |
376 media_packets.insert(media_packets.end(), | 428 media_packets.insert(media_packets.end(), |
377 std::make_move_iterator(frame_media_packets.begin()), | 429 std::make_move_iterator(frame_media_packets.begin()), |
378 std::make_move_iterator(frame_media_packets.end())); | 430 std::make_move_iterator(frame_media_packets.end())); |
379 augmented_media_packets.insert(augmented_media_packets.end(), | 431 augmented_media_packets.insert(augmented_media_packets.end(), |
380 frame_augmented_media_packets.begin(), | 432 frame_augmented_media_packets.begin(), |
381 frame_augmented_media_packets.end()); | 433 frame_augmented_media_packets.end()); |
382 } | 434 } |
383 // Insert the oldest media packet. The corresponding FEC packet is too old | 435 // Insert the oldest media packet. The corresponding FEC packet is too old |
384 // and should have been dropped. Only the media packet we inserted will be | 436 // and should have been dropped. Only the media packet we inserted will be |
385 // returned. | 437 // returned. |
386 BuildAndAddRedMediaPacket(augmented_media_packets.front()); | 438 BuildAndAddRedMediaPacket(augmented_media_packets.front()); |
387 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 439 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
388 .Times(1).WillRepeatedly(Return(true)); | 440 .Times(1).WillRepeatedly(Return(true)); |
389 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 441 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
390 } | 442 } |
391 | 443 |
392 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, | |
393 size_t length, | |
394 uint8_t ulpfec_payload_type) { | |
395 webrtc::RTPHeader header; | |
396 std::unique_ptr<webrtc::RtpHeaderParser> parser( | |
397 webrtc::RtpHeaderParser::Create()); | |
398 ASSERT_TRUE(parser->Parse(data, length, &header)); | |
399 | |
400 webrtc::NullRtpData null_callback; | |
401 std::unique_ptr<webrtc::FecReceiver> receiver_fec( | |
402 webrtc::FecReceiver::Create(&null_callback)); | |
403 | |
404 receiver_fec->AddReceivedRedPacket(header, data, length, ulpfec_payload_type); | |
405 } | |
406 | |
407 TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) { | 444 TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) { |
408 const uint8_t kTruncatedPacket[] = {0x80, | 445 const uint8_t kTruncatedPacket[] = {0x80, |
409 0x2a, | 446 0x2a, |
410 0x68, | 447 0x68, |
411 0x71, | 448 0x71, |
412 0x29, | 449 0x29, |
413 0xa1, | 450 0xa1, |
414 0x27, | 451 0x27, |
415 0x3a, | 452 0x3a, |
416 0x29, | 453 0x29, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 0x27, | 548 0x27, |
512 0xc4, | 549 0xc4, |
513 0x2a, | 550 0x2a, |
514 0x21, | 551 0x21, |
515 0x2a, | 552 0x2a, |
516 0x28}; | 553 0x28}; |
517 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); | 554 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); |
518 } | 555 } |
519 | 556 |
520 } // namespace webrtc | 557 } // namespace webrtc |
OLD | NEW |