/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "testing/gtest/include/gtest/gtest.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
#include "webrtc/modules/video_coding/codecs/vp8/reference_picture_selection.h"

using webrtc::ReferencePictureSelection;

// The minimum time between reference frame updates. Should match the values
// set in reference_picture_selection.h
static const uint32_t kMinUpdateInterval = 10;
// The minimum time between decoder refreshes through restricted prediction.
// Should match the values set in reference_picture_selection.h
static const int kRtt = 10;

static const int kNoPropagationGolden =
    VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
static const int kNoPropagationAltRef =
    VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
static const int kPropagateGolden = VP8_EFLAG_FORCE_GF | VP8_EFLAG_NO_UPD_ARF |
                                    VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_LAST;
static const int kPropagateAltRef = VP8_EFLAG_FORCE_ARF | VP8_EFLAG_NO_UPD_GF |
                                    VP8_EFLAG_NO_REF_ARF |
                                    VP8_EFLAG_NO_REF_LAST;
static const int kRefreshFromGolden =
    VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF;
static const int kRefreshFromAltRef =
    VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;

class TestRPS : public ::testing::Test {
 protected:
  virtual void SetUp() {
    rps_.Init();
    // Initialize with sending a key frame and acknowledging it.
    rps_.EncodedKeyFrame(0);
    rps_.ReceivedRPSI(0);
    rps_.SetRtt(kRtt);
  }

  ReferencePictureSelection rps_;
};

TEST_F(TestRPS, TestPropagateReferenceFrames) {
  // Should propagate the alt-ref reference.
  uint32_t time = (4 * kMinUpdateInterval) / 3 + 1;
  EXPECT_EQ(rps_.EncodeFlags(1, false, 90 * time), kPropagateAltRef);
  rps_.ReceivedRPSI(1);
  time += (4 * (time + kMinUpdateInterval)) / 3 + 1;
  // Should propagate the golden reference.
  EXPECT_EQ(rps_.EncodeFlags(2, false, 90 * time), kPropagateGolden);
  rps_.ReceivedRPSI(2);
  // Should propagate the alt-ref reference.
  time = (4 * (time + kMinUpdateInterval)) / 3 + 1;
  EXPECT_EQ(rps_.EncodeFlags(3, false, 90 * time), kPropagateAltRef);
  rps_.ReceivedRPSI(3);
  // Shouldn't propagate any reference frames (except last), and the established
  // reference is alt-ref.
  time = time + kMinUpdateInterval;
  EXPECT_EQ(rps_.EncodeFlags(4, false, 90 * time), kNoPropagationAltRef);
}

TEST_F(TestRPS, TestDecoderRefresh) {
  uint32_t time = kRtt + 1;
  // No more than one refresh per RTT.
  EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
  time += 5;
  EXPECT_EQ(rps_.ReceivedSLI(90 * time), false);
  time += kRtt - 4;
  EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
  // Enough time have elapsed since the previous reference propagation, we will
  // therefore get both a refresh from golden and a propagation of alt-ref.
  EXPECT_EQ(rps_.EncodeFlags(5, true, 90 * time),
            kRefreshFromGolden | kPropagateAltRef);
  rps_.ReceivedRPSI(5);
  time += kRtt + 1;
  // Enough time for a new refresh, but not enough time for a reference
  // propagation.
  EXPECT_EQ(rps_.ReceivedSLI(90 * time), true);
  EXPECT_EQ(rps_.EncodeFlags(6, true, 90 * time),
            kRefreshFromAltRef | kNoPropagationAltRef);
}

TEST_F(TestRPS, TestWrap) {
  EXPECT_EQ(rps_.ReceivedSLI(0xffffffff), true);
  EXPECT_EQ(rps_.ReceivedSLI(1), false);
  EXPECT_EQ(rps_.ReceivedSLI(90 * 100), true);

  EXPECT_EQ(rps_.EncodeFlags(7, false, 0xffffffff), kPropagateAltRef);
  EXPECT_EQ(rps_.EncodeFlags(8, false, 1), kNoPropagationGolden);
  EXPECT_EQ(rps_.EncodeFlags(10, false, 90 * 100), kPropagateAltRef);
}
