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

#include <cstdint>

#include "absl/memory/memory.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/vp8_frame_config.h"
#include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "vpx/vp8cx.h"

// TODO(bugs.webrtc.org/10582): Test the behavior of UpdateConfiguration().

namespace webrtc {
namespace test {
namespace {
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,
  kTemporalUpdateNoneNoRefGoldenAltRef =
      VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_REF_ARF |
      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,
};

using BufferFlags = Vp8FrameConfig::BufferFlags;
using Vp8BufferReference = Vp8FrameConfig::Vp8BufferReference;

constexpr uint8_t kNone = static_cast<uint8_t>(Vp8BufferReference::kNone);
constexpr uint8_t kLast = static_cast<uint8_t>(Vp8BufferReference::kLast);
constexpr uint8_t kGolden = static_cast<uint8_t>(Vp8BufferReference::kGolden);
constexpr uint8_t kAltref = static_cast<uint8_t>(Vp8BufferReference::kAltref);
constexpr uint8_t kAll = kLast | kGolden | kAltref;

constexpr int ToVp8CodecFlags(uint8_t referenced_buffers,
                              uint8_t updated_buffers,
                              bool update_entropy) {
  return (((referenced_buffers & kLast) == 0) ? VP8_EFLAG_NO_REF_LAST : 0) |
         (((referenced_buffers & kGolden) == 0) ? VP8_EFLAG_NO_REF_GF : 0) |
         (((referenced_buffers & kAltref) == 0) ? VP8_EFLAG_NO_REF_ARF : 0) |
         (((updated_buffers & kLast) == 0) ? VP8_EFLAG_NO_UPD_LAST : 0) |
         (((updated_buffers & kGolden) == 0) ? VP8_EFLAG_NO_UPD_GF : 0) |
         (((updated_buffers & kAltref) == 0) ? VP8_EFLAG_NO_UPD_ARF : 0) |
         (update_entropy ? 0 : VP8_EFLAG_NO_UPD_ENTROPY);
}

constexpr int kKeyFrameFlags = ToVp8CodecFlags(kNone, kAll, true);

std::vector<uint32_t> GetTemporalLayerRates(int target_bitrate_kbps,
                                            int framerate_fps,
                                            int num_temporal_layers) {
  VideoCodec codec;
  codec.codecType = VideoCodecType::kVideoCodecVP8;
  codec.numberOfSimulcastStreams = 1;
  codec.maxBitrate = target_bitrate_kbps;
  codec.maxFramerate = framerate_fps;
  codec.simulcastStream[0].targetBitrate = target_bitrate_kbps;
  codec.simulcastStream[0].maxBitrate = target_bitrate_kbps;
  codec.simulcastStream[0].numberOfTemporalLayers = num_temporal_layers;
  codec.simulcastStream[0].active = true;
  SimulcastRateAllocator allocator(codec);
  return allocator
      .Allocate(
          VideoBitrateAllocationParameters(target_bitrate_kbps, framerate_fps))
      .GetTemporalLayerAllocation(0);
}

constexpr int kDefaultBitrateBps = 500;
constexpr int kDefaultFramerate = 30;
constexpr int kDefaultBytesPerFrame =
    (kDefaultBitrateBps / 8) / kDefaultFramerate;
constexpr int kDefaultQp = 2;
}  // namespace

class TemporalLayersTest : public ::testing::Test {
 public:
  ~TemporalLayersTest() override = default;

  CodecSpecificInfo* IgnoredCodecSpecificInfo() {
    codec_specific_info_ = absl::make_unique<CodecSpecificInfo>();
    return codec_specific_info_.get();
  }

 private:
  std::unique_ptr<CodecSpecificInfo> codec_specific_info_;
};

TEST_F(TemporalLayersTest, 2Layers) {
  constexpr int kNumLayers = 2;
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  constexpr size_t kPatternSize = 4;
  constexpr size_t kRepetitions = 4;

  const int expected_flags[kPatternSize] = {
      ToVp8CodecFlags(kLast, kLast, true),
      ToVp8CodecFlags(kLast, kGolden, true),
      ToVp8CodecFlags(kLast, kLast, true),
      ToVp8CodecFlags(kLast | kGolden, kNone, false),
  };
  const int expected_temporal_idx[kPatternSize] = {0, 1, 0, 1};
  const bool expected_layer_sync[kPatternSize] = {false, true, false, false};

  uint32_t timestamp = 0;
  for (size_t i = 0; i < kPatternSize * kRepetitions; ++i) {
    const size_t ind = i % kPatternSize;
    const bool is_keyframe = (i == 0);
    CodecSpecificInfo info;
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
    EXPECT_EQ(is_keyframe ? kKeyFrameFlags : expected_flags[ind],
              LibvpxVp8Encoder::EncodeFlags(tl_config))
        << i;
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, is_keyframe,
                    kDefaultQp, &info);
    EXPECT_TRUE(checker.CheckTemporalConfig(is_keyframe, tl_config));
    EXPECT_EQ(expected_temporal_idx[ind], info.codecSpecific.VP8.temporalIdx);
    EXPECT_EQ(expected_temporal_idx[ind], tl_config.packetizer_temporal_idx);
    EXPECT_EQ(expected_temporal_idx[ind], tl_config.encoder_layer_id);
    EXPECT_EQ(is_keyframe || expected_layer_sync[ind],
              info.codecSpecific.VP8.layerSync);
    EXPECT_EQ(expected_layer_sync[ind], tl_config.layer_sync);
    timestamp += 3000;
  }
}

