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_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" 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 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_, 49 video_codec_.plType, 50 true)); 51 } 52 53 virtual void TearDown() { 54 VideoCodingModule::Destroy(vcm_); 55 } 56 57 void InsertPacket(uint32_t timestamp, 58 uint16_t seq_no, 59 bool first, 60 bool marker_bit, 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; 73 74 ASSERT_EQ(VCM_OK, vcm_->IncomingPacket(payload, kPayloadLen, rtp_info)); 75 } 76 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_; 85 }; 86 87 TEST_F(VCMRobustnessTest, TestHardNack) { 88 Sequence s; 89 EXPECT_CALL(request_callback_, ResendPackets(_, 2)) 90 .With(Args<0, 1>(ElementsAre(6, 7))) 91 .Times(1); 92 for (int ts = 0; ts <= 6000; ts += 3000) { 93 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, ts), 94 Field(&EncodedImage::_length, 95 kPayloadLen * 3), 96 Field(&EncodedImage::_completeFrame, 97 true)), 98 false, _, _, _)) 99 .Times(1) 100 .InSequence(s); 101 } 102 103 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( 104 VideoCodingModule::kHardNack, 105 kNoErrors)); 106 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); 111 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); 116 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)); 120 121 clock_->AdvanceTimeMilliseconds(10); 122 123 ASSERT_EQ(VCM_OK, vcm_->Process()); 124 125 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); 126 127 InsertPacket(6000, 8, false, true, kVideoFrameDelta); 128 clock_->AdvanceTimeMilliseconds(10); 129 ASSERT_EQ(VCM_OK, vcm_->Process()); 130 131 ASSERT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); 132 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()); 137 138 ASSERT_EQ(VCM_OK, vcm_->Decode(0)); 139 } 140 141 TEST_F(VCMRobustnessTest, TestHardNackNoneDecoded) { 142 EXPECT_CALL(request_callback_, ResendPackets(_, _)) 143 .Times(0); 144 EXPECT_CALL(frame_type_callback_, RequestKeyFrame()) 145 .Times(1); 146 147 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( 148 VideoCodingModule::kHardNack, 149 kNoErrors)); 150 151 InsertPacket(3000, 3, true, false, kVideoFrameDelta); 152 InsertPacket(3000, 4, false, false, kVideoFrameDelta); 153 InsertPacket(3000, 5, false, true, kVideoFrameDelta); 154 155 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); 156 ASSERT_EQ(VCM_OK, vcm_->Process()); 157 158 clock_->AdvanceTimeMilliseconds(10); 159 160 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); 161 ASSERT_EQ(VCM_OK, vcm_->Process()); 162 } 163 164 TEST_F(VCMRobustnessTest, TestDualDecoder) { 165 Sequence s1, s2; 166 EXPECT_CALL(request_callback_, ResendPackets(_, 1)) 167 .With(Args<0, 1>(ElementsAre(4))) 168 .Times(1); 169 170 EXPECT_CALL(decoder_, Copy()) 171 .Times(1) 172 .WillOnce(Return(&decoderCopy_)); 173 EXPECT_CALL(decoderCopy_, Copy()) 174 .Times(1) 175 .WillOnce(Return(&decoder_)); 176 177 // Decode operations 178 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 0), 179 Field(&EncodedImage::_completeFrame, 180 true)), 181 false, _, _, _)) 182 .Times(1) 183 .InSequence(s1); 184 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000), 185 Field(&EncodedImage::_completeFrame, 186 false)), 187 false, _, _, _)) 188 .Times(1) 189 .InSequence(s1); 190 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000), 191 Field(&EncodedImage::_completeFrame, 192 true)), 193 false, _, _, _)) 194 .Times(1) 195 .InSequence(s1); 196 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 9000), 197 Field(&EncodedImage::_completeFrame, 198 true)), 199 false, _, _, _)) 200 .Times(1) 201 .InSequence(s1); 202 203 EXPECT_CALL(decoderCopy_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000), 204 Field(&EncodedImage::_completeFrame, 205 true)), 206 false, _, _, _)) 207 .Times(1) 208 .InSequence(s2); 209 EXPECT_CALL(decoderCopy_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000), 210 Field(&EncodedImage::_completeFrame, 211 true)), 212 false, _, _, _)) 213 .Times(1) 214 .InSequence(s2); 215 216 217 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( 218 VideoCodingModule::kDualDecoder, kWithErrors)); 219 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. 224 225 clock_->AdvanceTimeMilliseconds(33); 226 InsertPacket(3000, 3, true, false, kVideoFrameDelta); 227 // Packet 4 missing. 228 InsertPacket(3000, 5, false, true, kVideoFrameDelta); 229 EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0)); 230 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); 235 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. 239 240 clock_->AdvanceTimeMilliseconds(10); 241 EXPECT_EQ(VCM_OK, vcm_->Process()); // Generate NACK list. 242 243 EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete. 244 EXPECT_EQ(0, vcm_->DecodeDualFrame(0)); // Expect no dual decoder action. 245 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. 250 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. 256 } 257 258 TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) { 259 EXPECT_CALL(decoder_, InitDecode(_, _)).Times(1); 260 EXPECT_CALL(decoder_, Release()).Times(1); 261 Sequence s1; 262 EXPECT_CALL(request_callback_, ResendPackets(_, 1)) 263 .With(Args<0, 1>(ElementsAre(4))) 264 .Times(0); 265 266 EXPECT_CALL(decoder_, Copy()) 267 .Times(0); 268 EXPECT_CALL(decoderCopy_, Copy()) 269 .Times(0); 270 271 // Decode operations 272 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 0), 273 Field(&EncodedImage::_completeFrame, 274 true)), 275 false, _, _, _)) 276 .Times(1) 277 .InSequence(s1); 278 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000), 279 Field(&EncodedImage::_completeFrame, 280 false)), 281 false, _, _, _)) 282 .Times(1) 283 .InSequence(s1); 284 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000), 285 Field(&EncodedImage::_completeFrame, 286 true)), 287 false, _, _, _)) 288 .Times(1) 289 .InSequence(s1); 290 EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 9000), 291 Field(&EncodedImage::_completeFrame, 292 true)), 293 false, _, _, _)) 294 .Times(1) 295 .InSequence(s1); 296 297 ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode( 298 VideoCodingModule::kNone, 299 kWithErrors)); 300 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. 306 307 clock_->AdvanceTimeMilliseconds(33); 308 InsertPacket(3000, 3, true, false, kVideoFrameDelta); 309 // Packet 4 missing 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. 313 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. 320 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. 324 325 clock_->AdvanceTimeMilliseconds(23); 326 InsertPacket(3000, 4, false, false, kVideoFrameDelta); 327 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. 332 } 333 } // namespace webrtc 334