/*
 * 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 "av1/common/av1_common_int.h"

#include "av1/encoder/encoder.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 AOM_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) {
  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);
  ++(*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] = 1;
  }
  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 AOM_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 AOM_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) {
  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);

  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 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);
      ++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);

    // 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]);
      }

      // 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);
        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);

    // 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);
  }
}

// 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 AOM_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 AOM_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 AOM_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 AOM_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) {
  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);
    } 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 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);
      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] = 1;
      }
      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);
    ++(*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);

    // 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);
  }
}

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, false, 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;

  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 : INTER_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;
  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);

      // 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);
    }
    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);

  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);
}

void av1_gop_setup_structure(AV1_COMP *cpi) {
  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;

  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;
  }

  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;
}