TEST_F(TemporalLayersTest, 3Layers) {
  constexpr int kNumLayers = 3;
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  int expected_flags[16] = {
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefGoldenAltRef,
      kTemporalUpdateGoldenWithoutDependency,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateGolden,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefGoldenAltRef,
      kTemporalUpdateGoldenWithoutDependency,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateGolden,
      kTemporalUpdateNoneNoRefAltRef,
  };
  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) {
    const bool is_keyframe = (i == 0);
    CodecSpecificInfo info;
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
    EXPECT_EQ(is_keyframe ? kKeyFrameFlags : expected_flags[i],
              LibvpxVp8Encoder::EncodeFlags(tl_config))
        << i;
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, is_keyframe,
                    kDefaultQp, &info);
    EXPECT_TRUE(checker.CheckTemporalConfig(is_keyframe, tl_config));
    EXPECT_EQ(expected_temporal_idx[i], info.codecSpecific.VP8.temporalIdx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
    EXPECT_EQ(is_keyframe || expected_layer_sync[i],
              info.codecSpecific.VP8.layerSync);
    EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
    timestamp += 3000;
  }
}

TEST_F(TemporalLayersTest, Alternative3Layers) {
  constexpr int kNumLayers = 3;
  ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  int expected_flags[8] = {kTemporalUpdateLast,
                           kTemporalUpdateAltrefWithoutDependency,
                           kTemporalUpdateGoldenWithoutDependency,
                           kTemporalUpdateNone,
                           kTemporalUpdateLast,
                           kTemporalUpdateAltrefWithoutDependency,
                           kTemporalUpdateGoldenWithoutDependency,
                           kTemporalUpdateNone};
  int expected_temporal_idx[8] = {0, 2, 1, 2, 0, 2, 1, 2};

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

  unsigned int timestamp = 0;
  for (int i = 0; i < 8; ++i) {
    const bool is_keyframe = (i == 0);
    CodecSpecificInfo info;
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
    EXPECT_EQ(is_keyframe ? kKeyFrameFlags : expected_flags[i],
              LibvpxVp8Encoder::EncodeFlags(tl_config))
        << i;
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, is_keyframe,
                    kDefaultQp, &info);
    EXPECT_TRUE(checker.CheckTemporalConfig(is_keyframe, tl_config));
    EXPECT_EQ(expected_temporal_idx[i], info.codecSpecific.VP8.temporalIdx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
    EXPECT_EQ(is_keyframe || expected_layer_sync[i],
              info.codecSpecific.VP8.layerSync);
    EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
    timestamp += 3000;
  }
}

TEST_F(TemporalLayersTest, SearchOrder) {
  constexpr int kNumLayers = 3;
  ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Use a repeating pattern of tl 0, 2, 1, 2.
  // Tl 0, 1, 2 update last, golden, altref respectively.

  // Start with a key-frame. tl_config flags can be ignored.
  uint32_t timestamp = 0;
  Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame. First one only references TL0. Updates altref.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
  EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);

  // TL1 frame. Can only reference TL0. Updated golden.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
  EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);

  // TL2 frame. Can reference all three buffers. Golden was the last to be
  // updated, the next to last was altref.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kGolden);
  EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kAltref);
}

TEST_F(TemporalLayersTest, SearchOrderWithDrop) {
  constexpr int kNumLayers = 3;
  ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Use a repeating pattern of tl 0, 2, 1, 2.
  // Tl 0, 1, 2 update last, golden, altref respectively.

  // Start with a key-frame. tl_config flags can be ignored.
  uint32_t timestamp = 0;
  Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame. First one only references TL0. Updates altref.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
  EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);

  // Dropped TL1 frame. Can only reference TL0. Should have updated golden.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);

  // TL2 frame. Can normally reference all three buffers, but golden has not
  // been populated this cycle. Altref was last to be updated, before that last.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kAltref);
  EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kLast);
}

