/*
 *  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 <memory>

#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/gmock.h"
#include "test/gtest.h"
#include "vpx/vp8cx.h"

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

namespace webrtc {
namespace test {
namespace {

using ::testing::Each;

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_ = std::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_EQ(0, info.generic_frame_info->temporal_id)
        << "Key frame should always be packetized as layer 0";
    EXPECT_THAT(info.generic_frame_info->decode_target_indications,
                Each(DecodeTargetIndication::kSwitch))
        << "Key frame is universal switch";
    EXPECT_TRUE(checker.CheckTemporalConfig(true, tl_config));
  }
}

TEST_F(TemporalLayersTest, SetsTlCountOnFirstConfigUpdate) {
  // Create an instance and fetch config update without setting any rate.
  constexpr int kNumLayers = 2;
  DefaultTemporalLayers tl(kNumLayers);
  Vp8EncoderConfig config = tl.UpdateConfiguration(0);

  // Config should indicate correct number of temporal layers, but zero bitrate.
  ASSERT_TRUE(config.temporal_layer_config.has_value());
  EXPECT_EQ(config.temporal_layer_config->ts_number_layers,
            uint32_t{kNumLayers});
  std::array<uint32_t, Vp8EncoderConfig::TemporalLayerConfig::kMaxLayers>
      kZeroRate = {};
  EXPECT_EQ(config.temporal_layer_config->ts_target_bitrate, kZeroRate);

  // On second call, no new update.
  config = tl.UpdateConfiguration(0);
  EXPECT_FALSE(config.temporal_layer_config.has_value());
}

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
