/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#include <math.h>
#include <string.h>

#include "config/aom_dsp_rtcd.h"
#include "config/aom_scale_rtcd.h"

#include "aom/aom_integer.h"
#include "aom_ports/system_state.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/reconinter.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/pickcdef.h"

#define REDUCED_PRI_STRENGTHS_LVL1 8
#define REDUCED_PRI_STRENGTHS_LVL2 5
#define REDUCED_SEC_STRENGTHS_LVL3 2

#define REDUCED_TOTAL_STRENGTHS_LVL1 \
  (REDUCED_PRI_STRENGTHS_LVL1 * CDEF_SEC_STRENGTHS)
#define REDUCED_TOTAL_STRENGTHS_LVL2 \
  (REDUCED_PRI_STRENGTHS_LVL2 * CDEF_SEC_STRENGTHS)
#define REDUCED_TOTAL_STRENGTHS_LVL3 \
  (REDUCED_PRI_STRENGTHS_LVL2 * REDUCED_SEC_STRENGTHS_LVL3)
#define TOTAL_STRENGTHS (CDEF_PRI_STRENGTHS * CDEF_SEC_STRENGTHS)

static const int priconv_lvl1[REDUCED_PRI_STRENGTHS_LVL1] = { 0, 1, 2,  3,
                                                              5, 7, 10, 13 };
static const int priconv_lvl2[REDUCED_PRI_STRENGTHS_LVL2] = { 0, 2, 4, 8, 14 };
static const int secconv_lvl3[REDUCED_SEC_STRENGTHS_LVL3] = { 0, 2 };
static const int nb_cdef_strengths[CDEF_PICK_METHODS] = {
  TOTAL_STRENGTHS, REDUCED_TOTAL_STRENGTHS_LVL1, REDUCED_TOTAL_STRENGTHS_LVL2,
  REDUCED_TOTAL_STRENGTHS_LVL3, TOTAL_STRENGTHS
};

// Get primary and secondary filter strength for the given strength index and
// search method
static INLINE void get_cdef_filter_strengths(CDEF_PICK_METHOD pick_method,
                                             int *pri_strength,
                                             int *sec_strength,
                                             int strength_idx) {
  const int tot_sec_filter = (pick_method == CDEF_FAST_SEARCH_LVL3)
                                 ? REDUCED_SEC_STRENGTHS_LVL3
                                 : CDEF_SEC_STRENGTHS;
  const int pri_idx = strength_idx / tot_sec_filter;
  const int sec_idx = strength_idx % tot_sec_filter;
  *pri_strength = pri_idx;
  *sec_strength = sec_idx;
  if (pick_method == CDEF_FULL_SEARCH) return;

  switch (pick_method) {
    case CDEF_FAST_SEARCH_LVL1: *pri_strength = priconv_lvl1[pri_idx]; break;
    case CDEF_FAST_SEARCH_LVL2: *pri_strength = priconv_lvl2[pri_idx]; break;
    case CDEF_FAST_SEARCH_LVL3:
      *pri_strength = priconv_lvl2[pri_idx];
      *sec_strength = secconv_lvl3[sec_idx];
      break;
    default: assert(0 && "Invalid CDEF search method");
  }
}

// Store CDEF filter strength calculated from strength index for given search
// method
#define STORE_CDEF_FILTER_STRENGTH(cdef_strength, pick_method, strength_idx) \
  get_cdef_filter_strengths((pick_method), &pri_strength, &sec_strength,     \
                            (strength_idx));                                 \
  cdef_strength = pri_strength * CDEF_SEC_STRENGTHS + sec_strength;

/* Search for the best strength to add as an option, knowing we
   already selected nb_strengths options. */
static uint64_t search_one(int *lev, int nb_strengths,
                           uint64_t mse[][TOTAL_STRENGTHS], int sb_count,
                           CDEF_PICK_METHOD pick_method) {
  uint64_t tot_mse[TOTAL_STRENGTHS];
  const int total_strengths = nb_cdef_strengths[pick_method];
  int i, j;
  uint64_t best_tot_mse = (uint64_t)1 << 63;
  int best_id = 0;
  memset(tot_mse, 0, sizeof(tot_mse));
  for (i = 0; i < sb_count; i++) {
    int gi;
    uint64_t best_mse = (uint64_t)1 << 63;
    /* Find best mse among already selected options. */
    for (gi = 0; gi < nb_strengths; gi++) {
      if (mse[i][lev[gi]] < best_mse) {
        best_mse = mse[i][lev[gi]];
      }
    }
    /* Find best mse when adding each possible new option. */
    for (j = 0; j < total_strengths; j++) {
      uint64_t best = best_mse;
      if (mse[i][j] < best) best = mse[i][j];
      tot_mse[j] += best;
    }
  }
  for (j = 0; j < total_strengths; j++) {
    if (tot_mse[j] < best_tot_mse) {
      best_tot_mse = tot_mse[j];
      best_id = j;
    }
  }
  lev[nb_strengths] = best_id;
  return best_tot_mse;
}

