/*
 *  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 "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/codecs/vp8/default_temporal_layers.h"

#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"

namespace webrtc {

enum {
  kTemporalUpdateLast = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
                        VP8_EFLAG_NO_REF_GF |
                        VP8_EFLAG_NO_REF_ARF,
  kTemporalUpdateGoldenWithoutDependency =
      VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
      VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateGolden =
      VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateAltrefWithoutDependency =
      VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
      VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateAltref = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateNone = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
                        VP8_EFLAG_NO_UPD_LAST |
                        VP8_EFLAG_NO_UPD_ENTROPY,
  kTemporalUpdateNoneNoRefAltRef = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
                                   VP8_EFLAG_NO_UPD_ARF |
                                   VP8_EFLAG_NO_UPD_LAST |
                                   VP8_EFLAG_NO_UPD_ENTROPY,
  kTemporalUpdateNoneNoRefGolden = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
                                   VP8_EFLAG_NO_UPD_ARF |
                                   VP8_EFLAG_NO_UPD_LAST |
                                   VP8_EFLAG_NO_UPD_ENTROPY,
  kTemporalUpdateGoldenWithoutDependencyRefAltRef =
      VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateGoldenRefAltRef = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST,
  kTemporalUpdateLastRefAltRef =
      VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF,
  kTemporalUpdateLastAndGoldenRefAltRef =
      VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF,
};

TEST(TemporalLayersTest, 2Layers) {
  DefaultTemporalLayers tl(2, 0);
  vpx_codec_enc_cfg_t cfg;
  CodecSpecificInfoVP8 vp8_info;
  tl.ConfigureBitrates(500, 500, 30, &cfg);

  int expected_flags[16] = {
      kTemporalUpdateLastAndGoldenRefAltRef,
      kTemporalUpdateGoldenWithoutDependencyRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateLastAndGoldenRefAltRef,
      kTemporalUpdateGoldenWithoutDependencyRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNone,
  };
  int expected_temporal_idx[16] = {0, 1, 0, 1, 0, 1, 0, 1,
                                   0, 1, 0, 1, 0, 1, 0, 1};

  bool expected_layer_sync[16] = {false, true,  false, false, false, false,
                                  false, false, false, true,  false, false,
                                  false, false, false, false};

  uint32_t timestamp = 0;
  for (int i = 0; i < 16; ++i) {
    EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
    tl.PopulateCodecSpecific(false, &vp8_info, 0);
    EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
    EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
    timestamp += 3000;
  }
}

TEST(TemporalLayersTest, 3Layers) {
  DefaultTemporalLayers tl(3, 0);
  vpx_codec_enc_cfg_t cfg;
  CodecSpecificInfoVP8 vp8_info;
  tl.ConfigureBitrates(500, 500, 30, &cfg);

  int expected_flags[16] = {
      kTemporalUpdateLastAndGoldenRefAltRef,
      kTemporalUpdateNoneNoRefGolden,
      kTemporalUpdateGoldenWithoutDependencyRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateLastAndGoldenRefAltRef,
      kTemporalUpdateNoneNoRefGolden,
      kTemporalUpdateGoldenWithoutDependencyRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateNone,
  };
  int expected_temporal_idx[16] = {0, 2, 1, 2, 0, 2, 1, 2,
                                   0, 2, 1, 2, 0, 2, 1, 2};

  bool expected_layer_sync[16] = {false, true,  true,  false, false, false,
                                  false, false, false, true,  true,  false,
                                  false, false, false, false};

  unsigned int timestamp = 0;
  for (int i = 0; i < 16; ++i) {
    EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
    tl.PopulateCodecSpecific(false, &vp8_info, 0);
    EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
    EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
    timestamp += 3000;
  }
}

TEST(TemporalLayersTest, 4Layers) {
  DefaultTemporalLayers tl(4, 0);
  vpx_codec_enc_cfg_t cfg;
  CodecSpecificInfoVP8 vp8_info;
  tl.ConfigureBitrates(500, 500, 30, &cfg);
  int expected_flags[16] = {
      kTemporalUpdateLast,
      kTemporalUpdateNone,
      kTemporalUpdateAltrefWithoutDependency,
      kTemporalUpdateNone,
      kTemporalUpdateGoldenWithoutDependency,
      kTemporalUpdateNone,
      kTemporalUpdateAltref,
      kTemporalUpdateNone,
      kTemporalUpdateLast,
      kTemporalUpdateNone,
      kTemporalUpdateAltref,
      kTemporalUpdateNone,
      kTemporalUpdateGolden,
      kTemporalUpdateNone,
      kTemporalUpdateAltref,
      kTemporalUpdateNone,
  };
  int expected_temporal_idx[16] = {0, 3, 2, 3, 1, 3, 2, 3,
                                   0, 3, 2, 3, 1, 3, 2, 3};

  bool expected_layer_sync[16] = {false, true, true,  true, true,  true,
                                  false, true, false, true, false, true,
                                  false, true, false, true};

  uint32_t timestamp = 0;
  for (int i = 0; i < 16; ++i) {
    EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
    tl.PopulateCodecSpecific(false, &vp8_info, 0);
    EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
    EXPECT_EQ(expected_layer_sync[i], vp8_info.layerSync);
    timestamp += 3000;
  }
}

TEST(TemporalLayersTest, KeyFrame) {
  DefaultTemporalLayers tl(3, 0);
  vpx_codec_enc_cfg_t cfg;
  CodecSpecificInfoVP8 vp8_info;
  tl.ConfigureBitrates(500, 500, 30, &cfg);

  int expected_flags[8] = {
      kTemporalUpdateLastAndGoldenRefAltRef,
      kTemporalUpdateNoneNoRefGolden,
      kTemporalUpdateGoldenWithoutDependencyRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNone,
      kTemporalUpdateGoldenRefAltRef,
      kTemporalUpdateNone,
  };
  int expected_temporal_idx[8] = {0, 0, 0, 0, 0, 0, 0, 2};

  uint32_t timestamp = 0;
  for (int i = 0; i < 7; ++i) {
    EXPECT_EQ(expected_flags[i], tl.EncodeFlags(timestamp));
    tl.PopulateCodecSpecific(true, &vp8_info, 0);
    EXPECT_EQ(expected_temporal_idx[i], vp8_info.temporalIdx);
    EXPECT_EQ(true, vp8_info.layerSync);
    timestamp += 3000;
  }
  EXPECT_EQ(expected_flags[7], tl.EncodeFlags(timestamp));
  tl.PopulateCodecSpecific(false, &vp8_info, 0);
  EXPECT_EQ(expected_temporal_idx[7], vp8_info.temporalIdx);
  EXPECT_EQ(true, vp8_info.layerSync);
}
}  // namespace webrtc
