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