/* Search for the best luma+chroma strength to add as an option, knowing we
   already selected nb_strengths options. */
static uint64_t search_one_dual(int *lev0, int *lev1, int nb_strengths,
                                uint64_t (**mse)[TOTAL_STRENGTHS], int sb_count,
                                CDEF_PICK_METHOD pick_method) {
  uint64_t tot_mse[TOTAL_STRENGTHS][TOTAL_STRENGTHS];
  int i, j;
  uint64_t best_tot_mse = (uint64_t)1 << 63;
  int best_id0 = 0;
  int best_id1 = 0;
  const int total_strengths = nb_cdef_strengths[pick_method];
  memset(tot_mse, 0, sizeof(tot_mse));
  for (i = 0; i < sb_count; i++) {
    int gi;
    uint64_t best_mse = (uint64_t)1 << 63;
    /* Find best mse among already selected options. */
    for (gi = 0; gi < nb_strengths; gi++) {
      uint64_t curr = mse[0][i][lev0[gi]];
      curr += mse[1][i][lev1[gi]];
      if (curr < best_mse) {
        best_mse = curr;
      }
    }
    /* Find best mse when adding each possible new option. */
    for (j = 0; j < total_strengths; j++) {
      int k;
      for (k = 0; k < total_strengths; k++) {
        uint64_t best = best_mse;
        uint64_t curr = mse[0][i][j];
        curr += mse[1][i][k];
        if (curr < best) best = curr;
        tot_mse[j][k] += best;
      }
    }
  }
  for (j = 0; j < total_strengths; j++) {
    int k;
    for (k = 0; k < total_strengths; k++) {
      if (tot_mse[j][k] < best_tot_mse) {
        best_tot_mse = tot_mse[j][k];
        best_id0 = j;
        best_id1 = k;
      }
    }
  }
  lev0[nb_strengths] = best_id0;
  lev1[nb_strengths] = best_id1;
  return best_tot_mse;
}

/* Search for the set of strengths that minimizes mse. */
static uint64_t joint_strength_search(int *best_lev, int nb_strengths,
                                      uint64_t mse[][TOTAL_STRENGTHS],
                                      int sb_count,
                                      CDEF_PICK_METHOD pick_method) {
  uint64_t best_tot_mse;
  int fast = (pick_method >= CDEF_FAST_SEARCH_LVL1 &&
              pick_method <= CDEF_FAST_SEARCH_LVL3);
  int i;
  best_tot_mse = (uint64_t)1 << 63;
  /* Greedy search: add one strength options at a time. */
  for (i = 0; i < nb_strengths; i++) {
    best_tot_mse = search_one(best_lev, i, mse, sb_count, pick_method);
  }
  /* Trying to refine the greedy search by reconsidering each
     already-selected option. */
  if (!fast) {
    for (i = 0; i < 4 * nb_strengths; i++) {
      int j;
      for (j = 0; j < nb_strengths - 1; j++) best_lev[j] = best_lev[j + 1];
      best_tot_mse =
          search_one(best_lev, nb_strengths - 1, mse, sb_count, pick_method);
    }
  }
  return best_tot_mse;
}

/* Search for the set of luma+chroma strengths that minimizes mse. */
static uint64_t joint_strength_search_dual(int *best_lev0, int *best_lev1,
                                           int nb_strengths,
                                           uint64_t (**mse)[TOTAL_STRENGTHS],
                                           int sb_count,
                                           CDEF_PICK_METHOD pick_method) {
  uint64_t best_tot_mse;
  int i;
  best_tot_mse = (uint64_t)1 << 63;
  /* Greedy search: add one strength options at a time. */
  for (i = 0; i < nb_strengths; i++) {
    best_tot_mse =
        search_one_dual(best_lev0, best_lev1, i, mse, sb_count, pick_method);
  }
  /* Trying to refine the greedy search by reconsidering each
     already-selected option. */
  for (i = 0; i < 4 * nb_strengths; i++) {
    int j;
    for (j = 0; j < nb_strengths - 1; j++) {
      best_lev0[j] = best_lev0[j + 1];
      best_lev1[j] = best_lev1[j + 1];
    }
    best_tot_mse = search_one_dual(best_lev0, best_lev1, nb_strengths - 1, mse,
                                   sb_count, pick_method);
  }
  return best_tot_mse;
}

typedef void (*copy_fn_t)(uint16_t *dst, int dstride, const void *src,
                          int src_voffset, int src_hoffset, int sstride,
                          int vsize, int hsize);
typedef uint64_t (*compute_cdef_dist_t)(void *dst, int dstride, uint16_t *src,
                                        cdef_list *dlist, int cdef_count,
                                        BLOCK_SIZE bsize, int coeff_shift,
                                        int row, int col);

static void copy_sb16_16_highbd(uint16_t *dst, int dstride, const void *src,
                                int src_voffset, int src_hoffset, int sstride,
                                int vsize, int hsize) {
  int r;
  const uint16_t *src16 = (uint16_t *)src;
  const uint16_t *base = &src16[src_voffset * sstride + src_hoffset];
  for (r = 0; r < vsize; r++)
    memcpy(dst + r * dstride, base + r * sstride, hsize * sizeof(*base));
}

