2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
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_interface.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/interface/clock.h"
21 using ::testing::Return;
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;
31 class VCMRobustnessTest : public ::testing::Test {
33 static const size_t kPayloadLen = 10;
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 ASSERT_EQ(0, vcm_->InitializeReceiver());
41 const size_t kMaxNackListSize = 250;
42 const int kMaxPacketAgeToNack = 450;
43 vcm_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0);
44 ASSERT_EQ(0, vcm_->RegisterFrameTypeCallback(&frame_type_callback_));
45 ASSERT_EQ(0, vcm_->RegisterPacketRequestCallback(&request_callback_));
46 ASSERT_EQ(VCM_OK, vcm_->Codec(kVideoCodecVP8, &video_codec_));
47 ASSERT_EQ(VCM_OK, vcm_->RegisterReceiveCodec(&video_codec_, 1));
48 ASSERT_EQ(VCM_OK, vcm_->RegisterExternalDecoder(&decoder_,
53 virtual void TearDown() {
54 VideoCodingModule::Destroy(vcm_);
57 void InsertPacket(uint32_t timestamp,
61 FrameType frame_type) {
62 const uint8_t payload[kPayloadLen] = {0};
63 WebRtcRTPHeader rtp_info;
64 memset(&rtp_info, 0, sizeof(rtp_info));
65 rtp_info.frameType = frame_type;
66 rtp_info.header.timestamp = timestamp;
67 rtp_info.header.sequenceNumber = seq_no;
68 rtp_info.header.markerBit = marker_bit;
69 rtp_info.header.payloadType = video_codec_.plType;
70 rtp_info.type.Video.codec = kRtpVideoVp8;
71 rtp_info.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
72 rtp_info.type.Video.isFirstPacket = first;
74 ASSERT_EQ(VCM_OK, vcm_->IncomingPacket(payload, kPayloadLen, rtp_info));
77 VideoCodingModule* vcm_;
78 VideoCodec video_codec_;
79 MockVCMFrameTypeCallback frame_type_callback_;
80 MockPacketRequestCallback request_callback_;
81 NiceMock<MockVideoDecoder> decoder_;
82 NiceMock<MockVideoDecoder> decoderCopy_;
83 scoped_ptr<SimulatedClock> clock_;
84 NullEventFactory event_factory_;
87 TEST_F(VCMRobustnessTest, TestHardNack) {
89 EXPECT_CALL(request_callback_, ResendPackets(_, 2))
90 .With(Args<0, 1>(ElementsAre(6, 7)))
92 for (int ts = 0; ts <= 6000; ts += 3000) {
93 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, ts),
94 Field(&EncodedImage::_length,
96 Field(&EncodedImage::_completeFrame,
103 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
104 VideoCodingModule::kHardNack,
107 InsertPacket(0, 0, true, false, kVideoFrameKey);
108 InsertPacket(0, 1, false, false, kVideoFrameKey);
109 InsertPacket(0, 2, false, true, kVideoFrameKey);
110 clock_->AdvanceTimeMilliseconds(1000 / 30);
112 InsertPacket(3000, 3, true, false, kVideoFrameDelta);
113 InsertPacket(3000, 4, false, false, kVideoFrameDelta);
114 InsertPacket(3000, 5, false, true, kVideoFrameDelta);
115 clock_->AdvanceTimeMilliseconds(1000 / 30);
117 ASSERT_EQ(VCM_OK, vcm_->Decode(0));
118 ASSERT_EQ(VCM_OK, vcm_->Decode(0));
119 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
121 clock_->AdvanceTimeMilliseconds(10);
123 ASSERT_EQ(VCM_OK, vcm_->Process());
125 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
127 InsertPacket(6000, 8, false, true, kVideoFrameDelta);
128 clock_->AdvanceTimeMilliseconds(10);
129 ASSERT_EQ(VCM_OK, vcm_->Process());
131 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
133 InsertPacket(6000, 6, true, false, kVideoFrameDelta);
134 InsertPacket(6000, 7, false, false, kVideoFrameDelta);
135 clock_->AdvanceTimeMilliseconds(10);
136 ASSERT_EQ(VCM_OK, vcm_->Process());
138 ASSERT_EQ(VCM_OK, vcm_->Decode(0));
141 TEST_F(VCMRobustnessTest, TestHardNackNoneDecoded) {
142 EXPECT_CALL(request_callback_, ResendPackets(_, _))
144 EXPECT_CALL(frame_type_callback_, RequestKeyFrame())
147 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
148 VideoCodingModule::kHardNack,
151 InsertPacket(3000, 3, true, false, kVideoFrameDelta);
152 InsertPacket(3000, 4, false, false, kVideoFrameDelta);
153 InsertPacket(3000, 5, false, true, kVideoFrameDelta);
155 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
156 ASSERT_EQ(VCM_OK, vcm_->Process());
158 clock_->AdvanceTimeMilliseconds(10);
160 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
161 ASSERT_EQ(VCM_OK, vcm_->Process());
164 TEST_F(VCMRobustnessTest, TestDualDecoder) {
166 EXPECT_CALL(request_callback_, ResendPackets(_, 1))
167 .With(Args<0, 1>(ElementsAre(4)))
170 EXPECT_CALL(decoder_, Copy())
172 .WillOnce(Return(&decoderCopy_));
173 EXPECT_CALL(decoderCopy_, Copy())
175 .WillOnce(Return(&decoder_));
178 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 0),
179 Field(&EncodedImage::_completeFrame,
184 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000),
185 Field(&EncodedImage::_completeFrame,
190 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000),
191 Field(&EncodedImage::_completeFrame,
196 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 9000),
197 Field(&EncodedImage::_completeFrame,
203 EXPECT_CALL(decoderCopy_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000),
204 Field(&EncodedImage::_completeFrame,
209 EXPECT_CALL(decoderCopy_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000),
210 Field(&EncodedImage::_completeFrame,
217 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
218 VideoCodingModule::kDualDecoder, kWithErrors));
220 InsertPacket(0, 0, true, false, kVideoFrameKey);
221 InsertPacket(0, 1, false, false, kVideoFrameKey);
222 InsertPacket(0, 2, false, true, kVideoFrameKey);
223 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 0.
225 clock_->AdvanceTimeMilliseconds(33);
226 InsertPacket(3000, 3, true, false, kVideoFrameDelta);
228 InsertPacket(3000, 5, false, true, kVideoFrameDelta);
229 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
231 clock_->AdvanceTimeMilliseconds(33);
232 InsertPacket(6000, 6, true, false, kVideoFrameDelta);
233 InsertPacket(6000, 7, false, false, kVideoFrameDelta);
234 InsertPacket(6000, 8, false, true, kVideoFrameDelta);
236 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 3000 incomplete.
237 // Spawn a decoder copy.
238 EXPECT_EQ(0, vcm_->DecodeDualFrame(0)); // Expect no dual decoder action.
240 clock_->AdvanceTimeMilliseconds(10);
241 EXPECT_EQ(VCM_OK, vcm_->Process()); // Generate NACK list.
243 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete.
244 EXPECT_EQ(0, vcm_->DecodeDualFrame(0)); // Expect no dual decoder action.
246 InsertPacket(3000, 4, false, false, kVideoFrameDelta);
247 EXPECT_EQ(1, vcm_->DecodeDualFrame(0)); // Dual decode of timestamp 3000.
248 EXPECT_EQ(1, vcm_->DecodeDualFrame(0)); // Dual decode of timestamp 6000.
249 EXPECT_EQ(0, vcm_->DecodeDualFrame(0)); // No more frames.
251 InsertPacket(9000, 9, true, false, kVideoFrameDelta);
252 InsertPacket(9000, 10, false, false, kVideoFrameDelta);
253 InsertPacket(9000, 11, false, true, kVideoFrameDelta);
254 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 9000 complete.
255 EXPECT_EQ(0, vcm_->DecodeDualFrame(0)); // Expect no dual decoder action.
258 TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) {
259 EXPECT_CALL(decoder_, InitDecode(_, _)).Times(1);
260 EXPECT_CALL(decoder_, Release()).Times(1);
262 EXPECT_CALL(request_callback_, ResendPackets(_, 1))
263 .With(Args<0, 1>(ElementsAre(4)))
266 EXPECT_CALL(decoder_, Copy())
268 EXPECT_CALL(decoderCopy_, Copy())
272 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 0),
273 Field(&EncodedImage::_completeFrame,
278 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000),
279 Field(&EncodedImage::_completeFrame,
284 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000),
285 Field(&EncodedImage::_completeFrame,
290 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 9000),
291 Field(&EncodedImage::_completeFrame,
297 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
298 VideoCodingModule::kNone,
301 InsertPacket(0, 0, true, false, kVideoFrameKey);
302 InsertPacket(0, 1, false, false, kVideoFrameKey);
303 InsertPacket(0, 2, false, true, kVideoFrameKey);
304 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 0.
305 EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
307 clock_->AdvanceTimeMilliseconds(33);
308 InsertPacket(3000, 3, true, false, kVideoFrameDelta);
310 InsertPacket(3000, 5, false, true, kVideoFrameDelta);
311 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
312 EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
314 clock_->AdvanceTimeMilliseconds(33);
315 InsertPacket(6000, 6, true, false, kVideoFrameDelta);
316 InsertPacket(6000, 7, false, false, kVideoFrameDelta);
317 InsertPacket(6000, 8, false, true, kVideoFrameDelta);
318 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 3000 incomplete.
319 EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
321 clock_->AdvanceTimeMilliseconds(10);
322 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete.
323 EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
325 clock_->AdvanceTimeMilliseconds(23);
326 InsertPacket(3000, 4, false, false, kVideoFrameDelta);
328 InsertPacket(9000, 9, true, false, kVideoFrameDelta);
329 InsertPacket(9000, 10, false, false, kVideoFrameDelta);
330 InsertPacket(9000, 11, false, true, kVideoFrameDelta);
331 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 9000 complete.
333 } // namespace webrtc