TEST_F(TemporalLayersTest, 4Layers) {
  constexpr int kNumLayers = 4;
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);
  int expected_flags[16] = {
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefGoldenAltRef,
      kTemporalUpdateAltrefWithoutDependency,
      kTemporalUpdateNoneNoRefGolden,
      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,  false, true,  false,
                                  false, false, false, false, false, false,
                                  false, false, false, false};

  uint32_t timestamp = 0;
  for (int i = 0; i < 16; ++i) {
    const bool is_keyframe = (i == 0);
    CodecSpecificInfo info;
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
    EXPECT_EQ(is_keyframe ? kKeyFrameFlags : expected_flags[i],
              LibvpxVp8Encoder::EncodeFlags(tl_config))
        << i;
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, is_keyframe,
                    kDefaultQp, &info);
    EXPECT_TRUE(checker.CheckTemporalConfig(is_keyframe, tl_config));
    EXPECT_EQ(expected_temporal_idx[i], info.codecSpecific.VP8.temporalIdx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.packetizer_temporal_idx);
    EXPECT_EQ(expected_temporal_idx[i], tl_config.encoder_layer_id);
    EXPECT_EQ(is_keyframe || expected_layer_sync[i],
              info.codecSpecific.VP8.layerSync);
    EXPECT_EQ(expected_layer_sync[i], tl_config.layer_sync);
    timestamp += 3000;
  }
}

TEST_F(TemporalLayersTest, DoesNotReferenceDroppedFrames) {
  constexpr int kNumLayers = 3;
  // Use a repeating pattern of tl 0, 2, 1, 2.
  // Tl 0, 1, 2 update last, golden, altref respectively.
  ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Start with a keyframe.
  uint32_t timestamp = 0;
  Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Dropped TL2 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);

  // Dropped TL1 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);

  // TL2 frame. Can reference all three buffers, valid since golden and altref
  // both contain the last keyframe.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_TRUE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_TRUE(tl_config.arf_buffer_flags & BufferFlags::kReference);

  // Restart of cycle!

  // TL0 base layer frame, updating and referencing last.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame, updating altref.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL1 frame, updating golden.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame. Can still reference all buffer since they have been update this
  // cycle.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_TRUE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_TRUE(tl_config.arf_buffer_flags & BufferFlags::kReference);

  // Restart of cycle!

  // TL0 base layer frame, updating and referencing last.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Dropped TL2 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);

  // Dropped TL1 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);

  // TL2 frame. This time golden and altref contain data from the previous cycle
  // and cannot be referenced.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
}

TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExist) {
  constexpr int kNumLayers = 3;
  // Use a repeating pattern of tl 0, 2, 1, 2.
  // Tl 0, 1 updates last, golden respectively. Altref is always last keyframe.
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Start with a keyframe.
  uint32_t timestamp = 0;
  Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Do a full cycle of the pattern.
  for (int i = 0; i < 7; ++i) {
    tl_config = tl.NextFrameConfig(0, ++timestamp);
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                    IgnoredCodecSpecificInfo());
  }

  // TL0 base layer frame, starting the cycle over.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Encoder has a hiccup and builds a queue, so frame encoding is delayed.
  // TL1 frame, updating golden.
  tl_config = tl.NextFrameConfig(0, ++timestamp);

  // TL2 frame, that should be referencing golden, but we can't be certain it's
  // not going to be dropped, so that is not allowed.
  tl_config = tl.NextFrameConfig(0, timestamp + 1);
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);

  // TL0 base layer frame.
  tl_config = tl.NextFrameConfig(0, timestamp + 2);

  // The previous four enqueued frames finally get encoded, and the updated
  // buffers are now OK to reference.
  // Enqueued TL1 frame ready.
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  // Enqueued TL2 frame.
  tl.OnEncodeDone(0, ++timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  // Enqueued TL0 frame.
  tl.OnEncodeDone(0, ++timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame, all buffers are now in a known good state, OK to reference.
  tl_config = tl.NextFrameConfig(0, ++timestamp + 1);
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_TRUE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
}

TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExistLongDelay) {
  constexpr int kNumLayers = 3;
  // Use a repeating pattern of tl 0, 2, 1, 2.
  // Tl 0, 1 updates last, golden, altref respectively.
  ScopedFieldTrials field_trial("WebRTC-UseShortVP8TL3Pattern/Enabled/");
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Start with a keyframe.
  uint32_t timestamp = 0;
  Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Do a full cycle of the pattern.
  for (int i = 0; i < 3; ++i) {
    tl_config = tl.NextFrameConfig(0, ++timestamp);
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                    IgnoredCodecSpecificInfo());
  }

  // TL0 base layer frame, starting the cycle over.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame.
  tl_config = tl.NextFrameConfig(0, ++timestamp);
  tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // Encoder has a hiccup and builds a queue, so frame encoding is delayed.
  // Encoded, but delayed frames in TL 1, 2.
  tl_config = tl.NextFrameConfig(0, timestamp + 1);
  tl_config = tl.NextFrameConfig(0, timestamp + 2);

  // Restart of the pattern!

  // Encoded, but delayed frames in TL 2, 1.
  tl_config = tl.NextFrameConfig(0, timestamp + 3);
  tl_config = tl.NextFrameConfig(0, timestamp + 4);

  // TL1 frame from last cycle is ready.
  tl.OnEncodeDone(0, timestamp + 1, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());
  // TL2 frame from last cycle is ready.
  tl.OnEncodeDone(0, timestamp + 2, kDefaultBytesPerFrame, false, kDefaultQp,
                  IgnoredCodecSpecificInfo());

  // TL2 frame, that should be referencing all buffers, but altref and golden
  // haven not been updated this cycle. (Don't be fooled by the late frames from
  // the last cycle!)
  tl_config = tl.NextFrameConfig(0, timestamp + 5);
  EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
  EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
}