static INLINE void init_src_params(int *src_stride, int *width, int *height,
                                   int *width_log2, int *height_log2,
                                   BLOCK_SIZE bsize) {
  *src_stride = block_size_wide[bsize];
  *width = block_size_wide[bsize];
  *height = block_size_high[bsize];
  *width_log2 = MI_SIZE_LOG2 + mi_size_wide_log2[bsize];
  *height_log2 = MI_SIZE_LOG2 + mi_size_high_log2[bsize];
}

/* Compute MSE only on the blocks we filtered. */
static uint64_t compute_cdef_dist_highbd(void *dst, int dstride, uint16_t *src,
                                         cdef_list *dlist, int cdef_count,
                                         BLOCK_SIZE bsize, int coeff_shift,
                                         int row, int col) {
  assert(bsize == BLOCK_4X4 || bsize == BLOCK_4X8 || bsize == BLOCK_8X4 ||
         bsize == BLOCK_8X8);
  uint64_t sum = 0;
  int bi, bx, by;
  uint16_t *dst16 = (uint16_t *)dst;
  uint16_t *dst_buff = &dst16[row * dstride + col];
  int src_stride, width, height, width_log2, height_log2;
  init_src_params(&src_stride, &width, &height, &width_log2, &height_log2,
                  bsize);
  for (bi = 0; bi < cdef_count; bi++) {
    by = dlist[bi].by;
    bx = dlist[bi].bx;
    sum += aom_mse_wxh_16bit_highbd(
        &dst_buff[(by << height_log2) * dstride + (bx << width_log2)], dstride,
        &src[bi << (height_log2 + width_log2)], src_stride, width, height);
  }
  return sum >> 2 * coeff_shift;
}

static int sb_all_skip(const CommonModeInfoParams *const mi_params, int mi_row,
                       int mi_col) {
  const int maxr = AOMMIN(mi_params->mi_rows - mi_row, MI_SIZE_64X64);
  const int maxc = AOMMIN(mi_params->mi_cols - mi_col, MI_SIZE_64X64);
  const int stride = mi_params->mi_stride;
  MB_MODE_INFO **mbmi = mi_params->mi_grid_base + mi_row * stride + mi_col;
  for (int r = 0; r < maxr; ++r, mbmi += stride) {
    for (int c = 0; c < maxc; ++c) {
      if (!mbmi[c]->skip_txfm[PLANE_TYPE_Y]) return 0;
    }
  }
  return 1;
}

static void pick_cdef_from_qp(AV1_COMMON *const cm) {
  const int bd = cm->seq_params.bit_depth;
  const int q = av1_ac_quant_QTX(cm->quant_params.base_qindex, 0, 0, bd) >>
                (bd - 8 + QUANT_TABLE_BITS);
  CdefInfo *const cdef_info = &cm->cdef_info;
  cdef_info->nb_cdef_strengths = 1;

  int damping_offset =
      clamp(cm->quant_params.base_qindex -
                (cm->seq_params.bit_depth == AOM_BITS_8    ? 0
                 : cm->seq_params.bit_depth == AOM_BITS_10 ? 2 * MAXQ_OFFSET
                                                           : 4 * MAXQ_OFFSET),
            MINQ, MAXQ_8_BITS) >>
      6;
  cdef_info->cdef_damping = AOMMIN(3 + damping_offset, 6);

  int predicted_y_f1 = 0;
  int predicted_y_f2 = 0;
  int predicted_uv_f1 = 0;
  int predicted_uv_f2 = 0;
  aom_clear_system_state();
  if (!frame_is_intra_only(cm)) {
    predicted_y_f1 = clamp((int)roundf(q * q * -0.0000023593946f +
                                       q * 0.0068615186f + 0.02709886f),
                           0, 15);
    predicted_y_f2 = clamp((int)roundf(q * q * -0.00000057629734f +
                                       q * 0.0013993345f + 0.03831067f),
                           0, 3);
    predicted_uv_f1 = clamp((int)roundf(q * q * -0.0000007095069f +
                                        q * 0.0034628846f + 0.00887099f),
                            0, 15);
    predicted_uv_f2 = clamp((int)roundf(q * q * 0.00000023874085f +
                                        q * 0.00028223585f + 0.05576307f),
                            0, 3);
  } else {
    predicted_y_f1 = clamp(
        (int)roundf(q * q * 0.0000033731974f + q * 0.008070594f + 0.0187634f),
        0, 15);
    predicted_y_f2 = clamp(
        (int)roundf(q * q * 0.0000029167343f + q * 0.0027798624f + 0.0079405f),
        0, 3);
    predicted_uv_f1 = clamp(
        (int)roundf(q * q * -0.0000130790995f + q * 0.012892405f - 0.00748388f),
        0, 15);
    predicted_uv_f2 = clamp((int)roundf(q * q * 0.0000032651783f +
                                        q * 0.00035520183f + 0.00228092f),
                            0, 3);
  }
  cdef_info->cdef_strengths[0] =
      predicted_y_f1 * CDEF_SEC_STRENGTHS + predicted_y_f2;
  cdef_info->cdef_uv_strengths[0] =
      predicted_uv_f1 * CDEF_SEC_STRENGTHS + predicted_uv_f2;

  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
  const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
  MB_MODE_INFO **mbmi = mi_params->mi_grid_base;
  for (int r = 0; r < nvfb; ++r) {
    for (int c = 0; c < nhfb; ++c) {
#if CONFIG_BRU
      if (cm->bru.enabled &&
          mbmi[MI_SIZE_64X64 * c]->sb_active_mode != BRU_ACTIVE_SB) {
        mbmi[MI_SIZE_64X64 * c]->cdef_strength = -1;
      } else
#endif  // CONFIG_BRU
        mbmi[MI_SIZE_64X64 * c]->cdef_strength = 0;
    }
    mbmi += MI_SIZE_64X64 * mi_params->mi_stride;
  }

  cdef_info->cdef_frame_enable =
      (cdef_info->nb_cdef_strengths > 1 || cdef_info->cdef_strengths[0] ||
       cdef_info->cdef_uv_strengths[0]);
}

