OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <memory> | |
12 | |
13 #include "webrtc/modules/video_coding/include/mock/mock_vcm_callbacks.h" | |
14 #include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h" | |
15 #include "webrtc/modules/video_coding/include/video_coding.h" | |
16 #include "webrtc/modules/video_coding/test/test_util.h" | |
17 #include "webrtc/system_wrappers/include/clock.h" | |
18 #include "webrtc/test/gmock.h" | |
19 #include "webrtc/test/gtest.h" | |
20 | |
21 namespace webrtc { | |
22 | |
23 using ::testing::_; | |
24 using ::testing::AllOf; | |
25 using ::testing::AnyNumber; | |
26 using ::testing::Args; | |
27 using ::testing::ElementsAre; | |
28 using ::testing::Field; | |
29 using ::testing::NiceMock; | |
30 using ::testing::Pointee; | |
31 using ::testing::Return; | |
32 using ::testing::Sequence; | |
33 | |
34 class VCMRobustnessTest : public ::testing::Test { | |
35 protected: | |
36 static const size_t kPayloadLen = 10; | |
37 | |
38 virtual void SetUp() { | |
39 clock_.reset(new SimulatedClock(0)); | |
40 ASSERT_TRUE(clock_.get() != NULL); | |
41 vcm_.reset(VideoCodingModule::Create(clock_.get(), &event_factory_)); | |
42 ASSERT_TRUE(vcm_ != NULL); | |
43 const size_t kMaxNackListSize = 250; | |
44 const int kMaxPacketAgeToNack = 450; | |
45 vcm_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0); | |
46 ASSERT_EQ(0, vcm_->RegisterFrameTypeCallback(&frame_type_callback_)); | |
47 ASSERT_EQ(0, vcm_->RegisterPacketRequestCallback(&request_callback_)); | |
48 VideoCodingModule::Codec(kVideoCodecVP8, &video_codec_); | |
49 ASSERT_EQ(VCM_OK, vcm_->RegisterReceiveCodec(&video_codec_, 1)); | |
50 vcm_->RegisterExternalDecoder(&decoder_, video_codec_.plType); | |
51 | |
52 // Since we call Decode, we need to provide a valid receive callback. | |
53 // However, for the purposes of these tests, we ignore the callbacks. | |
54 EXPECT_CALL(receive_callback_, OnIncomingPayloadType(_)).Times(AnyNumber()); | |
55 EXPECT_CALL(receive_callback_, OnDecoderImplementationName(_)) | |
56 .Times(AnyNumber()); | |
57 vcm_->RegisterReceiveCallback(&receive_callback_); | |
58 } | |
59 | |
60 virtual void TearDown() { vcm_.reset(); } | |
61 | |
62 void InsertPacket(uint32_t timestamp, | |
63 uint16_t seq_no, | |
64 bool first, | |
65 bool marker_bit, | |
66 FrameType frame_type) { | |
67 const uint8_t payload[kPayloadLen] = {0}; | |
68 WebRtcRTPHeader rtp_info; | |
69 memset(&rtp_info, 0, sizeof(rtp_info)); | |
70 rtp_info.frameType = frame_type; | |
71 rtp_info.header.timestamp = timestamp; | |
72 rtp_info.header.sequenceNumber = seq_no; | |
73 rtp_info.header.markerBit = marker_bit; | |
74 rtp_info.header.payloadType = video_codec_.plType; | |
75 rtp_info.type.Video.codec = kRtpVideoVp8; | |
76 rtp_info.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8(); | |
77 rtp_info.type.Video.is_first_packet_in_frame = first; | |
78 | |
79 ASSERT_EQ(VCM_OK, vcm_->IncomingPacket(payload, kPayloadLen, rtp_info)); | |
80 } | |
81 | |
82 std::unique_ptr<VideoCodingModule> vcm_; | |
83 MockVCMReceiveCallback receive_callback_; | |
84 VideoCodec video_codec_; | |
85 MockVCMFrameTypeCallback frame_type_callback_; | |
86 MockPacketRequestCallback request_callback_; | |
87 NiceMock<MockVideoDecoder> decoder_; | |
88 NiceMock<MockVideoDecoder> decoderCopy_; | |
89 std::unique_ptr<SimulatedClock> clock_; | |
90 NullEventFactory event_factory_; | |
91 }; | |
92 | |
93 TEST_F(VCMRobustnessTest, TestHardNack) { | |
94 Sequence s; | |
95 EXPECT_CALL(request_callback_, ResendPackets(_, 2)) | |
96 .With(Args<0, 1>(ElementsAre(6, 7))) | |
97 .Times(1); | |
98 for (int ts = 0; ts <= 6000; ts += 3000) { | |
99 EXPECT_CALL(decoder_, | |
100 Decode(AllOf(Field(&EncodedImage::_timeStamp, ts), | |
101 Field(&EncodedImage::_length, kPayloadLen * 3), | |
102 Field(&EncodedImage::_completeFrame, true)), | |
103 false, _, _, _)) | |
104 .Times(1) | |
105 .InSequence(s); | |
106 } | |
107 | |
108 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( | |
109 VideoCodingModule::kHardNack, kNoErrors)); | |
110 | |
111 InsertPacket(0, 0, true, false, kVideoFrameKey); | |
112 InsertPacket(0, 1, false, false, kVideoFrameKey); | |
113 InsertPacket(0, 2, false, true, kVideoFrameKey); | |
114 clock_->AdvanceTimeMilliseconds(1000 / 30); | |
115 | |
116 InsertPacket(3000, 3, true, false, kVideoFrameDelta); | |
117 InsertPacket(3000, 4, false, false, kVideoFrameDelta); | |
118 InsertPacket(3000, 5, false, true, kVideoFrameDelta); | |
119 clock_->AdvanceTimeMilliseconds(1000 / 30); | |
120 | |
121 ASSERT_EQ(VCM_OK, vcm_->Decode(0)); | |
122 ASSERT_EQ(VCM_OK, vcm_->Decode(0)); | |
123 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
124 | |
125 clock_->AdvanceTimeMilliseconds(10); | |
126 | |
127 vcm_->Process(); | |
128 | |
129 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
130 | |
131 InsertPacket(6000, 8, false, true, kVideoFrameDelta); | |
132 clock_->AdvanceTimeMilliseconds(10); | |
133 vcm_->Process(); | |
134 | |
135 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
136 | |
137 InsertPacket(6000, 6, true, false, kVideoFrameDelta); | |
138 InsertPacket(6000, 7, false, false, kVideoFrameDelta); | |
139 clock_->AdvanceTimeMilliseconds(10); | |
140 vcm_->Process(); | |
141 | |
142 ASSERT_EQ(VCM_OK, vcm_->Decode(0)); | |
143 } | |
144 | |
145 TEST_F(VCMRobustnessTest, TestHardNackNoneDecoded) { | |
146 EXPECT_CALL(request_callback_, ResendPackets(_, _)).Times(0); | |
147 EXPECT_CALL(frame_type_callback_, RequestKeyFrame()).Times(1); | |
148 | |
149 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( | |
150 VideoCodingModule::kHardNack, kNoErrors)); | |
151 | |
152 InsertPacket(3000, 3, true, false, kVideoFrameDelta); | |
153 InsertPacket(3000, 4, false, false, kVideoFrameDelta); | |
154 InsertPacket(3000, 5, false, true, kVideoFrameDelta); | |
155 | |
156 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
157 vcm_->Process(); | |
158 | |
159 clock_->AdvanceTimeMilliseconds(10); | |
160 | |
161 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
162 vcm_->Process(); | |
163 } | |
164 | |
165 TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) { | |
166 EXPECT_CALL(decoder_, InitDecode(_, _)).Times(1); | |
167 EXPECT_CALL(decoder_, Release()).Times(1); | |
168 Sequence s1; | |
169 EXPECT_CALL(request_callback_, ResendPackets(_, 1)) | |
170 .With(Args<0, 1>(ElementsAre(4))) | |
171 .Times(0); | |
172 | |
173 EXPECT_CALL(decoder_, Copy()).Times(0); | |
174 EXPECT_CALL(decoderCopy_, Copy()).Times(0); | |
175 | |
176 // Decode operations | |
177 EXPECT_CALL(decoder_, | |
178 Decode(AllOf(Field(&EncodedImage::_timeStamp, 0), | |
179 Field(&EncodedImage::_completeFrame, true)), | |
180 false, _, _, _)) | |
181 .Times(1) | |
182 .InSequence(s1); | |
183 EXPECT_CALL(decoder_, | |
184 Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000), | |
185 Field(&EncodedImage::_completeFrame, false)), | |
186 false, _, _, _)) | |
187 .Times(1) | |
188 .InSequence(s1); | |
189 EXPECT_CALL(decoder_, | |
190 Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000), | |
191 Field(&EncodedImage::_completeFrame, true)), | |
192 false, _, _, _)) | |
193 .Times(1) | |
194 .InSequence(s1); | |
195 EXPECT_CALL(decoder_, | |
196 Decode(AllOf(Field(&EncodedImage::_timeStamp, 9000), | |
197 Field(&EncodedImage::_completeFrame, true)), | |
198 false, _, _, _)) | |
199 .Times(1) | |
200 .InSequence(s1); | |
201 | |
202 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(VideoCodingModule::kNone, | |
203 kWithErrors)); | |
204 | |
205 InsertPacket(0, 0, true, false, kVideoFrameKey); | |
206 InsertPacket(0, 1, false, false, kVideoFrameKey); | |
207 InsertPacket(0, 2, false, true, kVideoFrameKey); | |
208 EXPECT_EQ(VCM_OK, vcm_->Decode(33)); // Decode timestamp 0. | |
209 vcm_->Process(); | |
210 | |
211 clock_->AdvanceTimeMilliseconds(33); | |
212 InsertPacket(3000, 3, true, false, kVideoFrameDelta); | |
213 // Packet 4 missing | |
214 InsertPacket(3000, 5, false, true, kVideoFrameDelta); | |
215 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); | |
216 vcm_->Process(); | |
217 | |
218 clock_->AdvanceTimeMilliseconds(33); | |
219 InsertPacket(6000, 6, true, false, kVideoFrameDelta); | |
220 InsertPacket(6000, 7, false, false, kVideoFrameDelta); | |
221 InsertPacket(6000, 8, false, true, kVideoFrameDelta); | |
222 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 3000 incomplete. | |
223 vcm_->Process(); | |
224 | |
225 clock_->AdvanceTimeMilliseconds(10); | |
226 EXPECT_EQ(VCM_OK, vcm_->Decode(23)); // Decode timestamp 6000 complete. | |
227 vcm_->Process(); | |
228 | |
229 clock_->AdvanceTimeMilliseconds(23); | |
230 InsertPacket(3000, 4, false, false, kVideoFrameDelta); | |
231 | |
232 InsertPacket(9000, 9, true, false, kVideoFrameDelta); | |
233 InsertPacket(9000, 10, false, false, kVideoFrameDelta); | |
234 InsertPacket(9000, 11, false, true, kVideoFrameDelta); | |
235 EXPECT_EQ(VCM_OK, vcm_->Decode(33)); // Decode timestamp 9000 complete. | |
236 } | |
237 } // namespace webrtc | |
OLD | NEW |