| 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 <string.h> | 11 #include <string.h> |
| 12 | 12 |
| 13 #include <list> | 13 #include <list> |
| 14 #include <memory> | 14 #include <memory> |
| 15 | 15 |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" | 18 #include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" |
| 19 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 19 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
| 20 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" | 20 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" |
| 21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 21 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 22 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" | 22 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | 23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" |
| 24 | 24 |
| 25 namespace webrtc { |
| 26 |
| 27 namespace { |
| 28 constexpr uint8_t kFecPayloadType = 96; |
| 29 } // namespace |
| 30 |
| 25 using ::testing::_; | 31 using ::testing::_; |
| 26 using ::testing::Args; | 32 using ::testing::Args; |
| 27 using ::testing::ElementsAreArray; | 33 using ::testing::ElementsAreArray; |
| 28 using ::testing::Return; | 34 using ::testing::Return; |
| 29 using Packet = webrtc::ForwardErrorCorrection::Packet; | |
| 30 | 35 |
| 31 namespace webrtc { | 36 using ::webrtc::test::fec::FrameGenerator; |
| 37 using Packet = ::webrtc::ForwardErrorCorrection::Packet; |
| 38 using ::webrtc::test::fec::RawRtpPacket; |
| 32 | 39 |
| 33 class ReceiverFecTest : public ::testing::Test { | 40 class ReceiverFecTest : public ::testing::Test { |
| 34 protected: | 41 protected: |
| 35 virtual void SetUp() { | 42 ReceiverFecTest() : receiver_fec_(FecReceiver::Create(&rtp_data_callback_)) {} |
| 36 fec_.reset(new ForwardErrorCorrection()); | |
| 37 receiver_fec_.reset(FecReceiver::Create(&rtp_data_callback_)); | |
| 38 generator_.reset(new FrameGenerator()); | |
| 39 } | |
| 40 | 43 |
| 41 void GenerateFec(ForwardErrorCorrection::PacketList* media_packets, | 44 void EncodeFec(ForwardErrorCorrection::PacketList* media_packets, |
| 42 std::list<ForwardErrorCorrection::Packet*>* fec_packets, | 45 std::list<ForwardErrorCorrection::Packet*>* fec_packets, |
| 43 unsigned int num_fec_packets) { | 46 unsigned int num_fec_packets) { |
| 44 uint8_t protection_factor = num_fec_packets * 255 / media_packets->size(); | 47 uint8_t protection_factor = num_fec_packets * 255 / media_packets->size(); |
| 45 EXPECT_EQ(0, fec_->GenerateFec(*media_packets, protection_factor, | 48 EXPECT_EQ(0, fec_.EncodeFec(*media_packets, protection_factor, 0, false, |
| 46 0, false, kFecMaskBursty, fec_packets)); | 49 kFecMaskBursty, fec_packets)); |
| 47 ASSERT_EQ(num_fec_packets, fec_packets->size()); | 50 ASSERT_EQ(num_fec_packets, fec_packets->size()); |
| 48 } | 51 } |
| 49 | 52 |
| 50 void GenerateFrame(int num_media_packets, | 53 void GenerateFrame(int num_media_packets, |
| 51 int frame_offset, | 54 int frame_offset, |
| 52 std::list<test::RawRtpPacket*>* media_rtp_packets, | 55 std::list<RawRtpPacket*>* media_rtp_packets, |
| 53 ForwardErrorCorrection::PacketList* media_packets) { | 56 ForwardErrorCorrection::PacketList* media_packets) { |
| 54 generator_->NewFrame(num_media_packets); | 57 generator_.NewFrame(num_media_packets); |
| 55 for (int i = 0; i < num_media_packets; ++i) { | 58 for (int i = 0; i < num_media_packets; ++i) { |
| 56 std::unique_ptr<test::RawRtpPacket> next_packet( | 59 std::unique_ptr<RawRtpPacket> next_packet( |
| 57 generator_->NextPacket(frame_offset + i, kRtpHeaderSize + 10)); | 60 generator_.NextPacket(frame_offset + i, kRtpHeaderSize + 10)); |
| 58 media_rtp_packets->push_back(next_packet.get()); | 61 media_rtp_packets->push_back(next_packet.get()); |
| 59 media_packets->push_back(std::move(next_packet)); | 62 media_packets->push_back(std::move(next_packet)); |
| 60 } | 63 } |
| 61 } | 64 } |
| 62 | 65 |
| 63 void VerifyReconstructedMediaPacket(const test::RawRtpPacket* packet, | 66 void VerifyReconstructedMediaPacket(const RawRtpPacket* packet, int times) { |
| 64 int times) { | |
| 65 // Verify that the content of the reconstructed packet is equal to the | 67 // Verify that the content of the reconstructed packet is equal to the |
| 66 // content of |packet|, and that the same content is received |times| number | 68 // content of |packet|, and that the same content is received |times| number |
| 67 // of times in a row. | 69 // of times in a row. |
| 68 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) | 70 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length)) |
| 69 .With(Args<0, 1>(ElementsAreArray(packet->data, | 71 .With(Args<0, 1>(ElementsAreArray(packet->data, |
| 70 packet->length))) | 72 packet->length))) |
| 71 .Times(times).WillRepeatedly(Return(true)); | 73 .Times(times).WillRepeatedly(Return(true)); |
| 72 } | 74 } |
| 73 | 75 |
| 74 void BuildAndAddRedMediaPacket(test::RawRtpPacket* packet) { | 76 void BuildAndAddRedMediaPacket(RawRtpPacket* packet) { |
| 75 std::unique_ptr<test::RawRtpPacket> red_packet( | 77 std::unique_ptr<RawRtpPacket> red_packet( |
| 76 generator_->BuildMediaRedPacket(packet)); | 78 generator_.BuildMediaRedPacket(packet)); |
| 77 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | 79 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( |
| 78 red_packet->header.header, red_packet->data, | 80 red_packet->header.header, red_packet->data, |
| 79 red_packet->length, kFecPayloadType)); | 81 red_packet->length, kFecPayloadType)); |
| 80 } | 82 } |
| 81 | 83 |
| 82 void BuildAndAddRedFecPacket(Packet* packet) { | 84 void BuildAndAddRedFecPacket(Packet* packet) { |
| 83 std::unique_ptr<test::RawRtpPacket> red_packet( | 85 std::unique_ptr<RawRtpPacket> red_packet( |
| 84 generator_->BuildFecRedPacket(packet)); | 86 generator_.BuildFecRedPacket(packet)); |
| 85 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( | 87 EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( |
| 86 red_packet->header.header, red_packet->data, | 88 red_packet->header.header, red_packet->data, |
| 87 red_packet->length, kFecPayloadType)); | 89 red_packet->length, kFecPayloadType)); |
| 88 } | 90 } |
| 89 | 91 |
| 90 void InjectGarbagePacketLength(size_t fec_garbage_offset); | 92 void InjectGarbagePacketLength(size_t fec_garbage_offset); |
| 91 static void SurvivesMaliciousPacket(const uint8_t* data, | 93 static void SurvivesMaliciousPacket(const uint8_t* data, |
| 92 size_t length, | 94 size_t length, |
| 93 uint8_t ulpfec_payload_type); | 95 uint8_t ulpfec_payload_type); |
| 94 | 96 |
| 95 MockRtpData rtp_data_callback_; | 97 MockRtpData rtp_data_callback_; |
| 96 std::unique_ptr<ForwardErrorCorrection> fec_; | 98 ForwardErrorCorrection fec_; |
| 97 std::unique_ptr<FecReceiver> receiver_fec_; | 99 std::unique_ptr<FecReceiver> receiver_fec_; |
| 98 std::unique_ptr<FrameGenerator> generator_; | 100 FrameGenerator generator_; |
| 99 }; | 101 }; |
| 100 | 102 |
| 101 TEST_F(ReceiverFecTest, TwoMediaOneFec) { | 103 TEST_F(ReceiverFecTest, TwoMediaOneFec) { |
| 102 const unsigned int kNumFecPackets = 1u; | 104 const unsigned int kNumFecPackets = 1u; |
| 103 std::list<test::RawRtpPacket*> media_rtp_packets; | 105 std::list<RawRtpPacket*> media_rtp_packets; |
| 104 ForwardErrorCorrection::PacketList media_packets; | 106 ForwardErrorCorrection::PacketList media_packets; |
| 105 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 107 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 106 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 108 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 107 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 109 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 108 | 110 |
| 109 // Recovery | 111 // Recovery |
| 110 auto it = media_rtp_packets.begin(); | 112 auto it = media_rtp_packets.begin(); |
| 111 BuildAndAddRedMediaPacket(*it); | 113 BuildAndAddRedMediaPacket(*it); |
| 112 VerifyReconstructedMediaPacket(*it, 1); | 114 VerifyReconstructedMediaPacket(*it, 1); |
| 113 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 115 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 114 // Drop one media packet. | 116 // Drop one media packet. |
| 115 auto fec_it = fec_packets.begin(); | 117 auto fec_it = fec_packets.begin(); |
| 116 BuildAndAddRedFecPacket(*fec_it); | 118 BuildAndAddRedFecPacket(*fec_it); |
| 117 ++it; | 119 ++it; |
| 118 VerifyReconstructedMediaPacket(*it, 1); | 120 VerifyReconstructedMediaPacket(*it, 1); |
| 119 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 121 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 120 | 122 |
| 121 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 123 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
| 122 EXPECT_EQ(2U, counter.num_packets); | 124 EXPECT_EQ(2U, counter.num_packets); |
| 123 EXPECT_EQ(1U, counter.num_fec_packets); | 125 EXPECT_EQ(1U, counter.num_fec_packets); |
| 124 EXPECT_EQ(1U, counter.num_recovered_packets); | 126 EXPECT_EQ(1U, counter.num_recovered_packets); |
| 125 } | 127 } |
| 126 | 128 |
| 127 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { | 129 void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { |
| 128 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 130 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 129 .WillRepeatedly(Return(true)); | 131 .WillRepeatedly(Return(true)); |
| 130 | 132 |
| 131 const unsigned int kNumFecPackets = 1u; | 133 const unsigned int kNumFecPackets = 1u; |
| 132 std::list<test::RawRtpPacket*> media_rtp_packets; | 134 std::list<RawRtpPacket*> media_rtp_packets; |
| 133 ForwardErrorCorrection::PacketList media_packets; | 135 ForwardErrorCorrection::PacketList media_packets; |
| 134 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 136 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 135 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 137 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 136 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 138 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 137 ByteWriter<uint16_t>::WriteBigEndian( | 139 ByteWriter<uint16_t>::WriteBigEndian( |
| 138 &fec_packets.front()->data[fec_garbage_offset], 0x4711); | 140 &fec_packets.front()->data[fec_garbage_offset], 0x4711); |
| 139 | 141 |
| 140 // Inject first media packet, then first FEC packet, skipping the second media | 142 // Inject first media packet, then first FEC packet, skipping the second media |
| 141 // packet to cause a recovery from the FEC packet. | 143 // packet to cause a recovery from the FEC packet. |
| 142 BuildAndAddRedMediaPacket(media_rtp_packets.front()); | 144 BuildAndAddRedMediaPacket(media_rtp_packets.front()); |
| 143 BuildAndAddRedFecPacket(fec_packets.front()); | 145 BuildAndAddRedFecPacket(fec_packets.front()); |
| 144 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 146 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 145 | 147 |
| 146 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); | 148 FecPacketCounter counter = receiver_fec_->GetPacketCounter(); |
| 147 EXPECT_EQ(2u, counter.num_packets); | 149 EXPECT_EQ(2u, counter.num_packets); |
| 148 EXPECT_EQ(1u, counter.num_fec_packets); | 150 EXPECT_EQ(1u, counter.num_fec_packets); |
| 149 EXPECT_EQ(0u, counter.num_recovered_packets); | 151 EXPECT_EQ(0u, counter.num_recovered_packets); |
| 150 } | 152 } |
| 151 | 153 |
| 152 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { | 154 TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) { |
| 153 // Byte offset 8 is the 'length recovery' field of the FEC header. | 155 // Byte offset 8 is the 'length recovery' field of the FEC header. |
| 154 InjectGarbagePacketLength(8); | 156 InjectGarbagePacketLength(8); |
| 155 } | 157 } |
| 156 | 158 |
| 157 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { | 159 TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { |
| 158 // Byte offset 10 is the 'protection length' field in the first FEC level | 160 // Byte offset 10 is the 'protection length' field in the first FEC level |
| 159 // header. | 161 // header. |
| 160 InjectGarbagePacketLength(10); | 162 InjectGarbagePacketLength(10); |
| 161 } | 163 } |
| 162 | 164 |
| 163 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { | 165 TEST_F(ReceiverFecTest, TwoMediaTwoFec) { |
| 164 const unsigned int kNumFecPackets = 2u; | 166 const unsigned int kNumFecPackets = 2u; |
| 165 std::list<test::RawRtpPacket*> media_rtp_packets; | 167 std::list<RawRtpPacket*> media_rtp_packets; |
| 166 ForwardErrorCorrection::PacketList media_packets; | 168 ForwardErrorCorrection::PacketList media_packets; |
| 167 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); | 169 GenerateFrame(2, 0, &media_rtp_packets, &media_packets); |
| 168 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 170 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 169 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 171 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 170 | 172 |
| 171 // Recovery | 173 // Recovery |
| 172 // Drop both media packets. | 174 // Drop both media packets. |
| 173 auto it = media_rtp_packets.begin(); | 175 auto it = media_rtp_packets.begin(); |
| 174 auto fec_it = fec_packets.begin(); | 176 auto fec_it = fec_packets.begin(); |
| 175 BuildAndAddRedFecPacket(*fec_it); | 177 BuildAndAddRedFecPacket(*fec_it); |
| 176 VerifyReconstructedMediaPacket(*it, 1); | 178 VerifyReconstructedMediaPacket(*it, 1); |
| 177 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 179 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 178 ++fec_it; | 180 ++fec_it; |
| 179 BuildAndAddRedFecPacket(*fec_it); | 181 BuildAndAddRedFecPacket(*fec_it); |
| 180 ++it; | 182 ++it; |
| 181 VerifyReconstructedMediaPacket(*it, 1); | 183 VerifyReconstructedMediaPacket(*it, 1); |
| 182 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 184 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 183 } | 185 } |
| 184 | 186 |
| 185 TEST_F(ReceiverFecTest, TwoFramesOneFec) { | 187 TEST_F(ReceiverFecTest, TwoFramesOneFec) { |
| 186 const unsigned int kNumFecPackets = 1u; | 188 const unsigned int kNumFecPackets = 1u; |
| 187 std::list<test::RawRtpPacket*> media_rtp_packets; | 189 std::list<RawRtpPacket*> media_rtp_packets; |
| 188 ForwardErrorCorrection::PacketList media_packets; | 190 ForwardErrorCorrection::PacketList media_packets; |
| 189 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); | 191 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); |
| 190 GenerateFrame(1, 1, &media_rtp_packets, &media_packets); | 192 GenerateFrame(1, 1, &media_rtp_packets, &media_packets); |
| 191 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 193 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 192 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 194 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 193 | 195 |
| 194 // Recovery | 196 // Recovery |
| 195 auto it = media_rtp_packets.begin(); | 197 auto it = media_rtp_packets.begin(); |
| 196 BuildAndAddRedMediaPacket(media_rtp_packets.front()); | 198 BuildAndAddRedMediaPacket(media_rtp_packets.front()); |
| 197 VerifyReconstructedMediaPacket(*it, 1); | 199 VerifyReconstructedMediaPacket(*it, 1); |
| 198 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 200 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 199 // Drop one media packet. | 201 // Drop one media packet. |
| 200 BuildAndAddRedFecPacket(fec_packets.front()); | 202 BuildAndAddRedFecPacket(fec_packets.front()); |
| 201 ++it; | 203 ++it; |
| 202 VerifyReconstructedMediaPacket(*it, 1); | 204 VerifyReconstructedMediaPacket(*it, 1); |
| 203 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 205 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 204 } | 206 } |
| 205 | 207 |
| 206 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { | 208 TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { |
| 207 const unsigned int kNumFecPackets = 1u; | 209 const unsigned int kNumFecPackets = 1u; |
| 208 std::list<test::RawRtpPacket*> media_rtp_packets; | 210 std::list<RawRtpPacket*> media_rtp_packets; |
| 209 ForwardErrorCorrection::PacketList media_packets; | 211 ForwardErrorCorrection::PacketList media_packets; |
| 210 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); | 212 GenerateFrame(1, 0, &media_rtp_packets, &media_packets); |
| 211 GenerateFrame(2, 1, &media_rtp_packets, &media_packets); | 213 GenerateFrame(2, 1, &media_rtp_packets, &media_packets); |
| 212 | 214 |
| 213 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 215 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 214 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 216 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 215 | 217 |
| 216 // Recovery | 218 // Recovery |
| 217 auto it = media_rtp_packets.begin(); | 219 auto it = media_rtp_packets.begin(); |
| 218 BuildAndAddRedMediaPacket(*it); // First frame: one packet. | 220 BuildAndAddRedMediaPacket(*it); // First frame: one packet. |
| 219 VerifyReconstructedMediaPacket(*it, 1); | 221 VerifyReconstructedMediaPacket(*it, 1); |
| 220 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 222 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 221 ++it; | 223 ++it; |
| 222 BuildAndAddRedMediaPacket(*it); // First packet of second frame. | 224 BuildAndAddRedMediaPacket(*it); // First packet of second frame. |
| 223 VerifyReconstructedMediaPacket(*it, 1); | 225 VerifyReconstructedMediaPacket(*it, 1); |
| 224 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 226 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 225 } | 227 } |
| 226 | 228 |
| 227 TEST_F(ReceiverFecTest, MaxFramesOneFec) { | 229 TEST_F(ReceiverFecTest, MaxFramesOneFec) { |
| 228 const unsigned int kNumFecPackets = 1u; | 230 const unsigned int kNumFecPackets = 1u; |
| 229 const unsigned int kNumMediaPackets = 48u; | 231 const unsigned int kNumMediaPackets = 48u; |
| 230 std::list<test::RawRtpPacket*> media_rtp_packets; | 232 std::list<RawRtpPacket*> media_rtp_packets; |
| 231 ForwardErrorCorrection::PacketList media_packets; | 233 ForwardErrorCorrection::PacketList media_packets; |
| 232 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { | 234 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { |
| 233 GenerateFrame(1, i, &media_rtp_packets, &media_packets); | 235 GenerateFrame(1, i, &media_rtp_packets, &media_packets); |
| 234 } | 236 } |
| 235 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 237 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 236 GenerateFec(&media_packets, &fec_packets, kNumFecPackets); | 238 EncodeFec(&media_packets, &fec_packets, kNumFecPackets); |
| 237 | 239 |
| 238 // Recovery | 240 // Recovery |
| 239 auto it = media_rtp_packets.begin(); | 241 auto it = media_rtp_packets.begin(); |
| 240 ++it; // Drop first packet. | 242 ++it; // Drop first packet. |
| 241 for (; it != media_rtp_packets.end(); ++it) { | 243 for (; it != media_rtp_packets.end(); ++it) { |
| 242 BuildAndAddRedMediaPacket(*it); | 244 BuildAndAddRedMediaPacket(*it); |
| 243 VerifyReconstructedMediaPacket(*it, 1); | 245 VerifyReconstructedMediaPacket(*it, 1); |
| 244 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 246 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 245 } | 247 } |
| 246 BuildAndAddRedFecPacket(fec_packets.front()); | 248 BuildAndAddRedFecPacket(fec_packets.front()); |
| 247 it = media_rtp_packets.begin(); | 249 it = media_rtp_packets.begin(); |
| 248 VerifyReconstructedMediaPacket(*it, 1); | 250 VerifyReconstructedMediaPacket(*it, 1); |
| 249 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 251 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 250 } | 252 } |
| 251 | 253 |
| 252 TEST_F(ReceiverFecTest, TooManyFrames) { | 254 TEST_F(ReceiverFecTest, TooManyFrames) { |
| 253 const unsigned int kNumFecPackets = 1u; | 255 const unsigned int kNumFecPackets = 1u; |
| 254 const unsigned int kNumMediaPackets = 49u; | 256 const unsigned int kNumMediaPackets = 49u; |
| 255 std::list<test::RawRtpPacket*> media_rtp_packets; | 257 std::list<RawRtpPacket*> media_rtp_packets; |
| 256 ForwardErrorCorrection::PacketList media_packets; | 258 ForwardErrorCorrection::PacketList media_packets; |
| 257 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { | 259 for (unsigned int i = 0; i < kNumMediaPackets; ++i) { |
| 258 GenerateFrame(1, i, &media_rtp_packets, &media_packets); | 260 GenerateFrame(1, i, &media_rtp_packets, &media_packets); |
| 259 } | 261 } |
| 260 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 262 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 261 EXPECT_EQ(-1, fec_->GenerateFec(media_packets, | 263 EXPECT_EQ( |
| 262 kNumFecPackets * 255 / kNumMediaPackets, 0, | 264 -1, fec_.EncodeFec(media_packets, kNumFecPackets * 255 / kNumMediaPackets, |
| 263 false, kFecMaskBursty, &fec_packets)); | 265 0, false, kFecMaskBursty, &fec_packets)); |
| 264 } | 266 } |
| 265 | 267 |
| 266 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { | 268 TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { |
| 267 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 269 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
| 268 // Delay the FEC packet. | 270 // Delay the FEC packet. |
| 269 Packet* delayed_fec = NULL; | 271 Packet* delayed_fec = NULL; |
| 270 const unsigned int kNumFecPacketsBatch1 = 1u; | 272 const unsigned int kNumFecPacketsBatch1 = 1u; |
| 271 const unsigned int kNumMediaPacketsBatch1 = 2u; | 273 const unsigned int kNumMediaPacketsBatch1 = 2u; |
| 272 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; | 274 std::list<RawRtpPacket*> media_rtp_packets_batch1; |
| 273 ForwardErrorCorrection::PacketList media_packets_batch1; | 275 ForwardErrorCorrection::PacketList media_packets_batch1; |
| 274 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, | 276 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, |
| 275 &media_packets_batch1); | 277 &media_packets_batch1); |
| 276 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 278 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 277 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); | 279 EncodeFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); |
| 278 | 280 |
| 279 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); | 281 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); |
| 280 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 282 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 281 .Times(1).WillRepeatedly(Return(true)); | 283 .Times(1).WillRepeatedly(Return(true)); |
| 282 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 284 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 283 delayed_fec = fec_packets.front(); | 285 delayed_fec = fec_packets.front(); |
| 284 | 286 |
| 285 // Fill the FEC decoder. No packets should be dropped. | 287 // Fill the FEC decoder. No packets should be dropped. |
| 286 const unsigned int kNumMediaPacketsBatch2 = 46u; | 288 const unsigned int kNumMediaPacketsBatch2 = 46u; |
| 287 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; | 289 std::list<RawRtpPacket*> media_rtp_packets_batch2; |
| 288 ForwardErrorCorrection::PacketList media_packets_batch2; | 290 ForwardErrorCorrection::PacketList media_packets_batch2; |
| 289 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { | 291 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { |
| 290 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); | 292 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); |
| 291 } | 293 } |
| 292 for (auto it = media_rtp_packets_batch2.begin(); | 294 for (auto it = media_rtp_packets_batch2.begin(); |
| 293 it != media_rtp_packets_batch2.end(); ++it) { | 295 it != media_rtp_packets_batch2.end(); ++it) { |
| 294 BuildAndAddRedMediaPacket(*it); | 296 BuildAndAddRedMediaPacket(*it); |
| 295 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 297 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 296 .Times(1).WillRepeatedly(Return(true)); | 298 .Times(1).WillRepeatedly(Return(true)); |
| 297 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 299 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 298 } | 300 } |
| 299 | 301 |
| 300 // Add the delayed FEC packet. One packet should be reconstructed. | 302 // Add the delayed FEC packet. One packet should be reconstructed. |
| 301 BuildAndAddRedFecPacket(delayed_fec); | 303 BuildAndAddRedFecPacket(delayed_fec); |
| 302 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 304 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 303 .Times(1).WillRepeatedly(Return(true)); | 305 .Times(1).WillRepeatedly(Return(true)); |
| 304 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 306 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 305 } | 307 } |
| 306 | 308 |
| 307 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { | 309 TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { |
| 308 // 1 frame with 2 media packets and one FEC packet. One media packet missing. | 310 // 1 frame with 2 media packets and one FEC packet. One media packet missing. |
| 309 // Delay the FEC packet. | 311 // Delay the FEC packet. |
| 310 Packet* delayed_fec = NULL; | 312 Packet* delayed_fec = NULL; |
| 311 const unsigned int kNumFecPacketsBatch1 = 1u; | 313 const unsigned int kNumFecPacketsBatch1 = 1u; |
| 312 const unsigned int kNumMediaPacketsBatch1 = 2u; | 314 const unsigned int kNumMediaPacketsBatch1 = 2u; |
| 313 std::list<test::RawRtpPacket*> media_rtp_packets_batch1; | 315 std::list<RawRtpPacket*> media_rtp_packets_batch1; |
| 314 ForwardErrorCorrection::PacketList media_packets_batch1; | 316 ForwardErrorCorrection::PacketList media_packets_batch1; |
| 315 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, | 317 GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, |
| 316 &media_packets_batch1); | 318 &media_packets_batch1); |
| 317 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 319 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 318 GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); | 320 EncodeFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); |
| 319 | 321 |
| 320 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); | 322 BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); |
| 321 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 323 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 322 .Times(1).WillRepeatedly(Return(true)); | 324 .Times(1).WillRepeatedly(Return(true)); |
| 323 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 325 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 324 delayed_fec = fec_packets.front(); | 326 delayed_fec = fec_packets.front(); |
| 325 | 327 |
| 326 // Fill the FEC decoder and force the last packet to be dropped. | 328 // Fill the FEC decoder and force the last packet to be dropped. |
| 327 const unsigned int kNumMediaPacketsBatch2 = 48u; | 329 const unsigned int kNumMediaPacketsBatch2 = 48u; |
| 328 std::list<test::RawRtpPacket*> media_rtp_packets_batch2; | 330 std::list<RawRtpPacket*> media_rtp_packets_batch2; |
| 329 ForwardErrorCorrection::PacketList media_packets_batch2; | 331 ForwardErrorCorrection::PacketList media_packets_batch2; |
| 330 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { | 332 for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { |
| 331 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); | 333 GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); |
| 332 } | 334 } |
| 333 for (auto it = media_rtp_packets_batch2.begin(); | 335 for (auto it = media_rtp_packets_batch2.begin(); |
| 334 it != media_rtp_packets_batch2.end(); ++it) { | 336 it != media_rtp_packets_batch2.end(); ++it) { |
| 335 BuildAndAddRedMediaPacket(*it); | 337 BuildAndAddRedMediaPacket(*it); |
| 336 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 338 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 337 .Times(1).WillRepeatedly(Return(true)); | 339 .Times(1).WillRepeatedly(Return(true)); |
| 338 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 340 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 339 } | 341 } |
| 340 | 342 |
| 341 // Add the delayed FEC packet. No packet should be reconstructed since the | 343 // Add the delayed FEC packet. No packet should be reconstructed since the |
| 342 // first media packet of that frame has been dropped due to being too old. | 344 // first media packet of that frame has been dropped due to being too old. |
| 343 BuildAndAddRedFecPacket(delayed_fec); | 345 BuildAndAddRedFecPacket(delayed_fec); |
| 344 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 346 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 345 .Times(0); | 347 .Times(0); |
| 346 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 348 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 347 } | 349 } |
| 348 | 350 |
| 349 TEST_F(ReceiverFecTest, OldFecPacketDropped) { | 351 TEST_F(ReceiverFecTest, OldFecPacketDropped) { |
| 350 // 49 frames with 2 media packets and one FEC packet. All media packets | 352 // 49 frames with 2 media packets and one FEC packet. All media packets |
| 351 // missing. | 353 // missing. |
| 352 const unsigned int kNumMediaPackets = 49 * 2; | 354 const unsigned int kNumMediaPackets = 49 * 2; |
| 353 std::list<test::RawRtpPacket*> media_rtp_packets; | 355 std::list<RawRtpPacket*> media_rtp_packets; |
| 354 ForwardErrorCorrection::PacketList media_packets; | 356 ForwardErrorCorrection::PacketList media_packets; |
| 355 for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) { | 357 for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) { |
| 356 std::list<test::RawRtpPacket*> frame_media_rtp_packets; | 358 std::list<RawRtpPacket*> frame_media_rtp_packets; |
| 357 ForwardErrorCorrection::PacketList frame_media_packets; | 359 ForwardErrorCorrection::PacketList frame_media_packets; |
| 358 std::list<ForwardErrorCorrection::Packet*> fec_packets; | 360 std::list<ForwardErrorCorrection::Packet*> fec_packets; |
| 359 GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets); | 361 GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets); |
| 360 GenerateFec(&frame_media_packets, &fec_packets, 1); | 362 EncodeFec(&frame_media_packets, &fec_packets, 1); |
| 361 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { | 363 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { |
| 362 // Only FEC packets inserted. No packets recoverable at this time. | 364 // Only FEC packets inserted. No packets recoverable at this time. |
| 363 BuildAndAddRedFecPacket(*it); | 365 BuildAndAddRedFecPacket(*it); |
| 364 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) | 366 EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) |
| 365 .Times(0); | 367 .Times(0); |
| 366 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); | 368 EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); |
| 367 } | 369 } |
| 368 // Move unique_ptr's to media_packets for lifetime management. | 370 // Move unique_ptr's to media_packets for lifetime management. |
| 369 media_packets.insert(media_packets.end(), | 371 media_packets.insert(media_packets.end(), |
| 370 std::make_move_iterator(frame_media_packets.begin()), | 372 std::make_move_iterator(frame_media_packets.begin()), |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 0x27, | 506 0x27, |
| 505 0xc4, | 507 0xc4, |
| 506 0x2a, | 508 0x2a, |
| 507 0x21, | 509 0x21, |
| 508 0x2a, | 510 0x2a, |
| 509 0x28}; | 511 0x28}; |
| 510 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); | 512 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); |
| 511 } | 513 } |
| 512 | 514 |
| 513 } // namespace webrtc | 515 } // namespace webrtc |
| OLD | NEW |