static AOM_INLINE int get_cdef_context(const AV1_COMMON *const cm,
                                       int cur_cdef_pos) {
  const CommonModeInfoParams *const mi_params = &cm->mi_params;

  int mi_row = cur_cdef_pos / mi_params->mi_stride;
  int mi_col = cur_cdef_pos % mi_params->mi_stride;

  const int neighbor0_cdef_x = mi_col - MI_SIZE_64X64;
  const int neighbor0_cdef_y = mi_row;
  const int neighbor1_cdef_x = mi_col;
  const int neighbor1_cdef_y = mi_row - MI_SIZE_64X64;
  if (mi_row > 0 && mi_col > 0) {
    const int neighbor0_cdef_idx =
        neighbor0_cdef_y * mi_params->mi_stride + neighbor0_cdef_x;
    const int neighbor1_cdef_idx =
        neighbor1_cdef_y * mi_params->mi_stride + neighbor1_cdef_x;

    const int neighbor0_strength_0 =
        mi_params->mi_grid_base[neighbor0_cdef_idx]->cdef_strength == 0;
    const int neighbor1_strength_0 =
        mi_params->mi_grid_base[neighbor1_cdef_idx]->cdef_strength == 0;
    return neighbor0_strength_0 && neighbor1_strength_0
               ? 3
               : neighbor0_strength_0 || neighbor1_strength_0;
  } else if (mi_row > 0 || mi_col > 0) {
    int neighbor_cdef_idx = 0;
    if (mi_row > 0) {
      neighbor_cdef_idx =
          neighbor1_cdef_y * mi_params->mi_stride + neighbor1_cdef_x;
    } else {
      neighbor_cdef_idx =
          neighbor0_cdef_y * mi_params->mi_stride + neighbor0_cdef_x;
    }

    const int neighbor_strength_0 =
        mi_params->mi_grid_base[neighbor_cdef_idx]->cdef_strength == 0;
    return neighbor_strength_0 ? 2 : 0;
  } else {
    return 0;
  }
}

static AOM_INLINE void reset_frame_mi_cdef_strength(AV1_COMMON *cm) {
  CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int mi_rows = mi_params->mi_rows;
  const int mi_cols = mi_params->mi_cols;
  const int mi_stride = mi_params->mi_stride;
  for (int mi_row = 0; mi_row < mi_rows; mi_row++) {
    for (int mi_col = 0; mi_col < mi_cols; mi_col++) {
      const int grid_idx = mi_row * mi_stride + mi_col;
      MB_MODE_INFO *const mbmi = mi_params->mi_grid_base[grid_idx];
      mbmi->cdef_strength = -1;
    }
  }
}

