| 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 class ReceiverFecTest : public ::testing::Test { | 33 class ReceiverFecTest : public ::testing::Test { |
| 34 protected: | 34 protected: |
| 35 virtual void SetUp() { | 35 virtual void SetUp() { |
| 36 fec_.reset(new ForwardErrorCorrection()); | 36 fec_.reset(new ForwardErrorCorrection()); |
| 37 receiver_fec_.reset(FecReceiver::Create(&rtp_data_callback_)); | 37 receiver_fec_.reset(FecReceiver::Create(&rtp_data_callback_)); |
| 38 generator_.reset(new FrameGenerator()); | 38 generator_.reset(new FrameGenerator()); |
| 39 } | 39 } |
| 40 | 40 |
| 41 void GenerateFec(ForwardErrorCorrection::PacketList* media_packets, | 41 void GenerateFec(ForwardErrorCorrection::PacketList* media_packets, |
| 42 ForwardErrorCorrection::PacketList* fec_packets, | 42 std::list<ForwardErrorCorrection::Packet*>* fec_packets, |
| 43 unsigned int num_fec_packets) { | 43 unsigned int num_fec_packets) { |
| 44 uint8_t protection_factor = num_fec_packets * 255 / media_packets->size(); | 44 uint8_t protection_factor = num_fec_packets * 255 / media_packets->size(); |
| 45 EXPECT_EQ(0, fec_->GenerateFec(*media_packets, protection_factor, | 45 EXPECT_EQ(0, fec_->GenerateFec(*media_packets, protection_factor, |
| 46 0, false, kFecMaskBursty, fec_packets)); | 46 0, false, kFecMaskBursty, fec_packets)); |
| 47 ASSERT_EQ(num_fec_packets, fec_packets->size()); | 47 ASSERT_EQ(num_fec_packets, fec_packets->size()); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void GenerateFrame(int num_media_packets, | 50 void GenerateFrame(int num_media_packets, |
| 51 int frame_offset, | 51 int frame_offset, |
| 52 std::list<test::RawRtpPacket*>* media_rtp_packets, | 52 std::list<test::RawRtpPacket*>* media_rtp_packets, |
| 53 ForwardErrorCorrection::PacketList* media_packets) { | 53 ForwardErrorCorrection::PacketList* media_packets) { |
| 54 generator_->NewFrame(num_media_packets); | 54 generator_->NewFrame(num_media_packets); |
| 55 for (int i = 0; i < num_media_packets; ++i) { | 55 for (int i = 0; i < num_media_packets; ++i) { |
| 56 media_rtp_packets->push_back( | 56 std::unique_ptr<test::RawRtpPacket> next_packet( |
| 57 generator_->NextPacket(frame_offset + i, kRtpHeaderSize + 10)); | 57 generator_->NextPacket(frame_offset + i, kRtpHeaderSize + 10)); |
| 58 media_packets->push_back(media_rtp_packets->back()); | 58 media_rtp_packets->push_back(next_packet.get()); |
| 59 media_packets->push_back(std::move(next_packet)); |
| 59 } | 60 } |
| 60 } | 61 } |
| 61 | 62 |
| 62 void VerifyReconstructedMediaPacket(const test::RawRtpPacket* packet, | 63 void VerifyReconstructedMediaPacket(const test::RawRtpPacket* packet, |
| 63 int times) { | 64 int times) { |
| 64 // Verify that the content of the reconstructed packet is equal to the | 65 // Verify that the content of the reconstructed packet is equal to the |
| 65 // content of |packet|, and that the same content is received |times| number | 66 // content of |packet|, and that the same content is received |times| number |
| 66 // of times in a row. | 67 // of times in a row. |
| 67 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) | 68 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) |
| 68 .With(Args<0, 1>(ElementsAreArray(packet->data, | 69 .With(Args<0, 1>(ElementsAreArray(packet->data, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 90 static void SurvivesMaliciousPacket(const uint8_t* data, | 91 static void SurvivesMaliciousPacket(const uint8_t* data, |
| 91 size_t length, | 92 size_t length, |
| 92 uint8_t ulpfec_payload_type); | 93 uint8_t ulpfec_payload_type); |
| 93 | 94 |
| 94 MockRtpData rtp_data_callback_; | 95 MockRtpData rtp_data_callback_; |
| 95 std::unique_ptr<ForwardErrorCorrection> fec_; | 96 std::unique_ptr<ForwardErrorCorrection> fec_; |
| 96 std::unique_ptr<FecReceiver> receiver_fec_; | 97 std::unique_ptr<FecReceiver> receiver_fec_; |
| 97 std::unique_ptr<FrameGenerator> generator_; | 98 std::unique_ptr<FrameGenerator> generator_; |
| 98 }; | 99 }; |
| 99 | 100 |
| 100 void DeletePackets(ForwardErrorCorrection::PacketList* packets) { | |
| 101 while (!packets->empty()) { | |
| 102 delete packets->front(); | |
| 103 packets->pop_front(); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 TEST_F(ReceiverFecTest, TwoMediaOneFec) { | 101 TEST_F(ReceiverFecTest, TwoMediaOneFec) { |
| 108 const unsigned int kNumFecPackets = 1u; | 102 const unsigned int kNumFecPackets = 1u; |
| 109 std::list<test::RawRtpPacket*> media_rtp_packets; | 103 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 110 ForwardErrorCorrection::PacketList media_packets; | 104 ForwardErrorCorrection::PacketList media_packets; |
| 111 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 105 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 112 ForwardErrorCorrection::PacketList fec_packets; | 106 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 113 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 107 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 114 | 108 |
| 115 // Recovery | 109 // Recovery |
| 116 auto it = media_rtp_packets.begin(); | 110 auto it = media_rtp_packets.begin(); |
| 117 BuildAndAddRedMediaPacket(*it); | 111 BuildAndAddRedMediaPacket(*it); |
| 118 VerifyReconstructedMediaPacket(*it, 1); | 112 VerifyReconstructedMediaPacket(*it, 1); |
| 119 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 113 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 120 // Drop one media packet. | 114 // Drop one media packet. |
| 121 auto fec_it = fec_packets.begin(); | 115 auto fec_it = fec_packets.begin(); |
| 122 BuildAndAddRedFecPacket(*fec_it); | 116 BuildAndAddRedFecPacket(*fec_it); |
| 123 ++it; | 117 ++it; |
| 124 VerifyReconstructedMediaPacket(*it, 1); | 118 VerifyReconstructedMediaPacket(*it, 1); |
| 125 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 119 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 126 | 120 |
| 127 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 121 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
| 128 EXPECT_EQ(2U, counter.num_packets); | 122 EXPECT_EQ(2U, counter.num_packets); |
| 129 EXPECT_EQ(1U, counter.num_fec_packets); | 123 EXPECT_EQ(1U, counter.num_fec_packets); |
| 130 EXPECT_EQ(1U, counter.num_recovered_packets); | 124 EXPECT_EQ(1U, counter.num_recovered_packets); |
| 131 | |
| 132 DeletePackets(&media_packets); | |
| 133 } | 125 } |
| 134 | 126 |
| 135 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { | 127 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { |
| 136 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 128 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 137 .WillRepeatedly(Return(true)); | 129 .WillRepeatedly(Return(true)); |
| 138 | 130 |
| 139 const unsigned int kNumFecPackets = 1u; | 131 const unsigned int kNumFecPackets = 1u; |
| 140 std::list<test::RawRtpPacket*> media_rtp_packets; | 132 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 141 ForwardErrorCorrection::PacketList media_packets; | 133 ForwardErrorCorrection::PacketList media_packets; |
| 142 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 134 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 143 ForwardErrorCorrection::PacketList fec_packets; | 135 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 144 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 136 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 145 ByteWriter<uint16_t>::WriteBigEndian( | 137 ByteWriter<uint16_t>::WriteBigEndian( |
| 146 &fec_packets.front()->data[fec_garbage_offset], 0x4711); | 138 &fec_packets.front()->data[fec_garbage_offset], 0x4711); |
| 147 | 139 |
| 148 // Inject first media packet, then first FEC packet, skipping the second media | 140 // Inject first media packet, then first FEC packet, skipping the second media |
| 149 // packet to cause a recovery from the FEC packet. | 141 // packet to cause a recovery from the FEC packet. |
| 150 BuildAndAddRedMediaPacket(media_rtp_packets.front()); | 142 BuildAndAddRedMediaPacket(media_rtp_packets.front()); |
| 151 BuildAndAddRedFecPacket(fec_packets.front()); | 143 BuildAndAddRedFecPacket(fec_packets.front()); |
| 152 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 144 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 153 | 145 |
| 154 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 146 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
| 155 EXPECT_EQ(2u, counter.num_packets); | 147 EXPECT_EQ(2u, counter.num_packets); |
| 156 EXPECT_EQ(1u, counter.num_fec_packets); | 148 EXPECT_EQ(1u, counter.num_fec_packets); |
| 157 EXPECT_EQ(0u, counter.num_recovered_packets); | 149 EXPECT_EQ(0u, counter.num_recovered_packets); |
| 158 | |
| 159 DeletePackets(&media_packets); | |
| 160 } | 150 } |
| 161 | 151 |
| 162 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { | 152 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { |
| 163 // Byte offset 8 is the 'length recovery' field of the FEC header. | 153 // Byte offset 8 is the 'length recovery' field of the FEC header. |
| 164 InjectGarbagePacketLength(8); | 154 InjectGarbagePacketLength(8); |
| 165 } | 155 } |
| 166 | 156 |
| 167 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { | 157 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { |
| 168 // Byte offset 10 is the 'protection length' field in the first FEC level | 158 // Byte offset 10 is the 'protection length' field in the first FEC level |
| 169 // header. | 159 // header. |
| 170 InjectGarbagePacketLength(10); | 160 InjectGarbagePacketLength(10); |
| 171 } | 161 } |
| 172 | 162 |
| 173 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { | 163 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { |
| 174 const unsigned int kNumFecPackets = 2u; | 164 const unsigned int kNumFecPackets = 2u; |
| 175 std::list<test::RawRtpPacket*> media_rtp_packets; | 165 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 176 ForwardErrorCorrection::PacketList media_packets; | 166 ForwardErrorCorrection::PacketList media_packets; |
| 177 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 167 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 178 ForwardErrorCorrection::PacketList fec_packets; | 168 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 179 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 169 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 180 | 170 |
| 181 // Recovery | 171 // Recovery |
| 182 // Drop both media packets. | 172 // Drop both media packets. |
| 183 auto it = media_rtp_packets.begin(); | 173 auto it = media_rtp_packets.begin(); |
| 184 auto fec_it = fec_packets.begin(); | 174 auto fec_it = fec_packets.begin(); |
| 185 BuildAndAddRedFecPacket(*fec_it); | 175 BuildAndAddRedFecPacket(*fec_it); |
| 186 VerifyReconstructedMediaPacket(*it, 1); | 176 VerifyReconstructedMediaPacket(*it, 1); |
| 187 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 177 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 188 ++fec_it; | 178 ++fec_it; |
| 189 BuildAndAddRedFecPacket(*fec_it); | 179 BuildAndAddRedFecPacket(*fec_it); |
| 190 ++it; | 180 ++it; |
| 191 VerifyReconstructedMediaPacket(*it, 1); | 181 VerifyReconstructedMediaPacket(*it, 1); |
| 192 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 182 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 193 | |
| 194 DeletePackets(&media_packets); | |
| 195 } | 183 } |
| 196 | 184 |
| 197 TEST_F(ReceiverFecTest, TwoFramesOneFec) { | 185 TEST_F(ReceiverFecTest, TwoFramesOneFec) { |
| 198 const unsigned int kNumFecPackets = 1u; | 186 const unsigned int kNumFecPackets = 1u; |
| 199 std::list<test::RawRtpPacket*> media_rtp_packets; | 187 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 200 ForwardErrorCorrection::PacketList media_packets; | 188 ForwardErrorCorrection::PacketList media_packets; |
| 201 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); | 189 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); |
| 202 GenerateFrame(1, 1, &media_rtp_packets, &media_packets); | 190 GenerateFrame(1, 1, &media_rtp_packets, &media_packets); |
| 203 ForwardErrorCorrection::PacketList fec_packets; | 191 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 204 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 192 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 205 | 193 |
| 206 // Recovery | 194 // Recovery |
| 207 auto it = media_rtp_packets.begin(); | 195 auto it = media_rtp_packets.begin(); |
| 208 BuildAndAddRedMediaPacket(media_rtp_packets.front()); | 196 BuildAndAddRedMediaPacket(media_rtp_packets.front()); |
| 209 VerifyReconstructedMediaPacket(*it, 1); | 197 VerifyReconstructedMediaPacket(*it, 1); |
| 210 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 198 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 211 // Drop one media packet. | 199 // Drop one media packet. |
| 212 BuildAndAddRedFecPacket(fec_packets.front()); | 200 BuildAndAddRedFecPacket(fec_packets.front()); |
| 213 ++it; | 201 ++it; |
| 214 VerifyReconstructedMediaPacket(*it, 1); | 202 VerifyReconstructedMediaPacket(*it, 1); |
| 215 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 203 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 216 | |
| 217 DeletePackets(&media_packets); | |
| 218 } | 204 } |
| 219 | 205 |
| 220 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { | 206 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { |
| 221 const unsigned int kNumFecPackets = 1u; | 207 const unsigned int kNumFecPackets = 1u; |
| 222 std::list<test::RawRtpPacket*> media_rtp_packets; | 208 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 223 ForwardErrorCorrection::PacketList media_packets; | 209 ForwardErrorCorrection::PacketList media_packets; |
| 224 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); | 210 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); |
| 225 GenerateFrame(2, 1, &media_rtp_packets, &media_packets); | 211 GenerateFrame(2, 1, &media_rtp_packets, &media_packets); |
| 226 | 212 |
| 227 ForwardErrorCorrection::PacketList fec_packets; | 213 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 228 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 214 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 229 | 215 |
| 230 // Recovery | 216 // Recovery |
| 231 auto it = media_rtp_packets.begin(); | 217 auto it = media_rtp_packets.begin(); |
| 232 BuildAndAddRedMediaPacket(*it); // First frame: one packet. | 218 BuildAndAddRedMediaPacket(*it); // First frame: one packet. |
| 233 VerifyReconstructedMediaPacket(*it, 1); | 219 VerifyReconstructedMediaPacket(*it, 1); |
| 234 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 220 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 235 ++it; | 221 ++it; |
| 236 BuildAndAddRedMediaPacket(*it); // First packet of second frame. | 222 BuildAndAddRedMediaPacket(*it); // First packet of second frame. |
| 237 VerifyReconstructedMediaPacket(*it, 1); | 223 VerifyReconstructedMediaPacket(*it, 1); |
| 238 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 224 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 239 | |
| 240 DeletePackets(&media_packets); | |
| 241 } | 225 } |
| 242 | 226 |
| 243 TEST_F(ReceiverFecTest, MaxFramesOneFec) { | 227 TEST_F(ReceiverFecTest, MaxFramesOneFec) { |
| 244 const unsigned int kNumFecPackets = 1u; | 228 const unsigned int kNumFecPackets = 1u; |
| 245 const unsigned int kNumMediaPackets = 48u; | 229 const unsigned int kNumMediaPackets = 48u; |
| 246 std::list<test::RawRtpPacket*> media_rtp_packets; | 230 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 247 ForwardErrorCorrection::PacketList media_packets; | 231 ForwardErrorCorrection::PacketList media_packets; |
| 248 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { | 232 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { |
| 249 GenerateFrame(1, i, &media_rtp_packets, &media_packets); | 233 GenerateFrame(1, i, &media_rtp_packets, &media_packets); |
| 250 } | 234 } |
| 251 ForwardErrorCorrection::PacketList fec_packets; | 235 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 252 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 236 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); |
| 253 | 237 |
| 254 // Recovery | 238 // Recovery |
| 255 auto it = media_rtp_packets.begin(); | 239 auto it = media_rtp_packets.begin(); |
| 256 ++it; // Drop first packet. | 240 ++it; // Drop first packet. |
| 257 for (; it != media_rtp_packets.end(); ++it) { | 241 for (; it != media_rtp_packets.end(); ++it) { |
| 258 BuildAndAddRedMediaPacket(*it); | 242 BuildAndAddRedMediaPacket(*it); |
| 259 VerifyReconstructedMediaPacket(*it, 1); | 243 VerifyReconstructedMediaPacket(*it, 1); |
| 260 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 244 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 261 } | 245 } |
| 262 BuildAndAddRedFecPacket(fec_packets.front()); | 246 BuildAndAddRedFecPacket(fec_packets.front()); |
| 263 it = media_rtp_packets.begin(); | 247 it = media_rtp_packets.begin(); |
| 264 VerifyReconstructedMediaPacket(*it, 1); | 248 VerifyReconstructedMediaPacket(*it, 1); |
| 265 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 249 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 266 | |
| 267 DeletePackets(&media_packets); | |
| 268 } | 250 } |
| 269 | 251 |
| 270 TEST_F(ReceiverFecTest, TooManyFrames) { | 252 TEST_F(ReceiverFecTest, TooManyFrames) { |
| 271 const unsigned int kNumFecPackets = 1u; | 253 const unsigned int kNumFecPackets = 1u; |
| 272 const unsigned int kNumMediaPackets = 49u; | 254 const unsigned int kNumMediaPackets = 49u; |
| 273 std::list<test::RawRtpPacket*> media_rtp_packets; | 255 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 274 ForwardErrorCorrection::PacketList media_packets; | 256 ForwardErrorCorrection::PacketList media_packets; |
| 275 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { | 257 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { |
| 276 GenerateFrame(1, i, &media_rtp_packets, &media_packets); | 258 GenerateFrame(1, i, &media_rtp_packets, &media_packets); |
| 277 } | 259 } |
| 278 ForwardErrorCorrection::PacketList fec_packets; | 260 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 279 EXPECT_EQ(-1, fec_->GenerateFec(media_packets, | 261 EXPECT_EQ(-1, fec_->GenerateFec(media_packets, |
| 280 kNumFecPackets * 255 / kNumMediaPackets, 0, | 262 kNumFecPackets * 255 / kNumMediaPackets, 0, |
| 281 false, kFecMaskBursty, &fec_packets)); | 263 false, kFecMaskBursty, &fec_packets)); |
| 282 | |
| 283 DeletePackets(&media_packets); | |
| 284 } | 264 } |
| 285 | 265 |
| 286 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { | 266 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { |
| 287 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 267 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
| 288 // Delay the FEC packet. | 268 // Delay the FEC packet. |
| 289 Packet* delayed_fec = NULL; | 269 Packet* delayed_fec = NULL; |
| 290 const unsigned int kNumFecPacketsBatch1 = 1u; | 270 const unsigned int kNumFecPacketsBatch1 = 1u; |
| 291 const unsigned int kNumMediaPacketsBatch1 = 2u; | 271 const unsigned int kNumMediaPacketsBatch1 = 2u; |
| 292 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; | 272 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; |
| 293 ForwardErrorCorrection::PacketList media_packets_batch1; | 273 ForwardErrorCorrection::PacketList media_packets_batch1; |
| 294 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, | 274 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, |
| 295 &media_packets_batch1); | 275 &media_packets_batch1); |
| 296 ForwardErrorCorrection::PacketList fec_packets; | 276 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 297 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); | 277 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); |
| 298 | 278 |
| 299 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); | 279 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); |
| 300 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 280 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 301 .Times(1).WillRepeatedly(Return(true)); | 281 .Times(1).WillRepeatedly(Return(true)); |
| 302 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 282 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 303 delayed_fec = fec_packets.front(); | 283 delayed_fec = fec_packets.front(); |
| 304 | 284 |
| 305 // Fill the FEC decoder. No packets should be dropped. | 285 // Fill the FEC decoder. No packets should be dropped. |
| 306 const unsigned int kNumMediaPacketsBatch2 = 46u; | 286 const unsigned int kNumMediaPacketsBatch2 = 46u; |
| 307 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; | 287 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; |
| 308 ForwardErrorCorrection::PacketList media_packets_batch2; | 288 ForwardErrorCorrection::PacketList media_packets_batch2; |
| 309 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { | 289 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { |
| 310 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); | 290 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); |
| 311 } | 291 } |
| 312 for (auto it = media_rtp_packets_batch2.begin(); | 292 for (auto it = media_rtp_packets_batch2.begin(); |
| 313 it != media_rtp_packets_batch2.end(); ++it) { | 293 it != media_rtp_packets_batch2.end(); ++it) { |
| 314 BuildAndAddRedMediaPacket(*it); | 294 BuildAndAddRedMediaPacket(*it); |
| 315 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 295 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 316 .Times(1).WillRepeatedly(Return(true)); | 296 .Times(1).WillRepeatedly(Return(true)); |
| 317 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 297 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 318 } | 298 } |
| 319 | 299 |
| 320 // Add the delayed FEC packet. One packet should be reconstructed. | 300 // Add the delayed FEC packet. One packet should be reconstructed. |
| 321 BuildAndAddRedFecPacket(delayed_fec); | 301 BuildAndAddRedFecPacket(delayed_fec); |
| 322 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 302 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 323 .Times(1).WillRepeatedly(Return(true)); | 303 .Times(1).WillRepeatedly(Return(true)); |
| 324 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 304 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 325 | |
| 326 DeletePackets(&media_packets_batch1); | |
| 327 DeletePackets(&media_packets_batch2); | |
| 328 } | 305 } |
| 329 | 306 |
| 330 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { | 307 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { |
| 331 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 308 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
| 332 // Delay the FEC packet. | 309 // Delay the FEC packet. |
| 333 Packet* delayed_fec = NULL; | 310 Packet* delayed_fec = NULL; |
| 334 const unsigned int kNumFecPacketsBatch1 = 1u; | 311 const unsigned int kNumFecPacketsBatch1 = 1u; |
| 335 const unsigned int kNumMediaPacketsBatch1 = 2u; | 312 const unsigned int kNumMediaPacketsBatch1 = 2u; |
| 336 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; | 313 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; |
| 337 ForwardErrorCorrection::PacketList media_packets_batch1; | 314 ForwardErrorCorrection::PacketList media_packets_batch1; |
| 338 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, | 315 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, |
| 339 &media_packets_batch1); | 316 &media_packets_batch1); |
| 340 ForwardErrorCorrection::PacketList fec_packets; | 317 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 341 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); | 318 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); |
| 342 | 319 |
| 343 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); | 320 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); |
| 344 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 321 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 345 .Times(1).WillRepeatedly(Return(true)); | 322 .Times(1).WillRepeatedly(Return(true)); |
| 346 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 323 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 347 delayed_fec = fec_packets.front(); | 324 delayed_fec = fec_packets.front(); |
| 348 | 325 |
| 349 // Fill the FEC decoder and force the last packet to be dropped. | 326 // Fill the FEC decoder and force the last packet to be dropped. |
| 350 const unsigned int kNumMediaPacketsBatch2 = 48u; | 327 const unsigned int kNumMediaPacketsBatch2 = 48u; |
| 351 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; | 328 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; |
| 352 ForwardErrorCorrection::PacketList media_packets_batch2; | 329 ForwardErrorCorrection::PacketList media_packets_batch2; |
| 353 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { | 330 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { |
| 354 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); | 331 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); |
| 355 } | 332 } |
| 356 for (auto it = media_rtp_packets_batch2.begin(); | 333 for (auto it = media_rtp_packets_batch2.begin(); |
| 357 it != media_rtp_packets_batch2.end(); ++it) { | 334 it != media_rtp_packets_batch2.end(); ++it) { |
| 358 BuildAndAddRedMediaPacket(*it); | 335 BuildAndAddRedMediaPacket(*it); |
| 359 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 336 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 360 .Times(1).WillRepeatedly(Return(true)); | 337 .Times(1).WillRepeatedly(Return(true)); |
| 361 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 338 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 362 } | 339 } |
| 363 | 340 |
| 364 // Add the delayed FEC packet. No packet should be reconstructed since the | 341 // Add the delayed FEC packet. No packet should be reconstructed since the |
| 365 // first media packet of that frame has been dropped due to being too old. | 342 // first media packet of that frame has been dropped due to being too old. |
| 366 BuildAndAddRedFecPacket(delayed_fec); | 343 BuildAndAddRedFecPacket(delayed_fec); |
| 367 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 344 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 368 .Times(0); | 345 .Times(0); |
| 369 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 346 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 370 | |
| 371 DeletePackets(&media_packets_batch1); | |
| 372 DeletePackets(&media_packets_batch2); | |
| 373 } | 347 } |
| 374 | 348 |
| 375 TEST_F(ReceiverFecTest, OldFecPacketDropped) { | 349 TEST_F(ReceiverFecTest, OldFecPacketDropped) { |
| 376 // 49 frames with 2 media packets and one FEC packet. All media packets | 350 // 49 frames with 2 media packets and one FEC packet. All media packets |
| 377 // missing. | 351 // missing. |
| 378 const unsigned int kNumMediaPackets = 49 * 2; | 352 const unsigned int kNumMediaPackets = 49 * 2; |
| 379 std::list<test::RawRtpPacket*> media_rtp_packets; | 353 std::list<test::RawRtpPacket*> media_rtp_packets; |
| 380 ForwardErrorCorrection::PacketList media_packets; | 354 ForwardErrorCorrection::PacketList media_packets; |
| 381 for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) { | 355 for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) { |
| 382 std::list<test::RawRtpPacket*> frame_media_rtp_packets; | 356 std::list<test::RawRtpPacket*> frame_media_rtp_packets; |
| 383 ForwardErrorCorrection::PacketList frame_media_packets; | 357 ForwardErrorCorrection::PacketList frame_media_packets; |
| 384 ForwardErrorCorrection::PacketList fec_packets; | 358 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 385 GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets); | 359 GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets); |
| 386 GenerateFec(&frame_media_packets, &fec_packets, 1); | 360 GenerateFec(&frame_media_packets, &fec_packets, 1); |
| 387 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { | 361 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { |
| 388 // Only FEC packets inserted. No packets recoverable at this time. | 362 // Only FEC packets inserted. No packets recoverable at this time. |
| 389 BuildAndAddRedFecPacket(*it); | 363 BuildAndAddRedFecPacket(*it); |
| 390 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 364 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 391 .Times(0); | 365 .Times(0); |
| 392 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 366 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 393 } | 367 } |
| 394 media_packets.insert(media_packets.end(), frame_media_packets.begin(), | 368 // Move unique_ptr's to media_packets for lifetime management. |
| 395 frame_media_packets.end()); | 369 media_packets.insert(media_packets.end(), |
| 370 std::make_move_iterator(frame_media_packets.begin()), |
| 371 std::make_move_iterator(frame_media_packets.end())); |
| 396 media_rtp_packets.insert(media_rtp_packets.end(), | 372 media_rtp_packets.insert(media_rtp_packets.end(), |
| 397 frame_media_rtp_packets.begin(), | 373 frame_media_rtp_packets.begin(), |
| 398 frame_media_rtp_packets.end()); | 374 frame_media_rtp_packets.end()); |
| 399 } | 375 } |
| 400 // Insert the oldest media packet. The corresponding FEC packet is too old | 376 // Insert the oldest media packet. The corresponding FEC packet is too old |
| 401 // and should've been dropped. Only the media packet we inserted will be | 377 // and should've been dropped. Only the media packet we inserted will be |
| 402 // returned. | 378 // returned. |
| 403 BuildAndAddRedMediaPacket(media_rtp_packets.front()); | 379 BuildAndAddRedMediaPacket(media_rtp_packets.front()); |
| 404 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 380 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 405 .Times(1).WillRepeatedly(Return(true)); | 381 .Times(1).WillRepeatedly(Return(true)); |
| 406 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 382 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 407 | |
| 408 DeletePackets(&media_packets); | |
| 409 } | 383 } |
| 410 | 384 |
| 411 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, | 385 void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data, |
| 412 size_t length, | 386 size_t length, |
| 413 uint8_t ulpfec_payload_type) { | 387 uint8_t ulpfec_payload_type) { |
| 414 webrtc::RTPHeader header; | 388 webrtc::RTPHeader header; |
| 415 std::unique_ptr<webrtc::RtpHeaderParser> parser( | 389 std::unique_ptr<webrtc::RtpHeaderParser> parser( |
| 416 webrtc::RtpHeaderParser::Create()); | 390 webrtc::RtpHeaderParser::Create()); |
| 417 ASSERT_TRUE(parser->Parse(data, length, &header)); | 391 ASSERT_TRUE(parser->Parse(data, length, &header)); |
| 418 | 392 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 0x27, | 504 0x27, |
| 531 0xc4, | 505 0xc4, |
| 532 0x2a, | 506 0x2a, |
| 533 0x21, | 507 0x21, |
| 534 0x2a, | 508 0x2a, |
| 535 0x28}; | 509 0x28}; |
| 536 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); | 510 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); |
| 537 } | 511 } |
| 538 | 512 |
| 539 } // namespace webrtc | 513 } // namespace webrtc |
| OLD | NEW |