TEST_F(TemporalLayersTest, KeyFrame) {
  constexpr int kNumLayers = 3;
  DefaultTemporalLayers tl(kNumLayers);
  DefaultTemporalLayersChecker checker(kNumLayers);
  tl.OnRatesUpdated(0,
                    GetTemporalLayerRates(kDefaultBytesPerFrame,
                                          kDefaultFramerate, kNumLayers),
                    kDefaultFramerate);
  tl.UpdateConfiguration(0);

  int expected_flags[8] = {
      kTemporalUpdateLastRefAltRef,
      kTemporalUpdateNoneNoRefGoldenAltRef,
      kTemporalUpdateGoldenWithoutDependency,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateLast,
      kTemporalUpdateNoneNoRefAltRef,
      kTemporalUpdateGolden,
      kTemporalUpdateNone,
  };
  int expected_temporal_idx[8] = {0, 2, 1, 2, 0, 2, 1, 2};
  bool expected_layer_sync[8] = {true,  true,  true,  false,
                                 false, false, false, false};

  uint32_t timestamp = 0;
  for (int i = 0; i < 7; ++i) {
    // Temporal pattern starts from 0 after key frame. Let the first |i| - 1
    // frames be delta frames, and the |i|th one key frame.
    for (int j = 1; j <= i; ++j) {
      // Since last frame was always a keyframe and thus index 0 in the pattern,
      // this loop starts at index 1.
      Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
      EXPECT_EQ(expected_flags[j], LibvpxVp8Encoder::EncodeFlags(tl_config))
          << j;
      tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
                      IgnoredCodecSpecificInfo());
      EXPECT_TRUE(checker.CheckTemporalConfig(false, tl_config));
      EXPECT_EQ(expected_temporal_idx[j], tl_config.packetizer_temporal_idx);
      EXPECT_EQ(expected_temporal_idx[j], tl_config.encoder_layer_id);
      EXPECT_EQ(expected_layer_sync[j], tl_config.layer_sync);
      timestamp += 3000;
    }

    CodecSpecificInfo info;
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
    tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
                    &info);
    EXPECT_TRUE(info.codecSpecific.VP8.layerSync)
        << "Key frame should be marked layer sync.";
    EXPECT_EQ(0, info.codecSpecific.VP8.temporalIdx)
        << "Key frame should always be packetized as layer 0";
    EXPECT_TRUE(checker.CheckTemporalConfig(true, tl_config));
  }
}

