blob: 2476b989b0347fa67665ef51de1ffb81a087fb19 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:231/*
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
stefan@webrtc.org2637d612013-03-13 08:46:2511#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_interface.h"
stefan@webrtc.org2637d612013-03-13 08:46:2514#include "webrtc/modules/video_coding/main/interface/mock/mock_vcm_callbacks.h"
pbos@webrtc.orga557f432013-07-16 12:32:0515#include "webrtc/modules/video_coding/main/interface/video_coding.h"
stefan@webrtc.org2637d612013-03-13 08:46:2516#include "webrtc/modules/video_coding/main/test/test_util.h"
stefan@webrtc.org1bb21462013-01-21 07:42:1117#include "webrtc/system_wrappers/interface/clock.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:2318
19namespace webrtc {
20
21using ::testing::Return;
22using ::testing::_;
23using ::testing::ElementsAre;
24using ::testing::AllOf;
25using ::testing::Args;
26using ::testing::Field;
27using ::testing::Pointee;
28using ::testing::NiceMock;
29using ::testing::Sequence;
30
31class VCMRobustnessTest : public ::testing::Test {
32 protected:
33 static const size_t kPayloadLen = 10;
34
35 virtual void SetUp() {
stefan@webrtc.org1bb21462013-01-21 07:42:1136 clock_.reset(new SimulatedClock(0));
37 ASSERT_TRUE(clock_.get() != NULL);
stefan@webrtc.org8edccce2014-04-11 14:08:3538 vcm_ = VideoCodingModule::Create(clock_.get(), &event_factory_);
andrew@webrtc.orgb015cbe2012-10-22 18:19:2339 ASSERT_TRUE(vcm_ != NULL);
stefan@webrtc.org7fff32c2013-02-01 15:09:5740 const size_t kMaxNackListSize = 250;
41 const int kMaxPacketAgeToNack = 450;
stefan@webrtc.org06ad3842013-05-07 19:16:3342 vcm_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0);
andrew@webrtc.orgb015cbe2012-10-22 18:19:2343 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_);
andrew@webrtc.orgb015cbe2012-10-22 18:19:2354 }
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;
wu@webrtc.org7fc75bb2013-08-15 23:38:5469 rtp_info.type.Video.codec = kRtpVideoVp8;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2370 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_;
kwiberg@webrtc.orgdeb9dae2015-02-26 14:34:5582 rtc::scoped_ptr<SimulatedClock> clock_;
stefan@webrtc.org2637d612013-03-13 08:46:2583 NullEventFactory event_factory_;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2384};
85
86TEST_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,
agalusza@google.com7b2147f2013-08-01 03:15:08104 kNoErrors));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23105
106 InsertPacket(0, 0, true, false, kVideoFrameKey);
107 InsertPacket(0, 1, false, false, kVideoFrameKey);
108 InsertPacket(0, 2, false, true, kVideoFrameKey);
mikhal@webrtc.org933f8852013-05-07 16:36:00109 clock_->AdvanceTimeMilliseconds(1000 / 30);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23110
111 InsertPacket(3000, 3, true, false, kVideoFrameDelta);
112 InsertPacket(3000, 4, false, false, kVideoFrameDelta);
113 InsertPacket(3000, 5, false, true, kVideoFrameDelta);
mikhal@webrtc.org933f8852013-05-07 16:36:00114 clock_->AdvanceTimeMilliseconds(1000 / 30);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23115
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
stefan@webrtc.org1bb21462013-01-21 07:42:11120 clock_->AdvanceTimeMilliseconds(10);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23121
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);
stefan@webrtc.org1bb21462013-01-21 07:42:11127 clock_->AdvanceTimeMilliseconds(10);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23128 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);
stefan@webrtc.org1bb21462013-01-21 07:42:11134 clock_->AdvanceTimeMilliseconds(10);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23135 ASSERT_EQ(VCM_OK, vcm_->Process());
136
137 ASSERT_EQ(VCM_OK, vcm_->Decode(0));
138}
139
140TEST_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,
agalusza@google.com7b2147f2013-08-01 03:15:08148 kNoErrors));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23149
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
stefan@webrtc.org1bb21462013-01-21 07:42:11157 clock_->AdvanceTimeMilliseconds(10);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23158
159 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
160 ASSERT_EQ(VCM_OK, vcm_->Process());
161}
162
andrew@webrtc.orgb015cbe2012-10-22 18:19:23163TEST_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,
agalusza@google.com7b2147f2013-08-01 03:15:08204 kWithErrors));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23205
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
stefan@webrtc.org1bb21462013-01-21 07:42:11212 clock_->AdvanceTimeMilliseconds(33);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23213 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
stefan@webrtc.org1bb21462013-01-21 07:42:11219 clock_->AdvanceTimeMilliseconds(33);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23220 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
stefan@webrtc.org1bb21462013-01-21 07:42:11226 clock_->AdvanceTimeMilliseconds(10);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23227 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete.
228 EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
229
stefan@webrtc.org1bb21462013-01-21 07:42:11230 clock_->AdvanceTimeMilliseconds(23);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23231 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}
andrew@webrtc.orgb015cbe2012-10-22 18:19:23238} // namespace webrtc