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