/* Copyright (c) 2013 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 <stdlib.h>

#include <algorithm>
#include <array>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {
DefaultTemporalLayers::PendingFrame::PendingFrame() = default;
DefaultTemporalLayers::PendingFrame::PendingFrame(
    uint32_t timestamp,
    bool expired,
    uint8_t updated_buffers_mask,
    const DependencyInfo& dependency_info)
    : timestamp(timestamp),
      expired(expired),
      updated_buffer_mask(updated_buffers_mask),
      dependency_info(dependency_info) {}

namespace {
using BufferFlags = Vp8FrameConfig::BufferFlags;
using FreezeEntropy = Vp8FrameConfig::FreezeEntropy;
using Vp8BufferReference = Vp8FrameConfig::Vp8BufferReference;

constexpr BufferFlags kNone = BufferFlags::kNone;
constexpr BufferFlags kReference = BufferFlags::kReference;
constexpr BufferFlags kUpdate = BufferFlags::kUpdate;
constexpr BufferFlags kReferenceAndUpdate = BufferFlags::kReferenceAndUpdate;
constexpr FreezeEntropy kFreezeEntropy = FreezeEntropy::kFreezeEntropy;

static constexpr uint8_t kUninitializedPatternIndex =
    std::numeric_limits<uint8_t>::max();
static constexpr std::array<Vp8BufferReference, 3> kAllBuffers = {
    {Vp8BufferReference::kLast, Vp8BufferReference::kGolden,
     Vp8BufferReference::kAltref}};

std::vector<unsigned int> GetTemporalIds(size_t num_layers) {
  switch (num_layers) {
    case 1:
      // Temporal layer structure (single layer):
      // 0 0 0 0 ...
      return {0};
    case 2:
      // Temporal layer structure:
      //   1   1 ...
      // 0   0   ...
      return {0, 1};
    case 3:
      // Temporal layer structure:
      //   2   2   2   2 ...
      //     1       1   ...
      // 0       0       ...
      return {0, 2, 1, 2};
    case 4:
      // Temporal layer structure:
      //   3   3   3   3   3   3   3   3 ...
      //     2       2       2       2   ...
      //         1               1       ...
      // 0               0               ...
      return {0, 3, 2, 3, 1, 3, 2, 3};
    default:
      RTC_DCHECK_NOTREACHED();
      break;
  }
  RTC_DCHECK_NOTREACHED();
  return {0};
}

uint8_t GetUpdatedBuffers(const Vp8FrameConfig& config) {
  uint8_t flags = 0;
  if (config.last_buffer_flags & BufferFlags::kUpdate) {
    flags |= static_cast<uint8_t>(Vp8BufferReference::kLast);
  }
  if (config.golden_buffer_flags & BufferFlags::kUpdate) {
    flags |= static_cast<uint8_t>(Vp8BufferReference::kGolden);
  }
  if (config.arf_buffer_flags & BufferFlags::kUpdate) {
    flags |= static_cast<uint8_t>(Vp8BufferReference::kAltref);
  }
  return flags;
}

size_t BufferToIndex(Vp8BufferReference buffer) {
  switch (buffer) {
    case Vp8FrameConfig::Vp8BufferReference::kLast:
      return 0;
    case Vp8FrameConfig::Vp8BufferReference::kGolden:
      return 1;
    case Vp8FrameConfig::Vp8BufferReference::kAltref:
      return 2;
    case Vp8FrameConfig::Vp8BufferReference::kNone:
      RTC_CHECK_NOTREACHED();
  }
}

}  // namespace

constexpr size_t DefaultTemporalLayers::kNumReferenceBuffers;

std::vector<DefaultTemporalLayers::DependencyInfo>
DefaultTemporalLayers::GetDependencyInfo(size_t num_layers) {
  // For indexing in the patterns described below (which temporal layers they
  // belong to), see the diagram above.
  // Layer sync is done similarly for all patterns (except single stream) and
  // happens every 8 frames:
  // TL1 layer syncs by periodically by only referencing TL0 ('last'), but still
  // updating 'golden', so it can be used as a reference by future TL1 frames.
  // TL2 layer syncs just before TL1 by only depending on TL0 (and not depending
  // on TL1's buffer before TL1 has layer synced).
  // TODO(pbos): Consider cyclically updating 'arf' (and 'golden' for 1TL) for
  // the base layer in 1-3TL instead of 'last' periodically on long intervals,
  // so that if scene changes occur (user walks between rooms or rotates webcam)
  // the 'arf' (or 'golden' respectively) is not stuck on a no-longer relevant
  // keyframe.

  switch (num_layers) {
    case 1:
      // Always reference and update the same buffer.
      return {{"S", {kReferenceAndUpdate, kNone, kNone}}};
    case 2:
      // All layers can reference but not update the 'alt' buffer, this means
      // that the 'alt' buffer reference is effectively the last keyframe.
      // TL0 also references and updates the 'last' buffer.
      // TL1 also references 'last' and references and updates 'golden'.
      //   1---1   1---1 ...
      //  /   /   /   /
      // 0---0---0---0 ...
      return {{"SS", {kReferenceAndUpdate, kNone, kNone}},
              {"-S", {kReference, kUpdate, kNone}},
              {"SR", {kReferenceAndUpdate, kNone, kNone}},
              {"-D", {kReference, kReference, kNone, kFreezeEntropy}}};
    case 3:
      // All layers can reference but not update the 'alt' buffer, this means
      // that the 'alt' buffer reference is effectively the last keyframe.
      // TL0 also references and updates the 'last' buffer.
      // TL1 also references 'last' and references and updates 'golden'.
      // TL2 references both 'last' and 'golden' but updates no buffer.
      //     2     __2  _____2     __2       2
      //    /     /____/    /     /         /
      //   /     1---------/-----1         /
      //  /_____/         /_____/         /
      // 0---------------0---------------0-----
      // 0   1   2   3   4   5   6   7   8   9 ...
      return {{"SSS", {kReferenceAndUpdate, kNone, kNone}},
              {"--D", {kReference, kNone, kNone, kFreezeEntropy}},
              {"-SS", {kReference, kUpdate, kNone}},
              {"--D", {kReference, kReference, kNone, kFreezeEntropy}},
              {"SRR", {kReferenceAndUpdate, kNone, kNone}},
              {"--D", {kReference, kReference, kNone, kFreezeEntropy}},
              {"-DS", {kReference, kReferenceAndUpdate, kNone}},
              {"--D", {kReference, kReference, kNone, kFreezeEntropy}}};
    case 4:
      // TL0 references and updates only the 'last' buffer.
      // TL1 references 'last' and updates and references 'golden'.
      // TL2 references 'last' and 'golden', and references and updates 'arf'.
      // TL3 references all buffers but update none of them.
      // TODO(philipel): Set decode target information for this structure.
      return {{"----", {kReferenceAndUpdate, kNone, kNone}},
              {"----", {kReference, kNone, kNone, kFreezeEntropy}},
              {"----", {kReference, kNone, kUpdate}},
              {"----", {kReference, kNone, kReference, kFreezeEntropy}},
              {"----", {kReference, kUpdate, kNone}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}},
              {"----", {kReference, kReference, kReferenceAndUpdate}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}},
              {"----", {kReferenceAndUpdate, kNone, kNone}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}},
              {"----", {kReference, kReference, kReferenceAndUpdate}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}},
              {"----", {kReference, kReferenceAndUpdate, kNone}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}},
              {"----", {kReference, kReference, kReferenceAndUpdate}},
              {"----", {kReference, kReference, kReference, kFreezeEntropy}}};
    default:
      RTC_DCHECK_NOTREACHED();
      break;
  }
  RTC_DCHECK_NOTREACHED();
  return {{"", {kNone, kNone, kNone}}};
}

std::bitset<DefaultTemporalLayers::kNumReferenceBuffers>
DefaultTemporalLayers::DetermineStaticBuffers(
    const std::vector<DependencyInfo>& temporal_pattern) {
  std::bitset<kNumReferenceBuffers> buffers;
  buffers.set();
  for (const DependencyInfo& info : temporal_pattern) {
    uint8_t updated_buffers = GetUpdatedBuffers(info.frame_config);

    for (Vp8BufferReference buffer : kAllBuffers) {
      if (static_cast<uint8_t>(buffer) & updated_buffers) {
        buffers.reset(BufferToIndex(buffer));
      }
    }
  }
  return buffers;
}

DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers)
    : num_layers_(std::max(1, number_of_temporal_layers)),
      temporal_ids_(GetTemporalIds(num_layers_)),
      temporal_pattern_(GetDependencyInfo(num_layers_)),
      is_static_buffer_(DetermineStaticBuffers(temporal_pattern_)),
      pattern_idx_(kUninitializedPatternIndex),
      new_bitrates_bps_(std::vector<uint32_t>(num_layers_, 0u)) {
  RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
  RTC_CHECK_GE(number_of_temporal_layers, 0);
  RTC_CHECK_LE(number_of_temporal_layers, 4);
  // pattern_idx_ wraps around temporal_pattern_.size, this is incorrect if
  // temporal_ids_ are ever longer. If this is no longer correct it needs to
  // wrap at max(temporal_ids_.size(), temporal_pattern_.size()).
  RTC_DCHECK_LE(temporal_ids_.size(), temporal_pattern_.size());

  RTC_DCHECK(
      checker_ = TemporalLayersChecker::CreateTemporalLayersChecker(
          Vp8TemporalLayersType::kFixedPattern, number_of_temporal_layers));

  // Always need to start with a keyframe, so pre-populate all frame counters.
  frames_since_buffer_refresh_.fill(0);
}

DefaultTemporalLayers::~DefaultTemporalLayers() = default;

void DefaultTemporalLayers::SetQpLimits(size_t stream_index,
                                        int min_qp,
                                        int max_qp) {
  RTC_DCHECK_LT(stream_index, StreamCount());
  // Ignore.
}

size_t DefaultTemporalLayers::StreamCount() const {
  return 1;
}

bool DefaultTemporalLayers::SupportsEncoderFrameDropping(
    size_t stream_index) const {
  RTC_DCHECK_LT(stream_index, StreamCount());
  // This class allows the encoder drop frames as it sees fit.
  return true;
}

void DefaultTemporalLayers::OnRatesUpdated(
    size_t stream_index,
    const std::vector<uint32_t>& bitrates_bps,
    int framerate_fps) {
  RTC_DCHECK_LT(stream_index, StreamCount());
  RTC_DCHECK_GT(bitrates_bps.size(), 0);
  RTC_DCHECK_LE(bitrates_bps.size(), num_layers_);
  // `bitrates_bps` uses individual rate per layer, but Vp8EncoderConfig wants
  // the accumulated rate, so sum them up.
  new_bitrates_bps_ = bitrates_bps;
  new_bitrates_bps_->resize(num_layers_);
  for (size_t i = 1; i < num_layers_; ++i) {
    (*new_bitrates_bps_)[i] += (*new_bitrates_bps_)[i - 1];
  }
}

Vp8EncoderConfig DefaultTemporalLayers::UpdateConfiguration(
    size_t stream_index) {
  RTC_DCHECK_LT(stream_index, StreamCount());

  Vp8EncoderConfig config;

  if (!new_bitrates_bps_) {
    return config;
  }

  config.temporal_layer_config.emplace();
  Vp8EncoderConfig::TemporalLayerConfig& ts_config =
      config.temporal_layer_config.value();

  for (size_t i = 0; i < num_layers_; ++i) {
    ts_config.ts_target_bitrate[i] = (*new_bitrates_bps_)[i] / 1000;
    // ..., 4, 2, 1
    ts_config.ts_rate_decimator[i] = 1 << (num_layers_ - i - 1);
  }

  ts_config.ts_number_layers = num_layers_;
  ts_config.ts_periodicity = temporal_ids_.size();
  std::copy(temporal_ids_.begin(), temporal_ids_.end(),
            ts_config.ts_layer_id.begin());

  new_bitrates_bps_.reset();

  return config;
}

bool DefaultTemporalLayers::IsSyncFrame(const Vp8FrameConfig& config) const {
  // Since we always assign TL0 to 'last' in these patterns, we can infer layer
  // sync by checking if temporal id > 0 and we only reference TL0 or buffers
  // containing the last key-frame.
  if (config.packetizer_temporal_idx == 0) {
    // TL0 frames are per definition not sync frames.
    return false;
  }

  if ((config.last_buffer_flags & BufferFlags::kReference) == 0) {
    // Sync frames must reference TL0.
    return false;
  }

  if ((config.golden_buffer_flags & BufferFlags::kReference) &&
      !is_static_buffer_[BufferToIndex(Vp8BufferReference::kGolden)]) {
    // Referencing a golden frame that contains a non-(base layer|key frame).
    return false;
  }
  if ((config.arf_buffer_flags & BufferFlags::kReference) &&
      !is_static_buffer_[BufferToIndex(Vp8BufferReference::kAltref)]) {
    // Referencing an altref frame that contains a non-(base layer|key frame).
    return false;
  }

  return true;
}

Vp8FrameConfig DefaultTemporalLayers::NextFrameConfig(size_t stream_index,
                                                      uint32_t timestamp) {
  RTC_DCHECK_LT(stream_index, StreamCount());
  RTC_DCHECK_GT(num_layers_, 0);
  RTC_DCHECK_GT(temporal_pattern_.size(), 0);

  RTC_DCHECK_GT(kUninitializedPatternIndex, temporal_pattern_.size());
  const bool first_frame = (pattern_idx_ == kUninitializedPatternIndex);

  pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size();
  DependencyInfo dependency_info = temporal_pattern_[pattern_idx_];
  Vp8FrameConfig& tl_config = dependency_info.frame_config;
  tl_config.encoder_layer_id = tl_config.packetizer_temporal_idx =
      temporal_ids_[pattern_idx_ % temporal_ids_.size()];

  if (pattern_idx_ == 0) {
    // Start of new pattern iteration, set up clear state by invalidating any
    // pending frames, so that we don't make an invalid reference to a buffer
    // containing data from a previous iteration.
    for (auto& frame : pending_frames_) {
      frame.expired = true;
    }
  }

  if (first_frame) {
    tl_config = Vp8FrameConfig::GetIntraFrameConfig();
  } else {
    // Last is always ok to reference as it contains the base layer. For other
    // buffers though, we need to check if the buffer has actually been
    // refreshed this cycle of the temporal pattern. If the encoder dropped
    // a frame, it might not have.
    ValidateReferences(&tl_config.golden_buffer_flags,
                       Vp8BufferReference::kGolden);
    ValidateReferences(&tl_config.arf_buffer_flags,
                       Vp8BufferReference::kAltref);
    // Update search order to let the encoder know which buffers contains the
    // most recent data.
    UpdateSearchOrder(&tl_config);
    // Figure out if this a sync frame (non-base-layer frame with only
    // base-layer references).
    tl_config.layer_sync = IsSyncFrame(tl_config);

    // Increment frame age, this needs to be in sync with `pattern_idx_`,
    // so must update it here. Resetting age to 0 must be done when encoding is
    // complete though, and so in the case of pipelining encoder it might lag.
    // To prevent this data spill over into the next iteration,
    // the `pedning_frames_` map is reset in loops. If delay is constant,
    // the relative age should still be OK for the search order.
    for (size_t& n : frames_since_buffer_refresh_) {
      ++n;
    }
  }

  // Add frame to set of pending frames, awaiting completion.
  pending_frames_.emplace_back(timestamp, false, GetUpdatedBuffers(tl_config),
                               dependency_info);

  // Checker does not yet support encoder frame dropping, so validate flags
  // here before they can be dropped.
  // TODO(sprang): Update checker to support dropping.
  RTC_DCHECK(checker_->CheckTemporalConfig(first_frame, tl_config));

  return tl_config;
}

void DefaultTemporalLayers::ValidateReferences(BufferFlags* flags,
                                               Vp8BufferReference ref) const {
  // Check if the buffer specified by `ref` is actually referenced, and if so
  // if it also a dynamically updating one (buffers always just containing
  // keyframes are always safe to reference).
  if ((*flags & BufferFlags::kReference) &&
      !is_static_buffer_[BufferToIndex(ref)]) {
    if (NumFramesSinceBufferRefresh(ref) >= pattern_idx_) {
      // No valid buffer state, or buffer contains frame that is older than the
      // current pattern. This reference is not valid, so remove it.
      *flags = static_cast<BufferFlags>(*flags & ~BufferFlags::kReference);
    }
  }
}

void DefaultTemporalLayers::UpdateSearchOrder(Vp8FrameConfig* config) {
  // Figure out which of the buffers we can reference, and order them so that
  // the most recently refreshed is first. Otherwise prioritize last first,
  // golden second, and altref third.
  using BufferRefAge = std::pair<Vp8BufferReference, size_t>;
  std::vector<BufferRefAge> eligible_buffers;
  if (config->last_buffer_flags & BufferFlags::kReference) {
    eligible_buffers.emplace_back(
        Vp8BufferReference::kLast,
        NumFramesSinceBufferRefresh(Vp8BufferReference::kLast));
  }
  if (config->golden_buffer_flags & BufferFlags::kReference) {
    eligible_buffers.emplace_back(
        Vp8BufferReference::kGolden,
        NumFramesSinceBufferRefresh(Vp8BufferReference::kGolden));
  }
  if (config->arf_buffer_flags & BufferFlags::kReference) {
    eligible_buffers.emplace_back(
        Vp8BufferReference::kAltref,
        NumFramesSinceBufferRefresh(Vp8BufferReference::kAltref));
  }

  std::sort(eligible_buffers.begin(), eligible_buffers.end(),
            [](const BufferRefAge& lhs, const BufferRefAge& rhs) {
              if (lhs.second != rhs.second) {
                // Lower count has highest precedence.
                return lhs.second < rhs.second;
              }
              return lhs.first < rhs.first;
            });

  // Populate the search order fields where possible.
  if (!eligible_buffers.empty()) {
    config->first_reference = eligible_buffers.front().first;
    if (eligible_buffers.size() > 1)
      config->second_reference = eligible_buffers[1].first;
  }
}

size_t DefaultTemporalLayers::NumFramesSinceBufferRefresh(
    Vp8FrameConfig::Vp8BufferReference ref) const {
  return frames_since_buffer_refresh_[BufferToIndex(ref)];
}

void DefaultTemporalLayers::ResetNumFramesSinceBufferRefresh(
    Vp8FrameConfig::Vp8BufferReference ref) {
  frames_since_buffer_refresh_[BufferToIndex(ref)] = 0;
}

void DefaultTemporalLayers::CullPendingFramesBefore(uint32_t timestamp) {
  while (!pending_frames_.empty() &&
         pending_frames_.front().timestamp != timestamp) {
    pending_frames_.pop_front();
  }
}

void DefaultTemporalLayers::OnEncodeDone(size_t stream_index,
                                         uint32_t rtp_timestamp,
                                         size_t size_bytes,
                                         bool is_keyframe,
                                         int qp,
                                         CodecSpecificInfo* info) {
  RTC_DCHECK_LT(stream_index, StreamCount());
  RTC_DCHECK_GT(num_layers_, 0);

  if (size_bytes == 0) {
    RTC_LOG(LS_WARNING) << "Empty frame; treating as dropped.";
    OnFrameDropped(stream_index, rtp_timestamp);
    return;
  }

  CullPendingFramesBefore(rtp_timestamp);
  RTC_CHECK(!pending_frames_.empty());
  PendingFrame& frame = pending_frames_.front();
  RTC_DCHECK_EQ(frame.timestamp, rtp_timestamp);
  const Vp8FrameConfig& frame_config = frame.dependency_info.frame_config;
  if (is_keyframe) {
    // Signal key-frame so checker resets state.
    RTC_DCHECK(checker_->CheckTemporalConfig(true, frame_config));
  }

  CodecSpecificInfoVP8& vp8_info = info->codecSpecific.VP8;
  if (num_layers_ == 1) {
    vp8_info.temporalIdx = kNoTemporalIdx;
    vp8_info.layerSync = false;
  } else {
    if (is_keyframe) {
      // Restart the temporal pattern on keyframes.
      pattern_idx_ = 0;
      vp8_info.temporalIdx = 0;
      vp8_info.layerSync = true;  // Keyframes are always sync frames.

      for (Vp8BufferReference buffer : kAllBuffers) {
        if (is_static_buffer_[BufferToIndex(buffer)]) {
          // Update frame count of all kf-only buffers, regardless of state of
          // `pending_frames_`.
          ResetNumFramesSinceBufferRefresh(buffer);
        } else {
          // Key-frames update all buffers, this should be reflected when
          // updating state in FrameEncoded().
          frame.updated_buffer_mask |= static_cast<uint8_t>(buffer);
        }
      }
    } else {
      // Delta frame, update codec specifics with temporal id and sync flag.
      vp8_info.temporalIdx = frame_config.packetizer_temporal_idx;
      vp8_info.layerSync = frame_config.layer_sync;
    }
  }

  vp8_info.useExplicitDependencies = true;
  RTC_DCHECK_EQ(vp8_info.referencedBuffersCount, 0u);
  RTC_DCHECK_EQ(vp8_info.updatedBuffersCount, 0u);

  GenericFrameInfo& generic_frame_info = info->generic_frame_info.emplace();

  for (int i = 0; i < static_cast<int>(Vp8FrameConfig::Buffer::kCount); ++i) {
    bool references = false;
    bool updates = is_keyframe;

    if (!is_keyframe &&
        frame_config.References(static_cast<Vp8FrameConfig::Buffer>(i))) {
      RTC_DCHECK_LT(vp8_info.referencedBuffersCount,
                    arraysize(CodecSpecificInfoVP8::referencedBuffers));
      references = true;
      vp8_info.referencedBuffers[vp8_info.referencedBuffersCount++] = i;
    }

    if (is_keyframe ||
        frame_config.Updates(static_cast<Vp8FrameConfig::Buffer>(i))) {
      RTC_DCHECK_LT(vp8_info.updatedBuffersCount,
                    arraysize(CodecSpecificInfoVP8::updatedBuffers));
      updates = true;
      vp8_info.updatedBuffers[vp8_info.updatedBuffersCount++] = i;
    }

    if (references || updates) {
      generic_frame_info.encoder_buffers.emplace_back(i, references, updates);
    }
  }

  // The templates are always present on keyframes, and then refered to by
  // subsequent frames.
  if (is_keyframe) {
    info->template_structure = GetTemplateStructure(num_layers_);
    generic_frame_info.decode_target_indications =
        temporal_pattern_.front().decode_target_indications;
    generic_frame_info.temporal_id = 0;
  } else {
    generic_frame_info.decode_target_indications =
        frame.dependency_info.decode_target_indications;
    generic_frame_info.temporal_id = frame_config.packetizer_temporal_idx;
  }

  if (!frame.expired) {
    for (Vp8BufferReference buffer : kAllBuffers) {
      if (frame.updated_buffer_mask & static_cast<uint8_t>(buffer)) {
        ResetNumFramesSinceBufferRefresh(buffer);
      }
    }
  }

  pending_frames_.pop_front();
}

void DefaultTemporalLayers::OnFrameDropped(size_t stream_index,
                                           uint32_t rtp_timestamp) {
  CullPendingFramesBefore(rtp_timestamp);
  RTC_CHECK(!pending_frames_.empty());
  RTC_DCHECK_EQ(pending_frames_.front().timestamp, rtp_timestamp);
  pending_frames_.pop_front();
}

void DefaultTemporalLayers::OnPacketLossRateUpdate(float packet_loss_rate) {}

void DefaultTemporalLayers::OnRttUpdate(int64_t rtt_ms) {}

void DefaultTemporalLayers::OnLossNotification(
    const VideoEncoder::LossNotification& loss_notification) {}

FrameDependencyStructure DefaultTemporalLayers::GetTemplateStructure(
    int num_layers) const {
  RTC_CHECK_LT(num_layers, 5);
  RTC_CHECK_GT(num_layers, 0);

  FrameDependencyStructure template_structure;
  template_structure.num_decode_targets = num_layers;

  switch (num_layers) {
    case 1: {
      template_structure.templates.resize(2);
      template_structure.templates[0].T(0).Dtis("S");
      template_structure.templates[1].T(0).Dtis("S").FrameDiffs({1});
      return template_structure;
    }
    case 2: {
      template_structure.templates.resize(5);
      template_structure.templates[0].T(0).Dtis("SS");
      template_structure.templates[1].T(0).Dtis("SS").FrameDiffs({2});
      template_structure.templates[2].T(0).Dtis("SR").FrameDiffs({2});
      template_structure.templates[3].T(1).Dtis("-S").FrameDiffs({1});
      template_structure.templates[4].T(1).Dtis("-D").FrameDiffs({2, 1});
      return template_structure;
    }
    case 3: {
      template_structure.templates.resize(7);
      template_structure.templates[0].T(0).Dtis("SSS");
      template_structure.templates[1].T(0).Dtis("SSS").FrameDiffs({4});
      template_structure.templates[2].T(0).Dtis("SRR").FrameDiffs({4});
      template_structure.templates[3].T(1).Dtis("-SS").FrameDiffs({2});
      template_structure.templates[4].T(1).Dtis("-DS").FrameDiffs({4, 2});
      template_structure.templates[5].T(2).Dtis("--D").FrameDiffs({1});
      template_structure.templates[6].T(2).Dtis("--D").FrameDiffs({3, 1});
      return template_structure;
    }
    case 4: {
      template_structure.templates.resize(8);
      template_structure.templates[0].T(0).Dtis("SSSS");
      template_structure.templates[1].T(0).Dtis("SSSS").FrameDiffs({8});
      template_structure.templates[2].T(1).Dtis("-SRR").FrameDiffs({4});
      template_structure.templates[3].T(1).Dtis("-SRR").FrameDiffs({4, 8});
      template_structure.templates[4].T(2).Dtis("--SR").FrameDiffs({2});
      template_structure.templates[5].T(2).Dtis("--SR").FrameDiffs({2, 4});
      template_structure.templates[6].T(3).Dtis("---D").FrameDiffs({1});
      template_structure.templates[7].T(3).Dtis("---D").FrameDiffs({1, 3});
      return template_structure;
    }
    default:
      RTC_DCHECK_NOTREACHED();
      // To make the compiler happy!
      return template_structure;
  }
}

// Returns list of temporal dependencies for each frame in the temporal pattern.
// Values are lists of indecies in the pattern.
std::vector<std::set<uint8_t>> GetTemporalDependencies(
    int num_temporal_layers) {
  switch (num_temporal_layers) {
    case 1:
      return {{0}};
    case 2:
      return {{2}, {0}, {0}, {1, 2}};
    case 3:
      return {{4}, {0}, {0}, {0, 2}, {0}, {2, 4}, {2, 4}, {4, 6}};
    case 4:
      return {{8},    {0},         {0},         {0, 2},
              {0},    {0, 2, 4},   {0, 2, 4},   {0, 4, 6},
              {0},    {4, 6, 8},   {4, 6, 8},   {4, 8, 10},
              {4, 8}, {8, 10, 12}, {8, 10, 12}, {8, 12, 14}};
    default:
      RTC_DCHECK_NOTREACHED();
      return {};
  }
}

DefaultTemporalLayersChecker::DefaultTemporalLayersChecker(
    int num_temporal_layers)
    : TemporalLayersChecker(num_temporal_layers),
      num_layers_(std::max(1, num_temporal_layers)),
      temporal_ids_(GetTemporalIds(num_layers_)),
      temporal_dependencies_(GetTemporalDependencies(num_layers_)),
      pattern_idx_(255) {
  int i = 0;
  while (temporal_ids_.size() < temporal_dependencies_.size()) {
    temporal_ids_.push_back(temporal_ids_[i++]);
  }
}

DefaultTemporalLayersChecker::~DefaultTemporalLayersChecker() = default;

bool DefaultTemporalLayersChecker::CheckTemporalConfig(
    bool frame_is_keyframe,
    const Vp8FrameConfig& frame_config) {
  if (!TemporalLayersChecker::CheckTemporalConfig(frame_is_keyframe,
                                                  frame_config)) {
    return false;
  }
  if (frame_config.drop_frame) {
    return true;
  }

  if (frame_is_keyframe) {
    pattern_idx_ = 0;
    last_ = BufferState();
    golden_ = BufferState();
    arf_ = BufferState();
    return true;
  }

  ++pattern_idx_;
  if (pattern_idx_ == temporal_ids_.size()) {
    // All non key-frame buffers should be updated each pattern cycle.
    if (!last_.is_keyframe && !last_.is_updated_this_cycle) {
      RTC_LOG(LS_ERROR) << "Last buffer was not updated during pattern cycle.";
      return false;
    }
    if (!arf_.is_keyframe && !arf_.is_updated_this_cycle) {
      RTC_LOG(LS_ERROR) << "Arf buffer was not updated during pattern cycle.";
      return false;
    }
    if (!golden_.is_keyframe && !golden_.is_updated_this_cycle) {
      RTC_LOG(LS_ERROR)
          << "Golden buffer was not updated during pattern cycle.";
      return false;
    }
    last_.is_updated_this_cycle = false;
    arf_.is_updated_this_cycle = false;
    golden_.is_updated_this_cycle = false;
    pattern_idx_ = 0;
  }
  uint8_t expected_tl_idx = temporal_ids_[pattern_idx_];
  if (frame_config.packetizer_temporal_idx != expected_tl_idx) {
    RTC_LOG(LS_ERROR) << "Frame has an incorrect temporal index. Expected: "
                      << static_cast<int>(expected_tl_idx) << " Actual: "
                      << static_cast<int>(frame_config.packetizer_temporal_idx);
    return false;
  }

  bool need_sync = temporal_ids_[pattern_idx_] > 0 &&
                   temporal_ids_[pattern_idx_] != kNoTemporalIdx;
  std::vector<int> dependencies;

  if (frame_config.last_buffer_flags & BufferFlags::kReference) {
    uint8_t referenced_layer = temporal_ids_[last_.pattern_idx];
    if (referenced_layer > 0) {
      need_sync = false;
    }
    if (!last_.is_keyframe) {
      dependencies.push_back(last_.pattern_idx);
    }
  } else if (frame_config.first_reference == Vp8BufferReference::kLast ||
             frame_config.second_reference == Vp8BufferReference::kLast) {
    RTC_LOG(LS_ERROR)
        << "Last buffer not referenced, but present in search order.";
    return false;
  }

  if (frame_config.arf_buffer_flags & BufferFlags::kReference) {
    uint8_t referenced_layer = temporal_ids_[arf_.pattern_idx];
    if (referenced_layer > 0) {
      need_sync = false;
    }
    if (!arf_.is_keyframe) {
      dependencies.push_back(arf_.pattern_idx);
    }
  } else if (frame_config.first_reference == Vp8BufferReference::kAltref ||
             frame_config.second_reference == Vp8BufferReference::kAltref) {
    RTC_LOG(LS_ERROR)
        << "Altret buffer not referenced, but present in search order.";
    return false;
  }

  if (frame_config.golden_buffer_flags & BufferFlags::kReference) {
    uint8_t referenced_layer = temporal_ids_[golden_.pattern_idx];
    if (referenced_layer > 0) {
      need_sync = false;
    }
    if (!golden_.is_keyframe) {
      dependencies.push_back(golden_.pattern_idx);
    }
  } else if (frame_config.first_reference == Vp8BufferReference::kGolden ||
             frame_config.second_reference == Vp8BufferReference::kGolden) {
    RTC_LOG(LS_ERROR)
        << "Golden buffer not referenced, but present in search order.";
    return false;
  }

  if (need_sync != frame_config.layer_sync) {
    RTC_LOG(LS_ERROR) << "Sync bit is set incorrectly on a frame. Expected: "
                      << need_sync << " Actual: " << frame_config.layer_sync;
    return false;
  }

  if (!frame_is_keyframe) {
    size_t i;
    for (i = 0; i < dependencies.size(); ++i) {
      if (temporal_dependencies_[pattern_idx_].find(dependencies[i]) ==
          temporal_dependencies_[pattern_idx_].end()) {
        RTC_LOG(LS_ERROR)
            << "Illegal temporal dependency out of defined pattern "
               "from position "
            << static_cast<int>(pattern_idx_) << " to position "
            << static_cast<int>(dependencies[i]);
        return false;
      }
    }
  }

  if (frame_config.last_buffer_flags & BufferFlags::kUpdate) {
    last_.is_updated_this_cycle = true;
    last_.pattern_idx = pattern_idx_;
    last_.is_keyframe = false;
  }
  if (frame_config.arf_buffer_flags & BufferFlags::kUpdate) {
    arf_.is_updated_this_cycle = true;
    arf_.pattern_idx = pattern_idx_;
    arf_.is_keyframe = false;
  }
  if (frame_config.golden_buffer_flags & BufferFlags::kUpdate) {
    golden_.is_updated_this_cycle = true;
    golden_.pattern_idx = pattern_idx_;
    golden_.is_keyframe = false;
  }
  return true;
}

}  // namespace webrtc
