Home | History | Annotate | Download | only in vp8
      1 /*
      2  *  Copyright (c) 2011 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/gtest/include/gtest/gtest.h"
     12 #include "vpx/vpx_encoder.h"
     13 #include "vpx/vp8cx.h"
     14 #include "webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.h"
     15 
     16 using webrtc::ReferencePictureSelection;
     17 
     18 // The minimum time between reference frame updates. Should match the values
     19 // set in reference_picture_selection.h
     20 static const uint32_t kMinUpdateInterval = 10;
     21 // The minimum time between decoder refreshes through restricted prediction.
     22 // Should match the values set in reference_picture_selection.h
     23 static const int kRtt = 10;
     24 
     25 static const int kNoPropagationGolden    = VP8_EFLAG_NO_REF_ARF |
     26                                            VP8_EFLAG_NO_UPD_GF |
     27                                            VP8_EFLAG_NO_UPD_ARF;
     28 static const int kNoPropagationAltRef    = VP8_EFLAG_NO_REF_GF |
     29                                            VP8_EFLAG_NO_UPD_GF |
     30                                            VP8_EFLAG_NO_UPD_ARF;
     31 static const int kPropagateGolden        = VP8_EFLAG_FORCE_GF |
     32                                            VP8_EFLAG_NO_UPD_ARF |
     33                                            VP8_EFLAG_NO_REF_GF |
     34                                            VP8_EFLAG_NO_REF_LAST;
     35 static const int kPropagateAltRef        = VP8_EFLAG_FORCE_ARF |
     36                                            VP8_EFLAG_NO_UPD_GF |
     37                                            VP8_EFLAG_NO_REF_ARF |
     38                                            VP8_EFLAG_NO_REF_LAST;
     39 static const int kRefreshFromGolden      = VP8_EFLAG_NO_REF_LAST |
     40                                            VP8_EFLAG_NO_REF_ARF;
     41 static const int kRefreshFromAltRef      = VP8_EFLAG_NO_REF_LAST |
     42                                            VP8_EFLAG_NO_REF_GF;
     43 
     44 
     45 class TestRPS : public ::testing::Test {
     46  protected:
     47   virtual void SetUp() {
     48     rps_.Init();
     49     // Initialize with sending a key frame and acknowledging it.
     50     rps_.EncodedKeyFrame(0);
     51     rps_.ReceivedRPSI(0);
     52     rps_.SetRtt(kRtt);
     53   }
     54 
     55   ReferencePictureSelection rps_;
     56 };
     57 
     58 TEST_F(TestRPS, TestPropagateReferenceFrames) {
     59   // Should propagate the alt-ref reference.
     60   uint32_t time = (4 * kMinUpdateInterval) / 3 + 1;
     61   EXPECT_EQ(rps_.EncodeFlags(1, false, 90 * time), kPropagateAltRef);
     62   rps_.ReceivedRPSI(1);
     63   time += (4 * (time + kMinUpdateInterval)) / 3 + 1;
     64   // Should propagate the golden reference.
     65   EXPECT_EQ(rps_.EncodeFlags(2, false, 90 * time), kPropagateGolden);
     66   rps_.ReceivedRPSI(2);
     67   // Should propagate the alt-ref reference.
     68   time = (4 * (time + kMinUpdateInterval)) / 3 + 1;
     69   EXPECT_EQ(rps_.EncodeFlags(3, false, 90 * time), kPropagateAltRef);
     70   rps_.ReceivedRPSI(3);
     71   // Shouldn't propagate any reference frames (except last), and the established
     72   // reference is alt-ref.
     73   time = time + kMinUpdateInterval;
     74   EXPECT_EQ(rps_.EncodeFlags(4, false, 90 * time), kNoPropagationAltRef);
     75 }
     76 
     77 TEST_F(TestRPS, TestDecoderRefresh) {
     78   uint32_t time = kRtt + 1;
     79   // No more than one refresh per RTT.
     80   EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
     81   time += 5;
     82   EXPECT_EQ(rps_.ReceivedSLI(90 * time), false);
     83   time += kRtt - 4;
     84   EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
     85   // Enough time have elapsed since the previous reference propagation, we will
     86   // therefore get both a refresh from golden and a propagation of alt-ref.
     87   EXPECT_EQ(rps_.EncodeFlags(5, true, 90 * time), kRefreshFromGolden |
     88             kPropagateAltRef);
     89   rps_.ReceivedRPSI(5);
     90   time += kRtt + 1;
     91   // Enough time for a new refresh, but not enough time for a reference
     92   // propagation.
     93   EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
     94   EXPECT_EQ(rps_.EncodeFlags(6, true, 90 * time), kRefreshFromAltRef |
     95             kNoPropagationAltRef);
     96 }
     97 
     98 TEST_F(TestRPS, TestWrap) {
     99   EXPECT_EQ(rps_.ReceivedSLI(0xffffffff), true);
    100   EXPECT_EQ(rps_.ReceivedSLI(1), false);
    101   EXPECT_EQ(rps_.ReceivedSLI(90 * 100), true);
    102 
    103   EXPECT_EQ(rps_.EncodeFlags(7, false, 0xffffffff), kPropagateAltRef);
    104   EXPECT_EQ(rps_.EncodeFlags(8, false, 1), kNoPropagationGolden);
    105   EXPECT_EQ(rps_.EncodeFlags(10, false, 90 * 100), kPropagateAltRef);
    106 }
    107