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