/*
 * Copyright (c) 2019, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <stdint.h>

#include "av1/common/blockd.h"
#include "config/aom_config.h"
#include "config/aom_scale_rtcd.h"

#include "aom/aom_codec.h"
#include "aom/aom_encoder.h"
#include "aom/aom_ext_ratectrl.h"

#include "av1/common/av1_common_int.h"

#include "av1/encoder/encoder.h"
#include "av1/encoder/av1_ext_ratectrl.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/gop_structure.h"
#include "av1/encoder/pass2_strategy.h"

// This function sets gf_group->frame_parallel_level for LF_UPDATE frames based
// on the value of parallel_frame_count.
static void set_frame_parallel_level(int *frame_parallel_level,
                                     int *parallel_frame_count,
                                     int max_parallel_frames) {
  assert(*parallel_frame_count > 0);
  // parallel_frame_count > 1 indicates subsequent frame(s) in the current
  // parallel encode set.
  *frame_parallel_level = 1 + (*parallel_frame_count > 1);
  // Update the count of no. of parallel frames.
  (*parallel_frame_count)++;
  if (*parallel_frame_count > max_parallel_frames) *parallel_frame_count = 1;
}

// This function sets gf_group->src_offset based on frame_parallel_level.
// Outputs are gf_group->src_offset and first_frame_index
static void set_src_offset(GF_GROUP *const gf_group, int *first_frame_index,
                           int cur_frame_idx, int frame_ind) {
  if (gf_group->frame_parallel_level[frame_ind] > 0) {
    if (gf_group->frame_parallel_level[frame_ind] == 1) {
      *first_frame_index = cur_frame_idx;
    }

    // Obtain the offset of the frame at frame_ind in the lookahead queue by
    // subtracting the display order hints of the current frame from the display
    // order hint of the first frame in parallel encoding set (at
    // first_frame_index).
    gf_group->src_offset[frame_ind] =
        (cur_frame_idx + gf_group->arf_src_offset[frame_ind]) -
        *first_frame_index;
  }
}

// Sets the GF_GROUP params for LF_UPDATE frames.
static inline void set_params_for_leaf_frames(
    const TWO_PASS *twopass, const TWO_PASS_FRAME *twopass_frame,
    const PRIMARY_RATE_CONTROL *p_rc, FRAME_INFO *frame_info,
    GF_GROUP *const gf_group, int *cur_frame_idx, int *frame_ind,
    int *parallel_frame_count, int max_parallel_frames,
    int do_frame_parallel_encode, int *first_frame_index, int *cur_disp_index,
    int layer_depth, int start, int end, const bool scale_max_boost) {
  gf_group->update_type[*frame_ind] = LF_UPDATE;
  gf_group->arf_src_offset[*frame_ind] = 0;
  gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
  gf_group->layer_depth[*frame_ind] = MAX_ARF_LAYERS;
  gf_group->frame_type[*frame_ind] = INTER_FRAME;
  gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;
  gf_group->max_layer_depth = AOMMAX(gf_group->max_layer_depth, layer_depth);
  gf_group->display_idx[*frame_ind] = (*cur_disp_index);
  gf_group->arf_boost[*frame_ind] =
      av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, start,
                         end - start, 0, NULL, NULL, 0, scale_max_boost);
  ++(*cur_disp_index);

  // Set the level of parallelism for the LF_UPDATE frame.
  if (do_frame_parallel_encode) {
    set_frame_parallel_level(&gf_group->frame_parallel_level[*frame_ind],
                             parallel_frame_count, max_parallel_frames);
    // Set LF_UPDATE frames as non-reference frames.
    gf_group->is_frame_non_ref[*frame_ind] = true;
  }
  set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);

  ++(*frame_ind);
  ++(*cur_frame_idx);
}

// Sets the GF_GROUP params for INTNL_OVERLAY_UPDATE frames.
static inline void set_params_for_intnl_overlay_frames(
    GF_GROUP *const gf_group, int *cur_frame_idx, int *frame_ind,
    int *first_frame_index, int *cur_disp_index, int layer_depth) {
  gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE;
  gf_group->arf_src_offset[*frame_ind] = 0;
  gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
  gf_group->layer_depth[*frame_ind] = layer_depth;
  gf_group->frame_type[*frame_ind] = INTER_FRAME;
  gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;
  gf_group->display_idx[*frame_ind] = (*cur_disp_index);
  ++(*cur_disp_index);

  set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);
  ++(*frame_ind);
  ++(*cur_frame_idx);
}

// Sets the GF_GROUP params for INTNL_ARF_UPDATE frames.
static inline void set_params_for_internal_arfs(
    const TWO_PASS *twopass, const TWO_PASS_FRAME *twopass_frame,
    const PRIMARY_RATE_CONTROL *p_rc, FRAME_INFO *frame_info,
    GF_GROUP *const gf_group, int *cur_frame_idx, int *frame_ind,
    int *parallel_frame_count, int max_parallel_frames,
    int do_frame_parallel_encode, int *first_frame_index, int depth_thr,
    int *cur_disp_idx, int layer_depth, int arf_src_offset, int offset,
    int f_frames, int b_frames, const bool scale_max_boost) {
  gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
  gf_group->arf_src_offset[*frame_ind] = arf_src_offset;
  gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
  gf_group->layer_depth[*frame_ind] = layer_depth;
  gf_group->frame_type[*frame_ind] = INTER_FRAME;
  gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;
  gf_group->display_idx[*frame_ind] =
      (*cur_disp_idx) + gf_group->arf_src_offset[*frame_ind];
  gf_group->arf_boost[*frame_ind] =
      av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, offset,
                         f_frames, b_frames, NULL, NULL, 0, scale_max_boost);

  if (do_frame_parallel_encode) {
    if (depth_thr != INT_MAX) {
      assert(depth_thr == 3 || depth_thr == 4);
      assert(IMPLIES(depth_thr == 3, layer_depth == 4));
      assert(IMPLIES(depth_thr == 4, layer_depth == 5));
      // Set frame_parallel_level of the first frame in the given layer to 1.
      if (gf_group->layer_depth[(*frame_ind) - 1] != layer_depth) {
        gf_group->frame_parallel_level[*frame_ind] = 1;
      } else {
        // Set frame_parallel_level of the consecutive frame in the same given
        // layer to 2.
        assert(gf_group->frame_parallel_level[(*frame_ind) - 1] == 1);
        gf_group->frame_parallel_level[*frame_ind] = 2;
        // Store the display order hints of the past 2 INTNL_ARF_UPDATE
        // frames which would not have been displayed at the time of the encode
        // of current frame.
        gf_group->skip_frame_refresh[*frame_ind][0] =
            gf_group->display_idx[(*frame_ind) - 1];
        gf_group->skip_frame_refresh[*frame_ind][1] =
            gf_group->display_idx[(*frame_ind) - 2];
        // Set the display_idx of frame_parallel_level 1 frame in
        // gf_group->skip_frame_as_ref.
        gf_group->skip_frame_as_ref[*frame_ind] =
            gf_group->display_idx[(*frame_ind) - 1];
      }
    }
    // If max_parallel_frames is not exceeded and if the frame will not be
    // temporally filtered, encode the next internal ARF frame in parallel.
    if (*parallel_frame_count > 1 &&
        *parallel_frame_count <= max_parallel_frames) {
      if (gf_group->arf_src_offset[*frame_ind] < TF_LOOKAHEAD_IDX_THR)
        gf_group->frame_parallel_level[*frame_ind] = 2;
      *parallel_frame_count = 1;
    }
  }
  set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);
  ++(*frame_ind);
}

// Set parameters for frames between 'start' and 'end' (excluding both).
static void set_multi_layer_params_for_fp(
    const TWO_PASS *twopass, const TWO_PASS_FRAME *twopass_frame,
    GF_GROUP *const gf_group, const PRIMARY_RATE_CONTROL *p_rc,
    RATE_CONTROL *rc, FRAME_INFO *frame_info, int start, int end,
    int *cur_frame_idx, int *frame_ind, int *parallel_frame_count,
    int max_parallel_frames, int do_frame_parallel_encode,
    int *first_frame_index, int depth_thr, int *cur_disp_idx, int layer_depth,
    const bool scale_max_boost) {
  const int num_frames_to_process = end - start;

  // Either we are at the last level of the pyramid, or we don't have enough
  // frames between 'l' and 'r' to create one more level.
  if (layer_depth > gf_group->max_layer_depth_allowed ||
      num_frames_to_process < 3) {
    // Leaf nodes.
    while (start < end) {
      set_params_for_leaf_frames(
          twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx,
          frame_ind, parallel_frame_count, max_parallel_frames,
          do_frame_parallel_encode, first_frame_index, cur_disp_idx,
          layer_depth, start, end, scale_max_boost);
      ++start;
    }
  } else {
    const int m = (start + end - 1) / 2;

    // Internal ARF.
    int arf_src_offset = m - start;
    set_params_for_internal_arfs(
        twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx,
        frame_ind, parallel_frame_count, max_parallel_frames,
        do_frame_parallel_encode, first_frame_index, INT_MAX, cur_disp_idx,
        layer_depth, arf_src_offset, m, end - m, m - start, scale_max_boost);

    // If encode reordering is enabled, configure the multi-layers accordingly
    // and return. For e.g., the encode order for gf-interval 16 after
    // reordering would be 0-> 16-> 8-> 4-> 2-> 6-> 1-> 3-> 5-> 7-> 12-> 10->
    // 14-> 9-> 11-> 13-> 15.
    if (layer_depth >= depth_thr) {
      int m1 = (m + start - 1) / 2;
      int m2 = (m + 1 + end) / 2;
      int arf_src_offsets[2] = { m1 - start, m2 - start };
      // Parameters to compute arf_boost.
      int offset[2] = { m1, m2 };
      int f_frames[2] = { m - m1, end - m2 };
      int b_frames[2] = { m1 - start, m2 - (m + 1) };

      // Set GF_GROUP params for INTNL_ARF_UPDATE frames which are reordered.
      for (int i = 0; i < 2; i++) {
        set_params_for_internal_arfs(
            twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx,
            frame_ind, parallel_frame_count, max_parallel_frames,
            do_frame_parallel_encode, first_frame_index, depth_thr,
            cur_disp_idx, layer_depth + 1, arf_src_offsets[i], offset[i],
            f_frames[i], b_frames[i], scale_max_boost);
      }

      // Initialize the start and end indices to configure LF_UPDATE frames.
      int start_idx[4] = { start, m1 + 1, m + 1, end - 1 };
      int end_idx[4] = { m1, m, m2, end };
      int layer_depth_for_intnl_overlay[4] = { layer_depth + 1, layer_depth,
                                               layer_depth + 1, INVALID_IDX };

      // Set GF_GROUP params for the rest of LF_UPDATE and INTNL_OVERLAY_UPDATE
      // frames after reordering.
      for (int i = 0; i < 4; i++) {
        set_multi_layer_params_for_fp(
            twopass, twopass_frame, gf_group, p_rc, rc, frame_info,
            start_idx[i], end_idx[i], cur_frame_idx, frame_ind,
            parallel_frame_count, max_parallel_frames, do_frame_parallel_encode,
            first_frame_index, depth_thr, cur_disp_idx, layer_depth + 2,
            scale_max_boost);
        if (layer_depth_for_intnl_overlay[i] != INVALID_IDX)
          set_params_for_intnl_overlay_frames(
              gf_group, cur_frame_idx, frame_ind, first_frame_index,
              cur_disp_idx, layer_depth_for_intnl_overlay[i]);
      }
      return;
    }

    // Frames displayed before this internal ARF.
    set_multi_layer_params_for_fp(
        twopass, twopass_frame, gf_group, p_rc, rc, frame_info, start, m,
        cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames,
        do_frame_parallel_encode, first_frame_index, depth_thr, cur_disp_idx,
        layer_depth + 1, scale_max_boost);

    // Overlay for internal ARF.
    set_params_for_intnl_overlay_frames(gf_group, cur_frame_idx, frame_ind,
                                        first_frame_index, cur_disp_idx,
                                        layer_depth);

    // Frames displayed after this internal ARF.
    set_multi_layer_params_for_fp(
        twopass, twopass_frame, gf_group, p_rc, rc, frame_info, m + 1, end,
        cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames,
        do_frame_parallel_encode, first_frame_index, depth_thr, cur_disp_idx,
        layer_depth + 1, scale_max_boost);
  }
}

// Structure for bookkeeping start, end and display indices to configure
// INTNL_ARF_UPDATE frames.
typedef struct {
  int start;
  int end;
  int display_index;
} FRAME_REORDER_INFO;

// Updates the stats required to configure the GF_GROUP.
static inline void fill_arf_frame_stats(FRAME_REORDER_INFO *arf_frame_stats,
                                        int arf_frame_index, int display_idx,
                                        int start, int end) {
  arf_frame_stats[arf_frame_index].start = start;
  arf_frame_stats[arf_frame_index].end = end;
  arf_frame_stats[arf_frame_index].display_index = display_idx;
}

// Sets GF_GROUP params for INTNL_ARF_UPDATE frames. Also populates
// doh_gf_index_map and arf_frame_stats.
static inline void set_params_for_internal_arfs_in_gf14(
    GF_GROUP *const gf_group, FRAME_REORDER_INFO *arf_frame_stats,
    int *cur_frame_idx, int *cur_disp_idx, int *frame_ind,
    int *count_arf_frames, int *doh_gf_index_map, int start, int end,
    int layer_depth, int layer_with_parallel_encodes) {
  int index = (start + end - 1) / 2;
  gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
  gf_group->arf_src_offset[*frame_ind] = index - 1;
  gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
  gf_group->layer_depth[*frame_ind] = layer_depth;
  gf_group->frame_type[*frame_ind] = INTER_FRAME;
  gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;
  gf_group->display_idx[*frame_ind] =
      (*cur_disp_idx) + gf_group->arf_src_offset[*frame_ind];

  // Update the display index of the current frame with its gf index.
  doh_gf_index_map[index] = *frame_ind;
  if (layer_with_parallel_encodes) {
    assert(layer_depth == 4);
    // Set frame_parallel_level of the first frame in the given layer depth
    // to 1.
    if (gf_group->layer_depth[(*frame_ind) - 1] != layer_depth) {
      gf_group->frame_parallel_level[*frame_ind] = 1;
    } else {
      // Set frame_parallel_level of the consecutive frame in the same given
      // layer depth to 2.
      assert(gf_group->frame_parallel_level[(*frame_ind) - 1] == 1);
      gf_group->frame_parallel_level[*frame_ind] = 2;
      // Set the display_idx of frame_parallel_level 1 frame in
      // gf_group->skip_frame_as_ref.
      gf_group->skip_frame_as_ref[*frame_ind] =
          gf_group->display_idx[(*frame_ind) - 1];
    }
  }
  ++(*frame_ind);

  // Update arf_frame_stats.
  fill_arf_frame_stats(arf_frame_stats, *count_arf_frames, index, start, end);
  ++(*count_arf_frames);
}

// Sets GF_GROUP params for all INTNL_ARF_UPDATE frames in the given layer
// dpeth.
static inline void set_params_for_cur_layer_frames(
    GF_GROUP *const gf_group, FRAME_REORDER_INFO *arf_frame_stats,
    int *cur_frame_idx, int *cur_disp_idx, int *frame_ind,
    int *count_arf_frames, int *doh_gf_index_map, int num_dir, int node_start,
    int node_end, int layer_depth) {
  assert(num_dir < 3);
  int start, end;
  // Iterate through the nodes in the previous layer depth.
  for (int i = node_start; i < node_end; i++) {
    // For each node, check if a frame can be coded as INTNL_ARF_UPDATE frame on
    // either direction.
    for (int dir = 0; dir < num_dir; dir++) {
      // Checks for a frame to the left of current node.
      if (dir == 0) {
        start = arf_frame_stats[i].start;
        end = arf_frame_stats[i].display_index;
      } else {
        // Checks for a frame to the right of current node.
        start = arf_frame_stats[i].display_index + 1;
        end = arf_frame_stats[i].end;
      }
      const int num_frames_to_process = end - start;
      // Checks if a frame can be coded as INTNL_ARF_UPDATE frame. If
      // num_frames_to_process is less than 3, then there are not enough frames
      // between 'start' and 'end' to create another level.
      if (num_frames_to_process >= 3) {
        // Flag to indicate the lower layer depths for which parallel encoding
        // is enabled. Currently enabled for layer 4 frames.
        int layer_with_parallel_encodes = layer_depth == 4;
        set_params_for_internal_arfs_in_gf14(
            gf_group, arf_frame_stats, cur_frame_idx, cur_disp_idx, frame_ind,
            count_arf_frames, doh_gf_index_map, start, end, layer_depth,
            layer_with_parallel_encodes);
      }
    }
  }
}

// Configures multi-layers of the GF_GROUP when consecutive encode of frames in
// the same layer depth is enbaled.
static inline void set_multi_layer_params_for_gf14(
    const TWO_PASS *twopass, const TWO_PASS_FRAME *twopass_frame,
    const PRIMARY_RATE_CONTROL *p_rc, FRAME_INFO *frame_info,
    GF_GROUP *const gf_group, FRAME_REORDER_INFO *arf_frame_stats,
    int *cur_frame_idx, int *frame_ind, int *count_arf_frames,
    int *doh_gf_index_map, int *parallel_frame_count, int *first_frame_index,
    int *cur_disp_index, int gf_interval, int layer_depth,
    int max_parallel_frames, const bool scale_max_boost) {
  assert(layer_depth == 2);
  assert(gf_group->max_layer_depth_allowed >= 4);
  int layer, node_start, node_end = 0;
  // Maximum layer depth excluding LF_UPDATE frames is 4 since applicable only
  // for gf-interval 14.
  const int max_layer_depth = 4;
  // Iterate through each layer depth starting from 2 till 'max_layer_depth'.
  for (layer = layer_depth; layer <= max_layer_depth; layer++) {
    // 'node_start' and 'node_end' indicate the number of nodes from the
    // previous layer depth to be considered. It also corresponds to the indices
    // of arf_frame_stats.
    node_start = node_end;
    node_end = (*count_arf_frames);
    // 'num_dir' indicates the number of directions to traverse w.r.t. a given
    // node in order to choose an INTNL_ARF_UPDATE frame. Layer depth 2 would
    // have only one frame and hence needs to traverse only in the left
    // direction w.r.t the node in the previous layer.
    int num_dir = layer == 2 ? 1 : 2;
    set_params_for_cur_layer_frames(gf_group, arf_frame_stats, cur_frame_idx,
                                    cur_disp_index, frame_ind, count_arf_frames,
                                    doh_gf_index_map, num_dir, node_start,
                                    node_end, layer);
  }

  for (int i = 1; i < gf_interval; i++) {
    // Since doh_gf_index_map is already populated for all INTNL_ARF_UPDATE
    // frames in the GF_GROUP, any frame with INVALID_IDX would correspond to an
    // LF_UPDATE frame.
    if (doh_gf_index_map[i] == INVALID_IDX) {
      // LF_UPDATE frames.
      // TODO(Remya): Correct start and end parameters passed to
      // set_params_for_leaf_frames() once encode reordering for gf-interval 14
      // is enbaled for parallel encode of lower layer frames.
      set_params_for_leaf_frames(
          twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx,
          frame_ind, parallel_frame_count, max_parallel_frames, 1,
          first_frame_index, cur_disp_index, layer, 0, 0, scale_max_boost);
    } else {
      // In order to obtain the layer depths of INTNL_OVERLAY_UPDATE frames, get
      // the gf index of corresponding INTNL_ARF_UPDATE frames.
      int intnl_arf_index = doh_gf_index_map[i];
      int ld = gf_group->layer_depth[intnl_arf_index];
      set_params_for_intnl_overlay_frames(gf_group, cur_frame_idx, frame_ind,
                                          first_frame_index, cur_disp_index,
                                          ld);
    }
  }
}

// Set parameters for frames between 'start' and 'end' (excluding both).
static void set_multi_layer_params(
    const TWO_PASS *twopass, const TWO_PASS_FRAME *twopass_frame,
    GF_GROUP *const gf_group, const PRIMARY_RATE_CONTROL *p_rc,
    RATE_CONTROL *rc, FRAME_INFO *frame_info, int start, int end,
    int *cur_frame_idx, int *frame_ind, int *parallel_frame_count,
    int max_parallel_frames, int do_frame_parallel_encode,
    int *first_frame_index, int *cur_disp_idx, int layer_depth,
    const bool scale_max_boost) {
  const int num_frames_to_process = end - start;

  // Either we are at the last level of the pyramid, or we don't have enough
  // frames between 'l' and 'r' to create one more level.
  if (layer_depth > gf_group->max_layer_depth_allowed ||
      num_frames_to_process < 3) {
    // Leaf nodes.
    while (start < end) {
      gf_group->update_type[*frame_ind] = LF_UPDATE;
      gf_group->arf_src_offset[*frame_ind] = 0;
      gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
      gf_group->display_idx[*frame_ind] = *cur_disp_idx;
      gf_group->layer_depth[*frame_ind] = MAX_ARF_LAYERS;
      gf_group->arf_boost[*frame_ind] =
          av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, start,
                             end - start, 0, NULL, NULL, 0, scale_max_boost);
      gf_group->frame_type[*frame_ind] = INTER_FRAME;
      gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;
      gf_group->max_layer_depth =
          AOMMAX(gf_group->max_layer_depth, layer_depth);
      // Set the level of parallelism for the LF_UPDATE frame.
      if (do_frame_parallel_encode) {
        set_frame_parallel_level(&gf_group->frame_parallel_level[*frame_ind],
                                 parallel_frame_count, max_parallel_frames);
        // Set LF_UPDATE frames as non-reference frames.
        gf_group->is_frame_non_ref[*frame_ind] = true;
      }
      set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);
      ++(*frame_ind);
      ++(*cur_frame_idx);
      ++(*cur_disp_idx);
      ++start;
    }
  } else {
    const int m = (start + end - 1) / 2;

    // Internal ARF.
    gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
    gf_group->arf_src_offset[*frame_ind] = m - start;
    gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
    gf_group->display_idx[*frame_ind] =
        *cur_disp_idx + gf_group->arf_src_offset[*frame_ind];
    gf_group->layer_depth[*frame_ind] = layer_depth;
    gf_group->frame_type[*frame_ind] = INTER_FRAME;
    gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;

    if (do_frame_parallel_encode) {
      // If max_parallel_frames is not exceeded and if the frame will not be
      // temporally filtered, encode the next internal ARF frame in parallel.
      if (*parallel_frame_count > 1 &&
          *parallel_frame_count <= max_parallel_frames) {
        if (gf_group->arf_src_offset[*frame_ind] < TF_LOOKAHEAD_IDX_THR)
          gf_group->frame_parallel_level[*frame_ind] = 2;
        *parallel_frame_count = 1;
      }
    }
    set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);

    // Get the boost factor for intermediate ARF frames.
    gf_group->arf_boost[*frame_ind] =
        av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, m, end - m,
                           m - start, NULL, NULL, 0, scale_max_boost);
    ++(*frame_ind);

    // Frames displayed before this internal ARF.
    set_multi_layer_params(twopass, twopass_frame, gf_group, p_rc, rc,
                           frame_info, start, m, cur_frame_idx, frame_ind,
                           parallel_frame_count, max_parallel_frames,
                           do_frame_parallel_encode, first_frame_index,
                           cur_disp_idx, layer_depth + 1, scale_max_boost);

    // Overlay for internal ARF.
    gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE;
    gf_group->arf_src_offset[*frame_ind] = 0;
    gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx;
    gf_group->display_idx[*frame_ind] = *cur_disp_idx;
    gf_group->arf_boost[*frame_ind] = 0;
    gf_group->layer_depth[*frame_ind] = layer_depth;
    gf_group->frame_type[*frame_ind] = INTER_FRAME;
    gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE;

    set_src_offset(gf_group, first_frame_index, *cur_frame_idx, *frame_ind);
    ++(*frame_ind);
    ++(*cur_frame_idx);
    ++(*cur_disp_idx);

    // Frames displayed after this internal ARF.
    set_multi_layer_params(twopass, twopass_frame, gf_group, p_rc, rc,
                           frame_info, m + 1, end, cur_frame_idx, frame_ind,
                           parallel_frame_count, max_parallel_frames,
                           do_frame_parallel_encode, first_frame_index,
                           cur_disp_idx, layer_depth + 1, scale_max_boost);
  }
}

static int construct_multi_layer_gf_structure(
    AV1_COMP *cpi, TWO_PASS *twopass, GF_GROUP *const gf_group,
    RATE_CONTROL *rc, FRAME_INFO *const frame_info, int baseline_gf_interval,
    FRAME_UPDATE_TYPE first_frame_update_type) {
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  // TODO(angiebird): Why do we need "-1" here?
  const int gf_interval = baseline_gf_interval - 1;
  int frame_index = 0;
  int cur_frame_index = 0;

  // Set the display order hint for the first frame in the GF_GROUP.
  int cur_disp_index = (first_frame_update_type == KF_UPDATE)
                           ? 0
                           : cpi->common.current_frame.frame_number;

  // Initialize gf_group->frame_parallel_level, gf_group->is_frame_non_ref,
  // gf_group->src_offset and gf_group->is_frame_dropped with 0.
  memset(gf_group->frame_parallel_level, 0,
         sizeof(gf_group->frame_parallel_level));
  memset(gf_group->is_frame_non_ref, 0, sizeof(gf_group->is_frame_non_ref));
  memset(gf_group->src_offset, 0, sizeof(gf_group->src_offset));
  memset(gf_group->is_frame_dropped, 0, sizeof(gf_group->is_frame_dropped));
  // Initialize gf_group->skip_frame_refresh and gf_group->skip_frame_as_ref
  // with INVALID_IDX.
  memset(gf_group->skip_frame_refresh, INVALID_IDX,
         sizeof(gf_group->skip_frame_refresh));
  memset(gf_group->skip_frame_as_ref, INVALID_IDX,
         sizeof(gf_group->skip_frame_as_ref));

  int kf_decomp = cpi->oxcf.kf_cfg.enable_keyframe_filtering > 1;
  // This is a patch that fixes https://crbug.com/aomedia/3163
  // enable_keyframe_filtering > 1 will introduce an extra overlay frame at
  // key frame location. However when
  // baseline_gf_interval == MAX_STATIC_GF_GROUP_LENGTH, we can't
  // afford to have an extra overlay frame. Otherwise, the gf_group->size will
  // become MAX_STATIC_GF_GROUP_LENGTH + 1, which causes memory error.
  // A cheap solution is to turn of kf_decomp here.
  // TODO(angiebird): Find a systematic way to solve this issue.
  if (baseline_gf_interval == MAX_STATIC_GF_GROUP_LENGTH) {
    kf_decomp = 0;
  }
  if (first_frame_update_type == KF_UPDATE) {
    gf_group->update_type[frame_index] = kf_decomp ? ARF_UPDATE : KF_UPDATE;
    gf_group->arf_src_offset[frame_index] = 0;
    gf_group->cur_frame_idx[frame_index] = cur_frame_index;
    gf_group->layer_depth[frame_index] = 0;
    gf_group->frame_type[frame_index] = KEY_FRAME;
    gf_group->refbuf_state[frame_index] = REFBUF_RESET;
    gf_group->max_layer_depth = 0;
    gf_group->display_idx[frame_index] = cur_disp_index;
    if (!kf_decomp) cur_disp_index++;
    ++frame_index;

    if (kf_decomp) {
      gf_group->update_type[frame_index] = OVERLAY_UPDATE;
      gf_group->arf_src_offset[frame_index] = 0;
      gf_group->cur_frame_idx[frame_index] = cur_frame_index;
      gf_group->layer_depth[frame_index] = 0;
      gf_group->frame_type[frame_index] = INTER_FRAME;
      gf_group->refbuf_state[frame_index] = REFBUF_UPDATE;
      gf_group->max_layer_depth = 0;
      gf_group->display_idx[frame_index] = cur_disp_index;
      cur_disp_index++;
      ++frame_index;
    }
    cur_frame_index++;
  }

  if (first_frame_update_type == GF_UPDATE) {
    gf_group->update_type[frame_index] = GF_UPDATE;
    gf_group->arf_src_offset[frame_index] = 0;
    gf_group->cur_frame_idx[frame_index] = cur_frame_index;
    gf_group->layer_depth[frame_index] = 0;
    gf_group->frame_type[frame_index] = INTER_FRAME;
    gf_group->refbuf_state[frame_index] = REFBUF_UPDATE;
    gf_group->max_layer_depth = 0;
    gf_group->display_idx[frame_index] = cur_disp_index;
    cur_disp_index++;
    ++frame_index;
    ++cur_frame_index;
  }

  // ALTREF.
  const int use_altref = gf_group->max_layer_depth_allowed > 0;
  int is_fwd_kf = rc->frames_to_fwd_kf == gf_interval;

  const int sframe_dist = cpi->oxcf.kf_cfg.sframe_dist;
  const int sframe_mode = cpi->oxcf.kf_cfg.sframe_mode;
  const int sframe_enabled = (sframe_mode > 0) && (sframe_dist > 0);

  if (sframe_enabled) {
    switch (sframe_mode) {
      case 1: gf_group->is_sframe_due = use_altref; break;
      case 2:
        gf_group->is_sframe_due |=
            (frame_index && !(frame_index % sframe_dist));
        break;
    }
  }

  if (use_altref) {
    gf_group->update_type[frame_index] = ARF_UPDATE;
    gf_group->arf_src_offset[frame_index] = gf_interval - cur_frame_index;
    gf_group->cur_frame_idx[frame_index] = cur_frame_index;
    gf_group->layer_depth[frame_index] = 1;
    gf_group->arf_boost[frame_index] = cpi->ppi->p_rc.gfu_boost;
    gf_group->frame_type[frame_index] = is_fwd_kf                 ? KEY_FRAME
                                        : gf_group->is_sframe_due ? S_FRAME
                                                                  : INTER_FRAME;
    gf_group->is_sframe_due =
        sframe_enabled && gf_group->frame_type[frame_index] != S_FRAME;
    gf_group->refbuf_state[frame_index] = REFBUF_UPDATE;
    gf_group->max_layer_depth = 1;
    gf_group->arf_index = frame_index;
    gf_group->display_idx[frame_index] =
        cur_disp_index + gf_group->arf_src_offset[frame_index];
    ++frame_index;
  } else {
    gf_group->arf_index = -1;
  }

  // Flag to indicate if multi-layer configuration is complete.
  int is_multi_layer_configured = 0;

  // Running count of no. of frames that is part of a given parallel
  // encode set in a gf_group. Value of 1 indicates no parallel encode.
  int parallel_frame_count = 1;
  // Enable parallel encode of frames if gf_group has a multi-layer pyramid
  // structure with minimum 4 layers.
  int do_frame_parallel_encode = (cpi->ppi->num_fp_contexts > 1 && use_altref &&
                                  gf_group->max_layer_depth_allowed >= 4);

  int first_frame_index = cur_frame_index;
  const bool scale_max_boost = (cpi->oxcf.mode != REALTIME);

  if (do_frame_parallel_encode) {
    // construct_multi_layer_gf_structure() takes the input parameter
    // 'gf_interval' as p_rc->baseline_gf_interval - 1 . Below code computes the
    // actual GF_GROUP length by compensating for this offset.
    int actual_gf_length = ((first_frame_update_type == KF_UPDATE) ||
                            (first_frame_update_type == GF_UPDATE))
                               ? gf_interval
                               : gf_interval + 1;

    // In order to facilitate parallel encoding of frames in lower layer depths,
    // encode reordering is done. Currently encode reordering is enabled only
    // for gf-intervals 16 and 32. NOTE: Since the buffer holding the
    // reference frames is of size 8 (ref_frame_map[REF_FRAMES]), there is a
    // limitation on the number of hidden frames possible at any given point and
    // hence the reordering is enabled only for gf-intervals 16 and 32.
    // Disabling encode reordering for gf-interval 14 since some cross-frame
    // dependencies related to temporal filtering for FPMT is currently not
    // handled.
    int disable_gf14_reorder = 1;
    if (actual_gf_length == 14 && !disable_gf14_reorder) {
      // This array holds the gf index of INTNL_ARF_UPDATE frames in the slot
      // corresponding to their display order hint. This is used while
      // configuring the LF_UPDATE frames and INTNL_OVERLAY_UPDATE frames.
      int doh_gf_index_map[FIXED_GF_INTERVAL];
      // Initialize doh_gf_index_map with INVALID_IDX.
      memset(&doh_gf_index_map[0], INVALID_IDX,
             (sizeof(doh_gf_index_map[0]) * FIXED_GF_INTERVAL));

      FRAME_REORDER_INFO arf_frame_stats[REF_FRAMES - 1];
      // Store the stats corresponding to layer 1 frame.
      fill_arf_frame_stats(arf_frame_stats, 0, actual_gf_length, 1,
                           actual_gf_length);
      int count_arf_frames = 1;

      // Sets multi-layer params for gf-interval 14 to consecutively encode
      // frames in the same layer depth, i.e., encode order would be 0-> 14->
      // 7-> 3-> 10-> 5-> 12-> 1-> 2-> 4-> 6-> 8-> 9-> 11-> 13.
      // TODO(Remya): Set GF_GROUP param 'arf_boost' for all frames.
      set_multi_layer_params_for_gf14(
          twopass, &cpi->twopass_frame, p_rc, frame_info, gf_group,
          arf_frame_stats, &cur_frame_index, &frame_index, &count_arf_frames,
          doh_gf_index_map, &parallel_frame_count, &first_frame_index,
          &cur_disp_index, actual_gf_length, use_altref + 1,
          cpi->ppi->num_fp_contexts, scale_max_boost);

      // Set gf_group->skip_frame_refresh.
      for (int i = 0; i < actual_gf_length; i++) {
        int count = 0;
        if (gf_group->update_type[i] == INTNL_ARF_UPDATE) {
          for (int j = 0; j < i; j++) {
            // Store the display order hint of the frames which would not
            // have been displayed at the encode call of frame 'i'.
            if ((gf_group->display_idx[j] < gf_group->display_idx[i]) &&
                gf_group->update_type[j] == INTNL_ARF_UPDATE) {
              gf_group->skip_frame_refresh[i][count++] =
                  gf_group->display_idx[j];
            }
          }
        }
      }
    } else {
      // Set layer depth threshold for reordering as per the gf length.
      int depth_thr = (actual_gf_length == 16)   ? 3
                      : (actual_gf_length == 32) ? 4
                                                 : INT_MAX;

      set_multi_layer_params_for_fp(
          twopass, &cpi->twopass_frame, gf_group, p_rc, rc, frame_info,
          cur_frame_index, gf_interval, &cur_frame_index, &frame_index,
          &parallel_frame_count, cpi->ppi->num_fp_contexts,
          do_frame_parallel_encode, &first_frame_index, depth_thr,
          &cur_disp_index, use_altref + 1, scale_max_boost);
    }
    is_multi_layer_configured = 1;
  }

  // Rest of the frames.
  if (!is_multi_layer_configured)
    set_multi_layer_params(twopass, &cpi->twopass_frame, gf_group, p_rc, rc,
                           frame_info, cur_frame_index, gf_interval,
                           &cur_frame_index, &frame_index,
                           &parallel_frame_count, cpi->ppi->num_fp_contexts,
                           do_frame_parallel_encode, &first_frame_index,
                           &cur_disp_index, use_altref + 1, scale_max_boost);

  if (use_altref) {
    gf_group->update_type[frame_index] = OVERLAY_UPDATE;
    gf_group->arf_src_offset[frame_index] = 0;
    gf_group->cur_frame_idx[frame_index] = cur_frame_index;
    gf_group->layer_depth[frame_index] = MAX_ARF_LAYERS;
    gf_group->arf_boost[frame_index] = NORMAL_BOOST;
    gf_group->frame_type[frame_index] = INTER_FRAME;
    gf_group->refbuf_state[frame_index] =
        is_fwd_kf ? REFBUF_RESET : REFBUF_UPDATE;
    gf_group->display_idx[frame_index] = cur_disp_index;
    ++frame_index;
  } else {
    for (; cur_frame_index <= gf_interval; ++cur_frame_index) {
      gf_group->update_type[frame_index] = LF_UPDATE;
      gf_group->arf_src_offset[frame_index] = 0;
      gf_group->cur_frame_idx[frame_index] = cur_frame_index;
      gf_group->layer_depth[frame_index] = MAX_ARF_LAYERS;
      gf_group->arf_boost[frame_index] = NORMAL_BOOST;
      gf_group->frame_type[frame_index] = INTER_FRAME;
      gf_group->refbuf_state[frame_index] = REFBUF_UPDATE;
      gf_group->max_layer_depth = AOMMAX(gf_group->max_layer_depth, 2);
      set_src_offset(gf_group, &first_frame_index, cur_frame_index,
                     frame_index);
      gf_group->display_idx[frame_index] = cur_disp_index;
      cur_disp_index++;
      ++frame_index;
    }
  }
  if (do_frame_parallel_encode) {
    // Iterate through the gf_group and reset frame_parallel_level to 0 in case
    // a frame is marked as frame_parallel_level 1 with no subsequent
    // frame_parallel_level 2 frame(s).
    int level1_frame_idx = INT_MAX;
    int level2_frame_count = 0;
    for (int frame_idx = 0; frame_idx < frame_index; frame_idx++) {
      if (gf_group->frame_parallel_level[frame_idx] == 1) {
        // Set frame_parallel_level to 0 if only one frame is present in a
        // parallel encode set.
        if (level1_frame_idx != INT_MAX && !level2_frame_count)
          gf_group->frame_parallel_level[level1_frame_idx] = 0;
        // Book-keep frame_idx of frame_parallel_level 1 frame and reset the
        // count of frame_parallel_level 2 frames in the corresponding parallel
        // encode set.
        level1_frame_idx = frame_idx;
        level2_frame_count = 0;
      }
      if (gf_group->frame_parallel_level[frame_idx] == 2) level2_frame_count++;
    }
    // If frame_parallel_level is set to 1 for the last LF_UPDATE
    // frame in the gf_group, reset it to zero since there are no subsequent
    // frames in the gf_group.
    if (gf_group->frame_parallel_level[frame_index - 2] == 1) {
      assert(gf_group->update_type[frame_index - 2] == LF_UPDATE);
      gf_group->frame_parallel_level[frame_index - 2] = 0;
    }
  }

  for (int gf_idx = frame_index; gf_idx < MAX_STATIC_GF_GROUP_LENGTH;
       ++gf_idx) {
    gf_group->update_type[gf_idx] = LF_UPDATE;
    gf_group->arf_src_offset[gf_idx] = 0;
    gf_group->cur_frame_idx[gf_idx] = gf_idx;
    gf_group->layer_depth[gf_idx] = MAX_ARF_LAYERS;
    gf_group->arf_boost[gf_idx] = NORMAL_BOOST;
    gf_group->frame_type[gf_idx] = INTER_FRAME;
    gf_group->refbuf_state[gf_idx] = REFBUF_UPDATE;
    gf_group->max_layer_depth = AOMMAX(gf_group->max_layer_depth, 2);
  }

  return frame_index;
}

static void set_ld_layer_depth(GF_GROUP *gf_group, int gop_length) {
  int log_gop_length = 0;
  while ((1 << log_gop_length) < gop_length) {
    ++log_gop_length;
  }

  for (int gf_index = 0; gf_index < gf_group->size; ++gf_index) {
    int count = 0;
    // Find the trailing zeros
    for (; count < MAX_ARF_LAYERS; ++count) {
      if ((gf_index >> count) & 0x01) break;
    }
    gf_group->layer_depth[gf_index] = AOMMAX(log_gop_length - count, 0);
  }
  gf_group->max_layer_depth = AOMMIN(log_gop_length, MAX_ARF_LAYERS);
}

static void construct_gop_structure_from_rc(
    GF_GROUP *gf_group, aom_rc_gop_decision_t *rc_gop_decision) {
  gf_group->size = rc_gop_decision->gop_frame_count;
  for (int frame_index = 0; frame_index < gf_group->size; ++frame_index) {
    aom_rc_gop_frame_t *gop_frame_rc =
        &rc_gop_decision->gop_frame_list[frame_index];
    gf_group->update_type[frame_index] = gop_frame_rc->update_type;
    gf_group->layer_depth[frame_index] = gop_frame_rc->layer_depth;
    gf_group->update_ref_idx[frame_index] = gop_frame_rc->update_ref_idx;
    // `display_idx` means differently in libaom and RC.
    // - in libaom: it is display order index in the GOP, equivalent to
    //              `order_idx` in RC
    // - in RC: it is the number of display frames precedeing this frame, which
    //          is equivalent to `cur_frame_idx` in libaom.
    gf_group->display_idx[frame_index] = gop_frame_rc->order_idx;
    gf_group->cur_frame_idx[frame_index] = gop_frame_rc->display_idx;
    switch (gf_group->update_type[frame_index]) {
      case LF_UPDATE:
      case INTNL_OVERLAY_UPDATE:
        gf_group->arf_src_offset[frame_index] = 0;
        break;
      case ARF_UPDATE:
      case INTNL_ARF_UPDATE:
        gf_group->arf_src_offset[frame_index] =
            gop_frame_rc->order_idx - gop_frame_rc->display_idx;
        break;
      default: gf_group->arf_src_offset[frame_index] = 0;
    }
    gf_group->frame_type[frame_index] =
        gop_frame_rc->is_key_frame ? KEY_FRAME : INTER_FRAME;
    gf_group->refbuf_state[frame_index] =
        gop_frame_rc->is_key_frame ? REFBUF_RESET : REFBUF_UPDATE;
    // Always override the ref frame map from external RC.
    gf_group->use_ext_ref_frame_map[frame_index] = 1;
    for (int i = 0; i < REF_FRAMES; ++i) {
      gf_group->ref_frame_list[frame_index][i] = INVALID_IDX;
    }
    for (int i = 0; i < AOM_RC_MAX_REF_FRAMES; ++i) {
      int ref_name = gop_frame_rc->ref_frame_list.name[i];
      int buf_idx = gop_frame_rc->ref_frame_list.index[i];
      if (ref_name >= LAST_FRAME && ref_name <= ALTREF_FRAME) {
        gf_group->ref_frame_list[frame_index][ref_name] = (int8_t)buf_idx;
      }
    }
  }
}

void av1_gop_setup_structure(AV1_COMP *cpi, const int is_final_pass) {
  RATE_CONTROL *const rc = &cpi->rc;
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  GF_GROUP *const gf_group = &cpi->ppi->gf_group;
  TWO_PASS *const twopass = &cpi->ppi->twopass;
  FRAME_INFO *const frame_info = &cpi->frame_info;
  const int key_frame = rc->frames_since_key == 0;
  FRAME_UPDATE_TYPE first_frame_update_type = ARF_UPDATE;

  // define_gf_group() is called twice in av1_set_second_pass_params() with
  // `is_final_pass` being 0 and 1 separately. But only one GOP can be advanced
  // with the external RC. That is only done when `is_final_pass` is true.
  if (cpi->ext_ratectrl.ready &&
      (cpi->ext_ratectrl.funcs.rc_type & AOM_RC_GOP) != 0 &&
      cpi->ext_ratectrl.funcs.get_gop_decision != NULL && is_final_pass) {
    aom_rc_gop_decision_t gop_decision;
    aom_codec_err_t codec_status =
        av1_extrc_get_gop_decision(&cpi->ext_ratectrl, &gop_decision);
    if (codec_status != AOM_CODEC_OK) {
      aom_internal_error(cpi->common.error, codec_status,
                         "av1_extrc_get_gop_decision() failed");
    }
    construct_gop_structure_from_rc(gf_group, &gop_decision);
    if (gop_decision.gop_frame_list[0].is_key_frame) {
      rc->frames_since_key = 0;
    }
  } else {
    if (key_frame) {
      first_frame_update_type = KF_UPDATE;
      if (cpi->oxcf.kf_max_pyr_height != -1) {
        gf_group->max_layer_depth_allowed = AOMMIN(
            cpi->oxcf.kf_max_pyr_height, gf_group->max_layer_depth_allowed);
      }
    } else if (!cpi->ppi->gf_state.arf_gf_boost_lst) {
      first_frame_update_type = GF_UPDATE;
    }

    if (cpi->oxcf.algo_cfg.sharpness == 3)
      gf_group->max_layer_depth_allowed =
          AOMMIN(gf_group->max_layer_depth_allowed, 2);

    gf_group->size = construct_multi_layer_gf_structure(
        cpi, twopass, gf_group, rc, frame_info, p_rc->baseline_gf_interval,
        first_frame_update_type);

    if (gf_group->max_layer_depth_allowed == 0)
      set_ld_layer_depth(gf_group, p_rc->baseline_gf_interval);
  }
}

int av1_gop_check_forward_keyframe(const GF_GROUP *gf_group,
                                   int gf_frame_index) {
  return gf_group->frame_type[gf_frame_index] == KEY_FRAME &&
         gf_group->refbuf_state[gf_frame_index] == REFBUF_UPDATE;
}

int av1_gop_is_second_arf(const GF_GROUP *gf_group, int gf_frame_index) {
  const int arf_src_offset = gf_group->arf_src_offset[gf_frame_index];
  // TODO(angiebird): when gf_group->size == 32, it's possble to
  // have "two" second arf. Check if this is acceptable.
  if (gf_group->update_type[gf_frame_index] == INTNL_ARF_UPDATE &&
      arf_src_offset >= TF_LOOKAHEAD_IDX_THR) {
    return 1;
  }
  return 0;
}
