Home | History | Annotate | Download | only in source
      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