/*
 * 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] = 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 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] = 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);
    ++(*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, 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;

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