class TemporalLayersReferenceTest : public TemporalLayersTest,
                                    public ::testing::WithParamInterface<int> {
 public:
  TemporalLayersReferenceTest()
      : timestamp_(1),
        last_sync_timestamp_(timestamp_),
        tl0_reference_(nullptr) {}
  virtual ~TemporalLayersReferenceTest() {}

 protected:
  static const int kMaxPatternLength = 32;

  struct BufferState {
    BufferState() : BufferState(-1, 0, false) {}
    BufferState(int temporal_idx, uint32_t timestamp, bool sync)
        : temporal_idx(temporal_idx), timestamp(timestamp), sync(sync) {}
    int temporal_idx;
    uint32_t timestamp;
    bool sync;
  };

  bool UpdateSyncRefState(const BufferFlags& flags, BufferState* buffer_state) {
    if (flags & BufferFlags::kReference) {
      if (buffer_state->temporal_idx == -1)
        return true;  // References key-frame.
      if (buffer_state->temporal_idx == 0) {
        // No more than one reference to TL0 frame.
        EXPECT_EQ(nullptr, tl0_reference_);
        tl0_reference_ = buffer_state;
        return true;
      }
      return false;  // References higher layer.
    }
    return true;  // No reference, does not affect sync frame status.
  }

  void ValidateReference(const BufferFlags& flags,
                         const BufferState& buffer_state,
                         int temporal_layer) {
    if (flags & BufferFlags::kReference) {
      if (temporal_layer > 0 && buffer_state.timestamp > 0) {
        // Check that high layer reference does not go past last sync frame.
        EXPECT_GE(buffer_state.timestamp, last_sync_timestamp_);
      }
      // No reference to buffer in higher layer.
      EXPECT_LE(buffer_state.temporal_idx, temporal_layer);
    }
  }

  uint32_t timestamp_ = 1;
  uint32_t last_sync_timestamp_ = timestamp_;
  BufferState* tl0_reference_;

  BufferState last_state;
  BufferState golden_state;
  BufferState altref_state;
};

INSTANTIATE_TEST_SUITE_P(DefaultTemporalLayersTest,
                         TemporalLayersReferenceTest,
                         ::testing::Range(1, kMaxTemporalStreams + 1));

TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) {
  const int num_layers = GetParam();
  DefaultTemporalLayers tl(num_layers);
  tl.OnRatesUpdated(
      0, GetTemporalLayerRates(kDefaultBytesPerFrame, kDefaultFramerate, 1),
      kDefaultFramerate);
  tl.UpdateConfiguration(0);

  // Run through the pattern and store the frame dependencies, plus keep track
  // of the buffer state; which buffers references which temporal layers (if
  // (any). If a given buffer is never updated, it is legal to reference it
  // even for sync frames. In order to be general, don't assume TL0 always
  // updates |last|.
  std::vector<Vp8FrameConfig> tl_configs(kMaxPatternLength);
  for (int i = 0; i < kMaxPatternLength; ++i) {
    Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp_);
    tl.OnEncodeDone(0, timestamp_, kDefaultBytesPerFrame, i == 0, kDefaultQp,
                    IgnoredCodecSpecificInfo());
    ++timestamp_;
    EXPECT_FALSE(tl_config.drop_frame);
    tl_configs.push_back(tl_config);
    int temporal_idx = tl_config.encoder_layer_id;
    // For the default layers, always keep encoder and rtp layers in sync.
    EXPECT_EQ(tl_config.packetizer_temporal_idx, temporal_idx);

    // Determine if this frame is in a higher layer but references only TL0
    // or untouched buffers, if so verify it is marked as a layer sync.
    bool is_sync_frame = true;
    tl0_reference_ = nullptr;
    if (temporal_idx <= 0) {
      is_sync_frame = false;  // TL0 by definition not a sync frame.
    } else if (!UpdateSyncRefState(tl_config.last_buffer_flags, &last_state)) {
      is_sync_frame = false;
    } else if (!UpdateSyncRefState(tl_config.golden_buffer_flags,
                                   &golden_state)) {
      is_sync_frame = false;
    } else if (!UpdateSyncRefState(tl_config.arf_buffer_flags, &altref_state)) {
      is_sync_frame = false;
    }
    if (is_sync_frame) {
      // Cache timestamp for last found sync frame, so that we can verify no
      // references back past this frame.
      ASSERT_TRUE(tl0_reference_);
      last_sync_timestamp_ = tl0_reference_->timestamp;
    }
    EXPECT_EQ(tl_config.layer_sync, is_sync_frame);

    // Validate no reference from lower to high temporal layer, or backwards
    // past last reference frame.
    ValidateReference(tl_config.last_buffer_flags, last_state, temporal_idx);
    ValidateReference(tl_config.golden_buffer_flags, golden_state,
                      temporal_idx);
    ValidateReference(tl_config.arf_buffer_flags, altref_state, temporal_idx);

    // Update the current layer state.
    BufferState state = {temporal_idx, timestamp_, is_sync_frame};
    if (tl_config.last_buffer_flags & BufferFlags::kUpdate)
      last_state = state;
    if (tl_config.golden_buffer_flags & BufferFlags::kUpdate)
      golden_state = state;
    if (tl_config.arf_buffer_flags & BufferFlags::kUpdate)
      altref_state = state;
  }
}
}  // namespace test
}  // namespace webrtc