void av1_cdef_search(const YV12_BUFFER_CONFIG *frame,
                     const YV12_BUFFER_CONFIG *ref, AV1_COMMON *cm,
                     MACROBLOCKD *xd,
#if CONFIG_ENTROPY_STATS
                     ThreadData *td,
#endif  // CONFIG_ENTROPY_STATS
                     CDEF_PICK_METHOD pick_method, int rdmult) {
  if (cm->seq_params.enable_cdef_on_skip_txfm == CDEF_ON_SKIP_TXFM_DISABLED) {
    cm->cdef_info.cdef_on_skip_txfm_frame_enable = 0;
  } else {
    cm->cdef_info.cdef_on_skip_txfm_frame_enable = 1;
  }

  reset_frame_mi_cdef_strength(cm);

  if (pick_method == CDEF_PICK_FROM_Q) {
    pick_cdef_from_qp(cm);
    return;
  }

  aom_cdf_prob cdef_strength_index0_cdf[CDEF_STRENGTH_INDEX0_CTX][CDF_SIZE(2)];
  aom_cdf_prob cdef_cdf[CDEF_STRENGTHS_NUM - 1][CDF_SIZE(CDEF_STRENGTHS_NUM)];
  av1_copy(cdef_strength_index0_cdf, cm->fc->cdef_strength_index0_cdf);
  av1_copy(cdef_cdf, cm->fc->cdef_cdf);

  cdef_list dlist[MI_SIZE_256X256 * MI_SIZE_256X256];
  int dir[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
  int var[CDEF_NBLOCKS][CDEF_NBLOCKS] = { { 0 } };
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
  const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
  int *sb_index = aom_malloc(nvfb * nhfb * sizeof(*sb_index));

  int damping_offset =
      clamp(cm->quant_params.base_qindex -
                (cm->seq_params.bit_depth == AOM_BITS_8    ? 0
                 : cm->seq_params.bit_depth == AOM_BITS_10 ? 2 * MAXQ_OFFSET
                                                           : 4 * MAXQ_OFFSET),
            MINQ, MAXQ_8_BITS) >>
      6;
  const int damping = AOMMIN(3 + damping_offset, 6);
  const int fast = (pick_method >= CDEF_FAST_SEARCH_LVL1 &&
                    pick_method <= CDEF_FAST_SEARCH_LVL3);
  const int total_strengths = nb_cdef_strengths[pick_method];
  DECLARE_ALIGNED(32, uint16_t, tmp_dst[1 << (MAX_SB_SIZE_LOG2 * 2)]);
  const int num_planes = av1_num_planes(cm);
  av1_setup_dst_planes(xd->plane, frame, 0, 0, 0, num_planes, NULL);
  uint64_t(*mse[2])[TOTAL_STRENGTHS];
  mse[0] = aom_malloc(sizeof(**mse) * nvfb * nhfb);
  mse[1] = aom_malloc(sizeof(**mse) * nvfb * nhfb);
  uint64_t unfiltered_mse = 0;

  int bsize[3];
  int mi_wide_l2[3];
  int mi_high_l2[3];
  int xdec[3];
  int ydec[3];
  uint16_t *ref_buffer[3] = { ref->y_buffer, ref->u_buffer, ref->v_buffer };
  int ref_stride[3] = { ref->y_stride, ref->uv_stride, ref->uv_stride };

  for (int pli = 0; pli < num_planes; pli++) {
    xdec[pli] = xd->plane[pli].subsampling_x;
    ydec[pli] = xd->plane[pli].subsampling_y;
    bsize[pli] = ydec[pli] ? (xdec[pli] ? BLOCK_4X4 : BLOCK_8X4)
                           : (xdec[pli] ? BLOCK_4X8 : BLOCK_8X8);
    mi_wide_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_x;
    mi_high_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_y;
  }

  copy_fn_t copy_fn;
  compute_cdef_dist_t compute_cdef_dist_fn;

  copy_fn = copy_sb16_16_highbd;
  compute_cdef_dist_fn = compute_cdef_dist_highbd;

  DECLARE_ALIGNED(32, uint16_t, inbuf[CDEF_INBUF_SIZE]);
  uint16_t *const in = inbuf + CDEF_VBORDER * CDEF_BSTRIDE + CDEF_HBORDER;
  const int coeff_shift = AOMMAX(cm->seq_params.bit_depth - 8, 0);
  int sb_count = 0;
  for (int fbr = 0; fbr < nvfb; ++fbr) {
    for (int fbc = 0; fbc < nhfb; ++fbc) {
      // No filtering if the entire filter block is skipped
      if (cm->cdef_info.cdef_on_skip_txfm_frame_enable == 0 &&
          sb_all_skip(mi_params, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64)) {
        continue;
      }

#if CONFIG_BRU
      MB_MODE_INFO *const mbmi =
          mi_params->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
                                  MI_SIZE_64X64 * fbc];
      if (cm->bru.enabled && mbmi->sb_active_mode != BRU_ACTIVE_SB) {
        mbmi->cdef_strength = -1;
        continue;
      }
#else
      const MB_MODE_INFO *const mbmi =
          mi_params->mi_grid_base[MI_SIZE_64X64 * fbr * mi_params->mi_stride +
                                  MI_SIZE_64X64 * fbc];
#endif  // CONFIG_BRU
      BLOCK_SIZE bs = mbmi->sb_type[PLANE_TYPE_Y];
      if (bs > BLOCK_64X64 && bs <= BLOCK_256X256) {
        const int bw = block_size_wide[bs];
        const int bh = block_size_high[bs];
        if ((bw == 256 && (fbc & 3)) || (bh == 256 && (fbr & 3))) {
          continue;
        };
        if ((bw == 128 && (fbc & 1)) || (bh == 128 && (fbr & 1))) {
          continue;
        };
      }

      int nhb = AOMMIN(MI_SIZE_64X64, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
      int nvb = AOMMIN(MI_SIZE_64X64, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
      int hb_step = 1;
      int vb_step = 1;
      if (bs > BLOCK_64X64 && bs <= BLOCK_256X256) {
        if (block_size_wide[bs] == 256) {
          nhb =
              AOMMIN(MI_SIZE_256X256, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
          hb_step = 4;
        }
        if (block_size_high[bs] == 256) {
          nvb =
              AOMMIN(MI_SIZE_256X256, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
          vb_step = 4;
        }
        if (block_size_wide[bs] == 128) {
          nhb =
              AOMMIN(MI_SIZE_128X128, mi_params->mi_cols - MI_SIZE_64X64 * fbc);
          hb_step = 2;
        }
        if (block_size_high[bs] == 128) {
          nvb =
              AOMMIN(MI_SIZE_128X128, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
          vb_step = 2;
        }
      } else {
        bs = BLOCK_64X64;
      }

      const int cdef_count = av1_cdef_compute_sb_list(
          cm, mi_params, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64, dlist, bs);

      const int yoff = CDEF_VBORDER * (fbr != 0);
      const int xoff = CDEF_HBORDER * (fbc != 0);
      int dirinit = 0;
      for (int pli = 0; pli < num_planes; pli++) {
        for (int i = 0; i < CDEF_INBUF_SIZE; i++) inbuf[i] = CDEF_VERY_LARGE;
        /* We avoid filtering the pixels for which some of the pixels to
           average are outside the frame. We could change the filter instead,
           but it would add special cases for any future vectorization. */
        const int ysize = (nvb << mi_high_l2[pli]) +
                          CDEF_VBORDER * (fbr + vb_step < nvfb) + yoff;
        const int xsize = (nhb << mi_wide_l2[pli]) +
                          CDEF_HBORDER * (fbc + hb_step < nhfb) + xoff;
        const int row = fbr * MI_SIZE_64X64 << mi_high_l2[pli];
        const int col = fbc * MI_SIZE_64X64 << mi_wide_l2[pli];
        for (int gi = 0; gi < total_strengths; gi++) {
          int pri_strength, sec_strength;
          get_cdef_filter_strengths(pick_method, &pri_strength, &sec_strength,
                                    gi);
          copy_fn(&in[(-yoff * CDEF_BSTRIDE - xoff)], CDEF_BSTRIDE,
                  xd->plane[pli].dst.buf, row - yoff, col - xoff,
                  xd->plane[pli].dst.stride, ysize, xsize);
          av1_cdef_filter_fb(
              NULL, tmp_dst, CDEF_BSTRIDE, in, xdec[pli], ydec[pli], dir,
              &dirinit, var, pli, dlist, cdef_count, pri_strength,
              sec_strength + (sec_strength == 3), damping, coeff_shift);
          const uint64_t curr_mse = compute_cdef_dist_fn(
              ref_buffer[pli], ref_stride[pli], tmp_dst, dlist, cdef_count,
              bsize[pli], coeff_shift, row, col);
          if (gi == 0) {
            unfiltered_mse += curr_mse;
          }
          if (pli < 2)
            mse[pli][sb_count][gi] = curr_mse;
          else
            mse[1][sb_count][gi] += curr_mse;
        }
      }
      sb_index[sb_count++] =
          MI_SIZE_64X64 * fbr * mi_params->mi_stride + MI_SIZE_64X64 * fbc;
    }
  }

  /* Search for different number of signalling bits. */
  int best_nb_strength = 0;
  uint64_t best_rd = UINT64_MAX;
  CdefInfo *const cdef_info = &cm->cdef_info;
  int best_cdef_on = 0;
  for (int nb_strengths = 1; nb_strengths <= 8; nb_strengths++) {
    int best_lev0[CDEF_MAX_STRENGTHS];
    int best_lev1[CDEF_MAX_STRENGTHS] = { 0 };
    uint64_t tot_mse;
    if (num_planes > 1) {
      tot_mse = joint_strength_search_dual(best_lev0, best_lev1, nb_strengths,
                                           mse, sb_count, pick_method);
    } else {
      tot_mse = joint_strength_search(best_lev0, nb_strengths, mse[0], sb_count,
                                      pick_method);
    }

    int luma_strength_less_4_count = 0;
    int chroma_strength_less_4_count = 0;
    for (int level = 0; level < nb_strengths; ++level) {
      if (best_lev0[level] < 4) {
        luma_strength_less_4_count++;
      }
      if (num_planes > 1 && best_lev1[level] < 4) {
        chroma_strength_less_4_count++;
      }
    }
    int luma_bits = luma_strength_less_4_count * 2;
    luma_bits +=
        (nb_strengths - luma_strength_less_4_count) * CDEF_STRENGTH_BITS;
    // Bits to indicate if each strength is less than 4
    luma_bits += nb_strengths;

    int chroma_bits = 0;
    if (num_planes > 1) {
      chroma_bits += chroma_strength_less_4_count * 2;
      chroma_bits +=
          (nb_strengths - chroma_strength_less_4_count) * CDEF_STRENGTH_BITS;
      // Bits to indicate if each strength is less than 4
      chroma_bits += nb_strengths;
    }

    /* check if cdef is on for the current frame, and assign total bits
     * accordingly. */
    const int cdef_on_bits = luma_bits + chroma_bits + 1 + 2 + 3;

    const int cdef_off_bit = 1;
    const int is_cdef_on = (nb_strengths != 1 || best_lev0[0] || best_lev1[0]);
    const int total_bits = is_cdef_on ? cdef_on_bits : cdef_off_bit;
    int rate_cost = av1_cost_literal(total_bits);
    if (is_cdef_on) {
      tot_mse = 0;
      for (int count_idx = 0; count_idx < sb_count; count_idx++) {
        uint64_t best_mse = UINT64_MAX;
        uint64_t best_rdo = UINT64_MAX;
        int best_sb_rate_cost = 0;
        int best_gi = 0;
        int strength_index0_cost_from_cdf[CDEF_STRENGTH_INDEX0_CTX][2];
        int cost_from_cdf[CDEF_STRENGTHS_NUM - 1][CDEF_STRENGTHS_NUM];
        if (nb_strengths >= 2) {
          for (int ctx = 0; ctx < CDEF_STRENGTH_INDEX0_CTX; ++ctx) {
            av1_cost_tokens_from_cdf(strength_index0_cost_from_cdf[ctx],
                                     cdef_strength_index0_cdf[ctx], NULL);
          }
          if (nb_strengths > 2) {
            av1_cost_tokens_from_cdf(cost_from_cdf[nb_strengths - 3],
                                     cdef_cdf[nb_strengths - 3], NULL);
          }
        }
        const int strength_index0_ctx =
            get_cdef_context(cm, sb_index[count_idx]);
        for (int gi = 0; gi < nb_strengths; gi++) {
          uint64_t curr = mse[0][count_idx][best_lev0[gi]];
          if (num_planes > 1) curr += mse[1][count_idx][best_lev1[gi]];
          int sb_rate_cost = 0;
          if (nb_strengths >= 2) {
            if (gi == 0) {
              sb_rate_cost =
                  strength_index0_cost_from_cdf[strength_index0_ctx][1];
            } else if (gi == 1 && nb_strengths == 2) {
              sb_rate_cost =
                  strength_index0_cost_from_cdf[strength_index0_ctx][0];
            } else {
              sb_rate_cost =
                  strength_index0_cost_from_cdf[strength_index0_ctx][0] +
                  cost_from_cdf[nb_strengths - 3][gi - 1];
            }
          }

          const uint64_t curr_rdo = RDCOST(rdmult, sb_rate_cost, curr * 16);
          if (curr_rdo < best_rdo) {
            best_gi = gi;
            best_sb_rate_cost = sb_rate_cost;
            best_mse = curr;
            best_rdo = curr_rdo;
          }
        }
        rate_cost += best_sb_rate_cost;
        tot_mse += best_mse;
        if (nb_strengths >= 2) {
          update_cdf(cdef_strength_index0_cdf[strength_index0_ctx],
                     best_gi == 0, 2);
          if (nb_strengths > 2 && best_gi >= 1) {
            update_cdf(cdef_cdf[nb_strengths - 3], best_gi - 1,
                       nb_strengths - 1);
          }
        }

        mi_params->mi_grid_base[sb_index[count_idx]]->cdef_strength = best_gi;
        BLOCK_SIZE bsize_y =
            mi_params->mi_grid_base[sb_index[count_idx]]->sb_type[PLANE_TYPE_Y];
        const int bh = mi_size_high[bsize_y];
        const int bw = mi_size_wide[bsize_y];
        int mi_row = sb_index[count_idx] / mi_params->mi_stride;
        int mi_col = sb_index[count_idx] % mi_params->mi_stride;
        if (bsize_y == BLOCK_256X256 || bsize_y == BLOCK_256X128 ||
            bsize_y == BLOCK_128X256 || bsize_y == BLOCK_128X128 ||
            bsize_y == BLOCK_128X64 || bsize_y == BLOCK_64X128) {
          const int x_inside_boundary = AOMMIN(bw, mi_params->mi_cols - mi_col);
          const int y_inside_boundary = AOMMIN(bh, mi_params->mi_rows - mi_row);
          int idx = mi_params->mi_stride;
          for (int y = 0; y < y_inside_boundary; ++y) {
            for (int x = 0; x < x_inside_boundary; ++x) {
              mi_params->mi_grid_base[sb_index[count_idx] + y * idx + x]
                  ->cdef_strength = best_gi;
            }
          }
        }
      }
    }
    const uint64_t dist = tot_mse * 16;
    const uint64_t rd = RDCOST(rdmult, rate_cost, dist);
    if (rd < best_rd) {
      best_cdef_on = is_cdef_on;
      best_rd = rd;
      best_nb_strength = nb_strengths;
      memcpy(cdef_info->cdef_strengths, best_lev0,
             nb_strengths * sizeof(best_lev0[0]));
      if (num_planes > 1) {
        memcpy(cdef_info->cdef_uv_strengths, best_lev1,
               nb_strengths * sizeof(best_lev1[0]));
      }
    }
  }

  if (best_cdef_on) {
    const uint64_t unfiltered_rd =
        RDCOST(rdmult, av1_cost_literal(1), unfiltered_mse * 16);
    if (unfiltered_rd < best_rd) {
      best_nb_strength = 1;
      cm->cdef_info.cdef_frame_enable = 0;
      cm->cdef_info.cdef_strengths[0] = 0;
      cm->cdef_info.nb_cdef_strengths = 1;
      cm->cdef_info.cdef_uv_strengths[0] = 0;
    }
  }

  av1_copy(cdef_strength_index0_cdf, cm->fc->cdef_strength_index0_cdf);
  av1_copy(cdef_cdf, cm->fc->cdef_cdf);
  cdef_info->nb_cdef_strengths = best_nb_strength;
  for (int i = 0; i < sb_count; i++) {
    uint64_t best_mse = UINT64_MAX;
    int best_gi = 0;
    int strength_index0_cost_from_cdf[CDEF_STRENGTH_INDEX0_CTX][2];
    int cost_from_cdf[CDEF_STRENGTHS_NUM - 1][CDEF_STRENGTHS_NUM];
    if (best_nb_strength >= 2) {
      for (int ctx = 0; ctx < CDEF_STRENGTH_INDEX0_CTX; ++ctx) {
        av1_cost_tokens_from_cdf(strength_index0_cost_from_cdf[ctx],
                                 cdef_strength_index0_cdf[ctx], NULL);
      }
      if (best_nb_strength > 2) {
        av1_cost_tokens_from_cdf(cost_from_cdf[best_nb_strength - 3],
                                 cdef_cdf[best_nb_strength - 3], NULL);
      }
    }
    const int strength_index0_ctx = get_cdef_context(cm, sb_index[i]);
    for (int gi = 0; gi < best_nb_strength; gi++) {
      uint64_t curr = mse[0][i][cdef_info->cdef_strengths[gi]];
      if (num_planes > 1) curr += mse[1][i][cdef_info->cdef_uv_strengths[gi]];
      int sb_rate_cost = 0;
      if (best_nb_strength >= 2) {
        if (gi == 0) {
          sb_rate_cost = strength_index0_cost_from_cdf[strength_index0_ctx][1];
        } else if (gi == 1 && best_nb_strength == 2) {
          sb_rate_cost = strength_index0_cost_from_cdf[strength_index0_ctx][0];
        } else {
          sb_rate_cost = strength_index0_cost_from_cdf[strength_index0_ctx][0] +
                         cost_from_cdf[best_nb_strength - 3][gi - 1];
        }
      }

      curr = RDCOST(rdmult, sb_rate_cost, curr * 16);
      if (curr < best_mse) {
        best_gi = gi;
        best_mse = curr;
      }
    }
    if (best_nb_strength >= 2) {
#if CONFIG_ENTROPY_STATS
      ++td->counts
            ->cdef_strength_index0_cnts[strength_index0_ctx][best_gi == 0];
      if (best_nb_strength > 2 && best_gi >= 1) {
        ++td->counts->cdef_cnts[best_nb_strength - 3][best_gi];
      }
#endif  // CONFIG_ENTROPY_STATS
      update_cdf(cdef_strength_index0_cdf[strength_index0_ctx], best_gi == 0,
                 2);
      if (best_nb_strength > 2 && best_gi >= 1) {
        update_cdf(cdef_cdf[best_nb_strength - 3], best_gi - 1,
                   best_nb_strength - 1);
      }
    }

    mi_params->mi_grid_base[sb_index[i]]->cdef_strength = best_gi;
    BLOCK_SIZE bsize_y =
        mi_params->mi_grid_base[sb_index[i]]->sb_type[PLANE_TYPE_Y];
    const int bh = mi_size_high[bsize_y];
    const int bw = mi_size_wide[bsize_y];
    int mi_row = sb_index[i] / mi_params->mi_stride;
    int mi_col = sb_index[i] % mi_params->mi_stride;
    int nhb = AOMMIN(AOMMAX(bw, MI_SIZE_64X64), mi_params->mi_cols - mi_col);
    int nvb = AOMMIN(AOMMAX(bh, MI_SIZE_64X64), mi_params->mi_rows - mi_row);
    for (int j = 0; j < nvb; j++) {
      for (int k = 0; k < nhb; k++) {
        const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
        mi_params->mi_grid_base[grid_idx]->cdef_strength = best_gi;
      }
    }
  }

  if (fast) {
    for (int j = 0; j < cdef_info->nb_cdef_strengths; j++) {
      const int luma_strength = cdef_info->cdef_strengths[j];
      const int chroma_strength = cdef_info->cdef_uv_strengths[j];
      int pri_strength, sec_strength;

      STORE_CDEF_FILTER_STRENGTH(cdef_info->cdef_strengths[j], pick_method,
                                 luma_strength);
      STORE_CDEF_FILTER_STRENGTH(cdef_info->cdef_uv_strengths[j], pick_method,
                                 chroma_strength);
    }
  }

  cdef_info->cdef_damping = damping;
  cdef_info->cdef_frame_enable =
      (cdef_info->nb_cdef_strengths > 1 || cdef_info->cdef_strengths[0] ||
       cdef_info->cdef_uv_strengths[0]);

  aom_free(mse[0]);
  aom_free(mse[1]);
  aom_free(sb_index);
}
