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