/*
 * 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 <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>

#include "av2/common/av2_common_int.h"
#include "av2/common/blockd.h"
#include "av2/common/bru.h"
#include "av2/common/enums.h"
#include "av2/common/filter.h"
#include "av2/common/scan.h"
#include "config/avm_config.h"
#include "config/avm_dsp_rtcd.h"
#include "config/avm_scale_rtcd.h"
#include "config/av2_rtcd.h"
#include "av2/common/level.h"

#include "avm/avm_codec.h"
#include "avm_dsp/avm_dsp_common.h"
#include "avm_dsp/binary_codes_reader.h"
#include "avm_dsp/bitreader.h"
#include "avm_dsp/bitreader_buffer.h"
#include "avm_mem/avm_mem.h"
#include "avm_ports/avm_timer.h"
#include "avm_ports/mem.h"
#include "avm_ports/mem_ops.h"
#include "avm_scale/avm_scale.h"
#include "avm_util/avm_thread.h"

#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
#include "avm_util/debug_util.h"
#endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG

#include "av2/common/alloccommon.h"
#include "av2/common/cdef.h"

#include "av2/common/gdf.h"

#include "av2/common/ccso.h"
#include "av2/common/cfl.h"
#if CONFIG_INSPECTION
#include "av2/decoder/inspection.h"
#endif
#include "av2/common/common.h"
#include "av2/common/entropy.h"
#include "av2/common/entropymode.h"
#include "av2/common/entropymv.h"
#include "av2/common/frame_buffers.h"
#include "av2/common/idct.h"
#include "av2/common/mvref_common.h"
#include "av2/common/pred_common.h"
#include "av2/common/quant_common.h"
#include "av2/common/reconinter.h"
#include "av2/common/reconintra.h"
#include "av2/common/resize.h"
#include "av2/common/seg_common.h"
#include "av2/common/thread_common.h"
#include "av2/common/tile_common.h"
#include "av2/common/tip.h"
#include "av2/common/warped_motion.h"
#include "av2/decoder/decodeframe.h"
#include "av2/decoder/decodemv.h"
#include "av2/decoder/decoder.h"
#include "av2/decoder/decodetxb.h"
#include "av2/decoder/detokenize.h"
#include "av2/decoder/obu.h"

#define AVM_MIN_THREADS_PER_TILE 1
#define AVM_MAX_THREADS_PER_TILE 2

#define MC_TEMP_BUF_PELS                           \
  (((MAX_SB_SIZE) * 2 + (AVM_INTERP_EXTEND) * 2) * \
   ((MAX_SB_SIZE) * 2 + (AVM_INTERP_EXTEND) * 2))

static void read_wienerns_framefilters_hdr(AV2_COMMON *cm, int plane,
                                           struct avm_read_bit_buffer *rb);

void copy_frame_filters_to_runits_if_needed(AV2_COMMON *cm) {
  const int num_planes = av2_num_planes(cm);
  for (int plane = 0; plane < num_planes; plane++) {
    if (!is_frame_filters_enabled(plane)) continue;
    RestorationInfo *rsi = &cm->rst_info[plane];
    if ((rsi->frame_restoration_type == RESTORE_WIENER_NONSEP ||
         rsi->frame_restoration_type == RESTORE_SWITCHABLE) &&
        rsi->frame_filters_on) {
      assert(rsi->frame_filters_initialized);
      for (int runit_idx = 0;
           runit_idx < rsi->horz_units_per_frame * rsi->vert_units_per_frame;
           ++runit_idx) {
        RestorationUnitInfo *rui = &rsi->unit_info[runit_idx];
        if (rui->restoration_type == RESTORE_WIENER_NONSEP) {
          copy_nsfilter_taps(&rui->wienerns_info, &rsi->frame_filters);
        }
      }
    }
  }
}

#if CONFIG_THROUGHPUT_ANALYSIS
int64_t tot_ctx_syms = { 0 };
int64_t tot_bypass_syms = { 0 };
int64_t max_ctx_syms = { 0 };
int64_t max_bypass_syms = { 0 };
int64_t max_bits = { 0 };
int64_t tot_bits = { 0 };
int64_t tot_frames = { 0 };
int64_t total_context_switch = { 0 };
int64_t total_total_hits = { 0 };
#endif  // CONFIG_THROUGHPUT_ANALYSIS

int av2_check_byte_alignment(AV2_COMMON *const cm,
                             struct avm_read_bit_buffer *const rb) {
  while (rb->bit_offset & 7) {
    if (avm_rb_read_bit(rb)) {
      cm->error.error_code = AVM_CODEC_CORRUPT_FRAME;
      return -1;
    }
  }
  return 0;
}

// Checks that the remaining bits start with a 1 and ends with 0s.
// It consumes an additional byte, if already byte aligned before the check.
int av2_check_trailing_bits(AV2Decoder *pbi, struct avm_read_bit_buffer *rb) {
  AV2_COMMON *const cm = &pbi->common;
  // bit_offset is set to 0 (mod 8) when the reader is already byte aligned
  int bits_before_alignment = 8 - rb->bit_offset % 8;
  int trailing = avm_rb_read_literal(rb, bits_before_alignment);
  if (trailing != (1 << (bits_before_alignment - 1))) {
    cm->error.error_code = AVM_CODEC_CORRUPT_FRAME;
    return -1;
  }
  return 0;
}

// Use only_chroma = 1 to only set the chroma planes
static AVM_INLINE void set_planes_to_neutral_grey(
    const SequenceHeader *const seq_params, const YV12_BUFFER_CONFIG *const buf,
    int only_chroma) {
  const int val = 1 << (seq_params->bit_depth - 1);
  for (int plane = only_chroma; plane < MAX_MB_PLANE; plane++) {
    const int is_uv = plane > 0;
    uint16_t *const base = buf->buffers[plane];
    // Set the first row to neutral grey. Then copy the first row to all
    // subsequent rows.
    if (buf->crop_heights[is_uv] > 0) {
      avm_memset16(base, val, buf->crop_widths[is_uv]);
      for (int row_idx = 1; row_idx < buf->crop_heights[is_uv]; row_idx++) {
        memcpy(&base[row_idx * buf->strides[is_uv]], base,
               sizeof(*base) * buf->crop_widths[is_uv]);
      }
    }
  }
}

static AVM_INLINE void loop_restoration_read_sb_coeffs(AV2_COMMON *cm,
                                                       MACROBLOCKD *xd,
                                                       avm_reader *const r,
                                                       int plane,
                                                       int runit_idx);

static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
  return len != 0 && len <= (size_t)(end - start);
}

static TX_MODE read_tx_mode(struct avm_read_bit_buffer *rb,
                            int coded_lossless) {
  if (coded_lossless) return ONLY_4X4;
  return avm_rb_read_bit(rb) ? TX_MODE_SELECT : TX_MODE_LARGEST;
}

static REFERENCE_MODE read_frame_reference_mode(
    const AV2_COMMON *cm, struct avm_read_bit_buffer *rb) {
  if (frame_is_intra_only(cm)) {
    return SINGLE_REFERENCE;
  } else {
    return avm_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
  }
}

static AVM_INLINE void inverse_transform_block(DecoderCodingBlock *dcb,
                                               const AV2_COMMON *cm, int plane,
                                               const TX_TYPE tx_type,
                                               const TX_SIZE tx_size,
                                               uint16_t *dst, int stride,
                                               int reduced_tx_set) {
  tran_low_t *dqcoeff = dcb->dqcoeff_block[plane] + dcb->cb_offset[plane];
  eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
  uint16_t scan_line = eob_data->max_scan_line;
  uint16_t eob = eob_data->eob;
  // Update eob and scan_line according to those of the other chroma plane
  if (plane && is_cctx_allowed(cm, &dcb->xd)) {
    eob_info *eob_data_c1 =
        dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
    eob_info *eob_data_c2 =
        dcb->eob_data[AVM_PLANE_V] + dcb->txb_offset[AVM_PLANE_V];
    scan_line = AVMMAX(eob_data_c1->max_scan_line, eob_data_c2->max_scan_line);
    eob = AVMMAX(eob_data_c1->eob, eob_data_c2->eob);
  }
  av2_inverse_transform_block(
      &dcb->xd, dqcoeff, plane, tx_type, tx_size, dst, stride, eob,
      replace_adst_by_ddt(cm->seq_params.enable_inter_ddt,
                          cm->features.allow_screen_content_tools, &dcb->xd),
      reduced_tx_set);
  const int width = tx_size_wide[tx_size] <= 32 ? tx_size_wide[tx_size] : 32;
  const int height = tx_size_high[tx_size] <= 32 ? tx_size_high[tx_size] : 32;
  const int sbSize = (width >= 8 && height >= 8) ? 8 : 4;
  int32_t nz0 = (sbSize - 1) * tx_size_wide[tx_size] + sbSize;
  int32_t nz1 = (scan_line + 1);
  memset(dqcoeff, 0, AVMMAX(nz0, nz1) * sizeof(dqcoeff[0]));
}

static AVM_INLINE void read_coeffs_tx_intra_block(
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
    const int plane, const int row, const int col, const TX_SIZE tx_size) {
  MB_MODE_INFO *mbmi = dcb->xd.mi[0];
  if (!mbmi->skip_txfm[dcb->xd.tree_type == CHROMA_PART]) {
#if TXCOEFF_TIMER
    struct avm_usec_timer timer;
    avm_usec_timer_start(&timer);
#endif
    av2_read_coeffs_txb_facade(cm, dcb, r, plane, row, col, tx_size);
#if TXCOEFF_TIMER
    avm_usec_timer_mark(&timer);
    const int64_t elapsed_time = avm_usec_timer_elapsed(&timer);
    cm->txcoeff_timer += elapsed_time;
    ++cm->txb_count;
#endif
  } else {
    // all tx blocks are skipped.
    av2_update_txk_skip_array(cm, dcb->xd.mi_row, dcb->xd.mi_col,
                              dcb->xd.tree_type, &mbmi->chroma_ref_info, plane,
                              row, col, tx_size);
  }
}

static AVM_INLINE void decode_block_void(const AV2_COMMON *const cm,
                                         DecoderCodingBlock *dcb,
                                         avm_reader *const r, const int plane,
                                         const int row, const int col,
                                         const TX_SIZE tx_size) {
  (void)cm;
  (void)dcb;
  (void)r;
  (void)plane;
  (void)row;
  (void)col;
  (void)tx_size;
}

static AVM_INLINE void predict_inter_block_void(AV2_COMMON *const cm,
                                                DecoderCodingBlock *dcb,
                                                BLOCK_SIZE bsize) {
  (void)cm;
  (void)dcb;
  (void)bsize;
}

static AVM_INLINE void predict_and_reconstruct_intra_block(
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
    const int plane, const int row, const int col, const TX_SIZE tx_size) {
  (void)r;
  MACROBLOCKD *const xd = &dcb->xd;
  MB_MODE_INFO *mbmi = xd->mi[0];
  PLANE_TYPE plane_type = get_plane_type(plane);

  av2_predict_intra_block_facade(cm, xd, plane, col, row, tx_size);
#if CONFIG_INSPECTION
  {
    const int txwpx = tx_size_wide[tx_size];
    const int txhpx = tx_size_high[tx_size];

    struct macroblockd_plane *const pd = &xd->plane[plane];
    const int dst_stride = pd->dst.stride;
    uint16_t *dst = &pd->dst.buf[(row * dst_stride + col) << MI_SIZE_LOG2];
    for (int i = 0; i < txhpx; i++) {
      for (int j = 0; j < txwpx; j++) {
        uint16_t pixel = dst[i * dst_stride + j];
        int stride = cm->predicted_pixels.strides[plane > 0];
        int pixel_c, pixel_r;

        if (plane) {
          mi_to_pixel_loc(&pixel_c, &pixel_r,
                          mbmi->chroma_ref_info.mi_col_chroma_base,
                          mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
                          pd->subsampling_x, pd->subsampling_y);
        } else {
          mi_to_pixel_loc(&pixel_c, &pixel_r, xd->mi_col, xd->mi_row, col, row,
                          pd->subsampling_x, pd->subsampling_y);
        }

        pixel_c += j;
        pixel_r += i;
        cm->predicted_pixels.buffers[plane][pixel_r * stride + pixel_c] = pixel;
      }
    }
  }
#endif  // CONFIG_INSPECTION

#if CONFIG_MISMATCH_DEBUG
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
  const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
  int pixel_c, pixel_r;
  const int blk_w = tx_size_wide[tx_size];
  const int blk_h = tx_size_high[tx_size];
  if (plane == 0 || xd->is_chroma_ref) {
    struct macroblockd_plane *const pd = &xd->plane[plane];
    if (plane) {
      mi_to_pixel_loc(&pixel_c, &pixel_r,
                      mbmi->chroma_ref_info.mi_col_chroma_base,
                      mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
                      pd->subsampling_x, pd->subsampling_y);
    } else {
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row,
                      pd->subsampling_x, pd->subsampling_y);
    }
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
    mismatch_check_block_pre(pd->dst.buf, pd->dst.stride,
                             cm->current_frame.display_order_hint, pixels_c,
                             pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
  }
#endif  // CONFIG_MISMATCH_DEBUG

  if (!mbmi->skip_txfm[xd->tree_type == CHROMA_PART]) {
    eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
    // In CCTX, when C2 eob = 0 but C1 eob > 0, plane V reconstruction is
    // still needed
    int recon_with_cctx = 0;
    if (is_cctx_allowed(cm, xd) && plane == AVM_PLANE_V &&
        av2_get_cctx_type(xd, row, col) > CCTX_NONE) {
      eob_info *eob_data_c1 =
          dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
      recon_with_cctx = eob_data_c1->eob > 0;
    }
    if (eob_data->eob || recon_with_cctx) {
      const uint8_t reduced_tx_set_used =
          is_reduced_tx_set_used(cm, plane_type);
      // tx_type was read out in av2_read_coeffs_txb.
      const TX_TYPE tx_type = av2_get_tx_type(xd, plane_type, row, col, tx_size,
                                              reduced_tx_set_used);
      struct macroblockd_plane *const pd = &xd->plane[plane];
      uint16_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << MI_SIZE_LOG2];
      inverse_transform_block(dcb, cm, plane, tx_type, tx_size, dst,
                              pd->dst.stride, reduced_tx_set_used);
    }
  }

#if CONFIG_MISMATCH_DEBUG
  {
    struct macroblockd_plane *const pd = &xd->plane[plane];
    uint16_t *dst = &pd->dst.buf[(row * pd->dst.stride + col) << MI_SIZE_LOG2];
    if (plane) {
      mi_to_pixel_loc(&pixel_c, &pixel_r,
                      mbmi->chroma_ref_info.mi_col_chroma_base,
                      mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
                      pd->subsampling_x, pd->subsampling_y);
    } else {
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row,
                      pd->subsampling_x, pd->subsampling_y);
    }
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
    mismatch_check_block_tx(dst, pd->dst.stride,
                            cm->current_frame.display_order_hint, pixels_c,
                            pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
  }
#endif  // CONFIG_MISMATCH_DEBUG
}

// Facade function for inverse cross chroma component transform
static AVM_INLINE void inverse_cross_chroma_transform_block(
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
    const int plane, const int blk_row, const int blk_col,
    const TX_SIZE tx_size) {
  (void)cm;
  (void)r;
  (void)plane;
  tran_low_t *dqcoeff_c1 =
      dcb->dqcoeff_block[AVM_PLANE_U] + dcb->cb_offset[AVM_PLANE_U];
  tran_low_t *dqcoeff_c2 =
      dcb->dqcoeff_block[AVM_PLANE_V] + dcb->cb_offset[AVM_PLANE_V];
  MACROBLOCKD *const xd = &dcb->xd;
  const CctxType cctx_type = av2_get_cctx_type(xd, blk_row, blk_col);
  av2_inv_cross_chroma_tx_block(dqcoeff_c1, dqcoeff_c2, tx_size, cctx_type,
                                xd->bd);
}

static AVM_INLINE void inverse_transform_inter_block(
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
    const int plane, const int blk_row, const int blk_col,
    const TX_SIZE tx_size) {
  (void)r;
  MACROBLOCKD *const xd = &dcb->xd;
  PLANE_TYPE plane_type = get_plane_type(plane);
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  const uint8_t reduced_tx_set_used = is_reduced_tx_set_used(cm, plane_type);
  // tx_type was read out in av2_read_coeffs_txb.
  const TX_TYPE tx_type = av2_get_tx_type(xd, plane_type, blk_row, blk_col,
                                          tx_size, reduced_tx_set_used);

  uint16_t *dst =
      &pd->dst.buf[(blk_row * pd->dst.stride + blk_col) << MI_SIZE_LOG2];
  inverse_transform_block(dcb, cm, plane, tx_type, tx_size, dst, pd->dst.stride,
                          reduced_tx_set_used);
#if CONFIG_MISMATCH_DEBUG
  int pixel_c, pixel_r;
  const int blk_w = tx_size_wide[tx_size];
  const int blk_h = tx_size_high[tx_size];
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
  const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
  if (plane) {
    MB_MODE_INFO *const mbmi = xd->mi[0];
    mi_to_pixel_loc(&pixel_c, &pixel_r,
                    mbmi->chroma_ref_info.mi_col_chroma_base,
                    mbmi->chroma_ref_info.mi_row_chroma_base, blk_col, blk_row,
                    pd->subsampling_x, pd->subsampling_y);
  } else {
    mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, blk_col, blk_row,
                    pd->subsampling_x, pd->subsampling_y);
  }
  int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
  int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
  mismatch_check_block_tx(dst, pd->dst.stride,
                          cm->current_frame.display_order_hint, pixels_c,
                          pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
#endif  // CONFIG_MISMATCH_DEBUG
}

static AVM_INLINE void set_cb_buffer_offsets(DecoderCodingBlock *dcb,
                                             TX_SIZE tx_size, int plane) {
  dcb->cb_offset[plane] += tx_size_wide[tx_size] * tx_size_high[tx_size];
  dcb->txb_offset[plane] =
      dcb->cb_offset[plane] / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
}

static AVM_INLINE void decode_reconstruct_tx(
    AV2_COMMON *cm, ThreadData *const td, avm_reader *r,
    MB_MODE_INFO *const mbmi, int plane, BLOCK_SIZE plane_bsize, int blk_row,
    int blk_col, TX_SIZE tx_size, int *eob_total) {
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  if (plane == AVM_PLANE_U && is_cctx_allowed(cm, xd)) return;
  int txp_index = av2_get_txb_size_index(plane_bsize, blk_row, blk_col);
  // Scale to match transform block unit.
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);

  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;

  if (mbmi->tx_partition_type[txp_index] == TX_PARTITION_NONE || plane) {
    if (plane == AVM_PLANE_V && is_cctx_allowed(cm, xd)) {
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_U, blk_row,
                                           blk_col, tx_size);
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_V, blk_row,
                                           blk_col, tx_size);
      td->inverse_cctx_block_visit(cm, dcb, r, -1, blk_row, blk_col, tx_size);
      td->inverse_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_U, blk_row,
                                       blk_col, tx_size);
      td->inverse_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_V, blk_row,
                                       blk_col, tx_size);
      eob_info *eob_data_c1 =
          dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
      eob_info *eob_data_c2 =
          dcb->eob_data[AVM_PLANE_V] + dcb->txb_offset[AVM_PLANE_V];
      *eob_total += eob_data_c1->eob + eob_data_c2->eob;
      set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_U);
      set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_V);
    } else {
      assert(plane == AVM_PLANE_Y || !is_cctx_allowed(cm, xd));
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, plane, blk_row, blk_col,
                                           tx_size);

      td->inverse_tx_inter_block_visit(cm, dcb, r, plane, blk_row, blk_col,
                                       tx_size);
      eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
      *eob_total += eob_data->eob;
      set_cb_buffer_offsets(dcb, tx_size, plane);
    }
  } else {
    get_tx_partition_sizes(mbmi->tx_partition_type[txp_index], tx_size,
                           &mbmi->txb_pos, mbmi->sub_txs, xd->error_info);

    for (int txb_idx = 0; txb_idx < mbmi->txb_pos.n_partitions; ++txb_idx) {
      mbmi->txb_idx = 0;
      const TX_SIZE sub_tx = mbmi->sub_txs[txb_idx];
      const int offsetr = blk_row + mbmi->txb_pos.row_offset[txb_idx];
      const int offsetc = blk_col + mbmi->txb_pos.col_offset[txb_idx];
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;

      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, plane, offsetr, offsetc,
                                           sub_tx);
      td->inverse_tx_inter_block_visit(cm, dcb, r, plane, offsetr, offsetc,
                                       sub_tx);
      eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
      *eob_total += eob_data->eob;
      set_cb_buffer_offsets(dcb, sub_tx, plane);
    }
  }
}

static AVM_INLINE void set_offsets(AV2_COMMON *const cm, MACROBLOCKD *const xd,
                                   BLOCK_SIZE bsize, int mi_row, int mi_col,
                                   int bw, int bh, int x_inside_boundary,
                                   int y_inside_boundary,
                                   PARTITION_TREE *parent, int index) {
  const int num_planes = av2_num_planes(cm);
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const TileInfo *const tile = &xd->tile;

  set_mi_offsets(mi_params, xd, mi_row, mi_col, x_inside_boundary,
                 y_inside_boundary);
  xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART] = bsize;
  if (xd->tree_type != CHROMA_PART) {
    xd->mi[0]->mi_row_start = mi_row;
    xd->mi[0]->mi_col_start = mi_col;
  }
#if CONFIG_RD_DEBUG
  xd->mi[0]->mi_row = mi_row;
  xd->mi[0]->mi_col = mi_col;
#endif

  if (xd->tree_type == SHARED_PART) {
    assert(x_inside_boundary && y_inside_boundary);
    for (int x = 1; x < x_inside_boundary; ++x) xd->mi[x] = xd->mi[0];
    int idx = mi_params->mi_stride;
    for (int y = 1; y < y_inside_boundary; ++y) {
      memcpy(&xd->mi[idx], &xd->mi[0], x_inside_boundary * sizeof(xd->mi[0]));
      idx += mi_params->mi_stride;
    }
  }

  CHROMA_REF_INFO *chroma_ref_info = &xd->mi[0]->chroma_ref_info;
  set_chroma_ref_info(xd->tree_type, mi_row, mi_col, index, bsize,
                      chroma_ref_info, parent ? &parent->chroma_ref_info : NULL,
                      parent ? parent->bsize : BLOCK_INVALID,
                      parent ? parent->partition : PARTITION_NONE,
                      xd->plane[1].subsampling_x, xd->plane[1].subsampling_y);
  set_plane_n4(xd, bw, bh, num_planes, chroma_ref_info);
  set_entropy_context(xd, mi_row, mi_col, num_planes, chroma_ref_info);

  // Distance of Mb to the various image edges. These are specified to 8th pel
  // as they are always compared to values that are in 1/8th pel units
  set_mi_row_col(cm, xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
                 mi_params->mi_cols, chroma_ref_info);
  xd->mi[0]->chroma_mi_row_start = mi_row;
  xd->mi[0]->chroma_mi_col_start = mi_col;

  av2_setup_dst_planes(xd->plane, &cm->cur_frame->buf, mi_row, mi_col, 0,
                       num_planes, chroma_ref_info);
}

static INLINE void extend_mc_border(const struct scale_factors *const sf,
                                    struct buf_2d *const pre_buf,
                                    MV32 scaled_mv, PadBlock block,
                                    int subpel_x_mv, int subpel_y_mv,
                                    int do_warp, int is_intrabc,
                                    uint16_t *mc_buf, uint16_t **pre,
                                    int *src_stride) {
  int x_pad = 0, y_pad = 0;
  if (update_extend_mc_border_params(sf, pre_buf, scaled_mv, &block,
                                     subpel_x_mv, subpel_y_mv, do_warp,
                                     is_intrabc, &x_pad, &y_pad, NULL)) {
    // Get reference block pointer.
    const uint16_t *const buf_ptr =
        pre_buf->buf0 + block.y0 * pre_buf->stride + block.x0;
    int buf_stride = pre_buf->stride;
    const int b_w = block.x1 - block.x0;
    const int b_h = block.y1 - block.y0;

    // Extend the border.
    highbd_build_mc_border(buf_ptr, buf_stride, mc_buf, b_w, block.x0, block.y0,
                           b_w, b_h, pre_buf->width, pre_buf->height);

    *src_stride = b_w;
    *pre = mc_buf + y_pad * (AVM_INTERP_EXTEND - 1) * b_w +
           x_pad * (AVM_INTERP_EXTEND - 1);
  }
}
static void dec_calc_subpel_params_and_extend(
    const MV *const src_mv, InterPredParams *const inter_pred_params,
    MACROBLOCKD *const xd, int mi_x, int mi_y, int ref,
    int use_optflow_refinement, uint16_t **mc_buf, uint16_t **pre,
    SubpelParams *subpel_params, int *src_stride) {
  if (inter_pred_params->use_ref_padding) {
    common_calc_subpel_params_and_extend(
        src_mv, inter_pred_params, xd, mi_x, mi_y, ref, use_optflow_refinement,
        mc_buf, pre, subpel_params, src_stride);
    return;
  }

  PadBlock block;
  MV32 scaled_mv;
  int subpel_x_mv, subpel_y_mv;
  dec_calc_subpel_params(
      src_mv, inter_pred_params, xd, mi_x, mi_y, pre, subpel_params, src_stride,
      &block, use_optflow_refinement, &scaled_mv, &subpel_x_mv, &subpel_y_mv);
  extend_mc_border(inter_pred_params->scale_factors,
                   &inter_pred_params->ref_frame_buf, scaled_mv, block,
                   subpel_x_mv, subpel_y_mv,
                   inter_pred_params->mode == WARP_PRED,
                   inter_pred_params->is_intrabc, mc_buf[ref], pre, src_stride);
}

// Allocate and copy data for TIP multi threading.
static void copy_tip_worker_data(AV2Decoder *pbi, AV2_COMMON *cm) {
  int num_worker = pbi->max_threads;
  avm_free(pbi->tip_worker_data);
  CHECK_MEM_ERROR(
      cm, pbi->tip_worker_data,
      avm_memalign(32, num_worker * sizeof(*(pbi->tip_worker_data))));

  for (int worker_idx = 0; worker_idx < num_worker; ++worker_idx) {
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
    TIPWorkerData *const tip_worker_data = pbi->tip_worker_data + worker_idx;
    tip_worker_data->xd = pbi->dcb.xd;
    tip_worker_data->mc_buf[0] = thread_data->td->mc_buf[0];
    tip_worker_data->mc_buf[1] = thread_data->td->mc_buf[1];
    tip_worker_data->tmp_conv_dst = thread_data->td->tmp_conv_dst;
    // Temporary buffers used during the DMVR and OPFL processing.
    tip_worker_data->xd.opfl_vxy_bufs = thread_data->td->opfl_vxy_bufs;
    tip_worker_data->xd.opfl_gxy_bufs = thread_data->td->opfl_gxy_bufs;
    tip_worker_data->xd.opfl_dst_bufs = thread_data->td->opfl_dst_bufs;
  }
}

static void av2_dec_setup_tip_frame(AV2Decoder *pbi, AV2_COMMON *cm,
                                    MACROBLOCKD *xd) {
  av2_setup_tip_motion_field(cm);
  if (pbi->num_workers > 1) {
    copy_tip_worker_data(pbi, cm);
    av2_setup_tip_frame_mt(cm, dec_calc_subpel_params_and_extend,
                           1 /* copy_refined_mvs */, pbi->tile_workers,
                           pbi->num_workers, &pbi->tip_sync,
                           pbi->tip_worker_data);
  } else {
    xd->opfl_vxy_bufs = pbi->td.opfl_vxy_bufs;
    xd->opfl_gxy_bufs = pbi->td.opfl_gxy_bufs;
    xd->opfl_dst_bufs = pbi->td.opfl_dst_bufs;
    av2_setup_tip_frame(cm, xd, pbi->td.mc_buf, pbi->td.tmp_conv_dst,
                        dec_calc_subpel_params_and_extend,
                        1 /* copy_refined_mvs */
    );
  }

  if (cm->seq_params.enable_tip_explicit_qp == 0) {
    const int avg_u_ac_delta_q =
        (cm->tip_ref.ref_frame_buffer[0]->u_ac_delta_q +
         cm->tip_ref.ref_frame_buffer[1]->u_ac_delta_q + 1) >>
        1;
    const int avg_v_ac_delta_q =
        (cm->tip_ref.ref_frame_buffer[0]->v_ac_delta_q +
         cm->tip_ref.ref_frame_buffer[1]->v_ac_delta_q + 1) >>
        1;
    const int base_qindex =
        (cm->tip_ref.ref_frame_buffer[0]->base_qindex +
         cm->tip_ref.ref_frame_buffer[1]->base_qindex + 1) >>
        1;
    cm->cur_frame->base_qindex = cm->quant_params.base_qindex = base_qindex;
    cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q =
        avg_u_ac_delta_q;
    cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q =
        avg_v_ac_delta_q;
  }
  if (cm->seq_params.enable_lf_sub_pu && cm->features.allow_lf_sub_pu) {
    init_tip_lf_parameter(cm, 0, av2_num_planes(cm));
    loop_filter_tip_frame(cm, xd, 0, av2_num_planes(cm));
  }
}

static AVM_INLINE void decode_mbmi_block(AV2Decoder *const pbi,
                                         DecoderCodingBlock *dcb, int mi_row,
                                         int mi_col, avm_reader *r,
                                         PARTITION_TYPE partition,
                                         BLOCK_SIZE bsize,
                                         PARTITION_TREE *parent, int index) {
  AV2_COMMON *const cm = &pbi->common;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int x_mis = AVMMIN(bw, cm->mi_params.mi_cols - mi_col);
  const int y_mis = AVMMIN(bh, cm->mi_params.mi_rows - mi_row);
  MACROBLOCKD *const xd = &dcb->xd;

#if CONFIG_ACCOUNTING
  avm_accounting_set_context(&pbi->accounting, mi_col, mi_row, xd->tree_type);
#endif
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, parent,
              index);
  xd->mi[0]->partition = partition;
  // set region_type for each mbmi
  xd->mi[0]->region_type = parent->region_type;
  // set tree_type for each mbmi
  xd->mi[0]->tree_type = xd->tree_type;
  xd->mi[0]->sb_root_partition_info = parent->sb_root_partition_info;
  xd->mi[0]->local_rest_type =
      1;  // set non zero default type, it is only matter 1 or 0 in SW
  xd->mi[0]->local_ccso_blk_flag =
      1;  // set non zero default type, it is only matter 1 or 0 in SW
  xd->mi[0]->local_gdf_mode =
      1;  // set non zero default type, it is only matter 1 or 0 in SW
  if (!bru_is_sb_active(cm, mi_col, mi_row) ||
      cm->bridge_frame_info.is_bridge_frame) {
    xd->mi[0]->sb_active_mode = xd->sbi->sb_active_mode;
    bru_set_default_inter_mb_mode_info(cm, xd, xd->mi[0], bsize);
    const int w = mi_size_wide[cm->seq_params.sb_size];
    const int h = mi_size_high[cm->seq_params.sb_size];
    const int x_inside_boundary = AVMMIN(w, cm->mi_params.mi_cols - mi_col);
    const int y_inside_boundary = AVMMIN(h, cm->mi_params.mi_rows - mi_row);
    if (cm->bridge_frame_info.is_bridge_frame) {
      bru_zero_sb_mvs(cm, -1, mi_row, mi_col, x_inside_boundary,
                      y_inside_boundary);
    } else if (pbi->bru_opt_mode && cm->bru.enabled) {
      // only update ref MVS for optimized decoder
      bru_zero_sb_mvs(cm, cm->bru.update_ref_idx, mi_row, mi_col,
                      x_inside_boundary, y_inside_boundary);
    }
    if (!cm->bru.frame_inactive_flag &&
        !cm->bridge_frame_info.is_bridge_frame) {
      if (xd->tree_type != CHROMA_PART) {
        read_gdf(cm, r, xd);
      }
      if (cm->seq_params.enable_ccso && xd->tree_type != CHROMA_PART) {
        read_ccso(cm, r, xd);
      }
    }
  } else
    av2_read_mode_info(pbi, dcb, r, x_mis, y_mis);

  if (xd->tree_type != LUMA_PART) {
    const struct macroblockd_plane *const pd_u = &xd->plane[1];
    const BLOCK_SIZE chroma_bsize_base =
        get_bsize_base(xd, xd->mi[0], AVM_PLANE_U);
    assert(chroma_bsize_base < BLOCK_SIZES_ALL);
    if (get_plane_block_size(chroma_bsize_base, pd_u->subsampling_x,
                             pd_u->subsampling_y) == BLOCK_INVALID) {
      avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
                         "Block size %dx%d invalid with this subsampling mode",
                         block_size_wide[chroma_bsize_base],
                         block_size_high[chroma_bsize_base]);
    }
  }
}

static void dec_build_inter_predictors(const AV2_COMMON *cm,
                                       DecoderCodingBlock *dcb, int plane,
                                       MB_MODE_INFO *mi, int bw, int bh,
                                       int mi_x, int mi_y,
                                       int build_for_refine_mv_only) {
  av2_build_inter_predictors(cm, &dcb->xd, plane, mi, NULL,
                             build_for_refine_mv_only, 1 /* build_for_decode */,
                             bw, bh, mi_x, mi_y, dcb->mc_buf,
                             dec_calc_subpel_params_and_extend);
}

static AVM_INLINE void dec_build_inter_predictor(const AV2_COMMON *cm,
                                                 DecoderCodingBlock *dcb,
                                                 int mi_row, int mi_col,
                                                 BLOCK_SIZE bsize) {
  MACROBLOCKD *const xd = &dcb->xd;
  const int num_planes = av2_num_planes(cm);
  MB_MODE_INFO *mbmi = xd->mi[0];

  int need_subblock_mvs = xd->is_chroma_ref && mbmi->refinemv_flag &&
                          !is_intrabc_block(mbmi, xd->tree_type);
  assert(IMPLIES(need_subblock_mvs, !is_interintra_pred(mbmi)));
  if (need_subblock_mvs && default_refinemv_modes(mbmi))
    need_subblock_mvs &= (mbmi->comp_group_idx == 0 &&
                          mbmi->interinter_comp.type == COMPOUND_AVERAGE);
  if (need_subblock_mvs) {
    fill_subblock_refine_mv(xd->refinemv_subinfo, xd->plane[0].width,
                            xd->plane[0].height, mbmi->mv[0].as_mv,
                            mbmi->mv[1].as_mv);
  }

  for (int plane = 0; plane < num_planes; ++plane) {
    if (plane && !xd->is_chroma_ref) break;
    const int mi_x = mi_col * MI_SIZE;
    const int mi_y = mi_row * MI_SIZE;
    dec_build_inter_predictors(cm, dcb, plane, xd->mi[0],
                               xd->plane[plane].width, xd->plane[plane].height,
                               mi_x, mi_y, 0);

    int is_intra_inter_allowed = 1;
    if (mbmi->tree_type == SHARED_PART &&
        mbmi->region_type == MIXED_INTER_INTRA_REGION &&
        mbmi->chroma_ref_info.offset_started && plane > 0) {
      is_intra_inter_allowed = 0;
    }

    if (is_interintra_pred(xd->mi[0]) && is_intra_inter_allowed) {
      BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
                           xd->plane[2].dst.buf },
                         { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
                           xd->plane[2].dst.stride } };
      av2_build_interintra_predictor(cm, xd, xd->plane[plane].dst.buf,
                                     xd->plane[plane].dst.stride, &ctx, plane,
                                     bsize);
    }
  }

  if (mbmi->morph_pred) {
    assert(av2_allow_intrabc(cm, xd, bsize));
    assert(av2_allow_intrabc_morph_pred(cm));
    assert(is_intrabc_block(mbmi, xd->tree_type));
    av2_build_morph_pred(cm, xd, bsize, mi_row, mi_col);
  }
}

static AVM_INLINE void predict_inter_block(AV2_COMMON *const cm,
                                           DecoderCodingBlock *dcb,
                                           BLOCK_SIZE bsize) {
  MACROBLOCKD *const xd = &dcb->xd;
  MB_MODE_INFO *mbmi = xd->mi[0];
  const int num_planes = av2_num_planes(cm);
  const int mi_row = xd->mi_row;
  const int mi_col = xd->mi_col;
  const int is_compound =
      has_second_ref(mbmi) || is_tip_ref_frame(mbmi->ref_frame[0]);
  for (int ref = 0; ref < 1 + is_compound; ++ref) {
    const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
    if (frame == INTRA_FRAME) {
      assert(is_intrabc_block(mbmi, xd->tree_type));
      assert(ref == 0);
    } else {
      const RefCntBuffer *ref_buf = is_tip_ref_frame(mbmi->ref_frame[0])
                                        ? cm->tip_ref.ref_frame_buffer[ref]
                                        : get_ref_frame_buf(cm, frame);
      const struct scale_factors *ref_scale_factors =
          get_ref_scale_factors_const(cm, frame);

      xd->block_ref_scale_factors[ref] = ref_scale_factors;
      av2_setup_pre_planes(xd, ref, &ref_buf->buf, mi_row, mi_col,
                           ref_scale_factors, num_planes,
                           &mbmi->chroma_ref_info);
    }
  }

  dec_build_inter_predictor(cm, dcb, mi_row, mi_col, bsize);

#if CONFIG_MISMATCH_DEBUG
  const int plane_start = get_partition_plane_start(xd->tree_type);
  const int plane_end = get_partition_plane_end(xd->tree_type, num_planes);
  for (int plane = plane_start; plane < plane_end; ++plane) {
    const struct macroblockd_plane *pd = &xd->plane[plane];
    int pixel_c, pixel_r;
    if (plane && !xd->is_chroma_ref) continue;
    if (plane) {
      mi_to_pixel_loc(&pixel_c, &pixel_r,
                      mbmi->chroma_ref_info.mi_col_chroma_base,
                      mbmi->chroma_ref_info.mi_row_chroma_base, 0, 0,
                      pd->subsampling_x, pd->subsampling_y);
    } else {
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0,
                      pd->subsampling_x, pd->subsampling_y);
    }
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
    mismatch_check_block_pre(
        pd->dst.buf, pd->dst.stride, cm->current_frame.display_order_hint,
        pixels_c, pixels_r, plane, pixel_c, pixel_r, pd->width, pd->height);
  }
#endif  // CONFIG_MISMATCH_DEBUG

#if CONFIG_INSPECTION
  for (int plane = 0; plane < num_planes; plane++) {
    struct macroblockd_plane *const pd = &xd->plane[plane];
    const int dst_stride = pd->dst.stride;
    const int plane_block_size =
        get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
    const int plane_width = mi_size_wide[plane_block_size];
    const int plane_height = mi_size_high[plane_block_size];
    for (int i = 0; i < plane_height * MI_SIZE; i++) {
      for (int j = 0; j < plane_width * MI_SIZE; j++) {
        uint16_t pixel = pd->dst.buf[i * dst_stride + j];
        int stride = cm->predicted_pixels.strides[plane > 0];
        int pixel_c, pixel_r;
        if (plane) {
          mi_to_pixel_loc(&pixel_c, &pixel_r,
                          mbmi->chroma_ref_info.mi_col_chroma_base,
                          mbmi->chroma_ref_info.mi_row_chroma_base, 0, 0,
                          pd->subsampling_x, pd->subsampling_y);
        } else {
          mi_to_pixel_loc(&pixel_c, &pixel_r, xd->mi_col, xd->mi_row, 0, 0,
                          pd->subsampling_x, pd->subsampling_y);
        }
        pixel_c += j;
        pixel_r += i;
        cm->predicted_pixels.buffers[plane][pixel_r * stride + pixel_c] = pixel;
      }
    }
  }
#endif  // CONFIG_INSPECTION
}

static AVM_INLINE void copy_frame_mvs_inter_block(AV2_COMMON *const cm,
                                                  DecoderCodingBlock *dcb,
                                                  BLOCK_SIZE bsize) {
  if (!frame_is_intra_only(cm) &&
      cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
    MACROBLOCKD *const xd = &dcb->xd;
    MB_MODE_INFO *const mi = xd->mi[0];
    const int bw = mi_size_wide[bsize];
    const int bh = mi_size_high[bsize];
    const int x_inside_boundary =
        AVMMIN(bw, cm->mi_params.mi_cols - xd->mi_col);
    const int y_inside_boundary =
        AVMMIN(bh, cm->mi_params.mi_rows - xd->mi_row);
    if (enable_refined_mvs_in_tmvp(cm, xd, mi)) {
      av2_copy_frame_refined_mvs(cm, xd, mi, xd->mi_row, xd->mi_col,
                                 x_inside_boundary, y_inside_boundary);
    } else {
      av2_copy_frame_mvs(cm, xd, mi, xd->mi_row, xd->mi_col, x_inside_boundary,
                         y_inside_boundary);
    }
  }
}

static AVM_INLINE void set_color_index_map_offset(MACROBLOCKD *const xd,
                                                  int plane, avm_reader *r) {
  (void)r;
  Av2ColorMapParam params;
  const MB_MODE_INFO *const mbmi = xd->mi[0];
  av2_get_block_dimensions(mbmi->sb_type[plane > 0], plane, xd,
                           &params.plane_width, &params.plane_height, NULL,
                           NULL);
  xd->color_index_map_offset[plane] += params.plane_width * params.plane_height;
}

void dec_bru_swap_stage(AV2_COMMON *cm, MACROBLOCKD *const xd) {
  if (cm->bru.enabled) {
    RefCntBuffer *tmp_buf = cm->cur_frame;
    if (bru_swap_common(cm)) {
      BufferPool *pool = cm->buffer_pool;
      lock_buffer_pool(pool);
      if (tmp_buf != NULL) {
        assert(tmp_buf->ref_count == 0);
        if (tmp_buf->ref_count == 0 && tmp_buf->raw_frame_buffer.data) {
          pool->release_fb_cb(pool->cb_priv, &tmp_buf->raw_frame_buffer);
          tmp_buf->raw_frame_buffer.data = NULL;
          tmp_buf->raw_frame_buffer.size = 0;
          tmp_buf->raw_frame_buffer.priv = NULL;
        }
      }
      unlock_buffer_pool(pool);
      xd->cur_buf = &cm->cur_frame->buf;
    } else {
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                         "Decoder BRU swap stage error");
    }
    // correctly extend borders after swap
    // todo: this can be simplified by only extend support SB border
    // avm_extend_frame_borders(&cm->cur_frame->buf, num_planes);
    // Note, do not touch any recon region except the border
    // first col of sb
    const int sb_cols =
        (cm->mi_params.mi_cols + cm->mib_size - 1) / cm->mib_size;
    const int sb_rows =
        (cm->mi_params.mi_rows + cm->mib_size - 1) / cm->mib_size;
    for (int sb_row = 0; sb_row < sb_rows; sb_row++) {
      const int sb_mi_row = sb_row << cm->mib_size_log2;
      const int sb_mi_col = 0;
      BruActiveMode active_mode =
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
      if (active_mode == BRU_SUPPORT_SB) {
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
                             &cm->cur_frame->buf);
      }
    }
    // first row of sb
    for (int sb_col = 0; sb_col < sb_cols; sb_col++) {
      const int sb_mi_row = 0;
      const int sb_mi_col = sb_col << cm->mib_size_log2;
      BruActiveMode active_mode =
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
      if (active_mode == BRU_SUPPORT_SB) {
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
                             &cm->cur_frame->buf);
      }
    }
    // last col of sb
    for (int sb_row = 0; sb_row < sb_rows; sb_row++) {
      const int sb_mi_row = sb_row << cm->mib_size_log2;
      const int sb_mi_col = (sb_cols - 1) << cm->mib_size_log2;
      BruActiveMode active_mode =
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
      if (active_mode == BRU_SUPPORT_SB) {
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
                             &cm->cur_frame->buf);
      }
    }
    // last row of sb
    for (int sb_col = 0; sb_col < sb_cols; sb_col++) {
      const int sb_mi_row = (sb_rows - 1) << cm->mib_size_log2;
      const int sb_mi_col = sb_col << cm->mib_size_log2;
      BruActiveMode active_mode =
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
      if (active_mode == BRU_SUPPORT_SB) {
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
                             &cm->cur_frame->buf);
      }
    }
  }
}

static AVM_INLINE int bridge_frame_is_valid_inter(const AV2_COMMON *const cm,
                                                  MACROBLOCKD *const xd) {
  if (!cm->bridge_frame_info.is_bridge_frame) return 1;
  const MB_MODE_INFO *const mbmi = xd->mi[0];
  const int tip_ref_frame = is_tip_ref_frame(mbmi->ref_frame[0]);
  const int is_compound = has_second_ref(mbmi);
  if (tip_ref_frame || is_compound) return 0;
  if (mbmi->ref_frame[0] != cm->bridge_frame_info.bridge_frame_ref_idx_remapped)
    return 0;
  const int_mv mi_mv = mbmi->mv[0];
  // MV must be (0,0)
  if (mi_mv.as_int != 0) {
    return 0;
  }
  return 1;
}

static AVM_INLINE void decode_token_recon_block(AV2Decoder *const pbi,
                                                ThreadData *const td,
                                                avm_reader *r,
                                                PARTITION_TYPE partition,
                                                BLOCK_SIZE bsize) {
  AV2_COMMON *const cm = &pbi->common;
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  MB_MODE_INFO *mbmi = xd->mi[0];
  xd->mi[0]->partition = partition;
  const int plane_start = get_partition_plane_start(xd->tree_type);
  const int plane_end =
      get_partition_plane_end(xd->tree_type, av2_num_planes(cm));
  const int mu128_wide = mi_size_wide[BLOCK_128X128];
  const int mu128_high = mi_size_high[BLOCK_128X128];

  if (!is_inter_block(mbmi, xd->tree_type)) {
    // When row_mt is used, this function can be called with
    // td->read_coeffs_tx_intra_block_visit == decode_block_void.
    // In that case do not reset since it will erase previously set
    // values.
    // intra cannot be used in non-active SBs
    if (!bru_is_sb_active(cm, xd->mi_col, xd->mi_row)) {
      avm_internal_error(
          &cm->error, AVM_CODEC_ERROR,
          "Invalid BRU activte: only active SB can be predicted by intra");
    }
    if (cm->bridge_frame_info.is_bridge_frame) {
      avm_internal_error(
          &cm->error, AVM_CODEC_ERROR,
          "Invalid Bridge frame activate: can not be predicted by intra");
    }
    if (td->read_coeffs_tx_intra_block_visit != decode_block_void)
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 0,
                              xd->tree_type, &mbmi->chroma_ref_info,
                              plane_start, plane_end);
    int row, col;

    xd->cfl.use_dc_pred_cache = 0;
    xd->cfl.dc_pred_is_cached[0] = 0;
    xd->cfl.dc_pred_is_cached[1] = 0;
    assert(bsize == get_plane_block_size(bsize, xd->plane[0].subsampling_x,
                                         xd->plane[0].subsampling_y));
    const int max_blocks_wide = max_block_wide(xd, bsize, 0);
    const int max_blocks_high = max_block_high(xd, bsize, 0);
    const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
    int mu_blocks_wide = mi_size_wide[max_unit_bsize];
    int mu_blocks_high = mi_size_high[max_unit_bsize];
    mu_blocks_wide = AVMMIN(max_blocks_wide, mu_blocks_wide);
    mu_blocks_high = AVMMIN(max_blocks_high, mu_blocks_high);

    // For 256x256 and 256x128 coding blocks, the coefficents/resdiuals are
    // divided into 64x* blocks, and each 64x64 block is coded in 128x128 unit.
    // For example, for a 256x256 coding block, the coding order of 64x64
    // residual blocks are following:
    // A B E F
    // C D G H
    // I J M N
    // K L O P

    // Loop through each 128x128 block within the current coding block
    for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
      for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
        // Loop through each 64x64 block within the current 128x128 block
        for (row = row128; row < AVMMIN(row128 + mu128_high, max_blocks_high);
             row += mu_blocks_high) {
          for (col = col128; col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
               col += mu_blocks_wide) {
            for (int plane = plane_start; plane < plane_end; ++plane) {
              if (plane == AVM_PLANE_Y && !xd->lossless[mbmi->segment_id]) {
                const struct macroblockd_plane *const pd = &xd->plane[plane];
                const int ss_x = pd->subsampling_x;
                const int ss_y = pd->subsampling_y;
                const BLOCK_SIZE plane_bsize =
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
                const int plane_unit_height =
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
                const int plane_unit_width =
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);

                const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
                get_tx_partition_sizes(mbmi->tx_partition_type[0], max_tx_size,
                                       &mbmi->txb_pos, mbmi->sub_txs,
                                       xd->error_info);

                for (int txb_idx = 0; txb_idx < mbmi->txb_pos.n_partitions;
                     ++txb_idx) {
                  const TX_SIZE tx_size = mbmi->sub_txs[txb_idx];
                  mbmi->txb_idx = txb_idx;
                  int blk_row = row + mbmi->txb_pos.row_offset[txb_idx];
                  int blk_col = col + mbmi->txb_pos.col_offset[txb_idx];

                  if (blk_row >= plane_unit_height ||
                      blk_col >= plane_unit_width)
                    continue;

                  td->read_coeffs_tx_intra_block_visit(
                      cm, dcb, r, plane, blk_row, blk_col, tx_size);
                  td->predict_and_recon_intra_block_visit(
                      cm, dcb, r, plane, blk_row, blk_col, tx_size);
                  set_cb_buffer_offsets(dcb, tx_size, plane);
                }
                // finish luma coding
              } else {
                if (plane && !xd->is_chroma_ref) break;
                const struct macroblockd_plane *const pd = &xd->plane[plane];
                const int ss_x = pd->subsampling_x;
                const int ss_y = pd->subsampling_y;
                const BLOCK_SIZE plane_bsize =
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
                const TX_SIZE tx_size = av2_get_tx_size(plane, xd);
                if (plane == AVM_PLANE_U && is_cctx_allowed(cm, xd)) continue;
                const int stepr = tx_size_high_unit[tx_size];
                const int stepc = tx_size_wide_unit[tx_size];
                const int plane_unit_height =
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
                const int plane_unit_width =
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);

                const bool lossless = xd->lossless[mbmi->segment_id];
                const bool need_parsing =
                    !skip_parsing_recon(row, col, ss_x, ss_y, lossless);
                const bool need_reconstrution =
                    mbmi->uv_mode != UV_CFL_PRED || lossless
                        ? need_parsing
                        : !((row + mu_blocks_high < max_blocks_high) ||
                            (col + mu_blocks_wide < max_blocks_wide));

                for (int blk_row = row >> ss_y; blk_row < plane_unit_height;
                     blk_row += stepr) {
                  for (int blk_col = col >> ss_x; blk_col < plane_unit_width;
                       blk_col += stepc) {
                    if (plane == AVM_PLANE_V && is_cctx_allowed(cm, xd)) {
                      if (need_parsing) {
                        td->read_coeffs_tx_intra_block_visit(
                            cm, dcb, r, AVM_PLANE_U, blk_row, blk_col, tx_size);
                        td->read_coeffs_tx_intra_block_visit(
                            cm, dcb, r, AVM_PLANE_V, blk_row, blk_col, tx_size);
                        td->inverse_cctx_block_visit(cm, dcb, r, -1, blk_row,
                                                     blk_col, tx_size);
                      }

                      if (need_reconstrution) {
                        td->predict_and_recon_intra_block_visit(
                            cm, dcb, r, AVM_PLANE_U, blk_row & 0xf0,
                            blk_col & 0xf0, tx_size);
                        td->predict_and_recon_intra_block_visit(
                            cm, dcb, r, AVM_PLANE_V, blk_row & 0xf0,
                            blk_col & 0xf0, tx_size);
                      }
                      if (need_reconstrution) {
                        set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_U);
                        set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_V);
                      }
                    } else {
                      assert(plane == AVM_PLANE_Y || !is_cctx_allowed(cm, xd));
                      if (need_parsing)
                        td->read_coeffs_tx_intra_block_visit(
                            cm, dcb, r, plane, blk_row, blk_col, tx_size);
                      if (need_reconstrution) {
                        td->predict_and_recon_intra_block_visit(
                            cm, dcb, r, plane,
                            blk_row & (lossless ? 0xff : 0xf0),
                            blk_col & (lossless ? 0xff : 0xf0), tx_size);
                      }
                      if (need_reconstrution)
                        set_cb_buffer_offsets(dcb, tx_size, plane);
                    }
                  }
                }
                // finish coding of the chroma components
              }
            }
          }
        }
      }
    }
  } else {
    // When row_mt is used, this function can be called with
    // td->read_coeffs_tx_inter_block_visit == decode_block_void.
    // In that case do not reset since it will erase previously set
    // values.
    // check BRU inter prediction motion vector
    if (!bru_is_valid_inter(cm, xd)) {
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                         "Invalid BRU inter prediction");
    }
    if (!bridge_frame_is_valid_inter(cm, xd)) {
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                         "Invalid Bridge frame inter prediction");
    }
    if (td->read_coeffs_tx_inter_block_visit != decode_block_void)
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 0,
                              xd->tree_type, &mbmi->chroma_ref_info,
                              plane_start, plane_end);
    td->predict_inter_block_visit(cm, dcb, bsize);
    // Reconstruction
    if (!mbmi->skip_txfm[xd->tree_type == CHROMA_PART]) {
      int eobtotal = 0;
      if (!bru_is_sb_active(cm, xd->mi_col, xd->mi_row)) {
        avm_internal_error(
            &cm->error, AVM_CODEC_ERROR,
            "Invalid BRU skip_txfm: only active SB has transform");
      }
      if (cm->bridge_frame_info.is_bridge_frame) {
        avm_internal_error(
            &cm->error, AVM_CODEC_ERROR,
            "Invalid Bridge frame skip_txfm: can not have transform");
      }
      const int max_blocks_wide = max_block_wide(xd, bsize, 0);
      const int max_blocks_high = max_block_high(xd, bsize, 0);
      int row, col;

      const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
      assert(max_unit_bsize ==
             get_plane_block_size(BLOCK_64X64, xd->plane[0].subsampling_x,
                                  xd->plane[0].subsampling_y));
      int mu_blocks_wide = mi_size_wide[max_unit_bsize];
      int mu_blocks_high = mi_size_high[max_unit_bsize];

      mu_blocks_wide = AVMMIN(max_blocks_wide, mu_blocks_wide);
      mu_blocks_high = AVMMIN(max_blocks_high, mu_blocks_high);

      // Loop through each 128x128 block within the current coding block
      for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
        for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
          // Loop through each 64x64 block within the current 128x128 block
          for (row = row128; row < AVMMIN(row128 + mu128_high, max_blocks_high);
               row += mu_blocks_high) {
            for (col = col128;
                 col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
                 col += mu_blocks_wide) {
              for (int plane = plane_start; plane < plane_end; ++plane) {
                if (plane && !xd->is_chroma_ref) break;
                const struct macroblockd_plane *const pd = &xd->plane[plane];
                const int ss_x = pd->subsampling_x;
                const int ss_y = pd->subsampling_y;
                const BLOCK_SIZE plane_bsize =
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
                const TX_SIZE max_tx_size =
                    get_vartx_max_txsize(xd, plane_bsize, plane);
                const int bh_var_tx = tx_size_high_unit[max_tx_size];
                const int bw_var_tx = tx_size_wide_unit[max_tx_size];
                const int plane_unit_height =
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
                const int plane_unit_width =
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);

                // When chroma TU is assocated with multiple luma TUs, the
                // chroma TU is parsed/reconstructed fewer times than
                // associated luama TUs. For example, in YUV420 format, one
                // 64x64 chroma TU is associated with four 64x64 luma TUs,
                // the parsing and reconstruction of the first 64x64 chroma
                // TU is done once for the first 64x64 luma TU and skipped
                // for the remaining three 64x64 TUs.
                const bool lossless = xd->lossless[mbmi->segment_id];
                if (skip_parsing_recon(row, col, ss_x, ss_y, lossless)) {
                  continue;
                }
                for (int blk_row = row >> ss_y; blk_row < plane_unit_height;
                     blk_row += bh_var_tx) {
                  for (int blk_col = col >> ss_x; blk_col < plane_unit_width;
                       blk_col += bw_var_tx) {
                    decode_reconstruct_tx(cm, td, r, mbmi, plane, plane_bsize,
                                          blk_row, blk_col, max_tx_size,
                                          &eobtotal);
                  }
                }
              }
            }
          }
        }
      }
    } else if (is_cctx_enabled(cm, xd) && xd->is_chroma_ref &&
               xd->tree_type != LUMA_PART) {
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 1,
                              xd->tree_type, &mbmi->chroma_ref_info,
                              plane_start, plane_end);
      // fill cctx_type_map with CCTX_NONE for skip blocks so their
      // neighbors can derive cctx contexts
      const struct macroblockd_plane *const pd = &xd->plane[AVM_PLANE_U];
      const int ss_x = pd->subsampling_x;
      const int ss_y = pd->subsampling_y;
      const BLOCK_SIZE uv_plane_bsize =
          get_mb_plane_block_size(xd, mbmi, AVM_PLANE_U, ss_x, ss_y);
      const TX_SIZE max_tx_size =
          get_vartx_max_txsize(xd, uv_plane_bsize, AVM_PLANE_U);
      const int max_blocks_wide = max_block_wide(xd, bsize, 0);
      const int max_blocks_high = max_block_high(xd, bsize, 0);
      const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
      int mu_blocks_wide = mi_size_wide[max_unit_bsize];
      int mu_blocks_high = mi_size_high[max_unit_bsize];
      // Loop through each 128x128 block within the current coding block
      for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
        for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
          // Loop through each 64x64 block within the current 128x128 block
          for (int row = row128;
               row < AVMMIN(row128 + mu128_high, max_blocks_high);
               row += mu_blocks_high) {
            for (int col = col128;
                 col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
                 col += mu_blocks_wide) {
              int row_offset, col_offset;
              get_chroma_mi_offsets(xd, &row_offset, &col_offset);
              update_cctx_array(xd, 0, 0, row_offset, col_offset, max_tx_size,
                                CCTX_NONE);
            }
          }
        }
      }
    } else {
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 1,
                              xd->tree_type, &mbmi->chroma_ref_info,
                              plane_start, plane_end);
    }
  }

  td->copy_frame_mvs_block_visit(cm, dcb, bsize);

  av2_visit_palette(pbi, xd, r, set_color_index_map_offset);
  av2_mark_block_as_coded(xd, bsize, cm->sb_size);
}

static TX_SIZE read_tx_partition(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
                                 TX_SIZE max_tx_size, int blk_row, int blk_col,
                                 avm_reader *r) {
  int plane_type = (xd->tree_type == CHROMA_PART);
  const BLOCK_SIZE bsize = mbmi->sb_type[plane_type];
  const int is_inter = is_inter_block(mbmi, xd->tree_type);
  const int max_blocks_high = max_block_high(xd, bsize, 0);
  const int max_blocks_wide = max_block_wide(xd, bsize, 0);
  if (is_inter && (blk_row >= max_blocks_high || blk_col >= max_blocks_wide))
    return TX_INVALID;
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  const int allow_horz = allow_tx_horz_split(bsize, max_tx_size);
  const int allow_vert = allow_tx_vert_split(bsize, max_tx_size);
  TX_PARTITION_TYPE partition = 0;
  const int is_fsc = (xd->mi[0]->fsc_mode[xd->tree_type == CHROMA_PART] &&
                      plane_type == PLANE_TYPE_Y);
  const int bsize_group = size_to_tx_part_group_lookup[bsize];
  const int txsize_group_h_and_v = get_vert_and_horz_group(bsize);
  const int txsize_group_h_or_v = get_vert_or_horz_group(bsize);
  assert(!(txsize_group_h_and_v == BLOCK_INVALID &&
           txsize_group_h_or_v == BLOCK_INVALID));
  int do_partition = 0;
  if (allow_horz || allow_vert) {
    avm_cdf_prob *do_partition_cdf =
        ec_ctx->txfm_do_partition_cdf[is_fsc][is_inter][bsize_group];
    do_partition =
        avm_read_symbol(r, do_partition_cdf, 2, ACCT_INFO("do_partition"));
  }

  if (do_partition) {
    if (allow_horz && allow_vert) {
      // Read 4way tree type
      assert(txsize_group_h_or_v > 0);
      avm_cdf_prob *partition_type_cdf =
          ec_ctx->txfm_4way_partition_type_cdf[is_fsc][is_inter]
                                              [txsize_group_h_and_v];

      const TX_PARTITION_TYPE partition_type =
          avm_read_symbol(r, partition_type_cdf, TX_PARTITION_TYPE_NUM,
                          ACCT_INFO("partition_type"));
      partition = partition_type + 1;
    } else if (txsize_group_h_or_v) {
      avm_cdf_prob *partition_type_cdf =
          ec_ctx->txfm_2or3_way_partition_type_cdf[is_fsc][is_inter]
                                                  [txsize_group_h_or_v - 1];
      const TX_PARTITION_TYPE partition_type =
          xd->reduced_tx_part_set
              ? 0
              : avm_read_symbol(r, partition_type_cdf, 2,
                                ACCT_INFO("partition_type"));
      if (allow_horz) {
        switch (partition_type) {
          case 0: partition = TX_PARTITION_HORZ; break;
          case 1: partition = TX_PARTITION_HORZ4; break;
          default: assert(0); break;
        }
      } else {
        switch (partition_type) {
          case 0: partition = TX_PARTITION_VERT; break;
          case 1: partition = TX_PARTITION_VERT4; break;
          default: assert(0); break;
        }
      }
    } else {
      partition = allow_horz ? TX_PARTITION_HORZ : TX_PARTITION_VERT;
    }
  } else {
    partition = TX_PARTITION_NONE;
  }

  TX_SIZE sub_txs[MAX_TX_PARTITIONS] = { 0 };
  int num_txfm_blocks = get_tx_partition_sizes(
      partition, max_tx_size, &mbmi->txb_pos, sub_txs, xd->error_info);
  mbmi->tx_size = sub_txs[num_txfm_blocks - 1];
  int index = is_inter ? av2_get_txb_size_index(bsize, blk_row, blk_col) : 0;
  mbmi->tx_partition_type[index] = partition;
  return sub_txs[num_txfm_blocks - 1];
}

static TX_SIZE read_tx_size(MACROBLOCKD *xd, TX_MODE tx_mode, int is_inter,
                            int allow_select_inter, avm_reader *r) {
  const BLOCK_SIZE bsize = xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART];
  if (xd->lossless[xd->mi[0]->segment_id]) {
    const bool is_fsc = xd->mi[0]->fsc_mode[xd->tree_type == CHROMA_PART];
    if (bsize == BLOCK_4X4 || (!is_inter && !is_fsc) || !allow_select_inter)
      return TX_4X4;
    else {
      const int bsize_group = size_group_lookup[bsize];
      const int is_tx_size_large = avm_read_symbol(
          r, xd->tile_ctx->lossless_tx_size_cdf[bsize_group][is_inter], 2,
          ACCT_INFO("lossless_tx_size"));
      if (is_tx_size_large) {
        return lossless_max_txsize_lookup[bsize];
      }
      return (TX_SIZE)is_tx_size_large;
    }
  }

  if (block_signals_txsize(bsize)) {
    if ((!is_inter || allow_select_inter) && tx_mode == TX_MODE_SELECT) {
      MB_MODE_INFO *mbmi = xd->mi[0];
      const TX_SIZE max_tx_size = max_txsize_rect_lookup[bsize];
      return read_tx_partition(xd, mbmi, max_tx_size, 0, 0, r);
    } else {
      return tx_size_from_tx_mode(bsize, tx_mode);
    }
  } else {
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
    return max_txsize_rect_lookup[bsize];
  }
}
static BruActiveMode read_bru_mode(AV2_COMMON *cm, const MACROBLOCKD *xd,
                                   avm_reader *r) {
  if (!cm->bru.enabled) return 0;
  BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
  if (is_sb_start_mi(cm, xd->mi_col, xd->mi_row)) {
    if (xd->tile.tile_active_mode == 0) {
      sb_active_mode = BRU_INACTIVE_SB;
    } else {
      FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
      // 0 inactive, 1 support, 2 active
      sb_active_mode = (BruActiveMode)avm_read_symbol(
          r, ec_ctx->bru_mode_cdf, 3, ACCT_INFO("sb_active_mode"));
    }
    xd->sbi->sb_active_mode = sb_active_mode;
  } else {
    const SB_INFO *sbi = av2_get_sb_info(cm, xd->mi_row, xd->mi_col);
    sb_active_mode = sbi->sb_active_mode;
  }
  return sb_active_mode;
}
static AVM_INLINE void parse_decode_block(AV2Decoder *const pbi,
                                          ThreadData *const td, int mi_row,
                                          int mi_col, avm_reader *r,
                                          PARTITION_TYPE partition,
                                          BLOCK_SIZE bsize,
                                          PARTITION_TREE *parent, int index) {
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  const int max_aspect_ratio =
      1 << (pbi->common.seq_params.max_pb_aspect_ratio_log2_m1 + 1);
  const int blk_w = block_size_wide[bsize];
  const int blk_h = block_size_high[bsize];
  if (blk_w > blk_h * max_aspect_ratio || blk_h > blk_w * max_aspect_ratio) {
    avm_internal_error(
        xd->error_info, AVM_CODEC_CORRUPT_FRAME,
        "Block size %dx%d violates aspect ratio constraint of %d", blk_w, blk_h,
        max_aspect_ratio);
  }
  decode_mbmi_block(pbi, dcb, mi_row, mi_col, r, partition, bsize, parent,
                    index);

  av2_visit_palette(pbi, xd, r, av2_decode_palette_tokens);

  AV2_COMMON *cm = &pbi->common;
  const int num_planes = av2_num_planes(cm);
  MB_MODE_INFO *mbmi = xd->mi[0];
  int inter_block_tx = is_inter_block(mbmi, xd->tree_type) ||
                       is_intrabc_block(mbmi, xd->tree_type);
  xd->reduced_tx_part_set = cm->seq_params.reduced_tx_part_set;
  if (xd->tree_type != CHROMA_PART) {
    memset(mbmi->tx_partition_type, TX_PARTITION_NONE,
           sizeof(mbmi->tx_partition_type));
    if (cm->features.tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) &&
        !mbmi->skip_txfm[xd->tree_type == CHROMA_PART] && inter_block_tx &&
        !xd->lossless[mbmi->segment_id]) {
      const TX_SIZE max_tx_size = max_txsize_rect_lookup[bsize];
      const int bh = tx_size_high_unit[max_tx_size];
      const int bw = tx_size_wide_unit[max_tx_size];
      const int width = mi_size_wide[bsize];
      const int height = mi_size_high[bsize];

      for (int idy = 0; idy < height; idy += bh)
        for (int idx = 0; idx < width; idx += bw)
          read_tx_partition(xd, mbmi, max_tx_size, idy, idx, r);
    } else {
      mbmi->tx_size =
          read_tx_size(xd, cm->features.tx_mode, inter_block_tx,
                       !mbmi->skip_txfm[xd->tree_type == CHROMA_PART], r);
    }
  }

  if (cm->delta_q_info.delta_q_present_flag) {
    for (int i = 0; i < MAX_SEGMENTS; i++) {
      const int current_qindex = av2_get_qindex(
          &cm->seg, i, xd->current_base_qindex, cm->seq_params.bit_depth);

      const CommonQuantParams *const quant_params = &cm->quant_params;
      for (int j = 0; j < num_planes; ++j) {
        const int dc_delta_q = j == 0 ? quant_params->y_dc_delta_q
                                      : (j == 1 ? quant_params->u_dc_delta_q
                                                : quant_params->v_dc_delta_q);
        const int ac_delta_q = j == 0 ? 0
                                      : (j == 1 ? quant_params->u_ac_delta_q
                                                : quant_params->v_ac_delta_q);
        xd->plane[j].seg_dequant_QTX[i][0] =
            av2_dc_quant_QTX(current_qindex, dc_delta_q,
                             j == 0 ? cm->seq_params.base_y_dc_delta_q
                                    : cm->seq_params.base_uv_dc_delta_q,
                             cm->seq_params.bit_depth);
        xd->plane[j].seg_dequant_QTX[i][1] =
            av2_ac_quant_QTX(current_qindex, ac_delta_q,
                             j == 0 ? 0 : cm->seq_params.base_uv_ac_delta_q,
                             cm->seq_params.bit_depth);
      }
    }
  }
  assert(bsize == mbmi->sb_type[av2_get_sdp_idx(xd->tree_type)]);
  if (mbmi->skip_txfm[xd->tree_type == CHROMA_PART])
    av2_reset_entropy_context(xd, bsize, num_planes);
  // For regular decoder, always do recon
  // For optimized decoder, only do reocn when support SB
  if (!pbi->bru_opt_mode ||
      (pbi->bru_opt_mode && bru_is_sb_active(cm, mi_col, mi_row)))
    decode_token_recon_block(pbi, td, r, partition, bsize);

  // Note: the copying here must match corresponding encoder-side copying in
  // av2_update_state().
  // TODO(any): Refactor.
  if (xd->tree_type != SHARED_PART) {
    const int bh = mi_size_high[bsize];
    const int bw = mi_size_wide[bsize];
    const CommonModeInfoParams *const mi_params = &cm->mi_params;
    const int x_inside_boundary = AVMMIN(bw, mi_params->mi_cols - mi_col);
    const int y_inside_boundary = AVMMIN(bh, mi_params->mi_rows - mi_row);
    int idx = mi_params->mi_stride;
    assert(x_inside_boundary && y_inside_boundary);
    if (xd->tree_type != CHROMA_PART) {
      for (int y = 0; y < y_inside_boundary; ++y) {
        for (int x = 0; x < x_inside_boundary; ++x) {
          if (x == 0 && y == 0) continue;
          set_blk_offsets(mi_params, xd, mi_row, mi_col, y, x);
          *(xd->mi[y * idx + x]) = *(xd->mi[0]);
        }
      }
    } else {
      assert(x_inside_boundary && y_inside_boundary);
      for (int y = 0; y < y_inside_boundary; ++y) {
        for (int x = 0; x < x_inside_boundary; ++x) {
          if (x == 0 && y == 0) continue;
          set_blk_offsets(mi_params, xd, mi_row, mi_col, y, x);
          xd->mi[y * idx + x]->sb_type[PLANE_TYPE_UV] =
              xd->mi[0]->sb_type[PLANE_TYPE_UV];
          xd->mi[y * idx + x]->uv_mode = xd->mi[0]->uv_mode;
          xd->mi[y * idx + x]->angle_delta[PLANE_TYPE_UV] =
              xd->mi[0]->angle_delta[PLANE_TYPE_UV];
          xd->mi[y * idx + x]->cfl_alpha_signs = xd->mi[0]->cfl_alpha_signs;
          xd->mi[y * idx + x]->cfl_alpha_idx = xd->mi[0]->cfl_alpha_idx;
          xd->mi[y * idx + x]->partition = xd->mi[0]->partition;
          xd->mi[y * idx + x]->chroma_mi_row_start =
              xd->mi[0]->chroma_mi_row_start;
          xd->mi[y * idx + x]->chroma_mi_col_start =
              xd->mi[0]->chroma_mi_col_start;
          if (av2_allow_palette(PLANE_TYPE_UV,
                                cm->features.allow_screen_content_tools,
                                bsize)) {
            xd->mi[y * idx + x]->palette_mode_info.palette_size[PLANE_TYPE_UV] =
                xd->mi[0]->palette_mode_info.palette_size[PLANE_TYPE_UV];
            for (int i = PALETTE_MAX_SIZE; i < 3 * PALETTE_MAX_SIZE; i++)
              xd->mi[y * idx + x]->palette_mode_info.palette_colors[i] =
                  xd->mi[0]->palette_mode_info.palette_colors[i];
          }
        }
      }
    }
  }
}

static AVM_INLINE void set_offsets_for_pred_and_recon(AV2Decoder *const pbi,
                                                      ThreadData *const td,
                                                      int mi_row, int mi_col,
                                                      BLOCK_SIZE bsize) {
  AV2_COMMON *const cm = &pbi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int num_planes = av2_num_planes(cm);

  const int offset = mi_row * mi_params->mi_stride + mi_col;
  const TileInfo *const tile = &xd->tile;

  xd->mi = mi_params->mi_grid_base + offset;
  xd->tx_type_map =
      &mi_params->tx_type_map[mi_row * mi_params->mi_stride + mi_col];
  xd->tx_type_map_stride = mi_params->mi_stride;
  xd->cctx_type_map =
      &mi_params->cctx_type_map[mi_row * mi_params->mi_stride + mi_col];
  xd->cctx_type_map_stride = mi_params->mi_stride;

  // It is assumed that CHROMA_REF_INFO is already set (during parsing stage).
  CHROMA_REF_INFO chroma_ref_info = xd->mi[0]->chroma_ref_info;
  // In case of semi-decoupled partitions, the variable is_chroma_ref is set to
  // 0 while parsing luma tree and is set to 1 while parsing chroma tree. Thus,
  // the value of is_chroma_ref set during parsing stage cannot be used and
  // needs to be explicitly updated here based on tree type.
  if (xd->tree_type != SHARED_PART)
    chroma_ref_info.is_chroma_ref = xd->tree_type == LUMA_PART ? 0 : 1;
  set_plane_n4(xd, bw, bh, num_planes, &chroma_ref_info);

  // Distance of Mb to the various image edges. These are specified to 8th pel
  // as they are always compared to values that are in 1/8th pel units
  set_mi_row_col(cm, xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
                 mi_params->mi_cols, &chroma_ref_info);

  av2_setup_dst_planes(xd->plane, &cm->cur_frame->buf, mi_row, mi_col, 0,
                       num_planes, &chroma_ref_info);
}

static AVM_INLINE void decode_block(AV2Decoder *const pbi, ThreadData *const td,
                                    int mi_row, int mi_col, avm_reader *r,
                                    PARTITION_TYPE partition, BLOCK_SIZE bsize,
                                    PARTITION_TREE *parent, int index) {
  (void)partition;
  (void)parent;
  (void)index;
  const int max_aspect_ratio =
      1 << (pbi->common.seq_params.max_pb_aspect_ratio_log2_m1 + 1);
  const int blk_w = block_size_wide[bsize];
  const int blk_h = block_size_high[bsize];
  if (blk_w > blk_h * max_aspect_ratio || blk_h > blk_w * max_aspect_ratio) {
    avm_internal_error(
        td->dcb.xd.error_info, AVM_CODEC_CORRUPT_FRAME,
        "Block size %dx%d violates aspect ratio constraint of %d", blk_w, blk_h,
        max_aspect_ratio);
  }
  set_offsets_for_pred_and_recon(pbi, td, mi_row, mi_col, bsize);
  decode_token_recon_block(pbi, td, r, partition, bsize);
}

/*!\brief Maps (ext_part, 4way, 4way_type, rect_type) to partition_type. */
static PARTITION_TYPE
    rect_part_table[2][2][NUM_UNEVEN_4WAY_PARTS][NUM_RECT_PARTS] = {
      {
          // !do_ext_partition
          {
              // !do_4way
              { // UNEVEN_4A
                PARTITION_HORZ, PARTITION_VERT },
              { // UNEVEN_4B
                PARTITION_HORZ, PARTITION_VERT },
          },
          {
              // do_4way
              { // UNEVEN_4A
                PARTITION_HORZ, PARTITION_VERT },
              { // UNEVEN_4B
                PARTITION_HORZ, PARTITION_VERT },
          },
      },
      {
          // do_ext_partition
          {
              // !do_4way
              { // UNEVEN_4A
                PARTITION_HORZ_3, PARTITION_VERT_3 },
              { // UNEVEN_4B
                PARTITION_HORZ_3, PARTITION_VERT_3 },
          },
          {
              // do_4way
              { // UNEVEN_4A
                PARTITION_HORZ_4A, PARTITION_VERT_4A },
              { // UNEVEN_4B
                PARTITION_HORZ_4B, PARTITION_VERT_4B },
          },
      },
    };

static PARTITION_TYPE read_partition(const AV2_COMMON *const cm,
                                     MACROBLOCKD *xd, int mi_row, int mi_col,
                                     avm_reader *r, int has_rows, int has_cols,
                                     const PARTITION_TREE *ptree,
                                     const PARTITION_TREE *ptree_luma,
                                     BLOCK_SIZE bsize) {
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;

  (void)has_rows;
  (void)has_cols;
  const int plane = xd->tree_type == CHROMA_PART;
  const int ssx = cm->seq_params.subsampling_x;
  const int ssy = cm->seq_params.subsampling_y;
  PARTITION_TYPE derived_partition = av2_get_normative_forced_partition_type(
      &cm->mi_params, xd->tree_type, ssx, ssy, mi_row, mi_col, bsize,
      ptree_luma);

  bool partition_allowed[ALL_PARTITION_TYPES];
  init_allowed_partitions_for_signaling(
      partition_allowed, cm, xd->tree_type,
      (ptree->parent ? ptree->parent->region_type : INTRA_REGION), mi_row,
      mi_col, ssx, ssy, bsize, &ptree->chroma_ref_info);
  if (derived_partition != PARTITION_INVALID &&
      partition_allowed[derived_partition]) {
    return derived_partition;
  }

  derived_partition = only_allowed_partition(partition_allowed);
  if (derived_partition != PARTITION_INVALID) {
    return derived_partition;
  }

  bool do_split;
  bool implied_do_split;
  // allow do whatever implied first, then if not possible
  // use BRU to set do split to false
  if (is_do_split_implied(partition_allowed, &implied_do_split)) {
    // BRU inactive won't go futher implied partition
    if (!bru_is_sb_active(cm, mi_col, mi_row) ||
        cm->bridge_frame_info.is_bridge_frame) {
      do_split = false;
    } else
      do_split = implied_do_split;
  } else {
    // if not derived partition, based on inactive/support set do_split to false
    if (!bru_is_sb_active(cm, mi_col, mi_row) ||
        cm->bridge_frame_info.is_bridge_frame) {
      do_split = false;
    } else {
      const int ctx =
          partition_plane_context(xd, mi_row, mi_col, bsize, 0, SPLIT_CTX_MODE);
      do_split = avm_read_symbol(r, ec_ctx->do_split_cdf[plane][ctx], 2,
                                 ACCT_INFO("do_split"));
    }
  }
  if (!do_split) {
    return PARTITION_NONE;
  }

  if (partition_allowed[PARTITION_SPLIT]) {
    const int square_split_ctx = partition_plane_context(
        xd, mi_row, mi_col, bsize, 0, SQUARE_SPLIT_CTX_MODE);
    const bool do_square_split =
        avm_read_symbol(r, ec_ctx->do_square_split_cdf[plane][square_split_ctx],
                        2, ACCT_INFO("do_square_split"));
    if (do_square_split) {
      return PARTITION_SPLIT;
    }
  }

  RECT_PART_TYPE rect_type = rect_type_implied_by_bsize(bsize, xd->tree_type);
  if (rect_type == RECT_INVALID) {
    rect_type = only_allowed_rect_type(partition_allowed);
  }
  if (rect_type == RECT_INVALID) {
    const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize, 0,
                                            RECT_TYPE_CTX_MODE);
    rect_type = avm_read_symbol(r, ec_ctx->rect_type_cdf[plane][ctx],
                                NUM_RECT_PARTS, ACCT_INFO("rect_type"));
  }

  bool do_ext_partition = false;
  bool do_uneven_4way_partition = false;
  UNEVEN_4WAY_PART_TYPE uneven_4way_partition_type = UNEVEN_4A;
  bool implied_do_ext;
  if (is_do_ext_partition_implied(partition_allowed, rect_type,
                                  &implied_do_ext)) {
    do_ext_partition = implied_do_ext;
  } else {
    const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize,
                                            rect_type, EXT_PART_CTX_MODE);
    do_ext_partition =
        avm_read_symbol(r, ec_ctx->do_ext_partition_cdf[plane][0][ctx], 2,
                        ACCT_INFO("do_ext_partition"));
  }
  if (do_ext_partition) {
    bool implied_do_uneven_4way;
    if (is_do_uneven_4way_partition_implied(partition_allowed, rect_type,
                                            &implied_do_uneven_4way)) {
      do_uneven_4way_partition = implied_do_uneven_4way;
    } else {
      const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize,
                                              rect_type, FOUR_WAY_CTX_MODE);
      do_uneven_4way_partition = avm_read_symbol(
          r, ec_ctx->do_uneven_4way_partition_cdf[plane][0][ctx], 2,
          ACCT_INFO("do_uneven_4way_partition"));
    }
    if (do_uneven_4way_partition) {
      uneven_4way_partition_type =
          avm_read_bit(r, ACCT_INFO("uneven_4way_partition_type"));
    }
  }
  return rect_part_table[do_ext_partition][do_uneven_4way_partition]
                        [uneven_4way_partition_type][rect_type];
}

// Set the superblock level parameters
static void set_sb_mv_precision(SB_INFO *sbi, AV2Decoder *const pbi) {
  AV2_COMMON *const cm = &pbi->common;
  sbi->sb_mv_precision = cm->features.fr_mv_precision;
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
static AVM_INLINE void decode_partition(
    AV2Decoder *const pbi, ThreadData *const td, int mi_row, int mi_col,
    avm_reader *reader, BLOCK_SIZE bsize, SB_INFO *sbi, PARTITION_TREE *ptree,
    PARTITION_TREE *ptree_luma, int parse_decode_flag) {
  assert(bsize < BLOCK_SIZES_ALL);
  AV2_COMMON *const cm = &pbi->common;
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  const int ss_x = xd->plane[1].subsampling_x;
  const int ss_y = xd->plane[1].subsampling_y;
  // Half block width/height.
  const int hbs_w = mi_size_wide[bsize] / 2;
  const int hbs_h = mi_size_high[bsize] / 2;
  // One-eighth block width/height.
  const int ebs_w = mi_size_wide[bsize] / 8;
  const int ebs_h = mi_size_high[bsize] / 8;
  PARTITION_TYPE partition;
  const int has_rows = (mi_row + hbs_h) < cm->mi_params.mi_rows;
  const int has_cols = (mi_col + hbs_w) < cm->mi_params.mi_cols;

  if (mi_row >= cm->mi_params.mi_rows || mi_col >= cm->mi_params.mi_cols) {
    av2_mark_block_as_pseudo_coded(xd, mi_row, mi_col, bsize, cm->sb_size);
    return;
  }

  const int is_intra_sdp_enabled = is_sdp_enabled_in_keyframe(cm);
  const int total_loop_num =
      is_intra_sdp_enabled && bsize == BLOCK_64X64 ? 2 : 1;
  if (total_loop_num == 2 && xd->tree_type == SHARED_PART) {
    xd->tree_type = LUMA_PART;
    decode_partition(pbi, td, mi_row, mi_col, reader, bsize, sbi, ptree,
                     ptree_luma, parse_decode_flag);
    xd->tree_type = CHROMA_PART;

    decode_partition(pbi, td, mi_row, mi_col, reader, bsize, sbi, ptree_luma,
                     ptree, parse_decode_flag);
    xd->tree_type = SHARED_PART;
    return;
  }

  // parse_decode_flag takes the following values :
  // 01 - do parse only
  // 10 - do decode only
  // 11 - do parse and decode
  static const block_visitor_fn_t block_visit[4] = { NULL, parse_decode_block,
                                                     decode_block,
                                                     parse_decode_block };
  if (ptree->parent) {
    if (ptree->parent->bsize == cm->sb_size) {
      if (ptree->parent->partition == PARTITION_VERT)
        ptree->sb_root_partition_info = SB_VERT_PARTITION;
      else if (ptree->parent->partition == PARTITION_HORZ ||
               ptree->parent->partition == PARTITION_SPLIT)
        ptree->sb_root_partition_info = SB_HORZ_OR_QUAD_PARTITION;
      else
        ptree->sb_root_partition_info = INVALID_INTRABC_SB_PARTITION;
    } else {
      ptree->sb_root_partition_info = ptree->parent->sb_root_partition_info;
    }
  }

  const int is_sb_root = bsize == cm->sb_size;
  if (is_sb_root) {
    xd->is_cfl_allowed_in_sdp =
        is_cfl_allowed_for_sdp(cm, xd, ptree_luma, PARTITION_NONE, bsize);
    ptree->is_cfl_allowed_for_this_chroma_partition = CFL_DISALLOWED_FOR_CHROMA;
    if (!frame_is_intra_only(cm)) {
      ptree->region_type = MIXED_INTER_INTRA_REGION;
      ptree->extended_sdp_allowed_flag = cm->seq_params.enable_extended_sdp;
    } else {
      ptree->region_type = INTRA_REGION;
      ptree->extended_sdp_allowed_flag = 0;
    }
  }

  if (parse_decode_flag & 1) {
    if (is_sb_root) {
      if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
        const int mi_grid_idx = get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
        const int mi_alloc_idx =
            get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
        cm->mi_params.mi_grid_base[mi_grid_idx] =
            &cm->mi_params.mi_alloc[mi_alloc_idx];
        // 'xd->mi' should point to an offset in 'mi_grid_base';
        xd->mi = cm->mi_params.mi_grid_base + mi_grid_idx;
        xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART] = bsize;
        xd->mi_row = mi_row;
        xd->mi_col = mi_col;
        if (!cm->bridge_frame_info.is_bridge_frame) {
          xd->sbi->sb_active_mode = read_bru_mode(cm, xd, reader);
          set_active_map(cm, mi_col, mi_row, xd->sbi->sb_active_mode);
        }
      }
      set_sb_mv_precision(sbi, pbi);
    }
    const int plane_start = get_partition_plane_start(xd->tree_type);
    const int plane_end =
        get_partition_plane_end(xd->tree_type, av2_num_planes(cm));
    for (int plane = plane_start; plane < plane_end; ++plane) {
      int rcol0, rcol1, rrow0, rrow1;
      if ((cm->rst_info[plane].frame_restoration_type != RESTORE_NONE) &&
          av2_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
                                             &rcol0, &rcol1, &rrow0, &rrow1)) {
        const int rstride = cm->rst_info[plane].horz_units_per_frame;
        for (int rrow = rrow0; rrow < rrow1; ++rrow) {
          for (int rcol = rcol0; rcol < rcol1; ++rcol) {
            const int runit_idx = rcol + rrow * rstride;
            loop_restoration_read_sb_coeffs(cm, xd, reader, plane, runit_idx);
          }
        }
      }
    }

    ptree->bsize = bsize;
    ptree->mi_row = mi_row;
    ptree->mi_col = mi_col;
    ptree->is_settled = 1;

    if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
      ptree_luma->bsize = bsize;
      ptree_luma->mi_row = mi_row;
      ptree_luma->mi_col = mi_col;
      ptree_luma->is_settled = 1;
      ptree_luma->is_cfl_allowed_for_this_chroma_partition =
          CFL_DISALLOWED_FOR_CHROMA;
    }

    PARTITION_TREE *parent = ptree->parent;
    set_chroma_ref_info(
        xd->tree_type, mi_row, mi_col, ptree->index, bsize,
        &ptree->chroma_ref_info, parent ? &parent->chroma_ref_info : NULL,
        parent ? parent->bsize : BLOCK_INVALID,
        parent ? parent->partition : PARTITION_NONE, ss_x, ss_y);

    partition = !is_partition_point(bsize)
                    ? PARTITION_NONE
                    : read_partition(cm, xd, mi_row, mi_col, reader, has_rows,
                                     has_cols, ptree, ptree_luma, bsize);
    ptree->is_cfl_allowed_for_this_chroma_partition |=
        is_cfl_allowed_for_sdp(cm, xd, ptree_luma, partition, bsize);
    CFL_ALLOWED_FOR_SDP_TYPE is_cfl_allowed_in_sdp =
        ptree->is_cfl_allowed_for_this_chroma_partition;
    ptree->partition = partition;

    if (!is_sb_root && parent) {
      if (parent->extended_sdp_allowed_flag)
        ptree->extended_sdp_allowed_flag =
            is_extended_sdp_allowed(cm->seq_params.enable_extended_sdp,
                                    parent->bsize, parent->partition);
      else
        ptree->extended_sdp_allowed_flag = 0;
      if (!frame_is_intra_only(cm) && ptree->partition &&
          parent->region_type != INTRA_REGION &&
          ptree->extended_sdp_allowed_flag &&
          bru_is_sb_active(cm, mi_col, mi_row) &&
          !cm->bridge_frame_info.is_bridge_frame &&
          is_bsize_allowed_for_extended_sdp(bsize, ptree->partition)) {
        const int ctx = get_intra_region_context(bsize);
        ptree->region_type =
            avm_read_symbol(reader, xd->tile_ctx->region_type_cdf[ctx],
                            REGION_TYPES, ACCT_INFO("region_type"));
        if (ptree->region_type == INTRA_REGION) xd->tree_type = LUMA_PART;
      } else if (!frame_is_intra_only(cm)) {
        ptree->region_type = parent->region_type;
      } else {
        ptree->region_type = INTRA_REGION;
      }
    }

    switch (partition) {
      case PARTITION_HORZ_4A:
      case PARTITION_HORZ_4B:
      case PARTITION_VERT_4A:
      case PARTITION_VERT_4B:
      case PARTITION_SPLIT:
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);
        ptree->sub_tree[2] = av2_alloc_ptree_node(ptree, 2);
        ptree->sub_tree[3] = av2_alloc_ptree_node(ptree, 3);
        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
          ptree_luma->sub_tree[2] = av2_alloc_ptree_node(ptree_luma, 2);
          ptree_luma->sub_tree[3] = av2_alloc_ptree_node(ptree_luma, 3);
        }
        break;
      case PARTITION_HORZ:
      case PARTITION_VERT:
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);

        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
        }
        break;
      case PARTITION_HORZ_3:
      case PARTITION_VERT_3:
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);
        ptree->sub_tree[2] = av2_alloc_ptree_node(ptree, 2);
        ptree->sub_tree[3] = av2_alloc_ptree_node(ptree, 3);

        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
          ptree_luma->sub_tree[2] = av2_alloc_ptree_node(ptree_luma, 2);
          ptree_luma->sub_tree[3] = av2_alloc_ptree_node(ptree_luma, 3);
        }
        break;
      default: break;
    }
    switch (partition) {
      case PARTITION_NONE:
        xd->is_cfl_allowed_in_sdp = is_cfl_allowed_in_sdp;
        break;
      case PARTITION_HORZ_4A:
      case PARTITION_HORZ_4B:
      case PARTITION_VERT_4A:
      case PARTITION_VERT_4B:
      case PARTITION_HORZ_3:
      case PARTITION_VERT_3:
      case PARTITION_SPLIT:
        ptree->sub_tree[0]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        ptree->sub_tree[1]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        ptree->sub_tree[2]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        ptree->sub_tree[3]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        break;
      case PARTITION_HORZ:
      case PARTITION_VERT:
        ptree->sub_tree[0]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        ptree->sub_tree[1]->is_cfl_allowed_for_this_chroma_partition =
            is_cfl_allowed_in_sdp;
        break;
      default: break;
    }
  } else {
    partition = ptree->partition;
    const PARTITION_TREE *parent = ptree->parent;
    if (!is_sb_root && parent) {
      if (!frame_is_intra_only(cm) && !cm->seq_params.monochrome &&
          ptree->partition && parent->region_type != INTRA_REGION &&
          ptree->region_type == INTRA_REGION) {
        xd->tree_type = LUMA_PART;
      }
    }
  }

  const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
  if (subsize == BLOCK_INVALID) {
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
                       "Partition %d is invalid for block size %dx%d",
                       partition, block_size_wide[bsize],
                       block_size_high[bsize]);
    assert(0);
  }
  // Check the bitstream is conformant: if there is subsampling on the
  // chroma planes, subsize must subsample to a valid block size.
  const struct macroblockd_plane *const pd_u = &xd->plane[1];
  BLOCK_SIZE test_subsize = subsize;
  if (xd->tree_type == SHARED_PART) {
    const PARTITION_TREE *parent = ptree;
    CHROMA_REF_INFO chroma_ref_info;
    const int index =
        (partition == PARTITION_HORZ || partition == PARTITION_VERT) ? 1 : 0;
    set_chroma_ref_info(xd->tree_type, mi_row, mi_col, index, subsize,
                        &chroma_ref_info,
                        parent ? &parent->chroma_ref_info : NULL,
                        parent ? parent->bsize : BLOCK_INVALID,
                        parent ? parent->partition : PARTITION_NONE,
                        xd->plane[1].subsampling_x, xd->plane[1].subsampling_y);
    test_subsize = chroma_ref_info.bsize_base;
    assert(test_subsize != BLOCK_INVALID);
  }
  if (xd->tree_type != LUMA_PART &&
      get_plane_block_size(test_subsize, pd_u->subsampling_x,
                           pd_u->subsampling_y) == BLOCK_INVALID) {
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
                       "Block size %dx%d invalid with this subsampling mode",
                       block_size_wide[test_subsize],
                       block_size_high[test_subsize]);
  }
  // Check that chroma ref block isn't completely outside the boundary.
  if (!is_chroma_ref_within_boundary(
          cm, xd->tree_type, ptree->chroma_ref_info.is_chroma_ref, mi_row,
          mi_col, bsize, partition, pd_u->subsampling_x, pd_u->subsampling_y)) {
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid partitioning %d at location [%d, %d]: chroma "
                       "info not coded.",
                       partition, mi_row << MI_SIZE_LOG2,
                       mi_col << MI_SIZE_LOG2);
  }

#define DEC_BLOCK_STX_ARG
#define DEC_BLOCK_EPT_ARG partition,
#define DEC_BLOCK(db_r, db_c, db_subsize, index)                               \
  block_visit[parse_decode_flag](pbi, td, DEC_BLOCK_STX_ARG(db_r), (db_c),     \
                                 reader, DEC_BLOCK_EPT_ARG(db_subsize), ptree, \
                                 index)
#define DEC_PARTITION(db_r, db_c, db_subsize, index)                 \
  decode_partition(pbi, td, DEC_BLOCK_STX_ARG(db_r), (db_c), reader, \
                   (db_subsize), sbi, ptree->sub_tree[(index)],      \
                   get_partition_subtree_const(ptree_luma, index),   \
                   parse_decode_flag)

  switch (partition) {
    case PARTITION_NONE: DEC_BLOCK(mi_row, mi_col, subsize, 0); break;
    case PARTITION_HORZ:
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
      DEC_PARTITION(mi_row + hbs_h, mi_col, subsize, 1);
      break;
    case PARTITION_VERT:
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
      DEC_PARTITION(mi_row, mi_col + hbs_w, subsize, 1);
      break;
    case PARTITION_HORZ_4A: {
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_HORZ);
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big];
      assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]);
      int this_mi_row = mi_row;
      DEC_PARTITION(this_mi_row, mi_col, subsize, 0);
      this_mi_row += ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, bsize_med, 1);
      this_mi_row += 2 * ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, bsize_big, 2);
      this_mi_row += 4 * ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, subsize, 3);
      break;
    }
    case PARTITION_HORZ_4B: {
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_HORZ);
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big];
      assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]);
      int this_mi_row = mi_row;
      DEC_PARTITION(this_mi_row, mi_col, subsize, 0);
      this_mi_row += ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, bsize_big, 1);
      this_mi_row += 4 * ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, bsize_med, 2);
      this_mi_row += 2 * ebs_h;
      DEC_PARTITION(this_mi_row, mi_col, subsize, 3);
      break;
    }
    case PARTITION_VERT_4A: {
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_VERT);
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big];
      assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]);
      int this_mi_col = mi_col;
      DEC_PARTITION(mi_row, this_mi_col, subsize, 0);
      this_mi_col += ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, bsize_med, 1);
      this_mi_col += 2 * ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, bsize_big, 2);
      this_mi_col += 4 * ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, subsize, 3);
      break;
    }
    case PARTITION_VERT_4B: {
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_VERT);
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big];
      assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]);
      int this_mi_col = mi_col;
      DEC_PARTITION(mi_row, this_mi_col, subsize, 0);
      this_mi_col += ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, bsize_big, 1);
      this_mi_col += 4 * ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, bsize_med, 2);
      this_mi_col += 2 * ebs_w;
      DEC_PARTITION(mi_row, this_mi_col, subsize, 3);
      break;
    }
    case PARTITION_HORZ_3:
    case PARTITION_VERT_3: {
      for (int i = 0; i < 4; ++i) {
        BLOCK_SIZE this_bsize = get_h_partition_subsize(bsize, i, partition);
        const int offset_r = get_h_partition_offset_mi_row(bsize, i, partition);
        const int offset_c = get_h_partition_offset_mi_col(bsize, i, partition);

        assert(this_bsize != BLOCK_INVALID);
        assert(offset_r >= 0 && offset_c >= 0);

        const int this_mi_row = mi_row + offset_r;
        const int this_mi_col = mi_col + offset_c;

        DEC_PARTITION(this_mi_row, this_mi_col, this_bsize, i);
      }
      break;
    }
    case PARTITION_SPLIT:
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
      DEC_PARTITION(mi_row, mi_col + hbs_w, subsize, 1);
      DEC_PARTITION(mi_row + hbs_h, mi_col, subsize, 2);
      DEC_PARTITION(mi_row + hbs_h, mi_col + hbs_w, subsize, 3);
      break;
    default: assert(0 && "Invalid partition type");
  }

  PARTITION_TREE *parent = ptree->parent;
  if (!is_sb_root && parent) {
    if (!frame_is_intra_only(cm) && !cm->seq_params.monochrome &&
        ptree->partition && parent->region_type != INTRA_REGION &&
        ptree->region_type == INTRA_REGION) {
      // decode chroma part in one intra region
      xd->tree_type = CHROMA_PART;
      DEC_BLOCK(mi_row, mi_col, bsize, 0);
      // reset back to shared part
      xd->tree_type = SHARED_PART;
    }
  }

#undef DEC_PARTITION
#undef DEC_BLOCK
#undef DEC_BLOCK_EPT_ARG
#undef DEC_BLOCK_STX_ARG

  if (parse_decode_flag & 1) {
    update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
    if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
      xd->tree_type = CHROMA_PART;
      update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
                                   partition);
      xd->tree_type = SHARED_PART;
    }
  }
}

static AVM_INLINE void setup_bool_decoder(
    const uint8_t *data, const uint8_t *data_end, const size_t read_size,
    struct avm_internal_error_info *error_info, avm_reader *r,
    uint8_t allow_update_cdf) {
  // Validate the calculated partition length. If the buffer
  // described by the partition can't be fully read, then restrict
  // it to the portion that can be (for EC mode) or throw an error.
  if (!read_is_valid(data, read_size, data_end))
    avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
                       "Truncated packet or corrupt tile length");

  if (avm_reader_init(r, data, read_size))
    avm_internal_error(error_info, AVM_CODEC_MEM_ERROR,
                       "Failed to allocate bool decoder %d", 1);

  r->allow_update_cdf = allow_update_cdf;
}

static AVM_INLINE void decode_partition_sb(AV2Decoder *const pbi,
                                           ThreadData *const td, int mi_row,
                                           int mi_col, avm_reader *reader,
                                           BLOCK_SIZE bsize,
                                           int parse_decode_flag) {
  assert(bsize < BLOCK_SIZES_ALL);
  AV2_COMMON *const cm = &pbi->common;
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;
  xd->tree_type = SHARED_PART;
  const int is_intra_sdp_enabled = is_sdp_enabled_in_keyframe(cm);

  if (parse_decode_flag & 1) {
    av2_reset_ptree_in_sbi(xd->sbi, xd->tree_type);
    if (is_intra_sdp_enabled) av2_reset_ptree_in_sbi(xd->sbi, CHROMA_PART);
  }
  decode_partition(
      pbi, td, mi_row, mi_col, reader, bsize, xd->sbi,
      td->dcb.xd.sbi->ptree_root[av2_get_sdp_idx(xd->tree_type)],
      (is_intra_sdp_enabled ? td->dcb.xd.sbi->ptree_root[1] : NULL),
      parse_decode_flag);

  if ((cm->bru.enabled && cm->current_frame.frame_type != KEY_FRAME) ||
      cm->bridge_frame_info.is_bridge_frame) {
    if (pbi->bru_opt_mode && !cm->bridge_frame_info.is_bridge_frame) {
      if (bru_is_sb_available(cm, mi_col, mi_row)) {
#ifndef NDEBUG
        RefCntBuffer *ref_buf = get_ref_frame_buf(cm, cm->bru.update_ref_idx);
        assert(ref_buf != NULL);
#endif
        // for active sb, update to bru ref
        // for support sb, prepare copy to cur_frame (prepare for intra)
        if (bru_is_sb_active(cm, mi_col, mi_row))
          bru_update_sb(cm, mi_col, mi_row);
        else
          bru_copy_sb(cm, mi_col, mi_row);
      }
    } else {
      if (!bru_is_sb_active(cm, mi_col, mi_row) ||
          cm->bridge_frame_info.is_bridge_frame) {
        if (cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
          const int sb_size = cm->seq_params.sb_size;
          // set cur_frame mvs to 0
          const int w = mi_size_wide[sb_size];
          const int h = mi_size_high[sb_size];
          const int x_inside_boundary =
              AVMMIN(w, cm->mi_params.mi_cols - mi_col) << MI_SIZE_LOG2;
          const int y_inside_boundary =
              AVMMIN(h, cm->mi_params.mi_rows - mi_row) << MI_SIZE_LOG2;
          bru_zero_sb_mvs(cm, -1, mi_row, mi_col,
                          x_inside_boundary >> MI_SIZE_LOG2,
                          y_inside_boundary >> MI_SIZE_LOG2);
        }
      }
    }
  }
#if CONFIG_INSPECTION
  if (pbi->inspect_sb_cb != NULL) {
    (*pbi->inspect_sb_cb)(pbi, pbi->inspect_ctx);
  }
#endif  // CONFIG_INSPECTION
}
static AVM_INLINE void setup_bru_active_info(AV2_COMMON *const cm,
                                             struct avm_read_bit_buffer *rb) {
  init_bru_params(cm);
  if (cm->current_frame.frame_type != INTER_FRAME) {
    return;
  }
  if (cm->bridge_frame_info.is_bridge_frame) {
    return;
  }
  // need to refresh bru.active_mode_map every frame
  memset(cm->bru.active_mode_map, 2, sizeof(uint8_t) * cm->bru.total_units);
  if (cm->seq_params.enable_bru) {
    cm->bru.enabled = avm_rb_read_bit(rb);
    if (cm->bru.enabled) {
      memset(cm->bru.active_mode_map, 0, sizeof(uint8_t) * cm->bru.total_units);
      cm->bru.update_ref_idx = avm_rb_read_literal(
          rb, avm_ceil_log2(cm->ref_frames_info.num_total_refs));
      cm->bru.frame_inactive_flag = avm_rb_read_bit(rb);
      if (cm->bru.frame_inactive_flag) {
        cm->features.disable_cdf_update = 1;
      }
      if (!cm->immediate_output_picture) {
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                           "Invalid immediate_output_picture: BRU frame must "
                           "be immediate_output_picture");
      }
    }
  }
}

static void read_seg_syntax_info_to_segmentation(
    struct segmentation *seg, struct avm_read_bit_buffer *rb) {
  const int max_seg_num = seg->enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
  av2_clearall_segfeatures(seg);

  for (int i = 0; i < max_seg_num; i++) {
    for (int j = 0; j < SEG_LVL_MAX; j++) {
      int data = 0;
      const int feature_enabled = avm_rb_read_bit(rb);
      if (feature_enabled) {
        av2_enable_segfeature(seg, i, j);
        const int data_max = av2_seg_feature_data_max(j);
        const int data_min = -data_max;
        const int ubits = get_unsigned_bits(data_max);

        if (av2_is_segfeature_signed(j)) {
          data = avm_rb_read_inv_signed_literal(rb, ubits);
        } else {
          data = avm_rb_read_literal(rb, ubits);
        }
        data = clamp(data, data_min, data_max);
      }
      av2_set_segdata(seg, i, j, data);
    }
  }

  av2_calculate_segdata(seg);
}

static AVM_INLINE void setup_segmentation(AV2_COMMON *const cm,
                                          struct avm_read_bit_buffer *rb) {
  struct segmentation *const seg = &cm->seg;

  seg->update_map = 0;
  seg->update_data = 0;
  seg->temporal_update = 0;
  seg->enable_ext_seg = cm->seq_params.enable_ext_seg;

  seg->enabled = avm_rb_read_bit(rb);
  if (!seg->enabled) {
    if (cm->cur_frame->seg_map) {
      memset(cm->cur_frame->seg_map, 0,
             (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
    }

    memset(seg, 0, sizeof(*seg));
    seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
    segfeatures_copy(&cm->cur_frame->seg, seg);
    return;
  }

  if (cm->seg.enabled && cm->prev_frame &&
      (cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
      (cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
    cm->last_frame_seg_map = cm->prev_frame->seg_map;
  } else {
    cm->last_frame_seg_map = NULL;
  }

  const SegmentationInfoSyntax *const seg_params =
      find_effective_seg_params(cm);
  int reuse = 0;
  if (seg_params && is_frame_seg_config_reuse_eligible(seg_params, seg)) {
    if (seg_params->allow_seg_info_change) {
      reuse = avm_rb_read_bit(rb);
    } else {
      reuse = 1;
    }
  }

  if (reuse) {
    av2_reconstruct_seg_params(seg_params, seg);
  } else {
    read_seg_syntax_info_to_segmentation(seg, rb);
  }

  if (cm->features.derived_primary_ref_frame == PRIMARY_REF_NONE) {
    // These frames can't use previous frames, so must signal map + features
    seg->update_map = 1;
    seg->temporal_update = 0;
    seg->update_data = 1;
    seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
  } else {
    seg->update_map = avm_rb_read_bit(rb);
    if (seg->update_map) {
      if (cm->current_frame.frame_type == S_FRAME)
        seg->temporal_update = 0;
      else
        seg->temporal_update = avm_rb_read_bit(rb);
    } else {
      seg->temporal_update = 0;
    }
    seg->update_data = reuse ? 0 : 1;
  }
}

// Same function as av2_read_uniform but reading from uncompressed header rb
static int rb_read_uniform(struct avm_read_bit_buffer *const rb, int n) {
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
  const int v = avm_rb_read_literal(rb, l - 1);
  assert(l != 0);
  if (v < m)
    return v;
  else
    return (v << 1) - m + avm_rb_read_bit(rb);
}

// Converts decoded index to frame restoration type depending on lr tools
// that are enabled for the frame for a given plane.
static RestorationType index_to_frame_restoration_type(
    const AV2_COMMON *const cm, int plane, int ndx) {
  RestorationType r = RESTORE_NONE;
  for (r = RESTORE_NONE; r < RESTORE_TYPES; ++r) {
    if (((cm->features.lr_tools_disable_mask[plane] >> r) & 1) == 0) {
      ndx--;
      if (ndx < 0) break;
    }
  }
  assert(r < RESTORE_TYPES);
  return r;
}

static AVM_INLINE void decode_restoration_mode(AV2_COMMON *cm,
                                               struct avm_read_bit_buffer *rb) {
  assert(!cm->features.all_lossless);
  const int num_planes = av2_num_planes(cm);
  int luma_none = 1, chroma_none = 1;
  for (int p = 0; p < num_planes; ++p) {
    RestorationInfo *rsi = &cm->rst_info[p];
    rsi->frame_filters_on = 0;
    cm->cur_frame->rst_info[p].frame_filters_on = 0;
    rsi->temporal_pred_flag = 0;
    cm->cur_frame->rst_info[p].temporal_pred_flag = 0;
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
        cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
      rsi->frame_restoration_type = RESTORE_NONE;
      continue;
    }
    uint8_t plane_lr_tools_disable_mask =
        cm->seq_params.lr_tools_disable_mask[p > 0];
    av2_set_lr_tools(plane_lr_tools_disable_mask, p, &cm->features);
    const int ndx = rb_read_uniform(rb, cm->features.lr_frame_tools_count[p]);
    rsi->frame_restoration_type = index_to_frame_restoration_type(cm, p, ndx);
    if (rsi->frame_restoration_type != RESTORE_NONE) {
      luma_none &= p > 0;
      chroma_none &= p == 0;
    }
    const int is_wiener_nonsep_possible =
        rsi->frame_restoration_type == RESTORE_WIENER_NONSEP ||
        rsi->frame_restoration_type == RESTORE_SWITCHABLE;
    if (is_wiener_nonsep_possible) {
      rsi->frame_filters_initialized = 0;
      if (is_frame_filters_enabled(p)) {
        rsi->frame_filters_on = avm_rb_read_bit(rb);
        rsi->rst_ref_pic_idx = 0;
        rsi->temporal_pred_flag = 0;
        if (rsi->frame_filters_on) {
          const int num_ref_frames =
              (frame_is_intra_only(cm) || frame_is_sframe(cm))
                  ? 0
                  : cm->ref_frames_info.num_total_refs;

          if (num_ref_frames > 0) rsi->temporal_pred_flag = avm_rb_read_bit(rb);
          int num_ref_frames_available = 0;
          for (int i = 0; i < num_ref_frames; i++) {
            if (cm->ref_frame_map[cm->remapped_ref_idx[i]] != NULL)
              num_ref_frames_available +=
                  !cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted;
          }
          if (num_ref_frames_available == 0)
            assert(rsi->temporal_pred_flag == 0);
          if (rsi->temporal_pred_flag && num_ref_frames > 1) {
            rsi->rst_ref_pic_idx = avm_rb_read_literal(
                rb,
                avm_ceil_log2(num_ref_frames));  // read_lr_reference_idx
            if (get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)->is_restricted) {
              avm_internal_error(
                  &cm->error, AVM_CODEC_ERROR,
                  "Invalid rst_ref_pic_idx: restricted reference buffer");
            }
          }
        }

        if (rsi->temporal_pred_flag) {
          RestorationInfo tmp_rsi =
              get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)->rst_info[p];
          if (!tmp_rsi.frame_filters_on) {
            const int alternate_plane = alternate_ref_plane(p);
            assert(alternate_plane != -1);
            tmp_rsi = get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)
                          ->rst_info[alternate_plane];
          }
          if (!tmp_rsi.frame_filters_on) {
            avm_internal_error(
                &cm->error, AVM_CODEC_ERROR,
                "Invalid rst_ref_pic_idx: ref frame frame filter disabled");
          }
          av2_copy_rst_frame_filters(rsi, &tmp_rsi);
          rsi->frame_filters_initialized = 1;

          av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[p], rsi);
        } else {
          if (rsi->frame_filters_on && max_num_classes(p) > 1) {
            rsi->num_filter_classes = decode_num_filter_classes(
                avm_rb_read_literal(rb, NUM_FILTER_CLASSES_BITS));
          } else
            rsi->num_filter_classes = 1;
        }
      } else {
        rsi->frame_filters_on = 0;
        rsi->num_filter_classes = NUM_WIENERNS_CLASS_INIT_CHROMA;
      }
    }
    assert(IMPLIES(!rsi->frame_filters_on, !rsi->temporal_pred_flag));
  }
  int subsampling_xy =
      AVMMAX(cm->seq_params.subsampling_x, cm->seq_params.subsampling_y);

  cm->rst_info[0].restoration_unit_size = RESTORATION_UNITSIZE_MAX >> 3;
  cm->rst_info[1].restoration_unit_size =
      RESTORATION_UNITSIZE_MAX >> (3 + subsampling_xy);
  cm->rst_info[2].restoration_unit_size = cm->rst_info[1].restoration_unit_size;

  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
    if (num_planes > 1) {
      cm->rst_info[1].restoration_unit_size =
          RESTORATION_UNITSIZE_MAX >> (3 + subsampling_xy);
      cm->rst_info[2].restoration_unit_size =
          cm->rst_info[1].restoration_unit_size;
    }
    return;
  }

  if (!luma_none) {
    int size = RESTORATION_UNITSIZE_MAX;
    if (avm_rb_read_bit(rb))
      cm->rst_info[0].restoration_unit_size = size >> 1;
    else {
      if (cm->mib_size == 64) {  // sb_szie == 256
        cm->rst_info[0].restoration_unit_size = size;
      } else {
        if (avm_rb_read_bit(rb))
          cm->rst_info[0].restoration_unit_size = size;
        else {
          if (cm->mib_size == 32) {  // sb_szie == 128
            cm->rst_info[0].restoration_unit_size = size >> 2;
          } else {
            if (avm_rb_read_bit(rb))
              cm->rst_info[0].restoration_unit_size = size >> 2;
            else
              cm->rst_info[0].restoration_unit_size = size >> 3;
          }
        }
      }
    }
  }
  if (num_planes > 1) {
    if (!chroma_none) {
      int size = RESTORATION_UNITSIZE_MAX >> subsampling_xy;
      if (avm_rb_read_bit(rb))
        cm->rst_info[1].restoration_unit_size = size >> 1;
      else {
        if (cm->mib_size == 64) {  // sb_szie == 256
          cm->rst_info[1].restoration_unit_size = size;
        } else {
          if (avm_rb_read_bit(rb))
            cm->rst_info[1].restoration_unit_size = size;
          else {
            if (cm->mib_size == 32) {  // sb_szie == 128
              cm->rst_info[1].restoration_unit_size = size >> 2;
            } else {
              if (avm_rb_read_bit(rb))
                cm->rst_info[1].restoration_unit_size = size >> 2;
              else
                cm->rst_info[1].restoration_unit_size = size >> 3;
            }
          }
        }
      }
      // ru_size can be not smaller than stripe size, this error could only be
      // triggered for 422 coding.
      if (cm->rst_info[1].restoration_unit_size <
          (64 >> cm->seq_params.subsampling_y)) {
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                           "Invalid RU size, RU size shall not be smaller than "
                           "stripe height which is 64 for 422 format");
        return;
      }
    }
    cm->rst_info[2].restoration_unit_size =
        cm->rst_info[1].restoration_unit_size;
  }

  // add the normative restriction of ru size so that a RU shall not cross any
  // tile boundaries
  int max_plane_ru_size =
      AVMMAX(cm->rst_info[0].restoration_unit_size,
             cm->rst_info[1].restoration_unit_size << subsampling_xy);
  for (int tile_col = 0; tile_col < cm->tiles.cols - 1; tile_col++) {
    int tile_w = (cm->tiles.col_start_sb[tile_col + 1] -
                  cm->tiles.col_start_sb[tile_col])
                 << (cm->mib_size_log2 + MI_SIZE_LOG2);
    if (tile_w % max_plane_ru_size) {
      avm_internal_error(
          &cm->error, AVM_CODEC_ERROR,
          "Invalid RU size, RU size shall be an integer divisor of tiles "
          "width or height, except right-most and bottom tiles");
      return;
    }
  }

  for (int tile_row = 0; tile_row < cm->tiles.rows - 1; tile_row++) {
    int tile_h = (cm->tiles.row_start_sb[tile_row + 1] -
                  cm->tiles.row_start_sb[tile_row])
                 << (cm->mib_size_log2 + MI_SIZE_LOG2);
    if (tile_h % max_plane_ru_size) {
      avm_internal_error(
          &cm->error, AVM_CODEC_ERROR,
          "Invalid RU size, RU size shall be an integer divisor of tiles "
          "width or height, except right-most and bottom tiles");
      return;
    }
  }

  for (int p = 0; p < num_planes; ++p) {
    if (is_frame_filters_enabled(p) &&
        to_readwrite_framefilters(&cm->rst_info[p], 0, 0)) {
      read_wienerns_framefilters_hdr(cm, p, rb);
    }
  }
}

// Decodes match indices.
static void read_match_indices_hdr(int plane, WienerNonsepInfo *wienerns_info,
                                   struct avm_read_bit_buffer *rb, int nopcw) {
  assert(NUM_MATCH_GROUPS == 3);
  int group_counts[NUM_MATCH_GROUPS];
  set_group_counts(plane, wienerns_info->num_classes,
                   wienerns_info->num_ref_filters, group_counts, nopcw);
  for (int c_id = 0; c_id < wienerns_info->num_classes; ++c_id) {
    // Read group-id.
    int only;
    const int pred_group =
        predict_group(c_id, wienerns_info->match_indices, group_counts, &only);
    int group = 0;
    int group_bit = only ? 0 : avm_rb_read_bit(rb);
    if (group_bit == 0) {
      // group-id matches prediction.
      group = pred_group;
    } else {
      int zero_group = -1;
      for (int i = 0; i < NUM_MATCH_GROUPS; ++i) {
        if (i == pred_group) continue;
        if (group_counts[i] == 0) {
          // There is a group-id with zero count.
          zero_group = i;
          break;
        }
      }
      if (zero_group != -1) {
        // group-id is the remaining non-zero group.
        group = 3 - (pred_group + zero_group);
      } else {
        const int convert_larger[] = { 2, 2, 1 };
        const int convert_smaller[] = { 1, 0, 0 };
        group_bit = avm_rb_read_bit(rb);
        // Infer group-id around pred_group.
        if (group_bit) {
          group = convert_larger[pred_group];
        } else {
          group = convert_smaller[pred_group];
        }
      }
    }
    // Decode match index with known group-id.
    const int ref = predict_within_group(
        group, c_id, wienerns_info->match_indices, group_counts);
    const int base = get_group_base(group, group_counts);
    const int n = group == 0 ? c_id + 1 : group_counts[group];
    int decoded_match = base;
    if (n > 1) {
      decoded_match +=
          (int)avm_rb_read_primitive_refsubexpfin(rb, n, 4, ref - base);
    }

    wienerns_info->match_indices[c_id] = decoded_match;
  }
}

// Read frame level wiener filters from the uncompressed frame header
static void read_wienerns_framefilters_hdr(AV2_COMMON *cm, int plane,
                                           struct avm_read_bit_buffer *rb) {
  const int base_qindex = cm->quant_params.base_qindex;
  const int is_uv = plane != AVM_PLANE_Y;
  const int nopcw = disable_pcwiener_filters_in_framefilters(&cm->seq_params);
  RestorationInfo *rsi = &cm->rst_info[plane];
  assert(is_frame_filters_enabled(plane));
  assert(rsi->frame_filters_on && !rsi->frame_filters_initialized);
  if (cm->frame_filter_dictionary == NULL) {
    allocate_frame_filter_dictionary(cm);
    translate_pcwiener_filters_to_wienerns(cm);
  }
  *cm->num_ref_filters = set_frame_filter_dictionary(
      plane, cm, rsi->num_filter_classes, cm->frame_filter_dictionary,
      cm->frame_filter_dictionary_stride);
  int16_t *frame_filter_dictionary = cm->frame_filter_dictionary;
  const int dict_stride = cm->frame_filter_dictionary_stride;
  assert(frame_filter_dictionary != NULL);
  assert(dict_stride > 0);

  int skip_filter_read_for_class[WIENERNS_MAX_CLASSES] = { 0 };
  const int num_classes = rsi->num_filter_classes;
  rsi->frame_filters.num_classes = num_classes;
  rsi->frame_filters.num_ref_filters = *cm->num_ref_filters;
  assert(num_classes <= WIENERNS_MAX_CLASSES);
  assert(!rsi->temporal_pred_flag);

  read_match_indices_hdr(plane, &rsi->frame_filters, rb, nopcw);

  for (int c_id = 0; c_id < num_classes; ++c_id) {
    const int exact_match = avm_rb_read_bit(rb);
    skip_filter_read_for_class[c_id] = exact_match;
  }
  const WienernsFilterParameters *nsfilter_params =
      get_wienerns_parameters(base_qindex, is_uv);
  const int(*wienerns_coeffs)[WIENERNS_COEFCFG_LEN] = nsfilter_params->coeffs;
  WienerNonsepInfoBank bank = { 0 };
  bank.filter[0].num_classes = num_classes;
  for (int c_id = 0; c_id < num_classes; ++c_id) {
    fill_first_slot_of_bank_with_filter_match(
        plane, &bank, &rsi->frame_filters, rsi->frame_filters.match_indices,
        base_qindex, c_id, frame_filter_dictionary, dict_stride, nopcw);
    if (skip_filter_read_for_class[c_id]) {
      copy_nsfilter_taps_for_class(
          &rsi->frame_filters, av2_constref_from_wienerns_bank(&bank, 0, c_id),
          c_id);
      continue;
    }
    const WienerNonsepInfo *ref_wienerns_info =
        av2_constref_from_wienerns_bank(&bank, 0, c_id);
    assert(ref_wienerns_info->num_classes == num_classes);
    int16_t *wienerns_info_nsfilter = nsfilter_taps(&rsi->frame_filters, c_id);
    const int16_t *ref_wienerns_info_nsfilter =
        const_nsfilter_taps(ref_wienerns_info, c_id);

    memset(wienerns_info_nsfilter, 0,
           nsfilter_params->ncoeffs * sizeof(wienerns_info_nsfilter[0]));

    const int beg_feat = 0;
    int end_feat = nsfilter_params->ncoeffs;
    int ncoeffs1, ncoeffs2;
    int ncoeffs =
        config2ncoeffs(&nsfilter_params->nsfilter_config, &ncoeffs1, &ncoeffs2);
    assert(nsfilter_params->ncoeffs == ncoeffs);
    (void)ncoeffs;
    int s = 0;
    for (int i = 0; i < nsfilter_params->nsubsets - 1; ++i) {
      const int filter_length_bit = avm_rb_read_bit(rb);
      s += filter_length_bit;
      if (!filter_length_bit) break;
    }
    assert((end_feat & 1) == 0);

    int sym = 1;
    if (!skip_sym_bit(nsfilter_params, s)) {
      assert(is_uv);
      sym = avm_rb_read_bit(rb);
    }

    for (int i = beg_feat; i < end_feat; ++i) {
      if (!nsfilter_params->subset_config[s][i]) continue;
      wienerns_info_nsfilter[i] =
          avm_rb_read_primitive_refsubexpfin(
              rb, 1 << wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID],
              wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID] - 3,
              ref_wienerns_info_nsfilter[i] -
                  wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID]) +
          wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID];
      const int is_asym_coeff =
          (i < nsfilter_params->nsfilter_config.asymmetric ||
           (i >= ncoeffs1 &&
            i - ncoeffs1 < nsfilter_params->nsfilter_config.asymmetric2));
      if (sym && is_asym_coeff) {
        // Fill in symmetrical tap without reading it
        wienerns_info_nsfilter[i + 1] = wienerns_info_nsfilter[i];
        i++;
      }
    }
  }
  rsi->frame_filters_initialized = 1;
  av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[plane], rsi);
}

static void read_wienerns_filter(MACROBLOCKD *xd, int is_uv,
                                 const RestorationInfo *rsi,
                                 WienerNonsepInfo *wienerns_info,
                                 WienerNonsepInfoBank *bank, avm_reader *rb) {
  int skip_filter_read_for_class[WIENERNS_MAX_CLASSES] = { 0 };
  int ref_for_class[WIENERNS_MAX_CLASSES] = { 0 };
  const int num_classes = wienerns_info->num_classes;
  assert(num_classes <= WIENERNS_MAX_CLASSES);
  if (rsi->frame_filters_on) return;
  for (int c_id = 0; c_id < num_classes; ++c_id) {
    const int exact_match = avm_read_bit(rb, ACCT_INFO("exact_match"));
    int ref;
    for (ref = 0; ref < bank->bank_size_for_class[c_id] - 1; ++ref) {
      if (avm_read_literal(rb, 1, ACCT_INFO("bank"))) break;
    }
    wienerns_info->bank_ref_for_class[c_id] = ref;
    skip_filter_read_for_class[c_id] = exact_match;
    ref_for_class[c_id] = ref;
  }
  const WienernsFilterParameters *nsfilter_params =
      get_wienerns_parameters(xd->current_base_qindex, is_uv);
  const int(*wienerns_coeffs)[WIENERNS_COEFCFG_LEN] = nsfilter_params->coeffs;
  for (int c_id = 0; c_id < num_classes; ++c_id) {
    if (skip_filter_read_for_class[c_id]) {
      copy_nsfilter_taps_for_class(
          wienerns_info,
          av2_constref_from_wienerns_bank(bank, ref_for_class[c_id], c_id),
          c_id);
      if (bank->bank_size_for_class[c_id] == 0)
        av2_add_to_wienerns_bank(bank, wienerns_info, c_id);
      continue;
    }
    const int ref = ref_for_class[c_id];

    const WienerNonsepInfo *ref_wienerns_info =
        av2_constref_from_wienerns_bank(bank, ref, c_id);
    assert(ref_wienerns_info->num_classes == num_classes);
    int16_t *wienerns_info_nsfilter = nsfilter_taps(wienerns_info, c_id);
    const int16_t *ref_wienerns_info_nsfilter =
        const_nsfilter_taps(ref_wienerns_info, c_id);

    memset(wienerns_info_nsfilter, 0,
           nsfilter_params->ncoeffs * sizeof(wienerns_info_nsfilter[0]));

    const int beg_feat = 0;
    int end_feat = nsfilter_params->ncoeffs;
    int ncoeffs1, ncoeffs2;
    int ncoeffs =
        config2ncoeffs(&nsfilter_params->nsfilter_config, &ncoeffs1, &ncoeffs2);
    assert(nsfilter_params->ncoeffs == ncoeffs);
    (void)ncoeffs;
    int s = 0;
    for (int i = 0; i < nsfilter_params->nsubsets - 1; ++i) {
      const int filter_length_bit =
          avm_read_symbol(rb, xd->tile_ctx->wienerns_length_cdf[is_uv], 2,
                          ACCT_INFO("wienerns_length"));
      s += filter_length_bit;
      if (!filter_length_bit) break;
    }
    assert((end_feat & 1) == 0);

    int sym = 1;
    if (!skip_sym_bit(nsfilter_params, s)) {
      assert(is_uv);
      sym = avm_read_symbol(rb, xd->tile_ctx->wienerns_uv_sym_cdf, 2,
                            ACCT_INFO("wienerns_uv_sym"));
    }

    for (int i = beg_feat; i < end_feat; ++i) {
      if (!nsfilter_params->subset_config[s][i]) continue;
      wienerns_info_nsfilter[i] =
          avm_read_4part_wref(
              rb,
              ref_wienerns_info_nsfilter[i] -
                  wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID],
              xd->tile_ctx->wienerns_4part_cdf
                  [wienerns_coeffs[i - beg_feat][WIENERNS_PAR_ID]],
              wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID],
              ACCT_INFO("wienerns_info_nsfilter")) +
          wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID];
      const int is_asym_coeff =
          (i < nsfilter_params->nsfilter_config.asymmetric ||
           (i >= ncoeffs1 &&
            i - ncoeffs1 < nsfilter_params->nsfilter_config.asymmetric2));
      if (sym && is_asym_coeff) {
        // Fill in symmetrical tap without reading it
        wienerns_info_nsfilter[i + 1] = wienerns_info_nsfilter[i];
        i++;
      }
    }
    av2_add_to_wienerns_bank(bank, wienerns_info, c_id);
  }
}

static AVM_INLINE void loop_restoration_read_sb_coeffs(AV2_COMMON *cm,
                                                       MACROBLOCKD *xd,
                                                       avm_reader *const r,
                                                       int plane,
                                                       int runit_idx) {
  RestorationInfo *rsi = &cm->rst_info[plane];
  RestorationUnitInfo *rui = &rsi->unit_info[runit_idx];
  assert(rsi->frame_restoration_type != RESTORE_NONE);

  assert(!cm->features.all_lossless);

  rui->wienerns_info.num_classes = rsi->num_filter_classes;

  if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
    assert(plane == AVM_PLANE_Y);
    rui->restoration_type = RESTORE_SWITCHABLE - 1;
    for (int re = 0; re <= RESTORE_SWITCHABLE - 2; re++) {
      if (cm->features.lr_tools_disable_mask[plane] & (1 << re)) continue;
      const int found = avm_read_symbol(
          r, xd->tile_ctx->switchable_flex_restore_cdf[re][plane], 2,
          ACCT_INFO("found"));
      if (found) {
        rui->restoration_type = re;
        break;
      }
    }
    switch (rui->restoration_type) {
      case RESTORE_WIENER_NONSEP:
        read_wienerns_filter(xd, plane != AVM_PLANE_Y, rsi, &rui->wienerns_info,
                             &xd->wienerns_info[plane], r);
        break;
      case RESTORE_PC_WIENER:
        // No side-information for now.
        break;
      default: assert(rui->restoration_type == RESTORE_NONE); break;
    }
  } else if (rsi->frame_restoration_type == RESTORE_WIENER_NONSEP) {
    if (avm_read_symbol(r, xd->tile_ctx->wienerns_restore_cdf, 2,
                        ACCT_INFO("wienerns_restore_cdf"))) {
      rui->restoration_type = RESTORE_WIENER_NONSEP;
      read_wienerns_filter(xd, plane != AVM_PLANE_Y, rsi, &rui->wienerns_info,
                           &xd->wienerns_info[plane], r);
    } else {
      rui->restoration_type = RESTORE_NONE;
    }
  } else if (rsi->frame_restoration_type == RESTORE_PC_WIENER) {
    if (avm_read_symbol(r, xd->tile_ctx->pc_wiener_restore_cdf, 2,
                        ACCT_INFO("pc_wiener_restore_cdf"))) {
      rui->restoration_type = RESTORE_PC_WIENER;
      // No side-information for now.
    } else {
      rui->restoration_type = RESTORE_NONE;
    }
  }

  assert(((cm->features.lr_tools_disable_mask[plane] >> rui->restoration_type) &
          1) == 0);
}

static AVM_INLINE void setup_loopfilter(AV2_COMMON *cm,
                                        struct avm_read_bit_buffer *rb) {
  CurrentFrame *const current_frame = &cm->current_frame;
  FeatureFlags *const features = &cm->features;
  const int num_planes = av2_num_planes(cm);
  struct loopfilter *lf = &cm->lf;
  if (cm->features.coded_lossless) {
    return;
  }
  assert(!cm->features.coded_lossless);
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
    return;
  if (current_frame->frame_type == INTER_FRAME) {
    if (cm->seq_params.enable_lf_sub_pu) {
      features->allow_lf_sub_pu = avm_rb_read_bit(rb);
    }
  }

  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    if (cm->seq_params.enable_lf_sub_pu && features->allow_lf_sub_pu) {
      cm->lf.apply_deblocking_filter_tip = avm_rb_read_bit(rb);
      if (cm->lf.apply_deblocking_filter_tip) {
        cm->lf.tip_delta = 0;
      }
    }
    return;
  }

  assert(cm->mfh_valid[cm->cur_mfh_id]);
  if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag)
    lf->apply_deblocking_filter[0] =
        cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[0];
  else
    lf->apply_deblocking_filter[0] = avm_rb_read_bit(rb);
  if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag)
    lf->apply_deblocking_filter[1] =
        cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[1];
  else
    lf->apply_deblocking_filter[1] = avm_rb_read_bit(rb);
  if (num_planes > 1) {
    if (lf->apply_deblocking_filter[0] || lf->apply_deblocking_filter[1]) {
      if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag) {
        lf->apply_deblocking_filter_u =
            cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[2];
        lf->apply_deblocking_filter_v =
            cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[3];
      } else {
        lf->apply_deblocking_filter_u = avm_rb_read_bit(rb);
        lf->apply_deblocking_filter_v = avm_rb_read_bit(rb);
      }
    } else {
      lf->apply_deblocking_filter_u = lf->apply_deblocking_filter_v = 0;
    }
  } else {
    lf->apply_deblocking_filter_u = lf->apply_deblocking_filter_v = 0;
  }

  const uint8_t df_par_bits = cm->seq_params.df_par_bits_minus2 + 2;
  const uint8_t df_par_offset = 1 << (df_par_bits - 1);

  if (lf->apply_deblocking_filter[0]) {
    int luma_delta_q = avm_rb_read_bit(rb);
    if (luma_delta_q) {
      lf->delta_q_luma[0] =
          avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
    } else {
      lf->delta_q_luma[0] = 0;
    }
    lf->delta_side_luma[0] = lf->delta_q_luma[0];
  } else {
    lf->delta_q_luma[0] = 0;
    lf->delta_side_luma[0] = 0;
  }
  if (lf->apply_deblocking_filter[1]) {
    int luma_delta_q = avm_rb_read_bit(rb);
    if (luma_delta_q) {
      lf->delta_q_luma[1] =
          avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
    } else {
      lf->delta_q_luma[1] = lf->delta_q_luma[0];
    }
    lf->delta_side_luma[1] = lf->delta_q_luma[1];
  } else {
    lf->delta_q_luma[1] = 0;
    lf->delta_side_luma[1] = 0;
  }

  if (lf->apply_deblocking_filter_u) {
    int u_delta_q = avm_rb_read_bit(rb);
    if (u_delta_q) {
      lf->delta_q_u = avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
    } else {
      lf->delta_q_u = 0;
    }
    lf->delta_side_u = lf->delta_q_u;
  } else {
    lf->delta_q_u = 0;
    lf->delta_side_u = 0;
  }
  if (lf->apply_deblocking_filter_v) {
    int v_delta_q = avm_rb_read_bit(rb);
    if (v_delta_q) {
      lf->delta_q_v = avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
    } else {
      lf->delta_q_v = 0;
    }
    lf->delta_side_v = lf->delta_q_v;
  } else {
    lf->delta_q_v = 0;
    lf->delta_side_v = 0;
  }
}

static AVM_INLINE void setup_gdf(AV2_COMMON *cm,
                                 struct avm_read_bit_buffer *rb) {
  cm->gdf_info.gdf_mode = 0;
  if (!is_allow_gdf(cm)) return;
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    return;
  }
  init_gdf(cm);
  if (cm->seq_params.single_picture_header_flag) {
    cm->gdf_info.gdf_mode = 1;
  } else {
    cm->gdf_info.gdf_mode = avm_rb_read_bit(rb);
  }
  if (cm->gdf_info.gdf_mode > 0) {
    alloc_gdf_buffers(&cm->gdf_info);
    if (cm->gdf_info.gdf_block_num > 1) {
      cm->gdf_info.gdf_mode += avm_rb_read_bit(rb);
    }
    cm->gdf_info.gdf_pic_qp_idx = avm_rb_read_literal(rb, GDF_RDO_QP_NUM_LOG2);
    cm->gdf_info.gdf_pic_scale_idx =
        avm_rb_read_literal(rb, GDF_RDO_SCALE_NUM_LOG2);
  }
}

static AVM_INLINE void setup_cdef(AV2_COMMON *cm,
                                  struct avm_read_bit_buffer *rb) {
  const int num_planes = av2_num_planes(cm);
  CdefInfo *const cdef_info = &cm->cdef_info;
  if (cm->bridge_frame_info.is_bridge_frame) {
    cdef_info->cdef_frame_enable = 0;
    return;
  }
  if (cm->bru.frame_inactive_flag ||
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT)
    return;
  if (cm->seq_params.single_picture_header_flag) {
    cdef_info->cdef_frame_enable = 1;
  } else {
    cdef_info->cdef_frame_enable = avm_rb_read_bit(rb);
  }
  if (!cdef_info->cdef_frame_enable) {
    cdef_info->cdef_on_skip_txfm_frame_enable = 0;
    return;
  }
  cdef_info->cdef_damping = avm_rb_read_literal(rb, 2) + 3;
  cdef_info->nb_cdef_strengths = avm_rb_read_literal(rb, 3) + 1;
  if (cm->seq_params.enable_cdef_on_skip_txfm == CDEF_ON_SKIP_TXFM_ADAPTIVE) {
    cdef_info->cdef_on_skip_txfm_frame_enable = avm_rb_read_bit(rb);
  } else if (cm->seq_params.enable_cdef_on_skip_txfm ==
             CDEF_ON_SKIP_TXFM_ALWAYS_ON) {
    cdef_info->cdef_on_skip_txfm_frame_enable = 1;
  } else {
    cdef_info->cdef_on_skip_txfm_frame_enable = 0;
  }
  for (int i = 0; i < cdef_info->nb_cdef_strengths; i++) {
    int less_4 = avm_rb_read_bit(rb);
    if (less_4) {
      cdef_info->cdef_strengths[i] = avm_rb_read_literal(rb, 2);
    } else {
      cdef_info->cdef_strengths[i] =
          avm_rb_read_literal(rb, CDEF_STRENGTH_BITS);
    }

    if (num_planes > 1) {
      less_4 = avm_rb_read_bit(rb);
      if (less_4) {
        cdef_info->cdef_uv_strengths[i] = avm_rb_read_literal(rb, 2);
      } else {
        cdef_info->cdef_uv_strengths[i] =
            avm_rb_read_literal(rb, CDEF_STRENGTH_BITS);
      }
    } else {
      cdef_info->cdef_uv_strengths[i] = 0;
    }
  }
}

// read offset idx using truncated unary coding
static AVM_INLINE int read_ccso_offset_idx(struct avm_read_bit_buffer *rb) {
  int offset_idx = 0;
  for (int idx = 0; idx < 7; ++idx) {
    const int cur_bit = avm_rb_read_bit(rb);
    if (!cur_bit) break;
    offset_idx++;
  }
  return offset_idx;
}
static AVM_INLINE void setup_ccso(AV2_COMMON *cm,
                                  struct avm_read_bit_buffer *rb) {
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    cm->cur_frame->ccso_info.ccso_enable[0] = 0;
    cm->cur_frame->ccso_info.ccso_enable[1] = 0;
    cm->cur_frame->ccso_info.ccso_enable[2] = 0;
    return;
  }
  const int ccso_offset[8] = { 0, 1, -1, 3, -3, 7, -7, -10 };
  const int ccso_scale[4] = { 1, 2, 3, 4 };
  const int num_ref_frames = (frame_is_intra_only(cm) || frame_is_sframe(cm))
                                 ? 0
                                 : cm->ref_frames_info.num_total_refs;
  int num_ref_frames_available = 0;
  for (int i = 0; i < num_ref_frames; i++) {
    if (cm->ref_frame_map[cm->remapped_ref_idx[i]] != NULL)
      num_ref_frames_available +=
          !cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted;
  }
  if (cm->bridge_frame_info.is_bridge_frame) {
    cm->ccso_info.ccso_frame_flag = 0;
  } else {
    if (cm->seq_params.single_picture_header_flag) {
      cm->ccso_info.ccso_frame_flag = 1;
    } else {
      cm->ccso_info.ccso_frame_flag = avm_rb_read_bit(rb);
    }
  }
  if (cm->ccso_info.ccso_frame_flag) {
    const int ccso_blk_size = get_ccso_unit_size_log2_adaptive_tile(
        cm, cm->mib_size_log2 + MI_SIZE_LOG2, CCSO_BLK_SIZE);
    cm->ccso_info.ccso_blk_size = ccso_blk_size;
    cm->cur_frame->ccso_info.ccso_blk_size = ccso_blk_size;
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
      CcsoInfo *ref_frame_ccso_info = NULL;
      cm->cur_frame->ccso_info.subsampling_y[plane] =
          plane ? cm->seq_params.subsampling_y : 0;
      cm->cur_frame->ccso_info.subsampling_x[plane] =
          plane ? cm->seq_params.subsampling_x : 0;
      cm->ccso_info.ccso_enable[plane] = avm_rb_read_bit(rb);
      if (cm->ccso_info.ccso_enable[plane]) {
        cm->cur_frame->ccso_info.ccso_enable[plane] = 1;
        if (!frame_is_intra_only(cm) && !frame_is_sframe(cm)) {
          cm->ccso_info.reuse_ccso[plane] = avm_rb_read_bit(rb);
          cm->ccso_info.sb_reuse_ccso[plane] = avm_rb_read_bit(rb);
        } else {
          cm->ccso_info.reuse_ccso[plane] = 0;
          cm->ccso_info.sb_reuse_ccso[plane] = 0;
        }
        if (num_ref_frames_available == 0)
          assert(cm->ccso_info.reuse_ccso[plane] == 0 &&
                 cm->ccso_info.sb_reuse_ccso[plane] == 0);
        if (cm->ccso_info.reuse_ccso[plane] ||
            cm->ccso_info.sb_reuse_ccso[plane]) {
          if (num_ref_frames > 1) {
            cm->ccso_info.ccso_ref_idx[plane] =
                avm_rb_read_literal(rb, avm_ceil_log2(num_ref_frames));
          } else {
            cm->ccso_info.ccso_ref_idx[plane] = 0;
          }
          if (cm->ccso_info.ccso_ref_idx[plane] >=
              cm->ref_frames_info.num_total_refs) {
            avm_internal_error(
                &cm->error, AVM_CODEC_ERROR,
                "Invalid ccso_ref_idx: ccso_ref_idx >= num_total_refs");
          }
          if (get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
                  ->is_restricted) {
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                               "Invalid ccso_ref_idx[%d] %d: restricted "
                               "refefence frame",
                               plane, cm->ccso_info.ccso_ref_idx[plane]);
          }
          ref_frame_ccso_info =
              &get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
                   ->ccso_info;
          if (!ref_frame_ccso_info->ccso_enable[plane]) {
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                               "Invalid ccso_ref_idx: ref frame ccso disabled");
          }
          if (cm->ccso_info.sb_reuse_ccso[plane] &&
              (cm->ccso_info.ccso_blk_size !=
                   ref_frame_ccso_info->ccso_blk_size ||
               cm->ccso_info.ccso_blk_size != CCSO_BLK_SIZE)) {
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                               "Invalid ccso_reuse: ccso_blk_size mismatch");
          }
        }

        if (cm->ccso_info.sb_reuse_ccso[plane] &&
            ((cm->mi_params.mi_rows !=
              get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
                  ->mi_rows) ||
             (cm->mi_params.mi_cols !=
              get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
                  ->mi_cols) ||
             (plane && ((cm->seq_params.subsampling_y !=
                         ref_frame_ccso_info->subsampling_y[plane]) ||
                        (cm->seq_params.subsampling_x !=
                         ref_frame_ccso_info->subsampling_x[plane]))))) {
          avm_internal_error(&cm->error, AVM_CODEC_ERROR, "Invalid ccso_reuse");
        }

        if (!cm->ccso_info.reuse_ccso[plane]) {
          cm->ccso_info.ccso_bo_only[plane] = avm_rb_read_bit(rb);
          cm->ccso_info.scale_idx[plane] = avm_rb_read_literal(rb, 2);
          if (cm->ccso_info.ccso_bo_only[plane]) {
            cm->ccso_info.quant_idx[plane] = 0;
            cm->ccso_info.ext_filter_support[plane] = 0;
            cm->ccso_info.edge_clf[plane] = 0;
            cm->ccso_info.max_band_log2[plane] = avm_rb_read_literal(rb, 3);
            if (cm->ccso_info.max_band_log2[plane] >
                compute_log2(CCSO_BAND_NUM)) {
              avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                                 "Invalid CCSO Band number");
            }
          } else {
            cm->ccso_info.quant_idx[plane] = avm_rb_read_literal(rb, 2);
            cm->ccso_info.ext_filter_support[plane] =
                avm_rb_read_literal(rb, 3);
            if (cm->ccso_info.ext_filter_support[plane] == 7) {
              avm_internal_error(
                  &cm->error, AVM_CODEC_CORRUPT_FRAME,
                  "Invalid ccso_ext_filter: ccso_ext_filter == 7");
            }
            if (quant_sz[cm->ccso_info.scale_idx[plane]]
                        [cm->ccso_info.quant_idx[plane]]) {
              cm->ccso_info.edge_clf[plane] = avm_rb_read_bit(rb);
            } else {
              cm->ccso_info.edge_clf[plane] = 0;
            }
            cm->ccso_info.max_band_log2[plane] = avm_rb_read_literal(rb, 2);
          }
          const int max_band = 1 << cm->ccso_info.max_band_log2[plane];
          const int edge_clf = cm->ccso_info.edge_clf[plane];
          const int max_edge_interval = edge_clf_to_edge_interval[edge_clf];
          const int num_edge_offset_intervals =
              cm->ccso_info.ccso_bo_only[plane] ? 1 : max_edge_interval;
          for (int d0 = 0; d0 < num_edge_offset_intervals; d0++) {
            for (int d1 = 0; d1 < num_edge_offset_intervals; d1++) {
              for (int band_num = 0; band_num < max_band; band_num++) {
                const int lut_idx_ext = (band_num << 4) + (d0 << 2) + d1;
                const int offset_idx = read_ccso_offset_idx(rb);
                cm->ccso_info.filter_offset[plane][lut_idx_ext] =
                    ccso_offset[offset_idx] *
                    ccso_scale[cm->ccso_info.scale_idx[plane]];
              }
            }
          }
          av2_copy_ccso_filters(&cm->cur_frame->ccso_info, &cm->ccso_info,
                                plane, 1, 0, 0);
          cm->cur_frame->ccso_info.ccso_enable[plane] = 1;

        } else {  // frame level ccso reuse is true
          av2_copy_ccso_filters(&cm->cur_frame->ccso_info, ref_frame_ccso_info,
                                plane, 1, 0, 0);
          av2_copy_ccso_filters(&cm->ccso_info, ref_frame_ccso_info, plane, 1,
                                0, 0);
        }
      } else {  // disable ccso
        cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
      }
    }
  } else {
    cm->cur_frame->ccso_info.ccso_enable[0] = 0;
    cm->cur_frame->ccso_info.ccso_enable[1] = 0;
    cm->cur_frame->ccso_info.ccso_enable[2] = 0;
    cm->ccso_info.ccso_enable[0] = 0;
    cm->ccso_info.ccso_enable[1] = 0;
    cm->ccso_info.ccso_enable[2] = 0;
  }
}

static INLINE int read_delta_q(struct avm_read_bit_buffer *rb) {
  return avm_rb_read_bit(rb) ? avm_rb_read_inv_signed_literal(rb, 6) : 0;
}

static AVM_INLINE void setup_quantization(CommonQuantParams *quant_params,
                                          int num_planes,
                                          const SequenceHeader *seq_params,
                                          struct avm_read_bit_buffer *rb) {
  avm_bit_depth_t bit_depth = seq_params->bit_depth;
  bool separate_uv_delta_q = seq_params->separate_uv_delta_q;
  quant_params->base_qindex = avm_rb_read_literal(
      rb, bit_depth == AVM_BITS_8 ? QINDEX_BITS_UNEXT : QINDEX_BITS);
  if (seq_params->y_dc_delta_q_enabled)
    quant_params->y_dc_delta_q = read_delta_q(rb);
  else
    quant_params->y_dc_delta_q = 0;
  if (num_planes > 1 && (seq_params->uv_dc_delta_q_enabled ||
                         seq_params->uv_ac_delta_q_enabled)) {
    int diff_uv_delta = 0;
    if (separate_uv_delta_q) diff_uv_delta = avm_rb_read_bit(rb);
    if (!seq_params->equal_ac_dc_q) {
      if (seq_params->uv_dc_delta_q_enabled)
        quant_params->u_dc_delta_q = read_delta_q(rb);
      else
        quant_params->u_dc_delta_q = 0;
    }
    if (seq_params->uv_ac_delta_q_enabled)
      quant_params->u_ac_delta_q = read_delta_q(rb);
    else
      quant_params->u_ac_delta_q = 0;
    if (seq_params->equal_ac_dc_q)
      quant_params->u_dc_delta_q = quant_params->u_ac_delta_q;
    if (diff_uv_delta) {
      if (!seq_params->equal_ac_dc_q) {
        if (seq_params->uv_dc_delta_q_enabled)
          quant_params->v_dc_delta_q = read_delta_q(rb);
        else
          quant_params->v_dc_delta_q = 0;
      }
      if (seq_params->uv_ac_delta_q_enabled)
        quant_params->v_ac_delta_q = read_delta_q(rb);
      else
        quant_params->v_ac_delta_q = 0;
      if (seq_params->equal_ac_dc_q)
        quant_params->v_dc_delta_q = quant_params->v_ac_delta_q;
    } else {
      quant_params->v_dc_delta_q = quant_params->u_dc_delta_q;
      quant_params->v_ac_delta_q = quant_params->u_ac_delta_q;
    }
  } else {
    quant_params->u_dc_delta_q = 0;
    quant_params->u_ac_delta_q = 0;
    quant_params->v_dc_delta_q = 0;
    quant_params->v_ac_delta_q = 0;
  }
}
void setup_quant_matrices(AV2Decoder *pbi, CommonQuantParams *quant_params,
                          int plane, int qmlevel) {
  AV2_COMMON *const cm = &pbi->common;
  if (qmlevel >= NUM_QM_LEVELS) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "qmlevel %d is out of boundary", qmlevel);
  }
  if (qmlevel == NUM_QM_LEVELS - 1) {
    for (int t = 0; t < TX_SIZES_ALL; ++t) {
      quant_params->giqmatrix[qmlevel][plane][t] = NULL;
    }
    return;
  }

  int qm_pos_found = -1;
  for (int qm_pos = 0; qm_pos < NUM_CUSTOM_QMS; qm_pos++) {
    if (pbi->qm_list[qm_pos].qm_id == qmlevel) {
      qm_pos_found = qm_pos;
      break;
    }
  }
  if (qm_pos_found < 0) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "quantiztion matrix with Id[%d] is not found", qmlevel);
  }
  const struct quantization_matrix_set *qmset = &pbi->qm_list[qm_pos_found];

  if (qmset->quantizer_matrix_num_planes != av2_num_planes(cm)) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "the quantization matrix and sequence header indicate "
                       "different numbers of planes: (%d, %d)",
                       qmset->quantizer_matrix_num_planes, av2_num_planes(cm));
  }

  //  when a picture indicated in an embedded layer with id equal obu_mlayer_id
  //  and in a temporal layer with id obu_tlayer_id is associated with either
  //  the sequence header or an embedded and temporal layer with ids qmMlayerId
  //  and qmTlayerId, respectively for which
  //  mlayer_dependency_map[obu_mlayer_id][qmMlayerId] and
  //  tlayer_dependency_map[obu_mlayer_id][obu_tlayer_id][qmTlayerId] are both
  //  equal to 1.
  if ((qmset->qm_tlayer_id != -1 &&
       cm->seq_params.tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
                                           [qmset->qm_tlayer_id] != 1) ||
      (qmset->qm_mlayer_id != -1 &&
       cm->seq_params.mlayer_dependency_map[cm->mlayer_id]
                                           [qmset->qm_mlayer_id] != 1)) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "the layer ids of the quantization matrices are out"
                       "of the limit: (%d, %d)",
                       qmset->qm_tlayer_id, qmset->qm_mlayer_id);
  }

  // Generate matrices for each tx size
  int current = 0;
  const bool is_user_defined_qm = qmset->is_user_defined_qm;
  for (int t = 0; t < TX_SIZES_ALL; ++t) {
    const int size = tx_size_2d[t];
    const int qm_tx_size = av2_get_adjusted_tx_size(t);
    if (t != qm_tx_size) {  // Reuse matrices for 'qm_tx_size'
      assert(t > qm_tx_size);
      quant_params->giqmatrix[qmlevel][plane][t] =
          quant_params->giqmatrix[qmlevel][plane][qm_tx_size];
    } else if (is_user_defined_qm &&
               (t <= TX_8X8 || t == TX_4X8 || t == TX_8X4)) {
      assert(current + size <= QM_TOTAL_SIZE);
      // Generate the iwt matrices from the base matrices.
      scale_tx(t, plane, &quant_params->iwt_matrix_ref[qmlevel][plane][current],
               qmset->quantizer_matrix);
      quant_params->giqmatrix[qmlevel][plane][t] =
          &quant_params->iwt_matrix_ref[qmlevel][plane][current];
      current += size;
    } else {
      // Fill with reference matrices.
      assert(current + size <= QM_TOTAL_SIZE);
      quant_params->giqmatrix[qmlevel][plane][t] =
          &predefined_iwt_matrix_ref[qmlevel][plane >= 1][current];
      current += size;
    }
  }
}

static AVM_INLINE void setup_qm_params(AV2Decoder *pbi,
                                       CommonQuantParams *quant_params,
                                       bool segmentation_enabled,
                                       int num_planes,
                                       struct avm_read_bit_buffer *rb) {
  quant_params->using_qmatrix = avm_rb_read_bit(rb);
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  if (quant_params->using_qmatrix) {
    if (segmentation_enabled) {
      quant_params->pic_qm_num = avm_rb_read_literal(rb, 2) + 1;
    } else {
      quant_params->pic_qm_num = 1;
    }
#if CONFIG_QM_DEBUG
    printf("[DEC-FRM] pic_qm_num: %d\n", quant_params->pic_qm_num);
#endif
    quant_params->qm_index_bits = avm_ceil_log2(quant_params->pic_qm_num);
    for (uint8_t i = 0; i < quant_params->pic_qm_num; i++) {
      quant_params->qm_y[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
      if (num_planes > 1) {
        const bool qm_uv_same_as_y = avm_rb_read_bit(rb);
#if CONFIG_QM_DEBUG
        printf("[DEC-FRM] qm_uv_same_as_y: %d\n", qm_uv_same_as_y);
#endif
        if (qm_uv_same_as_y) {
          quant_params->qm_u[i] = quant_params->qm_y[i];
          quant_params->qm_v[i] = quant_params->qm_y[i];
        } else {
          quant_params->qm_u[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
          if (!seq_params->separate_uv_delta_q) {
            quant_params->qm_v[i] = quant_params->qm_u[i];
          } else {
            quant_params->qm_v[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
          }
        }
      }
#if CONFIG_QM_DEBUG
      if (num_planes > 1) {
        printf("[DEC-FRM] qm_y/u/v[%d]: (%d,%d,%d)\n", i, quant_params->qm_y[i],
               quant_params->qm_u[i], quant_params->qm_v[i]);
      } else {
        printf("[DEC-FRM] qm_y[%d]: (%d)\n", i, quant_params->qm_y[i]);
      }
#endif
    }
    for (uint8_t i = 0; i < quant_params->pic_qm_num; i++) {
      setup_quant_matrices(pbi, quant_params, 0, quant_params->qm_y[i]);
      if (num_planes > 1) {
        setup_quant_matrices(pbi, quant_params, 1, quant_params->qm_u[i]);
        setup_quant_matrices(pbi, quant_params, 2, quant_params->qm_v[i]);
      }
    }
  } else {
    for (uint8_t i = 0; i < 4; i++) {
      quant_params->qm_y[i] = 0;
      quant_params->qm_u[i] = 0;
      quant_params->qm_v[i] = 0;
    }
  }
}
// Build y/uv dequant values based on segmentation.
static AVM_INLINE void setup_segmentation_dequant(AV2Decoder *const pbi,
                                                  MACROBLOCKD *const xd) {
  AV2_COMMON *const cm = &pbi->common;
  const int bit_depth = cm->seq_params.bit_depth;
  // When segmentation is disabled, only the first value is used.  The
  // remaining are don't cares.
  const int max_segments =
      cm->seg.enabled ? (cm->seg.enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8)
                      : 1;
  CommonQuantParams *const quant_params = &cm->quant_params;
  for (int i = 0; i < max_segments; ++i) {
    const int qindex = xd->qindex[i];
    quant_params->y_dequant_QTX[i][0] =
        av2_dc_quant_QTX(qindex, quant_params->y_dc_delta_q,
                         cm->seq_params.base_y_dc_delta_q, bit_depth);
    quant_params->y_dequant_QTX[i][1] =
        av2_ac_quant_QTX(qindex, 0, 0, bit_depth);
    quant_params->u_dequant_QTX[i][0] =
        av2_dc_quant_QTX(qindex, quant_params->u_dc_delta_q,
                         cm->seq_params.base_uv_dc_delta_q, bit_depth);
    quant_params->u_dequant_QTX[i][1] =
        av2_ac_quant_QTX(qindex, quant_params->u_ac_delta_q,
                         cm->seq_params.base_uv_ac_delta_q, bit_depth);
    quant_params->v_dequant_QTX[i][0] =
        av2_dc_quant_QTX(qindex, quant_params->v_dc_delta_q,
                         cm->seq_params.base_uv_dc_delta_q, bit_depth);
    quant_params->v_dequant_QTX[i][1] =
        av2_ac_quant_QTX(qindex, quant_params->v_ac_delta_q,
                         cm->seq_params.base_uv_ac_delta_q, bit_depth);
    const int use_qmatrix = av2_use_qmatrix(quant_params, xd, i);
    // NB: depends on base index so there is only 1 set per frame
    // No quant weighting when lossless or signalled not using QM
    const int qm_index = quant_params->qm_index[i];
    const int qmlevel_y =
        use_qmatrix ? quant_params->qm_y[qm_index] : NUM_QM_LEVELS - 1;
    const int qmlevel_y0 =
        use_qmatrix ? quant_params->qm_y[0] : NUM_QM_LEVELS - 1;

    for (int j = 0; j < TX_SIZES_ALL; ++j) {
      if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
        quant_params->y_iqmatrix[i][j] =
            av2_iqmatrix(quant_params, qmlevel_y0, AVM_PLANE_Y, j);
      else
        quant_params->y_iqmatrix[i][j] =
            av2_iqmatrix(quant_params, qmlevel_y, AVM_PLANE_Y, j);
    }
    const int num_planes = av2_num_planes(cm);
    if (num_planes > 1) {
      const int qmlevel_u =
          use_qmatrix ? quant_params->qm_u[qm_index] : NUM_QM_LEVELS - 1;
      const int qmlevel_u0 =
          use_qmatrix ? quant_params->qm_u[0] : NUM_QM_LEVELS - 1;
      for (int j = 0; j < TX_SIZES_ALL; ++j) {
        if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
          quant_params->u_iqmatrix[i][j] =
              av2_iqmatrix(quant_params, qmlevel_u0, AVM_PLANE_U, j);
        else
          quant_params->u_iqmatrix[i][j] =
              av2_iqmatrix(quant_params, qmlevel_u, AVM_PLANE_U, j);
      }
      const int qmlevel_v =
          use_qmatrix ? quant_params->qm_v[qm_index] : NUM_QM_LEVELS - 1;
      const int qmlevel_v0 =
          use_qmatrix ? quant_params->qm_v[0] : NUM_QM_LEVELS - 1;
      for (int j = 0; j < TX_SIZES_ALL; ++j) {
        if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
          quant_params->v_iqmatrix[i][j] =
              av2_iqmatrix(quant_params, qmlevel_v0, AVM_PLANE_V, j);
        else
          quant_params->v_iqmatrix[i][j] =
              av2_iqmatrix(quant_params, qmlevel_v, AVM_PLANE_V, j);
      }
#if CONFIG_QM_DEBUG
      printf("[DEC-FRM] qmlevel_y/u/v[%d]: (%d,%d,%d)\n", i, qmlevel_y,
             qmlevel_u, qmlevel_v);
#endif
    } else {
#if CONFIG_QM_DEBUG
      printf("[DEC-FRM] qmlevel_y[%d]: (%d)\n", i, qmlevel_y);
#endif
    }
  }
}

static InterpFilter read_frame_interp_filter(struct avm_read_bit_buffer *rb) {
  return avm_rb_read_bit(rb) ? SWITCHABLE
                             : avm_rb_read_literal(rb, LOG_SWITCHABLE_FILTERS);
}

static AVM_INLINE void setup_render_size(AV2_COMMON *cm,
                                         struct avm_read_bit_buffer *rb) {
  if (cm->bridge_frame_info.is_bridge_frame) {
    return;
  }

  (void)rb;
  if (cm->lcr != NULL && cm->lcr->valid) {
    struct LCRXLayerInfo *xlayer_info = NULL;
    if (cm->lcr->is_global) {
      // For global LCR find the lxayer inf for the current xlayer_id
      struct GlobalLayerConfigurationRecord *global_lcr = &cm->lcr->global_lcr;
      for (int i = 0; i < global_lcr->LcrMaxNumXLayerCount; i++) {
        if (global_lcr->LcrXLayerID[i] == cm->xlayer_id) {
          xlayer_info = &global_lcr->xlayer_info[i];
          break;
        }
      }
    } else {
      // for local lcr
      xlayer_info = &cm->lcr->local_lcr.xlayer_info;
    }
    if (xlayer_info != NULL && xlayer_info->lcr_rep_info_present_flag) {
      cm->render_width = xlayer_info->rep_params.lcr_max_pic_width;
      cm->render_height = xlayer_info->rep_params.lcr_max_pic_height;
    } else {
      cm->render_width = cm->width;
      cm->render_height = cm->height;
    }
  } else {
    // No active LCR, use the frame dimensions
    cm->render_width = cm->width;
    cm->render_height = cm->height;
  }
}

static AVM_INLINE void resize_context_buffers(AV2_COMMON *cm, int width,
                                              int height) {
#if CONFIG_SIZE_LIMIT
  if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Dimensions of %dx%d beyond allowed size of %dx%d.",
                       width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);
#endif
  if (cm->width != width || cm->height != height) {
    const int new_mi_rows =
        ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
    const int new_mi_cols =
        ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2;

    // Allocations in av2_alloc_context_buffers() depend on individual
    // dimensions as well as the overall size.
    if (new_mi_cols > cm->mi_params.mi_cols ||
        new_mi_rows > cm->mi_params.mi_rows) {
      if (av2_alloc_context_buffers(cm, width, height)) {
        // The cm->mi_* values have been cleared and any existing context
        // buffers have been freed. Clear cm->width and cm->height to be
        // consistent and to force a realloc next time.
        cm->width = 0;
        cm->height = 0;
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                           "Failed to allocate context buffers");
      }
    } else {
      cm->mi_params.set_mb_mi(&cm->mi_params, width, height);
    }
    av2_init_mi_buffers(&cm->mi_params);
    cm->width = width;
    cm->height = height;
  }

  // We also need to handle the case when `sb_rows` / `sb_cols` has
  // increased due to a change in superblock size. Note that total number of
  // superblocks can *increase* even if frame size has decreased, if
  // superblock size is reduced.
  // We call this function unconditionally, because it already has the logic
  // to reallocte only when necessary.
  if (av2_alloc_superblock_info_buffers(cm)) {
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                       "Failed to allocate superblock info buffers");
  }

  ensure_mv_buffer(cm->cur_frame, cm);
  cm->cur_frame->width = cm->width;
  cm->cur_frame->height = cm->height;
}

static AVM_INLINE void setup_tip_frame_size(AV2_COMMON *cm) {
  const SequenceHeader *const seq_params = &cm->seq_params;
  const ContentInterpretation *const ci_params =
      &cm->ci_params_per_layer[cm->mlayer_id];
  const ColorInfo *const color_info = &ci_params->color_info;
  YV12_BUFFER_CONFIG *tip_frame_buf = &cm->tip_ref.tip_frame->buf;
  if (avm_realloc_frame_buffer(
          tip_frame_buf, cm->width, cm->height, seq_params->subsampling_x,
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
          cm->features.byte_alignment, NULL, NULL, NULL, false)) {
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                       "Failed to allocate frame buffer");
  }

  if (tip_frame_buf) {
    tip_frame_buf->bit_depth = (unsigned int)seq_params->bit_depth;
    tip_frame_buf->color_primaries = color_info->color_primaries;
    tip_frame_buf->transfer_characteristics =
        color_info->transfer_characteristics;
    tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
    tip_frame_buf->monochrome = seq_params->monochrome;
    if (ci_params->ci_chroma_sample_position_present_flag)
      tip_frame_buf->chroma_sample_position =
          ci_params->ci_chroma_sample_position[0];
    else
      tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
    tip_frame_buf->color_range = color_info->full_range_flag;
    tip_frame_buf->render_width = cm->render_width;
    tip_frame_buf->render_height = cm->render_height;
  }

  tip_frame_buf = &cm->tip_ref.tmp_tip_frame->buf;
  if (avm_realloc_frame_buffer(
          tip_frame_buf, cm->width, cm->height, seq_params->subsampling_x,
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
          cm->features.byte_alignment, NULL, NULL, NULL, false)) {
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                       "Failed to allocate frame buffer");
  }

  if (tip_frame_buf) {
    tip_frame_buf->bit_depth = (unsigned int)seq_params->bit_depth;
    tip_frame_buf->color_primaries = color_info->color_primaries;
    tip_frame_buf->transfer_characteristics =
        color_info->transfer_characteristics;
    tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
    tip_frame_buf->monochrome = seq_params->monochrome;
    if (ci_params->ci_chroma_sample_position_present_flag)
      tip_frame_buf->chroma_sample_position =
          ci_params->ci_chroma_sample_position[0];
    else
      tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
    tip_frame_buf->color_range = color_info->full_range_flag;
    tip_frame_buf->render_width = cm->render_width;
    tip_frame_buf->render_height = cm->render_height;
  }
}

static AVM_INLINE void setup_buffer_pool(AV2_COMMON *cm) {
  BufferPool *const pool = cm->buffer_pool;
  const SequenceHeader *const seq_params = &cm->seq_params;
  const ContentInterpretation *const ci_params =
      &cm->ci_params_per_layer[cm->mlayer_id];
  const ColorInfo *const color_info = &ci_params->color_info;

  lock_buffer_pool(pool);
  if (avm_realloc_frame_buffer(
          &cm->cur_frame->buf, cm->width, cm->height, seq_params->subsampling_x,
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
          cm->features.byte_alignment, &cm->cur_frame->raw_frame_buffer,
          pool->get_fb_cb, pool->cb_priv, false)) {
    unlock_buffer_pool(pool);
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                       "Failed to allocate frame buffer");
  }
  unlock_buffer_pool(pool);

  cm->cur_frame->buf.bit_depth = (unsigned int)seq_params->bit_depth;
  cm->cur_frame->buf.color_primaries = color_info->color_primaries;
  cm->cur_frame->buf.transfer_characteristics =
      color_info->transfer_characteristics;
  cm->cur_frame->buf.matrix_coefficients = color_info->matrix_coefficients;
  cm->cur_frame->buf.monochrome = seq_params->monochrome;
  if (ci_params->ci_chroma_sample_position_present_flag)
    cm->cur_frame->buf.chroma_sample_position =
        ci_params->ci_chroma_sample_position[0];
  else
    cm->cur_frame->buf.chroma_sample_position = AVM_CSP_UNSPECIFIED;
  cm->cur_frame->buf.color_range = color_info->full_range_flag;
  cm->cur_frame->buf.render_width = cm->render_width;
  cm->cur_frame->buf.render_height = cm->render_height;
  if (seq_params->conf.conf_win_enabled_flag) {
    cm->cur_frame->buf.w_conf_win_enabled_flag =
        seq_params->conf.conf_win_enabled_flag;
    cm->cur_frame->buf.w_win_left_offset =
        seq_params->conf.conf_win_left_offset;
    cm->cur_frame->buf.w_win_right_offset =
        seq_params->conf.conf_win_right_offset;
    cm->cur_frame->buf.w_win_top_offset = seq_params->conf.conf_win_top_offset;
    cm->cur_frame->buf.w_win_bottom_offset =
        seq_params->conf.conf_win_bottom_offset;
  } else {
    cm->cur_frame->buf.w_win_left_offset = 0;
    cm->cur_frame->buf.w_win_right_offset = 0;
    cm->cur_frame->buf.w_win_top_offset = 0;
    cm->cur_frame->buf.w_win_bottom_offset = 0;
  }
  cm->cur_frame->buf.max_width = seq_params->max_frame_width;
  cm->cur_frame->buf.max_height = seq_params->max_frame_height;
  if (cm->seq_params.enable_tip) {
    setup_tip_frame_size(cm);
  }
}

void av2_validate_frame_level_conformance(
    const struct SequenceHeader *seq_params, int frame_width, int frame_height,
    struct avm_internal_error_info *error_info) {
  const struct CropWindow *conf = &seq_params->conf;
  if (!conf->conf_win_enabled_flag) return;

  const int SubX = seq_params->subsampling_x + 1;
  const int SubY = seq_params->subsampling_y + 1;
  const int LeftPosX =
      (conf->conf_win_left_offset * frame_width) / seq_params->max_frame_width;

  const int RightPosX = frame_width - 1 -
                        ((conf->conf_win_right_offset * frame_width) /
                         seq_params->max_frame_width);

  const int TopPosY =
      (conf->conf_win_top_offset * frame_height) / seq_params->max_frame_height;

  const int BottomPosY = frame_height - 1 -
                         ((conf->conf_win_bottom_offset * frame_height) /
                          seq_params->max_frame_height);

  // Conformance requirement 1: LeftPosX == SubX * (LeftPosX/Subx)
  if (!seq_params->monochrome && SubX > 1 &&
      LeftPosX != SubX * (LeftPosX / SubX)) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Conformance window left position %d must be a multiple of SubX=%d",
        LeftPosX, SubX);
  }

  // Conformance requirement 2: TopPosY == SubY * (TopPosY / SubY)
  if (!seq_params->monochrome && SubY > 1 &&
      TopPosY != SubY * (TopPosY / SubY)) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Conformance window top position %d must be a multiple of SubY=%d",
        TopPosY, SubY);
  }

  // Conformance requirement 3: LeftPosX<= RightPosX
  if (LeftPosX > RightPosX) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Conformance window left position %d must be <= right position=%d",
        LeftPosX, RightPosX);
  }

  // Conformance requirement 4: TopPosY <= BottomPosY
  if (TopPosY > BottomPosY) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Conformance window top position %d must be <= bottom position=%d",
        TopPosY, BottomPosY);
  }
}

static void check_lcr_frame_size_conformance_dec(AV2_COMMON *cm, int width,
                                                 int height) {
  int max_w, max_h, layer_id;
  if (check_lcr_frame_size_conformance(cm, width, height, &max_w, &max_h,
                                       &layer_id)) {
    avm_internal_error(
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
        "Frame dimensions (%dx%d) exceed LCR max expected dimensions (%dx%d) "
        "for embedded layer %d",
        width, height, max_w, max_h, layer_id);
  }
}

static AVM_INLINE void setup_frame_size(AV2_COMMON *cm,
                                        int frame_size_override_flag,
                                        struct avm_read_bit_buffer *rb) {
  const SequenceHeader *const seq_params = &cm->seq_params;
  int width, height;

  int num_bits_width = seq_params->num_bits_width;
  int num_bits_height = seq_params->num_bits_height;
  if (cm->bridge_frame_info.is_bridge_frame) {
    cm->bridge_frame_info.bridge_frame_max_width =
        avm_rb_read_literal(rb, num_bits_width) + 1;
    cm->bridge_frame_info.bridge_frame_max_height =
        avm_rb_read_literal(rb, num_bits_height) + 1;
    const RefCntBuffer *ref_buf = get_ref_frame_buf(
        cm, cm->bridge_frame_info.bridge_frame_ref_idx_remapped);
    width =
        AVMMIN(cm->bridge_frame_info.bridge_frame_max_width, ref_buf->width);
    height =
        AVMMIN(cm->bridge_frame_info.bridge_frame_max_height, ref_buf->height);
  } else {
    if (frame_size_override_flag) {
      av2_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
      if (width > seq_params->max_frame_width ||
          height > seq_params->max_frame_height) {
        avm_internal_error(
            &cm->error, AVM_CODEC_CORRUPT_FRAME,
            "Frame dimensions are larger than the maximum values");
      }
    } else {
      assert(cm->mfh_valid[cm->cur_mfh_id]);
      if (cm->mfh_params[cm->cur_mfh_id].mfh_frame_size_present_flag) {
        width = cm->mfh_params[cm->cur_mfh_id].mfh_frame_width;
        height = cm->mfh_params[cm->cur_mfh_id].mfh_frame_height;
      } else {
        width = seq_params->max_frame_width;
        height = seq_params->max_frame_height;
      }
    }
  }

  if (!cm->bridge_frame_info.is_bridge_frame) {
    check_lcr_frame_size_conformance_dec(cm, width, height);
  }

  resize_context_buffers(cm, width, height);
  setup_render_size(cm, rb);
  setup_buffer_pool(cm);
  realloc_bru_info(cm);
  av2_validate_frame_level_conformance(&cm->seq_params, width, height,
                                       &cm->error);
}

static AVM_INLINE void setup_seq_sb_size(SequenceHeader *seq_params,
                                         struct avm_read_bit_buffer *rb) {
  static const BLOCK_SIZE sb_sizes[] = { BLOCK_256X256, BLOCK_128X128,
                                         BLOCK_64X64 };
  int index = 0;
  bool bit = avm_rb_read_bit(rb);
  if (!bit) {
    index++;
    bit = avm_rb_read_bit(rb);
    if (!bit) {
      index++;
    }
  }
  BLOCK_SIZE sb_size = sb_sizes[index];
  seq_params->sb_size = sb_size;
  seq_params->mib_size = mi_size_wide[sb_size];
  seq_params->mib_size_log2 = mi_size_wide_log2[sb_size];
}

static INLINE int valid_ref_frame_img_fmt(avm_bit_depth_t ref_bit_depth,
                                          int ref_xss, int ref_yss,
                                          avm_bit_depth_t this_bit_depth,
                                          int this_xss, int this_yss) {
  return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
         ref_yss == this_yss;
}

static AVM_INLINE void setup_frame_size_with_refs(
    AV2_COMMON *cm, const int explicit_ref_frame_map,
    struct avm_read_bit_buffer *rb) {
  int width, height;
  int found = 0;
  // In implicit reference framework, the reference frame mapping up to this
  // point is a preliminary, resolution independent version, in which case
  // num_total_refs_res_indep and remapped_ref_idx_res_indep are used instead.
  const int num_refs = explicit_ref_frame_map
                           ? cm->ref_frames_info.num_total_refs
                           : cm->ref_frames_info.num_total_refs_res_indep;
  for (int i = 0; i < num_refs; ++i) {
    if (avm_rb_read_bit(rb)) {
      const RefCntBuffer *const ref_buf =
          explicit_ref_frame_map ? get_ref_frame_buf(cm, i)
                                 : get_ref_frame_buf_res_indep(cm, i);
      if (ref_buf->is_restricted) {
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "Invalid condition: restricted reference buffer");
      }
      // This will never be NULL in a normal stream, as streams are required to
      // have a shown keyframe before any inter frames, which would refresh all
      // the reference buffers. However, it might be null if we're starting in
      // the middle of a stream, and static analysis will error if we don't do
      // a null check here.
      if (ref_buf == NULL) {
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "Invalid condition: invalid reference buffer");
      } else {
        const YV12_BUFFER_CONFIG *const buf = &ref_buf->buf;
        width = buf->y_crop_width;
        height = buf->y_crop_height;
        cm->render_width = buf->render_width;
        cm->render_height = buf->render_height;
        resize_context_buffers(cm, width, height);
        found = 1;
        break;
      }
    }
  }

  const SequenceHeader *const seq_params = &cm->seq_params;
  if (!found) {
    int num_bits_width = seq_params->num_bits_width;
    int num_bits_height = seq_params->num_bits_height;

    av2_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
    resize_context_buffers(cm, width, height);
    setup_render_size(cm, rb);
  }

  if (width <= 0 || height <= 0)
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid frame size");

  check_lcr_frame_size_conformance_dec(cm, width, height);

  for (int i = 0; i < num_refs; ++i) {
    const RefCntBuffer *const ref_frame =
        explicit_ref_frame_map ? get_ref_frame_buf(cm, i)
                               : get_ref_frame_buf_res_indep(cm, i);
    if (!valid_ref_frame_img_fmt(
            ref_frame->buf.bit_depth, ref_frame->buf.subsampling_x,
            ref_frame->buf.subsampling_y, seq_params->bit_depth,
            seq_params->subsampling_x, seq_params->subsampling_y))
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Referenced frame has incompatible color format");
  }
  setup_buffer_pool(cm);
  realloc_bru_info(cm);
  av2_validate_frame_level_conformance(&cm->seq_params, width, height,
                                       &cm->error);
}

// Reconstructs the tile information
static void reconstruct_tile_info_max_tile(
    AV2_COMMON *const cm, const TileInfoSyntax *const tile_params) {
  CommonTileParams *const tiles = &cm->tiles;
  const CommonTileParams *const tile_info = &tile_params->tile_info;
  int width_sb = tile_info->sb_cols;
  int height_sb = tile_info->sb_rows;

  tiles->uniform_spacing = tile_info->uniform_spacing;

  // Read tile columns
  if (tiles->uniform_spacing) {
    tiles->log2_cols = tile_info->log2_cols;
  } else {
    int i;
    int start_sb;
    for (i = 0, start_sb = 0; width_sb > 0 && i < MAX_TILE_COLS; i++) {
      const int size_sb =
          tile_info->col_start_sb[i + 1] - tile_info->col_start_sb[i];
      tiles->col_start_sb[i] = start_sb;
      start_sb += size_sb;
      width_sb -= size_sb;
    }
    tiles->cols = i;
    tiles->col_start_sb[i] = start_sb + width_sb;
    assert(width_sb == 0);
  }
  av2_calculate_tile_cols(tiles);
  // Read tile rows
  if (tiles->uniform_spacing) {
    // tiles->log2_rows = tile_params->log2_rows + 1;
    tiles->log2_rows = tile_info->log2_rows;
  } else {
    int i;
    int start_sb;
    for (i = 0, start_sb = 0; height_sb > 0 && i < MAX_TILE_ROWS; i++) {
      const int size_sb =
          tile_info->row_start_sb[i + 1] - tile_info->row_start_sb[i];
      tiles->row_start_sb[i] = start_sb;
      start_sb += size_sb;
      height_sb -= size_sb;
    }
    tiles->rows = i;
    tiles->row_start_sb[i] = start_sb + height_sb;
    assert(height_sb == 0);
  }
  av2_calculate_tile_rows(tiles);
}

static AVM_INLINE void read_tile_info_max_tile(
    AV2_COMMON *const cm, struct avm_read_bit_buffer *const rb) {
  CommonTileParams *const tiles = &cm->tiles;
  int width_sb = tiles->sb_cols;
  int height_sb = tiles->sb_rows;

  tiles->uniform_spacing = avm_rb_read_bit(rb);

  // Read tile columns
  if (tiles->uniform_spacing) {
    tiles->log2_cols = tiles->min_log2_cols;
    while (tiles->log2_cols < tiles->max_log2_cols) {
      if (!avm_rb_read_bit(rb)) {
        break;
      }
      tiles->log2_cols++;
    }
  } else {
    int i;
    int start_sb;
    for (i = 0, start_sb = 0; width_sb > 0 && i < MAX_TILE_COLS; i++) {
      const int size_sb =
          1 + rb_read_uniform(rb, AVMMIN(width_sb, tiles->max_width_sb));
      tiles->col_start_sb[i] = start_sb;
      start_sb += size_sb;
      width_sb -= size_sb;
    }
    tiles->cols = i;
    tiles->col_start_sb[i] = start_sb + width_sb;
  }
  av2_calculate_tile_cols(tiles);

  // Read tile rows
  if (tiles->uniform_spacing) {
    tiles->log2_rows = tiles->min_log2_rows;
    while (tiles->log2_rows < tiles->max_log2_rows) {
      if (!avm_rb_read_bit(rb)) {
        break;
      }
      tiles->log2_rows++;
    }
  } else {
    int i;
    int start_sb;
    for (i = 0, start_sb = 0; height_sb > 0 && i < MAX_TILE_ROWS; i++) {
      const int size_sb =
          1 + rb_read_uniform(rb, AVMMIN(height_sb, tiles->max_height_sb));
      tiles->row_start_sb[i] = start_sb;
      start_sb += size_sb;
      height_sb -= size_sb;
    }
    tiles->rows = i;
    tiles->row_start_sb[i] = start_sb + height_sb;
  }
  av2_calculate_tile_rows(tiles);
}

static AVM_INLINE void read_tile_info(AV2Decoder *const pbi,
                                      struct avm_read_bit_buffer *const rb) {
  AV2_COMMON *const cm = &pbi->common;
  if (cm->bridge_frame_info.is_bridge_frame) {
    return;
  }
  av2_get_tile_limits(&cm->tiles, cm->mi_params.mi_rows, cm->mi_params.mi_cols,
                      cm->mib_size_log2, cm->seq_params.mib_size_log2,
                      cm->seq_params.seq_max_level_idx,
                      cm->seq_params.seq_tier);

  const TileInfoSyntax *const tile_params = find_effective_tile_params(cm);
  int reuse = 0;
  if (tile_params &&
      is_frame_tile_config_reuse_eligible(tile_params, &cm->tiles)) {
    if (tile_params->allow_tile_info_change)
      reuse = avm_rb_read_bit(rb);
    else
      reuse = 1;
  }
  if (reuse) {
    reconstruct_tile_info_max_tile(cm, tile_params);
  } else {
    read_tile_info_max_tile(cm, rb);
  }

  if (cm->bru.enabled) {
    const int num_tiles = cm->tiles.rows * cm->tiles.cols;
    memset(cm->tiles.tile_active_bitmap, 0, (num_tiles + 7) / 8);
    if (num_tiles == 1) {
      cm->tiles.tile_active_bitmap[0] = 1;
    }
  }
  pbi->context_update_tile_id = 0;
  if (cm->tiles.rows * cm->tiles.cols > 1 &&
      cm->features.tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
    if (!cm->seq_params.enable_avg_cdf || !cm->seq_params.avg_cdf_type) {
      // tile to use for cdf update
      pbi->context_update_tile_id =
          avm_rb_read_literal(rb, cm->tiles.log2_rows + cm->tiles.log2_cols);
      if (pbi->context_update_tile_id >= cm->tiles.rows * cm->tiles.cols) {
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "Invalid context_update_tile_id");
      }
    }
    // tile size magnitude
    pbi->tile_size_bytes = avm_rb_read_literal(rb, 2) + 1;
  }
}

static size_t mem_get_varsize(const uint8_t *src, int sz) {
  switch (sz) {
    case 1: return src[0];
    case 2: return mem_get_le16(src);
    case 3: return mem_get_le24(src);
    case 4: return mem_get_le32(src);
    default: assert(0 && "Invalid size"); return -1;
  }
}

// Reads the next tile returning its size and adjusting '*data' accordingly
// based on 'is_last'.
static AVM_INLINE void get_tile_buffer(
    const uint8_t *const data_end, const int tile_size_bytes, int is_last,
    struct avm_internal_error_info *error_info, const uint8_t **data,
    TileBufferDec *const buf) {
  size_t size;

  if (!is_last) {
    if (!read_is_valid(*data, tile_size_bytes, data_end))
      avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
                         "Not enough data to read tile size");

    size = mem_get_varsize(*data, tile_size_bytes) + AV2_MIN_TILE_SIZE_BYTES;
    *data += tile_size_bytes;

    if (size > (size_t)(data_end - *data))
      avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
                         "Truncated packet or corrupt tile size");
  } else {
    size = data_end - *data;
  }

  buf->data = *data;
  buf->size = size;

  *data += size;
}

static AVM_INLINE void get_tile_buffers(
    AV2Decoder *pbi, const uint8_t *data, const uint8_t *data_end,
    TileBufferDec (*const tile_buffers)[MAX_TILE_COLS], int start_tile,
    int end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  int tile_cols = cm->tiles.cols;
  int tile_rows = cm->tiles.rows;
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
    tile_cols = 1;
    tile_rows = 1;
    end_tile = 0;
  }
  int tc = 0;

  for (int r = 0; r < tile_rows; ++r) {
    for (int c = 0; c < tile_cols; ++c, ++tc) {
      TileBufferDec *const buf = &tile_buffers[r][c];

      const int is_last = (tc == end_tile);
      const size_t hdr_offset = 0;

      if (tc < start_tile || tc > end_tile) continue;

      if (data + hdr_offset >= data_end)
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "Data ended before all tiles were read.");
      data += hdr_offset;
      get_tile_buffer(data_end, pbi->tile_size_bytes, is_last,
                      &pbi->common.error, &data, buf);
      if (cm->bru.enabled) {
        const int tile_idx = r * tile_cols + c;
        TileDataDec *const this_tile = pbi->tile_data + tile_idx;
        const int tile_active_map_byte = tile_idx >> 3;
        const int tile_active_map_bit = tile_idx & 7;
        this_tile->tile_info.tile_active_mode =
            (cm->tiles.tile_active_bitmap[tile_active_map_byte] >>
             tile_active_map_bit) &
            1;
      }
    }
  }
}

static AVM_INLINE void set_cb_buffer(AV2Decoder *pbi, DecoderCodingBlock *dcb,
                                     CB_BUFFER *cb_buffer_base,
                                     const int num_planes, int mi_row,
                                     int mi_col) {
  AV2_COMMON *const cm = &pbi->common;
  int mib_size_log2 = cm->mib_size_log2;
  int stride = (cm->mi_params.mi_cols >> mib_size_log2) + 1;
  int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
  CB_BUFFER *cb_buffer = cb_buffer_base + offset;

  for (int plane = 0; plane < num_planes; ++plane) {
    dcb->dqcoeff_block[plane] = cb_buffer->dqcoeff[plane];
#if CONFIG_INSPECTION
    dcb->dqcoeff_block_copy[plane] = cb_buffer->dqcoeff_copy[plane];
    dcb->qcoeff_block[plane] = cb_buffer->qcoeff[plane];
    dcb->dequant_values[plane] = cb_buffer->dequant_values[plane];
#endif  // CONFIG_INSPECTION
    dcb->eob_data[plane] = cb_buffer->eob_data[plane];
    dcb->bob_data[plane] = cb_buffer->bob_data[plane];
    dcb->cb_offset[plane] = 0;
    dcb->txb_offset[plane] = 0;
  }
  MACROBLOCKD *const xd = &dcb->xd;
  xd->plane[0].color_index_map = cb_buffer->color_index_map[0];
  xd->plane[1].color_index_map = cb_buffer->color_index_map[1];
  xd->color_index_map_offset[0] = 0;
  xd->color_index_map_offset[1] = 0;
}

static AVM_INLINE void decoder_alloc_tile_data(AV2Decoder *pbi,
                                               const int n_tiles) {
  AV2_COMMON *const cm = &pbi->common;
  avm_free(pbi->tile_data);
  CHECK_MEM_ERROR(cm, pbi->tile_data,
                  avm_memalign(32, n_tiles * sizeof(*pbi->tile_data)));
  pbi->allocated_tiles = n_tiles;
  for (int i = 0; i < n_tiles; i++) {
    TileDataDec *const tile_data = pbi->tile_data + i;
    av2_zero(tile_data->dec_row_mt_sync);
  }
  pbi->allocated_row_mt_sync_rows = 0;
}

// Set up nsync by width.
// Note: currently returns a constant value.
// To use alternate nsync numbers picked by testing, see `get_sync_range()` in
// `thread_common.c`.
static INLINE int get_sync_range(int width) {
  (void)width;
  return 1;
}

// Allocate memory for decoder row synchronization
static AVM_INLINE void dec_row_mt_alloc(AV2DecRowMTSync *dec_row_mt_sync,
                                        AV2_COMMON *cm, int rows) {
  dec_row_mt_sync->allocated_sb_rows = rows;
#if CONFIG_MULTITHREAD
  {
    int i;

    CHECK_MEM_ERROR(cm, dec_row_mt_sync->mutex_,
                    avm_malloc(sizeof(*(dec_row_mt_sync->mutex_)) * rows));
    if (dec_row_mt_sync->mutex_) {
      for (i = 0; i < rows; ++i) {
        pthread_mutex_init(&dec_row_mt_sync->mutex_[i], NULL);
      }
    }

    CHECK_MEM_ERROR(cm, dec_row_mt_sync->cond_,
                    avm_malloc(sizeof(*(dec_row_mt_sync->cond_)) * rows));
    if (dec_row_mt_sync->cond_) {
      for (i = 0; i < rows; ++i) {
        pthread_cond_init(&dec_row_mt_sync->cond_[i], NULL);
      }
    }
  }
#endif  // CONFIG_MULTITHREAD

  CHECK_MEM_ERROR(cm, dec_row_mt_sync->cur_sb_col,
                  avm_malloc(sizeof(*(dec_row_mt_sync->cur_sb_col)) * rows));

  // Set up nsync.
  dec_row_mt_sync->sync_range = get_sync_range(cm->width);
}

// Deallocate decoder row synchronization related mutex and data
void av2_dec_row_mt_dealloc(AV2DecRowMTSync *dec_row_mt_sync) {
  if (dec_row_mt_sync != NULL) {
#if CONFIG_MULTITHREAD
    int i;
    if (dec_row_mt_sync->mutex_ != NULL) {
      for (i = 0; i < dec_row_mt_sync->allocated_sb_rows; ++i) {
        pthread_mutex_destroy(&dec_row_mt_sync->mutex_[i]);
      }
      avm_free(dec_row_mt_sync->mutex_);
    }
    if (dec_row_mt_sync->cond_ != NULL) {
      for (i = 0; i < dec_row_mt_sync->allocated_sb_rows; ++i) {
        pthread_cond_destroy(&dec_row_mt_sync->cond_[i]);
      }
      avm_free(dec_row_mt_sync->cond_);
    }
#endif  // CONFIG_MULTITHREAD
    avm_free(dec_row_mt_sync->cur_sb_col);

    // clear the structure as the source of this call may be a resize in which
    // case this call will be followed by an _alloc() which may fail.
    av2_zero(*dec_row_mt_sync);
  }
}

static INLINE void sync_read(AV2DecRowMTSync *const dec_row_mt_sync, int r,
                             int c) {
#if CONFIG_MULTITHREAD
  const int nsync = dec_row_mt_sync->sync_range;

  if (r && !(c & (nsync - 1))) {
    pthread_mutex_t *const mutex = &dec_row_mt_sync->mutex_[r - 1];
    pthread_mutex_lock(mutex);

    while (c > dec_row_mt_sync->cur_sb_col[r - 1] - nsync) {
      pthread_cond_wait(&dec_row_mt_sync->cond_[r - 1], mutex);
    }
    pthread_mutex_unlock(mutex);
  }
#else
  (void)dec_row_mt_sync;
  (void)r;
  (void)c;
#endif  // CONFIG_MULTITHREAD
}

static INLINE void sync_write(AV2DecRowMTSync *const dec_row_mt_sync, int r,
                              int c, const int sb_cols) {
#if CONFIG_MULTITHREAD
  const int nsync = dec_row_mt_sync->sync_range;
  int cur;
  int sig = 1;

  if (c < sb_cols - 1) {
    cur = c;
    if (c % nsync) sig = 0;
  } else {
    cur = sb_cols + nsync;
  }

  if (sig) {
    pthread_mutex_lock(&dec_row_mt_sync->mutex_[r]);

    dec_row_mt_sync->cur_sb_col[r] = cur;

    pthread_cond_signal(&dec_row_mt_sync->cond_[r]);
    pthread_mutex_unlock(&dec_row_mt_sync->mutex_[r]);
  }
#else
  (void)dec_row_mt_sync;
  (void)r;
  (void)c;
  (void)sb_cols;
#endif  // CONFIG_MULTITHREAD
}

static AVM_INLINE void decode_tile_sb_row(AV2Decoder *pbi, ThreadData *const td,
                                          TileInfo tile_info,
                                          const int mi_row) {
  AV2_COMMON *const cm = &pbi->common;
  const int num_planes = av2_num_planes(cm);
  TileDataDec *const tile_data =
      pbi->tile_data + tile_info.tile_row * cm->tiles.cols + tile_info.tile_col;
  const int sb_cols_in_tile = av2_get_sb_cols_in_tile(cm, tile_info);
  const int sb_row_in_tile =
      (mi_row - tile_info.mi_row_start) >> cm->mib_size_log2;
  int sb_col_in_tile = 0;

  av2_zero(td->dcb.xd.ref_mv_bank);
  av2_zero(td->dcb.xd.warp_param_bank);

  for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
       mi_col += cm->mib_size, sb_col_in_tile++) {
    av2_reset_is_mi_coded_map(&td->dcb.xd, cm->mib_size);
    td->dcb.xd.sbi = av2_get_sb_info(cm, mi_row, mi_col);
    set_cb_buffer(pbi, &td->dcb, pbi->cb_buffer_base, num_planes, mi_row,
                  mi_col);

    sync_read(&tile_data->dec_row_mt_sync, sb_row_in_tile, sb_col_in_tile);

    DecoderCodingBlock *const dcb = &td->dcb;
    MACROBLOCKD *const xd = &dcb->xd;

    av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);

    // Decoding of the super-block
    decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
                        0x2);

    sync_write(&tile_data->dec_row_mt_sync, sb_row_in_tile, sb_col_in_tile,
               sb_cols_in_tile);
  }
}

static int check_trailing_bits_after_symbol_coder(avm_reader *r) {
  if (avm_reader_has_overflowed(r)) return -1;

  uint32_t nb_bits = avm_reader_tell(r);
  uint32_t nb_bytes = (nb_bits + 7) >> 3;
  const uint8_t *p = avm_reader_find_begin(r) + nb_bytes;

  // avm_reader_tell() returns 1 for a newly initialized decoder, and the
  // return value only increases as values are decoded. So nb_bits > 0, and
  // thus p > p_begin. Therefore accessing p[-1] is safe.
  uint8_t last_byte = p[-1];
  uint8_t pattern = 128 >> ((nb_bits - 1) & 7);
  if ((last_byte & (2 * pattern - 1)) != pattern) return -1;

  // Make sure that all padding bytes are zero as required by the spec.
  const uint8_t *p_end = avm_reader_find_end(r);
  while (p < p_end) {
    if (*p != 0) return -1;
    p++;
  }
  return 0;
}

static AVM_INLINE void set_decode_func_pointers(ThreadData *td,
                                                int parse_decode_flag) {
  td->read_coeffs_tx_intra_block_visit = decode_block_void;
  td->predict_and_recon_intra_block_visit = decode_block_void;
  td->read_coeffs_tx_inter_block_visit = decode_block_void;
  td->inverse_tx_inter_block_visit = decode_block_void;
  td->inverse_cctx_block_visit = decode_block_void;
  td->predict_inter_block_visit = predict_inter_block_void;
  td->copy_frame_mvs_block_visit = predict_inter_block_void;

  if (parse_decode_flag & 0x1) {
    td->read_coeffs_tx_intra_block_visit = read_coeffs_tx_intra_block;
    td->read_coeffs_tx_inter_block_visit = av2_read_coeffs_txb_facade;
  }
  if (parse_decode_flag & 0x2) {
    td->predict_and_recon_intra_block_visit =
        predict_and_reconstruct_intra_block;
    td->inverse_tx_inter_block_visit = inverse_transform_inter_block;
    td->inverse_cctx_block_visit = inverse_cross_chroma_transform_block;
    td->predict_inter_block_visit = predict_inter_block;
    td->copy_frame_mvs_block_visit = copy_frame_mvs_inter_block;
  }
}

static AVM_INLINE void decode_tile(AV2Decoder *pbi, ThreadData *const td,
                                   int tile_row, int tile_col) {
  TileInfo tile_info;

  AV2_COMMON *const cm = &pbi->common;
  const int num_planes = av2_num_planes(cm);

  av2_tile_set_row(&tile_info, cm, tile_row);
  av2_tile_set_col(&tile_info, cm, tile_col);
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;

  av2_zero_above_context(cm, xd, tile_info.mi_col_start, tile_info.mi_col_end,
                         tile_row);

  int num_filter_classes[MAX_MB_PLANE];
  for (int p = 0; p < num_planes; ++p)
    num_filter_classes[p] = cm->rst_info[p].num_filter_classes;
  av2_reset_loop_restoration(xd, 0, num_planes, num_filter_classes);
  if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
      xd->tile.tile_active_mode = 0;
  }

  for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
       mi_row += cm->mib_size) {
    av2_zero_left_context(xd);
    av2_zero(xd->ref_mv_bank);

    av2_zero(xd->warp_param_bank);
#if !WARP_CU_BANK
    xd->warp_param_bank_pt = &td->warp_param_bank;
#endif  //! WARP_CU_BANK

    for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
         mi_col += cm->mib_size) {
      av2_reset_is_mi_coded_map(xd, cm->mib_size);
      BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
      av2_set_sb_info(cm, xd, mi_row, mi_col, sb_active_mode);
      set_cb_buffer(pbi, dcb, &td->cb_buffer_base, num_planes, 0, 0);
      // td->ref_mv_bank is initialized as xd->ref_mv_bank, and used
      // for MV referencing during decoding the tile.
      // xd->ref_mv_bank is updated as decoding goes.
      av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);

      decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
                          0x3);

      if (avm_reader_has_overflowed(td->bit_reader)) {
        avm_merge_corrupted_flag(&dcb->corrupted, 1);
        return;
      }
    }
  }
  int corrupted =
      (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) ? 0
      : (check_trailing_bits_after_symbol_coder(td->bit_reader))             ? 1
                                                                 : 0;
  avm_merge_corrupted_flag(&dcb->corrupted, corrupted);
}

#if CONFIG_THROUGHPUT_ANALYSIS
static void avm_accounting_cal_total(AV2Decoder *pbi) {
  if (pbi->decoding_first_frame) {
    pbi->common.sym_stats.frame_dec_order = 0;
    pbi->common.sym_stats.tot_ctx_syms = 0;
    pbi->common.sym_stats.total_total_hits = 0;
    pbi->common.sym_stats.total_context_switch = 0;
    pbi->common.sym_stats.tot_bypass_syms = 0;
    pbi->common.sym_stats.tot_bits = 0;
    pbi->common.sym_stats.peak_ctx_syms = 0;
    pbi->common.sym_stats.peak_bypass_syms = 0;
    pbi->common.sym_stats.peak_bits = 0;
  }
  Accounting accounting = pbi->accounting;
  int64_t frm_ctx_syms = accounting.syms.num_ctx_coded;
  int64_t frm_bypass_syms = accounting.syms.num_bypass_coded;
  int64_t frm_context_switch = accounting.syms.context_switch;
  int64_t frm_total_hits = accounting.syms.total_hits;
  int64_t frm_bits = 0;
  for (int i = 0; i < accounting.syms.num_syms; i++) {
    AccountingSymbol sym = accounting.syms.syms[i];
    frm_bits += sym.bits;
  }
  int64_t peak_ctx_syms = pbi->common.sym_stats.peak_ctx_syms;
  int64_t peak_bypass_syms = pbi->common.sym_stats.peak_bypass_syms;
  pbi->common.sym_stats.tot_ctx_syms += frm_ctx_syms;
  pbi->common.sym_stats.total_context_switch += frm_context_switch;
  pbi->common.sym_stats.total_total_hits += frm_total_hits;
  pbi->common.sym_stats.tot_bypass_syms += frm_bypass_syms;
  pbi->common.sym_stats.frame_dec_order += 1;
  pbi->common.sym_stats.tot_bits += frm_bits;
  if (frm_ctx_syms * 4 + frm_bypass_syms >
      peak_ctx_syms * 4 + peak_bypass_syms) {
    pbi->common.sym_stats.peak_ctx_syms = frm_ctx_syms;
    pbi->common.sym_stats.peak_bypass_syms = frm_bypass_syms;
    pbi->common.sym_stats.peak_bits = frm_bits;
  }
  tot_ctx_syms = pbi->common.sym_stats.tot_ctx_syms;
  tot_bypass_syms = pbi->common.sym_stats.tot_bypass_syms;
  tot_bits = pbi->common.sym_stats.tot_bits;
  total_context_switch = pbi->common.sym_stats.total_context_switch;
  total_total_hits = pbi->common.sym_stats.total_total_hits;
  max_ctx_syms = pbi->common.sym_stats.peak_ctx_syms;
  max_bypass_syms = pbi->common.sym_stats.peak_bypass_syms;
  max_bits = pbi->common.sym_stats.peak_bits;
  tot_frames = pbi->common.sym_stats.frame_dec_order;
}
#endif  // CONFIG_THROUGHPUT_ANALYSIS

static const uint8_t *decode_tiles(AV2Decoder *pbi, const uint8_t *data,
                                   const uint8_t *data_end, int start_tile,
                                   int end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  ThreadData *const td = &pbi->td;
  CommonTileParams *const tiles = &cm->tiles;
  const int tile_cols = tiles->cols;
  const int tile_rows = tiles->rows;
  const int n_tiles = tile_cols * tile_rows;
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
  int tile_rows_start;
  int tile_rows_end;
  int tile_cols_start;
  int tile_cols_end;
  int inv_col_order;
  int inv_row_order;
  int tile_row, tile_col;
  uint8_t allow_update_cdf;

  tile_rows_start = 0;
  tile_rows_end = tile_rows;
  tile_cols_start = 0;
  tile_cols_end = tile_cols;
  inv_col_order = pbi->inv_tile_order;
  inv_row_order = pbi->inv_tile_order;

  // No tiles to decode.
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
      // First tile is larger than end_tile.
      tile_rows_start * tiles->cols + tile_cols_start > end_tile ||
      // Last tile is smaller than start_tile.
      (tile_rows_end - 1) * tiles->cols + tile_cols_end - 1 < start_tile)
    return data;

  allow_update_cdf = !cm->features.disable_cdf_update;

  assert(tile_rows <= MAX_TILE_ROWS);
  assert(tile_cols <= MAX_TILE_COLS);
  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
    decoder_alloc_tile_data(pbi, n_tiles);
  }
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);
#if CONFIG_ACCOUNTING
  if (pbi->acct_enabled) {
    avm_accounting_reset(&pbi->accounting);
  }
#endif

  set_decode_func_pointers(&pbi->td, 0x3);

  // Load all tile information into thread_data.
  td->dcb = pbi->dcb;

  td->dcb.corrupted = 0;
  td->dcb.mc_buf[0] = td->mc_buf[0];
  td->dcb.mc_buf[1] = td->mc_buf[1];
  td->dcb.xd.tmp_conv_dst = td->tmp_conv_dst;

  // Temporary buffers used during the DMVR and OPFL processing.
  td->dcb.xd.opfl_vxy_bufs = td->opfl_vxy_bufs;
  td->dcb.xd.opfl_gxy_bufs = td->opfl_gxy_bufs;
  td->dcb.xd.opfl_dst_bufs = td->opfl_dst_bufs;

  for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
    const int row = inv_row_order ? tile_rows - 1 - tile_row : tile_row;

    for (tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
      const int col = inv_col_order ? tile_cols - 1 - tile_col : tile_col;
      TileDataDec *const tile_data = pbi->tile_data + row * tiles->cols + col;
      const TileBufferDec *const tile_bs_buf = &tile_buffers[row][col];

      if (row * tiles->cols + col < start_tile ||
          row * tiles->cols + col > end_tile)
        continue;

      td->bit_reader = &tile_data->bit_reader;
      // av2_zero(td->cb_buffer_base.dqcoeff);
      av2_tile_init(&td->dcb.xd.tile, cm, row, col);
      td->dcb.xd.current_base_qindex = cm->quant_params.base_qindex;
      setup_bool_decoder(tile_bs_buf->data, data_end, tile_bs_buf->size,
                         &cm->error, td->bit_reader, allow_update_cdf);
#if CONFIG_ACCOUNTING
      if (pbi->acct_enabled) {
        td->bit_reader->accounting = &pbi->accounting;
        td->bit_reader->accounting->last_tell_frac =
            avm_reader_tell_frac(td->bit_reader);
      } else {
        td->bit_reader->accounting = NULL;
      }
#endif
      av2_init_macroblockd(cm, &td->dcb.xd);
      av2_init_above_context(&cm->above_contexts, av2_num_planes(cm), row,
                             &td->dcb.xd);

      td->dcb.xd.tile.tile_active_mode = 1;
      if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
        td->dcb.xd.tile.tile_active_mode =
            tile_data->tile_info.tile_active_mode;
      }
      // Initialise the tile context from the frame context
      tile_data->tctx = *cm->fc;
      td->dcb.xd.tile_ctx = &tile_data->tctx;

      // decode tile
      decode_tile(pbi, td, row, col);
      avm_merge_corrupted_flag(&pbi->dcb.corrupted, td->dcb.corrupted);
      if (pbi->dcb.corrupted)
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "Failed to decode tile data");
    }
  }

  TileDataDec *const tile_data = pbi->tile_data + end_tile;
#if CONFIG_THROUGHPUT_ANALYSIS
  if (pbi->acct_enabled) {
    avm_accounting_cal_total(pbi);
  }
#endif  // CONFIG_THROUGHPUT_ANALYSIS
  return avm_reader_find_end(&tile_data->bit_reader);
}

static TileJobsDec *get_dec_job_info(AV2DecTileMT *tile_mt_info) {
  TileJobsDec *cur_job_info = NULL;
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(tile_mt_info->job_mutex);

  if (tile_mt_info->jobs_dequeued < tile_mt_info->jobs_enqueued) {
    cur_job_info = tile_mt_info->job_queue + tile_mt_info->jobs_dequeued;
    tile_mt_info->jobs_dequeued++;
  }

  pthread_mutex_unlock(tile_mt_info->job_mutex);
#else
  (void)tile_mt_info;
#endif
  return cur_job_info;
}

static AVM_INLINE void tile_worker_hook_init(
    AV2Decoder *const pbi, DecWorkerData *const thread_data,
    const TileBufferDec *const tile_buffer, TileDataDec *const tile_data,
    uint8_t allow_update_cdf) {
  AV2_COMMON *cm = &pbi->common;
  ThreadData *const td = thread_data->td;
  int tile_row = tile_data->tile_info.tile_row;
  int tile_col = tile_data->tile_info.tile_col;

  td->bit_reader = &tile_data->bit_reader;
  av2_zero(td->cb_buffer_base.dqcoeff);

  MACROBLOCKD *const xd = &td->dcb.xd;
  av2_tile_init(&xd->tile, cm, tile_row, tile_col);
  xd->current_base_qindex = cm->quant_params.base_qindex;
  setup_bool_decoder(tile_buffer->data, thread_data->data_end,
                     tile_buffer->size, &thread_data->error_info,
                     td->bit_reader, allow_update_cdf);
#if CONFIG_ACCOUNTING
  if (pbi->acct_enabled) {
    td->bit_reader->accounting = &pbi->accounting;
    td->bit_reader->accounting->last_tell_frac =
        avm_reader_tell_frac(td->bit_reader);
  } else {
    td->bit_reader->accounting = NULL;
  }
#endif
  av2_init_macroblockd(cm, xd);
  xd->error_info = &thread_data->error_info;
  av2_init_above_context(&cm->above_contexts, av2_num_planes(cm), tile_row, xd);
  td->dcb.xd.tile.tile_active_mode = 1;
  if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
    td->dcb.xd.tile.tile_active_mode = tile_data->tile_info.tile_active_mode;
  }
  // Initialise the tile context from the frame context
  tile_data->tctx = *cm->fc;
  xd->tile_ctx = &tile_data->tctx;
#if CONFIG_ACCOUNTING
  if (pbi->acct_enabled) {
    tile_data->bit_reader.accounting->last_tell_frac =
        avm_reader_tell_frac(&tile_data->bit_reader);
  }
#endif
}

static int tile_worker_hook(void *arg1, void *arg2) {
  DecWorkerData *const thread_data = (DecWorkerData *)arg1;
  AV2Decoder *const pbi = (AV2Decoder *)arg2;
  AV2_COMMON *cm = &pbi->common;
  ThreadData *const td = thread_data->td;
  uint8_t allow_update_cdf;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(thread_data->error_info.jmp)) {
    thread_data->error_info.setjmp = 0;
    thread_data->td->dcb.corrupted = 1;
    return 0;
  }
  thread_data->error_info.setjmp = 1;

  allow_update_cdf = !cm->features.disable_cdf_update;

  set_decode_func_pointers(td, 0x3);

  assert(cm->tiles.cols > 0);
  while (!td->dcb.corrupted) {
    TileJobsDec *cur_job_info = get_dec_job_info(&pbi->tile_mt_info);

    if (cur_job_info != NULL) {
      const TileBufferDec *const tile_buffer = cur_job_info->tile_buffer;
      TileDataDec *const tile_data = cur_job_info->tile_data;
      tile_worker_hook_init(pbi, thread_data, tile_buffer, tile_data,
                            allow_update_cdf);
      // decode tile
      int tile_row = tile_data->tile_info.tile_row;
      int tile_col = tile_data->tile_info.tile_col;
      decode_tile(pbi, td, tile_row, tile_col);
    } else {
      break;
    }
  }
  thread_data->error_info.setjmp = 0;
  return !td->dcb.corrupted;
}

static INLINE int get_max_row_mt_workers_per_tile(AV2_COMMON *cm,
                                                  TileInfo tile) {
  // NOTE: Currently value of max workers is calculated based
  // on the parse and decode time. As per the theoretical estimate
  // when percentage of parse time is equal to percentage of decode
  // time, number of workers needed to parse + decode a tile can not
  // exceed more than 2.
  // TODO(any): Modify this value if parsing is optimized in future.
  int sb_rows = av2_get_sb_rows_in_tile(cm, tile);
  int max_workers =
      sb_rows == 1 ? AVM_MIN_THREADS_PER_TILE : AVM_MAX_THREADS_PER_TILE;
  return max_workers;
}

// The caller must hold pbi->row_mt_mutex_ when calling this function.
// Returns 1 if either the next job is stored in *next_job_info or 1 is stored
// in *end_of_frame.
// NOTE: The caller waits on pbi->row_mt_cond_ if this function returns 0.
// The return value of this function depends on the following variables:
// - frame_row_mt_info->mi_rows_parse_done
// - frame_row_mt_info->mi_rows_decode_started
// - frame_row_mt_info->row_mt_exit
// Therefore we may need to signal or broadcast pbi->row_mt_cond_ if any of
// these variables is modified.
static int get_next_job_info(AV2Decoder *const pbi,
                             AV2DecRowMTJobInfo *next_job_info,
                             int *end_of_frame) {
  AV2_COMMON *cm = &pbi->common;
  TileDataDec *tile_data;
  AV2DecRowMTSync *dec_row_mt_sync;
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
  TileInfo tile_info;
  const int tile_rows_start = frame_row_mt_info->tile_rows_start;
  const int tile_rows_end = frame_row_mt_info->tile_rows_end;
  const int tile_cols_start = frame_row_mt_info->tile_cols_start;
  const int tile_cols_end = frame_row_mt_info->tile_cols_end;
  const int start_tile = frame_row_mt_info->start_tile;
  const int end_tile = frame_row_mt_info->end_tile;
  const int sb_mi_size = mi_size_wide[cm->sb_size];
  int num_mis_to_decode, num_threads_working;
  int num_mis_waiting_for_decode;
  int min_threads_working = INT_MAX;
  int max_mis_to_decode = 0;
  int tile_row_idx, tile_col_idx;
  int tile_row = -1;
  int tile_col = -1;

  memset(next_job_info, 0, sizeof(*next_job_info));

  // Frame decode is completed or error is encountered.
  *end_of_frame = (frame_row_mt_info->mi_rows_decode_started ==
                   frame_row_mt_info->mi_rows_to_decode) ||
                  (frame_row_mt_info->row_mt_exit == 1);
  if (*end_of_frame) {
    return 1;
  }

  // Decoding cannot start as bit-stream parsing is not complete.
  assert(frame_row_mt_info->mi_rows_parse_done >=
         frame_row_mt_info->mi_rows_decode_started);
  if (frame_row_mt_info->mi_rows_parse_done ==
      frame_row_mt_info->mi_rows_decode_started)
    return 0;

  // Choose the tile to decode.
  for (tile_row_idx = tile_rows_start; tile_row_idx < tile_rows_end;
       ++tile_row_idx) {
    for (tile_col_idx = tile_cols_start; tile_col_idx < tile_cols_end;
         ++tile_col_idx) {
      if (tile_row_idx * cm->tiles.cols + tile_col_idx < start_tile ||
          tile_row_idx * cm->tiles.cols + tile_col_idx > end_tile)
        continue;

      tile_data = pbi->tile_data + tile_row_idx * cm->tiles.cols + tile_col_idx;
      dec_row_mt_sync = &tile_data->dec_row_mt_sync;

      num_threads_working = dec_row_mt_sync->num_threads_working;
      num_mis_waiting_for_decode = (dec_row_mt_sync->mi_rows_parse_done -
                                    dec_row_mt_sync->mi_rows_decode_started) *
                                   dec_row_mt_sync->mi_cols;
      num_mis_to_decode =
          (dec_row_mt_sync->mi_rows - dec_row_mt_sync->mi_rows_decode_started) *
          dec_row_mt_sync->mi_cols;

      assert(num_mis_to_decode >= num_mis_waiting_for_decode);

      // Pick the tile which has minimum number of threads working on it.
      if (num_mis_waiting_for_decode > 0) {
        if (num_threads_working < min_threads_working) {
          min_threads_working = num_threads_working;
          max_mis_to_decode = 0;
        }
        if (num_threads_working == min_threads_working &&
            num_mis_to_decode > max_mis_to_decode &&
            num_threads_working <
                get_max_row_mt_workers_per_tile(cm, tile_data->tile_info)) {
          max_mis_to_decode = num_mis_to_decode;
          tile_row = tile_row_idx;
          tile_col = tile_col_idx;
        }
      }
    }
  }
  // No job found to process
  if (tile_row == -1 || tile_col == -1) return 0;

  tile_data = pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
  tile_info = tile_data->tile_info;
  dec_row_mt_sync = &tile_data->dec_row_mt_sync;

  next_job_info->tile_row = tile_row;
  next_job_info->tile_col = tile_col;
  next_job_info->mi_row =
      dec_row_mt_sync->mi_rows_decode_started + tile_info.mi_row_start;

  dec_row_mt_sync->num_threads_working++;
  dec_row_mt_sync->mi_rows_decode_started += sb_mi_size;
  frame_row_mt_info->mi_rows_decode_started += sb_mi_size;
  assert(frame_row_mt_info->mi_rows_parse_done >=
         frame_row_mt_info->mi_rows_decode_started);
#if CONFIG_MULTITHREAD
  if (frame_row_mt_info->mi_rows_decode_started ==
      frame_row_mt_info->mi_rows_to_decode) {
    pthread_cond_broadcast(pbi->row_mt_cond_);
  }
#endif

  return 1;
}

static INLINE void signal_parse_sb_row_done(AV2Decoder *const pbi,
                                            TileDataDec *const tile_data,
                                            const int sb_mi_size) {
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
  assert(frame_row_mt_info->mi_rows_parse_done >=
         frame_row_mt_info->mi_rows_decode_started);
  tile_data->dec_row_mt_sync.mi_rows_parse_done += sb_mi_size;
  frame_row_mt_info->mi_rows_parse_done += sb_mi_size;
#if CONFIG_MULTITHREAD
  // A new decode job is available. Wake up one worker thread to handle the
  // new decode job.
  // NOTE: This assumes we bump mi_rows_parse_done and mi_rows_decode_started
  // by the same increment (sb_mi_size).
  pthread_cond_signal(pbi->row_mt_cond_);
  pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
}

// This function is very similar to decode_tile(). It would be good to figure
// out how to share code.
static AVM_INLINE void parse_tile_row_mt(AV2Decoder *pbi, ThreadData *const td,
                                         TileDataDec *const tile_data) {
  AV2_COMMON *const cm = &pbi->common;
  const int sb_mi_size = mi_size_wide[cm->sb_size];
  const int num_planes = av2_num_planes(cm);
  TileInfo tile_info = tile_data->tile_info;
  int tile_row = tile_info.tile_row;
  DecoderCodingBlock *const dcb = &td->dcb;
  MACROBLOCKD *const xd = &dcb->xd;

  av2_zero_above_context(cm, xd, tile_info.mi_col_start, tile_info.mi_col_end,
                         tile_row);
  int num_filter_classes[MAX_MB_PLANE];
  for (int p = 0; p < num_planes; ++p)
    num_filter_classes[p] = cm->rst_info[p].num_filter_classes;
  av2_reset_loop_restoration(xd, 0, num_planes, num_filter_classes);
  if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
      xd->tile.tile_active_mode = 0;
  }
  for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
       mi_row += cm->mib_size) {
    av2_zero_left_context(xd);
    av2_zero(xd->ref_mv_bank);

    av2_zero(xd->warp_param_bank);
#if !WARP_CU_BANK
    xd->warp_param_bank_pt = &td->warp_param_bank;
#endif  //! WARP_CU_BANK

    for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
         mi_col += cm->mib_size) {
      av2_reset_is_mi_coded_map(xd, cm->mib_size);
      BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
      av2_set_sb_info(cm, xd, mi_row, mi_col, sb_active_mode);
      set_cb_buffer(pbi, dcb, pbi->cb_buffer_base, num_planes, mi_row, mi_col);
      av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);

      // Bit-stream parsing of the superblock
      decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
                          0x1);
      if (avm_reader_has_overflowed(td->bit_reader)) {
        avm_merge_corrupted_flag(&dcb->corrupted, 1);
        return;
      }
    }
    signal_parse_sb_row_done(pbi, tile_data, sb_mi_size);
  }

  int corrupted =
      (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) ? 0
      : (check_trailing_bits_after_symbol_coder(td->bit_reader))             ? 1
                                                                 : 0;
  avm_merge_corrupted_flag(&dcb->corrupted, corrupted);
}

static int row_mt_worker_hook(void *arg1, void *arg2) {
  DecWorkerData *const thread_data = (DecWorkerData *)arg1;
  AV2Decoder *const pbi = (AV2Decoder *)arg2;
  AV2_COMMON *cm = &pbi->common;
  ThreadData *const td = thread_data->td;
  uint8_t allow_update_cdf;
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
  td->dcb.corrupted = 0;

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(thread_data->error_info.jmp)) {
    thread_data->error_info.setjmp = 0;
    thread_data->td->dcb.corrupted = 1;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
    frame_row_mt_info->row_mt_exit = 1;
#if CONFIG_MULTITHREAD
    pthread_cond_broadcast(pbi->row_mt_cond_);
    pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
    return 0;
  }
  thread_data->error_info.setjmp = 1;

  allow_update_cdf = !cm->features.disable_cdf_update;

  set_decode_func_pointers(td, 0x1);

  assert(cm->tiles.cols > 0);
  while (!td->dcb.corrupted) {
    TileJobsDec *cur_job_info = get_dec_job_info(&pbi->tile_mt_info);

    if (cur_job_info != NULL) {
      const TileBufferDec *const tile_buffer = cur_job_info->tile_buffer;
      TileDataDec *const tile_data = cur_job_info->tile_data;
      tile_worker_hook_init(pbi, thread_data, tile_buffer, tile_data,
                            allow_update_cdf);
#if CONFIG_MULTITHREAD
      pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
      tile_data->dec_row_mt_sync.num_threads_working++;
#if CONFIG_MULTITHREAD
      pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
      // decode tile
      parse_tile_row_mt(pbi, td, tile_data);
#if CONFIG_MULTITHREAD
      pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
      tile_data->dec_row_mt_sync.num_threads_working--;
#if CONFIG_MULTITHREAD
      pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
    } else {
      break;
    }
  }

  if (td->dcb.corrupted) {
    thread_data->error_info.setjmp = 0;
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
    frame_row_mt_info->row_mt_exit = 1;
#if CONFIG_MULTITHREAD
    pthread_cond_broadcast(pbi->row_mt_cond_);
    pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
    return 0;
  }

  set_decode_func_pointers(td, 0x2);

  while (1) {
    AV2DecRowMTJobInfo next_job_info;
    int end_of_frame = 0;

#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
    while (!get_next_job_info(pbi, &next_job_info, &end_of_frame)) {
#if CONFIG_MULTITHREAD
      pthread_cond_wait(pbi->row_mt_cond_, pbi->row_mt_mutex_);
#endif
    }
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif

    if (end_of_frame) break;

    int tile_row = next_job_info.tile_row;
    int tile_col = next_job_info.tile_col;
    int mi_row = next_job_info.mi_row;

    TileDataDec *tile_data =
        pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
    AV2DecRowMTSync *dec_row_mt_sync = &tile_data->dec_row_mt_sync;
    TileInfo tile_info = tile_data->tile_info;

    av2_tile_init(&td->dcb.xd.tile, cm, tile_row, tile_col);
    av2_init_macroblockd(cm, &td->dcb.xd);
    td->dcb.xd.error_info = &thread_data->error_info;

    td->dcb.xd.tile.tile_active_mode = 1;
    if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
      td->dcb.xd.tile.tile_active_mode = tile_data->tile_info.tile_active_mode;
    }
    decode_tile_sb_row(pbi, td, tile_info, mi_row);

#if CONFIG_MULTITHREAD
    pthread_mutex_lock(pbi->row_mt_mutex_);
#endif
    dec_row_mt_sync->num_threads_working--;
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(pbi->row_mt_mutex_);
#endif
  }
  thread_data->error_info.setjmp = 0;
  return !td->dcb.corrupted;
}

// sorts in descending order
static int compare_tile_buffers(const void *a, const void *b) {
  const TileJobsDec *const buf1 = (const TileJobsDec *)a;
  const TileJobsDec *const buf2 = (const TileJobsDec *)b;
  return (((int)buf2->tile_buffer->size) - ((int)buf1->tile_buffer->size));
}

static AVM_INLINE void enqueue_tile_jobs(AV2Decoder *pbi, AV2_COMMON *cm,
                                         int tile_rows_start, int tile_rows_end,
                                         int tile_cols_start, int tile_cols_end,
                                         int start_tile, int end_tile) {
  AV2DecTileMT *tile_mt_info = &pbi->tile_mt_info;
  TileJobsDec *tile_job_queue = tile_mt_info->job_queue;
  tile_mt_info->jobs_enqueued = 0;
  tile_mt_info->jobs_dequeued = 0;

  for (int row = tile_rows_start; row < tile_rows_end; row++) {
    for (int col = tile_cols_start; col < tile_cols_end; col++) {
      if (row * cm->tiles.cols + col < start_tile ||
          row * cm->tiles.cols + col > end_tile)
        continue;
      tile_job_queue->tile_buffer = &pbi->tile_buffers[row][col];
      tile_job_queue->tile_data = pbi->tile_data + row * cm->tiles.cols + col;
      tile_job_queue++;
      tile_mt_info->jobs_enqueued++;
    }
  }
}

static AVM_INLINE void alloc_dec_jobs(AV2DecTileMT *tile_mt_info,
                                      AV2_COMMON *cm, int tile_rows,
                                      int tile_cols) {
  tile_mt_info->alloc_tile_rows = tile_rows;
  tile_mt_info->alloc_tile_cols = tile_cols;
  int num_tiles = tile_rows * tile_cols;
#if CONFIG_MULTITHREAD
  {
    CHECK_MEM_ERROR(cm, tile_mt_info->job_mutex,
                    avm_malloc(sizeof(*tile_mt_info->job_mutex) * num_tiles));

    for (int i = 0; i < num_tiles; i++) {
      pthread_mutex_init(&tile_mt_info->job_mutex[i], NULL);
    }
  }
#endif
  CHECK_MEM_ERROR(cm, tile_mt_info->job_queue,
                  avm_malloc(sizeof(*tile_mt_info->job_queue) * num_tiles));
}

void av2_free_mc_tmp_buf(ThreadData *thread_data) {
  int ref;
  for (ref = 0; ref < 2; ref++) {
    avm_free(thread_data->mc_buf[ref]);
    thread_data->mc_buf[ref] = NULL;
  }
  thread_data->mc_buf_size = 0;

  avm_free(thread_data->tmp_conv_dst);
  thread_data->tmp_conv_dst = NULL;
}

// Free-up the temporary buffers created for DMVR and OPFL processing.
void av2_free_opfl_tmp_bufs(ThreadData *thread_data) {
  avm_free(thread_data->opfl_vxy_bufs);
  thread_data->opfl_vxy_bufs = NULL;

  avm_free(thread_data->opfl_gxy_bufs);
  thread_data->opfl_gxy_bufs = NULL;

  avm_free(thread_data->opfl_dst_bufs);
  thread_data->opfl_dst_bufs = NULL;
}

// Allocate memory for temporary buffers used during the DMVR and OPFL
// processing.
static AVM_INLINE void allocate_opfl_tmp_bufs(AV2_COMMON *const cm,
                                              ThreadData *thread_data) {
  CHECK_MEM_ERROR(
      cm, thread_data->opfl_vxy_bufs,
      avm_memalign(32, N_OF_OFFSETS * 4 * sizeof(*thread_data->opfl_vxy_bufs)));

  CHECK_MEM_ERROR(cm, thread_data->opfl_gxy_bufs,
                  avm_memalign(32, MAX_SB_SQUARE * 4 *
                                       sizeof(*thread_data->opfl_gxy_bufs)));

  CHECK_MEM_ERROR(cm, thread_data->opfl_dst_bufs,
                  avm_memalign(32, MAX_SB_SQUARE * 2 *
                                       sizeof(*thread_data->opfl_dst_bufs)));
}

static AVM_INLINE void allocate_mc_tmp_buf(AV2_COMMON *const cm,
                                           ThreadData *thread_data,
                                           int buf_size) {
  for (int ref = 0; ref < 2; ref++) {
    // The mc_buf/hbd_mc_buf must be zeroed to fix a intermittent valgrind error
    // 'Conditional jump or move depends on uninitialised value' from the loop
    // filter. Uninitialized reads in convolve function (e.g. horiz_4tap path in
    // av2_convolve_2d_sr_avx2()) from mc_buf/hbd_mc_buf are seen to be the
    // potential reason for this issue.
    uint16_t *hbd_mc_buf;
    CHECK_MEM_ERROR(cm, hbd_mc_buf, (uint16_t *)avm_memalign(16, buf_size));
    memset(hbd_mc_buf, 0, buf_size);
    thread_data->mc_buf[ref] = hbd_mc_buf;
  }
  thread_data->mc_buf_size = buf_size;

  CHECK_MEM_ERROR(cm, thread_data->tmp_conv_dst,
                  avm_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
                                       sizeof(*thread_data->tmp_conv_dst)));
}

static AVM_INLINE void reset_dec_workers(AV2Decoder *pbi,
                                         AVxWorkerHook worker_hook,
                                         int num_workers) {
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();

  // Reset tile decoding hook
  for (int worker_idx = 0; worker_idx < num_workers; ++worker_idx) {
    AVxWorker *const worker = &pbi->tile_workers[worker_idx];
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
    thread_data->td->dcb = pbi->dcb;
    thread_data->td->dcb.corrupted = 0;
    thread_data->td->dcb.mc_buf[0] = thread_data->td->mc_buf[0];
    thread_data->td->dcb.mc_buf[1] = thread_data->td->mc_buf[1];
    thread_data->td->dcb.xd.tmp_conv_dst = thread_data->td->tmp_conv_dst;
    // Temporary buffers used during the DMVR and OPFL processing.
    thread_data->td->dcb.xd.opfl_vxy_bufs = thread_data->td->opfl_vxy_bufs;
    thread_data->td->dcb.xd.opfl_gxy_bufs = thread_data->td->opfl_gxy_bufs;
    thread_data->td->dcb.xd.opfl_dst_bufs = thread_data->td->opfl_dst_bufs;

    winterface->sync(worker);

    worker->hook = worker_hook;
    worker->data1 = thread_data;
    worker->data2 = pbi;
  }
#if CONFIG_ACCOUNTING
  if (pbi->acct_enabled) {
#if CONFIG_THROUGHPUT_ANALYSIS
    avm_accounting_cal_total(pbi);
#else
    avm_accounting_dump(&pbi->accounting);
#endif  // CONFIG_THROUGHPUT_ANALYSIS
    avm_accounting_reset(&pbi->accounting);
  }
#endif
}

static AVM_INLINE void launch_dec_workers(AV2Decoder *pbi,
                                          const uint8_t *data_end,
                                          int num_workers) {
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();

  for (int worker_idx = 0; worker_idx < num_workers; ++worker_idx) {
    AVxWorker *const worker = &pbi->tile_workers[worker_idx];
    DecWorkerData *const thread_data = (DecWorkerData *)worker->data1;

    thread_data->data_end = data_end;

    worker->had_error = 0;
    if (worker_idx == num_workers - 1) {
      winterface->execute(worker);
    } else {
      winterface->launch(worker);
    }
  }
}

static AVM_INLINE void sync_dec_workers(AV2Decoder *pbi, int num_workers) {
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
  int corrupted = 0;

  for (int worker_idx = num_workers; worker_idx > 0; --worker_idx) {
    AVxWorker *const worker = &pbi->tile_workers[worker_idx - 1];
    avm_merge_corrupted_flag(&corrupted, !winterface->sync(worker));
  }

  pbi->dcb.corrupted = corrupted;
}

static AVM_INLINE void decode_mt_init(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
  int worker_idx;

  // Create workers and thread_data
  if (pbi->num_workers == 0) {
    const int num_threads = pbi->max_threads;
    CHECK_MEM_ERROR(cm, pbi->tile_workers,
                    avm_malloc(num_threads * sizeof(*pbi->tile_workers)));
    CHECK_MEM_ERROR(cm, pbi->thread_data,
                    avm_malloc(num_threads * sizeof(*pbi->thread_data)));

    for (worker_idx = 0; worker_idx < num_threads; ++worker_idx) {
      AVxWorker *const worker = &pbi->tile_workers[worker_idx];
      DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
      ++pbi->num_workers;

      winterface->init(worker);
      worker->thread_name = "avm tile worker";
      if (worker_idx < num_threads - 1 && !winterface->reset(worker)) {
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                           "Tile decoder thread creation failed");
      }

      if (worker_idx < num_threads - 1) {
        // Allocate thread data.
        CHECK_MEM_ERROR(cm, thread_data->td,
                        avm_memalign(32, sizeof(*thread_data->td)));
        av2_zero(*thread_data->td);
      } else {
        // Main thread acts as a worker and uses the thread data in pbi
        thread_data->td = &pbi->td;
      }
      thread_data->error_info.error_code = AVM_CODEC_OK;
      thread_data->error_info.setjmp = 0;
    }
  }
  const int buf_size = MC_TEMP_BUF_PELS << 1;
  for (worker_idx = 0; worker_idx < pbi->max_threads - 1; ++worker_idx) {
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
    if (thread_data->td->mc_buf_size != buf_size) {
      av2_free_mc_tmp_buf(thread_data->td);
      av2_free_opfl_tmp_bufs(thread_data->td);

      allocate_mc_tmp_buf(cm, thread_data->td, buf_size);
      allocate_opfl_tmp_bufs(cm, thread_data->td);
    }
  }
}

static AVM_INLINE void tile_mt_queue(AV2Decoder *pbi, int tile_cols,
                                     int tile_rows, int tile_rows_start,
                                     int tile_rows_end, int tile_cols_start,
                                     int tile_cols_end, int start_tile,
                                     int end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  if (pbi->tile_mt_info.alloc_tile_cols != tile_cols ||
      pbi->tile_mt_info.alloc_tile_rows != tile_rows) {
    av2_dealloc_dec_jobs(&pbi->tile_mt_info);
    alloc_dec_jobs(&pbi->tile_mt_info, cm, tile_rows, tile_cols);
  }
  enqueue_tile_jobs(pbi, cm, tile_rows_start, tile_rows_end, tile_cols_start,
                    tile_cols_end, start_tile, end_tile);
  qsort(pbi->tile_mt_info.job_queue, pbi->tile_mt_info.jobs_enqueued,
        sizeof(pbi->tile_mt_info.job_queue[0]), compare_tile_buffers);
}

static const uint8_t *decode_tiles_mt(AV2Decoder *pbi, const uint8_t *data,
                                      const uint8_t *data_end, int start_tile,
                                      int end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  CommonTileParams *const tiles = &cm->tiles;
  const int tile_cols = tiles->cols;
  const int tile_rows = tiles->rows;
  const int n_tiles = tile_cols * tile_rows;
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
  int tile_rows_start;
  int tile_rows_end;
  int tile_cols_start;
  int tile_cols_end;
  int tile_count_tg;
  int num_workers;

  tile_rows_start = 0;
  tile_rows_end = tile_rows;
  tile_cols_start = 0;
  tile_cols_end = tile_cols;

  tile_count_tg = end_tile - start_tile + 1;
  num_workers = AVMMIN(pbi->max_threads, tile_count_tg);

  // No tiles to decode.
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
      // First tile is larger than end_tile.
      tile_rows_start * tile_cols + tile_cols_start > end_tile ||
      // Last tile is smaller than start_tile.
      (tile_rows_end - 1) * tile_cols + tile_cols_end - 1 < start_tile)
    return data;

  assert(tile_rows <= MAX_TILE_ROWS);
  assert(tile_cols <= MAX_TILE_COLS);
  assert(tile_count_tg > 0);
  assert(num_workers > 0);
  assert(start_tile <= end_tile);
  assert(start_tile >= 0 && end_tile < n_tiles);

  decode_mt_init(pbi);
  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
    decoder_alloc_tile_data(pbi, n_tiles);
  }
  // get tile size in tile group
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);

  for (int row = 0; row < tile_rows; row++) {
    for (int col = 0; col < tile_cols; col++) {
      TileDataDec *tile_data = pbi->tile_data + row * tiles->cols + col;
      av2_tile_init(&tile_data->tile_info, cm, row, col);
    }
  }

  tile_mt_queue(pbi, tile_cols, tile_rows, tile_rows_start, tile_rows_end,
                tile_cols_start, tile_cols_end, start_tile, end_tile);

  reset_dec_workers(pbi, tile_worker_hook, num_workers);
  launch_dec_workers(pbi, data_end, num_workers);
  sync_dec_workers(pbi, num_workers);

  if (pbi->dcb.corrupted)
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Failed to decode tile data");

  TileDataDec *const tile_data = pbi->tile_data + end_tile;

  return avm_reader_find_end(&tile_data->bit_reader);
}

static AVM_INLINE void dec_alloc_cb_buf(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  int size = ((cm->mi_params.mi_rows >> cm->mib_size_log2) + 1) *
             ((cm->mi_params.mi_cols >> cm->mib_size_log2) + 1);

  if (pbi->cb_buffer_alloc_size < size) {
    av2_dec_free_cb_buf(pbi);
    CHECK_MEM_ERROR(cm, pbi->cb_buffer_base,
                    avm_memalign(32, sizeof(*pbi->cb_buffer_base) * size));
    memset(pbi->cb_buffer_base, 0, sizeof(*pbi->cb_buffer_base) * size);
    pbi->cb_buffer_alloc_size = size;
  }
}

static AVM_INLINE void row_mt_frame_init(AV2Decoder *pbi, int tile_rows_start,
                                         int tile_rows_end, int tile_cols_start,
                                         int tile_cols_end, int start_tile,
                                         int end_tile, int max_sb_rows) {
  AV2_COMMON *const cm = &pbi->common;
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;

  frame_row_mt_info->tile_rows_start = tile_rows_start;
  frame_row_mt_info->tile_rows_end = tile_rows_end;
  frame_row_mt_info->tile_cols_start = tile_cols_start;
  frame_row_mt_info->tile_cols_end = tile_cols_end;
  frame_row_mt_info->start_tile = start_tile;
  frame_row_mt_info->end_tile = end_tile;
  frame_row_mt_info->mi_rows_to_decode = 0;
  frame_row_mt_info->mi_rows_parse_done = 0;
  frame_row_mt_info->mi_rows_decode_started = 0;
  frame_row_mt_info->row_mt_exit = 0;

  for (int tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
    for (int tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
      if (tile_row * cm->tiles.cols + tile_col < start_tile ||
          tile_row * cm->tiles.cols + tile_col > end_tile)
        continue;

      TileDataDec *const tile_data =
          pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
      TileInfo tile_info = tile_data->tile_info;

      tile_data->dec_row_mt_sync.mi_rows_parse_done = 0;
      tile_data->dec_row_mt_sync.mi_rows_decode_started = 0;
      tile_data->dec_row_mt_sync.num_threads_working = 0;
      tile_data->dec_row_mt_sync.mi_rows = ALIGN_POWER_OF_TWO(
          tile_info.mi_row_end - tile_info.mi_row_start, cm->mib_size_log2);
      tile_data->dec_row_mt_sync.mi_cols = ALIGN_POWER_OF_TWO(
          tile_info.mi_col_end - tile_info.mi_col_start, cm->mib_size_log2);

      frame_row_mt_info->mi_rows_to_decode +=
          tile_data->dec_row_mt_sync.mi_rows;

      // Initialize cur_sb_col to -1 for all SB rows.
      memset(tile_data->dec_row_mt_sync.cur_sb_col, -1,
             sizeof(*tile_data->dec_row_mt_sync.cur_sb_col) * max_sb_rows);
    }
  }

#if CONFIG_MULTITHREAD
  if (pbi->row_mt_mutex_ == NULL) {
    CHECK_MEM_ERROR(cm, pbi->row_mt_mutex_,
                    avm_malloc(sizeof(*(pbi->row_mt_mutex_))));
    if (pbi->row_mt_mutex_) {
      pthread_mutex_init(pbi->row_mt_mutex_, NULL);
    }
  }

  if (pbi->row_mt_cond_ == NULL) {
    CHECK_MEM_ERROR(cm, pbi->row_mt_cond_,
                    avm_malloc(sizeof(*(pbi->row_mt_cond_))));
    if (pbi->row_mt_cond_) {
      pthread_cond_init(pbi->row_mt_cond_, NULL);
    }
  }
#endif
}

static const uint8_t *decode_tiles_row_mt(AV2Decoder *pbi, const uint8_t *data,
                                          const uint8_t *data_end,
                                          int start_tile, int end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  CommonTileParams *const tiles = &cm->tiles;
  const int tile_cols = tiles->cols;
  const int tile_rows = tiles->rows;
  const int n_tiles = tile_cols * tile_rows;
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
  int tile_rows_start;
  int tile_rows_end;
  int tile_cols_start;
  int tile_cols_end;
  int tile_count_tg;
  int num_workers = 0;
  int max_threads;
  int max_sb_rows = 0;

  tile_rows_start = 0;
  tile_rows_end = tile_rows;
  tile_cols_start = 0;
  tile_cols_end = tile_cols;

  tile_count_tg = end_tile - start_tile + 1;
  max_threads = pbi->max_threads;

  // No tiles to decode.
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
      // First tile is larger than end_tile.
      tile_rows_start * tile_cols + tile_cols_start > end_tile ||
      // Last tile is smaller than start_tile.
      (tile_rows_end - 1) * tile_cols + tile_cols_end - 1 < start_tile)
    return data;

  assert(tile_rows <= MAX_TILE_ROWS);
  assert(tile_cols <= MAX_TILE_COLS);
  assert(tile_count_tg > 0);
  assert(max_threads > 0);
  assert(start_tile <= end_tile);
  assert(start_tile >= 0 && end_tile < n_tiles);

  (void)tile_count_tg;

  decode_mt_init(pbi);

  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
    if (pbi->tile_data != NULL) {
      for (int i = 0; i < pbi->allocated_tiles; i++) {
        TileDataDec *const tile_data = pbi->tile_data + i;
        av2_dec_row_mt_dealloc(&tile_data->dec_row_mt_sync);
      }
    }
    decoder_alloc_tile_data(pbi, n_tiles);
  }

  // get tile size in tile group
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);

  for (int row = 0; row < tile_rows; row++) {
    for (int col = 0; col < tile_cols; col++) {
      TileDataDec *tile_data = pbi->tile_data + row * tiles->cols + col;
      av2_tile_init(&tile_data->tile_info, cm, row, col);

      max_sb_rows = AVMMAX(max_sb_rows,
                           av2_get_sb_rows_in_tile(cm, tile_data->tile_info));
      num_workers += get_max_row_mt_workers_per_tile(cm, tile_data->tile_info);
    }
  }
  num_workers = AVMMIN(num_workers, max_threads);

  if (pbi->allocated_row_mt_sync_rows != max_sb_rows) {
    for (int i = 0; i < n_tiles; ++i) {
      TileDataDec *const tile_data = pbi->tile_data + i;
      av2_dec_row_mt_dealloc(&tile_data->dec_row_mt_sync);
      dec_row_mt_alloc(&tile_data->dec_row_mt_sync, cm, max_sb_rows);
    }
    pbi->allocated_row_mt_sync_rows = max_sb_rows;
  }

  tile_mt_queue(pbi, tile_cols, tile_rows, tile_rows_start, tile_rows_end,
                tile_cols_start, tile_cols_end, start_tile, end_tile);

  dec_alloc_cb_buf(pbi);

  row_mt_frame_init(pbi, tile_rows_start, tile_rows_end, tile_cols_start,
                    tile_cols_end, start_tile, end_tile, max_sb_rows);

  reset_dec_workers(pbi, row_mt_worker_hook, num_workers);
  launch_dec_workers(pbi, data_end, num_workers);
  sync_dec_workers(pbi, num_workers);

  if (pbi->dcb.corrupted)
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Failed to decode tile data");

  TileDataDec *const tile_data = pbi->tile_data + end_tile;

  return avm_reader_find_end(&tile_data->bit_reader);
}

static AVM_INLINE void error_handler(void *data, avm_codec_err_t error,
                                     const char *detail) {
  AV2_COMMON *const cm = (AV2_COMMON *)data;
  avm_internal_error(&cm->error, error, detail);
}

// Gets the bitdepth_lut_idx field in color_config() and returns bit_depth from
// the bitdepth list.
int av2_get_bitdepth_from_index(uint32_t bitdepth_lut_idx) {
  static avm_bit_depth_t bitdepth_list[] = { AVM_BITS_10, AVM_BITS_8,
                                             AVM_BITS_12 };
  if (bitdepth_lut_idx >= AVM_NUM_SUPPORTED_BITDEPTH) return -1;
  return bitdepth_list[bitdepth_lut_idx];
}
// Reads the bitdepth in color_config() and sets seq_params->bit_depth
// Reports errors by calling rb->error_handler() or
// avm_internal_error().
static AVM_INLINE void read_bitdepth(
    struct avm_read_bit_buffer *rb, SequenceHeader *seq_params,
    struct avm_internal_error_info *error_info) {
  const uint32_t bitdepth_lut_idx = avm_rb_read_uvlc(rb);
  const int bitdepth = av2_get_bitdepth_from_index(bitdepth_lut_idx);
  if (bitdepth >= 0)
    seq_params->bit_depth = bitdepth;
  else {
    avm_internal_error(error_info, AVM_CODEC_UNSUP_BITSTREAM,
                       "Unsupported profile/bit-depth combination");
  }
}
static void setup_film_grain(AV2Decoder *pbi, struct avm_read_bit_buffer *rb) {
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  memset(&cm->film_grain_params, 0, sizeof(cm->film_grain_params));
  // NOTE: immediate_output_picture is 1 when cm->show_existing_frame
  if (seq_params->film_grain_params_present &&
      (cm->immediate_output_picture || cm->implicit_output_picture)) {
    avm_film_grain_t *pars = &cm->film_grain_params;
    if (cm->seq_params.single_picture_header_flag) {
      pars->apply_grain = 1;
    } else {
      pars->apply_grain = avm_rb_read_bit(rb);
    }
    if (pars->apply_grain) {
      cm->fgm_id = avm_rb_read_literal(rb, FGM_ID_BITS);
      pars->random_seed = avm_rb_read_literal(rb, 16);
      pars->update_parameters = 1;
      if (pbi->fgm_list[cm->fgm_id].fgm_id < 0) {
        avm_internal_error(&cm->error, AVM_CODEC_INVALID_PARAM,
                           "fgm_list[%d] is unavailable", cm->fgm_id);
      }
      if (!seq_params->mlayer_dependency_map
               [cm->mlayer_id][pbi->fgm_list[cm->fgm_id].fgm_mlayer_id] ||
          !seq_params->tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
                                            [pbi->fgm_list[cm->fgm_id]
                                                 .fgm_tlayer_id]) {
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                           "mlayer_id(%d) or tlayer_id(%d) of the film grain "
                           "model is out of the limit",
                           pbi->fgm_list[cm->fgm_id].fgm_mlayer_id,
                           pbi->fgm_list[cm->fgm_id].fgm_tlayer_id);
      }
      uint32_t seq_chroma_format_idc = CHROMA_FORMAT_420;
      avm_codec_err_t err = av2_get_chroma_format_idc(
          seq_params->subsampling_x, seq_params->subsampling_y,
          seq_params->monochrome, &seq_chroma_format_idc);
      if (err != AVM_CODEC_OK) {
        avm_internal_error(
            &cm->error, err,
            "Unsupported subsampling_x = %d, subsampling_y = %d.",
            seq_params->subsampling_x, seq_params->subsampling_y);
      }
      if (seq_chroma_format_idc !=
          (uint32_t)pbi->fgm_list[cm->fgm_id].fgm_chroma_idc) {
        avm_internal_error(
            &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
            "chroma_format_idc(%d) of fgm_list[%d] is different from "
            "chroma_format_idc(%d) in the sequence header",
            pbi->fgm_list[cm->fgm_id].fgm_chroma_idc, cm->fgm_id,
            seq_chroma_format_idc);
      }
      copy_fgm_from_list(cm, pars, &pbi->fgm_list[cm->fgm_id]);
    }
  }
  cm->cur_frame->film_grain_params = cm->film_grain_params;
}

// Given chroma_format_idc, set the subsampling_x/y values in `seq_params`.
// Calls `avm_internal_error` in case of invalid chroma_format_idc.
static void set_seq_chroma_format(uint32_t seq_chroma_format_idc,
                                  SequenceHeader *seq_params,
                                  struct avm_internal_error_info *error_info) {
  avm_codec_err_t err = av2_get_chroma_subsampling(seq_chroma_format_idc,
                                                   &seq_params->subsampling_x,
                                                   &seq_params->subsampling_y);
  if (err != AVM_CODEC_OK) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Only 4:0:0, 4:4:4, 4:2:2 and 4:2:0 are currently supported. "
        "Invalid chroma_format_idc value: %d.\n",
        seq_chroma_format_idc);
  }
}

void av2_read_chroma_format_bitdepth(
    struct avm_read_bit_buffer *rb, SequenceHeader *seq_params,
    struct avm_internal_error_info *error_info) {
  const uint32_t seq_chroma_format_idc = avm_rb_read_uvlc(rb);
  set_seq_chroma_format(seq_chroma_format_idc, seq_params, error_info);

  read_bitdepth(rb, seq_params, error_info);

  const int is_monochrome = (seq_chroma_format_idc == CHROMA_FORMAT_400);
  seq_params->monochrome = is_monochrome;
}

void av2_read_timing_info_header(avm_timing_info_t *timing_info,
                                 struct avm_internal_error_info *error,
                                 struct avm_read_bit_buffer *rb) {
  timing_info->num_units_in_display_tick =
      avm_rb_read_unsigned_literal(rb,
                                   32);  // Number of units in a display tick
  timing_info->time_scale = avm_rb_read_unsigned_literal(rb, 32);  // Time scale
  if (timing_info->num_units_in_display_tick == 0 ||
      timing_info->time_scale == 0) {
    avm_internal_error(
        error, AVM_CODEC_UNSUP_BITSTREAM,
        "num_units_in_display_tick and time_scale must be greater than 0.");
  }
  timing_info->equal_elemental_interval =
      avm_rb_read_bit(rb);  // Equal picture interval bit
  if (timing_info->equal_elemental_interval) {
    const uint32_t num_ticks_per_picture_minus_1 = avm_rb_read_uvlc(rb);
    if (num_ticks_per_picture_minus_1 == UINT32_MAX) {
      avm_internal_error(
          error, AVM_CODEC_UNSUP_BITSTREAM,
          "num_ticks_per_picture_minus_1 cannot be (1 << 32) − 1.");
    }
    timing_info->num_ticks_per_elemental_duration =
        num_ticks_per_picture_minus_1 + 1;
  }
}

// This function reads the parameters for the conformance window
void av2_read_conformance_window(struct avm_read_bit_buffer *rb,
                                 struct SequenceHeader *seq_params) {
  struct CropWindow *conf = &seq_params->conf;
  conf->conf_win_enabled_flag = avm_rb_read_bit(rb);

  if (conf->conf_win_enabled_flag) {
    conf->conf_win_left_offset = avm_rb_read_uvlc(rb);
    conf->conf_win_right_offset = avm_rb_read_uvlc(rb);
    conf->conf_win_top_offset = avm_rb_read_uvlc(rb);
    conf->conf_win_bottom_offset = avm_rb_read_uvlc(rb);
  } else {
    conf->conf_win_left_offset = 0;
    conf->conf_win_right_offset = 0;
    conf->conf_win_top_offset = 0;
    conf->conf_win_bottom_offset = 0;
  }
}

void read_tile_syntax_info(TileInfoSyntax *tile_params,
                           struct avm_read_bit_buffer *rb) {
  tile_params->allow_tile_info_change = avm_rb_read_bit(rb);
  CommonTileParams *tile_info = &tile_params->tile_info;
  tile_info->uniform_spacing = avm_rb_read_bit(rb);

  // Read tile columns
  if (tile_info->uniform_spacing) {
    tile_info->log2_cols = tile_info->min_log2_cols;
    while (tile_info->log2_cols < tile_info->max_log2_cols) {
      if (!avm_rb_read_bit(rb)) {
        break;
      }
      tile_info->log2_cols++;
    }
  } else {
    int i;
    int start_sb;
    int width_sb = tile_info->sb_cols;
    for (i = 0, start_sb = 0; width_sb > 0 && i < MAX_TILE_COLS; i++) {
      const int size_sb =
          1 + rb_read_uniform(rb, AVMMIN(width_sb, tile_info->max_width_sb));
      tile_info->col_start_sb[i] = start_sb;
      start_sb += size_sb;
      width_sb -= size_sb;
    }
    tile_info->cols = i;
    tile_info->col_start_sb[i] = start_sb + width_sb;
    assert(width_sb == 0);
  }
  tile_info->min_log2_rows =
      AVMMAX(tile_info->min_log2 - tile_info->log2_cols, 0);
  av2_calculate_tile_cols(tile_info);

  // Read tile rows
  if (tile_info->uniform_spacing) {
    tile_info->log2_rows = tile_info->min_log2_rows;
    while (tile_info->log2_rows < tile_info->max_log2_rows) {
      if (!avm_rb_read_bit(rb)) {
        break;
      }
      tile_info->log2_rows++;
    }
  } else {
    int i;
    int start_sb;
    int height_sb = tile_info->sb_rows;
    for (i = 0, start_sb = 0; height_sb > 0 && i < MAX_TILE_ROWS; i++) {
      const int size_sb =
          1 + rb_read_uniform(rb, AVMMIN(height_sb, tile_info->max_height_sb));
      tile_info->row_start_sb[i] = start_sb;
      start_sb += size_sb;
      height_sb -= size_sb;
    }
    tile_info->rows = i;
    tile_info->row_start_sb[i] = start_sb + height_sb;
    assert(height_sb == 0);
  }
  av2_calculate_tile_rows(tile_info);
}

void read_sequence_tile_info(struct SequenceHeader *seq_params,
                             struct avm_read_bit_buffer *rb) {
  av2_get_seq_tile_limits(&seq_params->tile_params,
                          seq_params->max_frame_height,
                          seq_params->max_frame_width,
                          seq_params->mib_size_log2, seq_params->mib_size_log2,
                          seq_params->seq_max_level_idx, seq_params->seq_tier);
  read_tile_syntax_info(&seq_params->tile_params, rb);
}

static void read_sequence_tile_config(struct SequenceHeader *seq_params,
                                      struct avm_read_bit_buffer *rb) {
  seq_params->seq_tile_info_present_flag = avm_rb_read_bit(rb);
  if (seq_params->seq_tile_info_present_flag) {
    read_sequence_tile_info(seq_params, rb);
  }
}

static void read_seg_syntax_info(struct SegmentationInfoSyntax *seg_params,
                                 struct avm_read_bit_buffer *rb) {
  seg_params->allow_seg_info_change = avm_rb_read_bit(rb);

  const int max_seg_num =
      seg_params->enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;

  memset(seg_params->feature_mask, 0, sizeof(seg_params->feature_mask));
  memset(seg_params->feature_data, 0, sizeof(seg_params->feature_data));

  // Read segmentation feature data
  for (int i = 0; i < max_seg_num; i++) {
    for (int j = 0; j < SEG_LVL_MAX; j++) {
      const int feature_enabled = avm_rb_read_bit(rb);
      if (feature_enabled) {
        seg_params->feature_mask[i] |= (1 << j);

        const int data_max = av2_seg_feature_data_max(j);
        const int data_min = -data_max;
        const int ubits = get_unsigned_bits(data_max);
        int data = 0;

        if (av2_is_segfeature_signed(j)) {
          data = avm_rb_read_inv_signed_literal(rb, ubits);
        } else {
          data = avm_rb_read_literal(rb, ubits);
        }

        seg_params->feature_data[i][j] = clamp(data, data_min, data_max);
      }
    }
  }

  av2_calculate_segdata_from_syntax(seg_params);
}

void read_sequence_partition_group_tool_flags(struct SequenceHeader *seq_params,
                                              struct avm_read_bit_buffer *rb) {
  setup_seq_sb_size(seq_params, rb);
  seq_params->enable_sdp = seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_extended_sdp =
      (seq_params->enable_sdp && !seq_params->single_picture_header_flag)
          ? avm_rb_read_bit(rb)
          : 0;
  seq_params->enable_ext_partitions = avm_rb_read_bit(rb);
  if (seq_params->enable_ext_partitions)
    seq_params->enable_uneven_4way_partitions = avm_rb_read_bit(rb);
  else
    seq_params->enable_uneven_4way_partitions = 0;
  seq_params->max_pb_aspect_ratio_log2_m1 = 2;
  if (avm_rb_read_bit(rb)) {
    seq_params->max_pb_aspect_ratio_log2_m1 = avm_rb_read_bit(rb);
  }
}

void read_sequence_intra_group_tool_flags(struct SequenceHeader *seq_params,
                                          struct avm_read_bit_buffer *rb) {
  seq_params->enable_intra_dip = avm_rb_read_bit(rb);
  seq_params->enable_intra_edge_filter = avm_rb_read_bit(rb);
  seq_params->enable_mrls = avm_rb_read_bit(rb);
  seq_params->enable_cfl_intra = avm_rb_read_bit(rb);
  seq_params->cfl_ds_filter_index =
      seq_params->monochrome ? 0 : avm_rb_read_literal(rb, 2);
  seq_params->enable_mhccp = avm_rb_read_bit(rb);
  seq_params->enable_ibp = avm_rb_read_bit(rb);
}
void read_sequence_inter_group_tool_flags(struct SequenceHeader *seq_params,
                                          struct avm_read_bit_buffer *rb) {
  if (seq_params->single_picture_header_flag) {
    seq_params->seq_frame_motion_modes_present_flag = 0;
    seq_params->enable_six_param_warp_delta = 0;
    seq_params->seq_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
    seq_params->enable_masked_compound = 0;
    seq_params->order_hint_info.enable_ref_frame_mvs = 0;
    seq_params->order_hint_info.order_hint_bits_minus_1 = -1;
  } else {
    int seq_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
    uint8_t motion_mode_enabled = 0;
    uint8_t warp_delta_enabled = 0;
    for (int motion_mode = INTERINTRA; motion_mode < MOTION_MODES;
         motion_mode++) {
      int enabled = avm_rb_read_bit(rb);
      motion_mode_enabled |= enabled;
      if (motion_mode == WARP_DELTA && enabled) {
        warp_delta_enabled = 1;
      }
      if (enabled) {
        seq_enabled_motion_modes |= (1 << motion_mode);
      }
    }
    seq_params->seq_frame_motion_modes_present_flag =
        motion_mode_enabled ? avm_rb_read_bit(rb) : 0;
    seq_params->enable_six_param_warp_delta =
        warp_delta_enabled ? avm_rb_read_bit(rb) : 0;
    seq_params->seq_enabled_motion_modes = seq_enabled_motion_modes;
    seq_params->enable_masked_compound = avm_rb_read_bit(rb);
    seq_params->order_hint_info.enable_ref_frame_mvs = avm_rb_read_bit(rb);
    seq_params->order_hint_info.reduced_ref_frame_mvs_mode =
        seq_params->order_hint_info.enable_ref_frame_mvs ? avm_rb_read_bit(rb)
                                                         : 0;

    seq_params->order_hint_info.order_hint_bits_minus_1 =
        avm_rb_read_literal(rb, 4);
  }
  seq_params->enable_refmvbank = avm_rb_read_bit(rb);
  if (avm_rb_read_bit(rb)) {
    seq_params->enable_drl_reorder = DRL_REORDER_DISABLED;
  } else {
    seq_params->enable_drl_reorder =
        avm_rb_read_bit(rb) ? DRL_REORDER_CONSTRAINT : DRL_REORDER_ALWAYS;
  }
  if (seq_params->single_picture_header_flag) {
    seq_params->enable_explicit_ref_frame_map = 0;
    seq_params->ref_frames = 2;
    seq_params->ref_frames_log2 = 1;
    seq_params->number_of_bits_for_lt_frame_id = 0;
    seq_params->def_max_drl_bits = MIN_MAX_DRL_BITS;
    seq_params->allow_frame_max_drl_bits = 0;
  } else {
    seq_params->enable_explicit_ref_frame_map = avm_rb_read_bit(rb);
    if (avm_rb_read_bit(rb)) {
      seq_params->ref_frames =
          avm_rb_read_literal(rb, 4) + 1;  // explicitly signaled DPB size
    } else {
      seq_params->ref_frames = 8;  // default DPB size: 8
    }
    seq_params->ref_frames_log2 = avm_ceil_log2(seq_params->ref_frames);
    seq_params->number_of_bits_for_lt_frame_id = avm_rb_read_literal(rb, 3);
    seq_params->def_max_drl_bits =
        avm_rb_read_primitive_quniform(
            rb, MAX_MAX_DRL_BITS - MIN_MAX_DRL_BITS + 1) +
        MIN_MAX_DRL_BITS;
    seq_params->allow_frame_max_drl_bits = avm_rb_read_bit(rb);
  }
  seq_params->def_max_bvp_drl_bits =
      avm_rb_read_primitive_quniform(
          rb, MAX_MAX_IBC_DRL_BITS - MIN_MAX_IBC_DRL_BITS + 1) +
      MIN_MAX_IBC_DRL_BITS;
  seq_params->allow_frame_max_bvp_drl_bits = avm_rb_read_bit(rb);

  seq_params->num_same_ref_compound =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_literal(rb, 2);

  uint8_t enable_tip =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  if (enable_tip) {
    seq_params->enable_tip = 1 + avm_rb_read_bit(rb);
  } else {
    seq_params->enable_tip = 0;
  }
  if (seq_params->enable_tip) {
    seq_params->enable_tip_hole_fill = avm_rb_read_bit(rb);
  } else {
    seq_params->enable_tip_hole_fill = 0;
  }
  seq_params->enable_mv_traj =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_bawp = avm_rb_read_bit(rb);
  seq_params->enable_cwp =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_imp_msk_bld =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_lf_sub_pu =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  if (seq_params->enable_tip == 1 && seq_params->enable_lf_sub_pu) {
    seq_params->enable_tip_explicit_qp = avm_rb_read_bit(rb);
  } else {
    seq_params->enable_tip_explicit_qp = 0;
  }
  if (seq_params->single_picture_header_flag) {
    seq_params->enable_opfl_refine = AVM_OPFL_REFINE_NONE;
    seq_params->enable_refinemv = 0;
  } else {
    seq_params->enable_opfl_refine = avm_rb_read_literal(rb, 2);
    seq_params->enable_refinemv = avm_rb_read_bit(rb);
  }

  seq_params->enable_tip_refinemv =
      (seq_params->enable_tip &&
       (seq_params->enable_opfl_refine || seq_params->enable_refinemv))
          ? avm_rb_read_bit(rb)
          : 0;

  if (seq_params->single_picture_header_flag) {
    seq_params->enable_bru = 0;
    seq_params->enable_adaptive_mvd = 0;
    seq_params->enable_mvd_sign_derive = 0;
    seq_params->enable_flex_mvres = 0;
  } else {
    seq_params->enable_bru = avm_rb_read_bit(rb);
    seq_params->enable_adaptive_mvd = avm_rb_read_bit(rb);
    seq_params->enable_mvd_sign_derive = avm_rb_read_bit(rb);
    seq_params->enable_flex_mvres = avm_rb_read_bit(rb);
  }
  if (seq_params->single_picture_header_flag) {
    seq_params->enable_global_motion = 0;
  } else {
    seq_params->enable_global_motion = avm_rb_read_bit(rb);
  }

  if (seq_params->single_picture_header_flag) {
    seq_params->enable_short_refresh_frame_flags = 0;
  } else {
    seq_params->enable_short_refresh_frame_flags = avm_rb_read_bit(rb);
  }
}

void read_sequence_scc_group_tool_flags(struct SequenceHeader *seq_params,
                                        struct avm_read_bit_buffer *rb) {
  if (seq_params->single_picture_header_flag) {
    seq_params->force_screen_content_tools = 2;  // SELECT_SCREEN_CONTENT_TOOLS
    seq_params->force_integer_mv = 2;            // SELECT_INTEGER_MV
  } else {
    if (avm_rb_read_bit(rb)) {
      seq_params->force_screen_content_tools =
          2;  // SELECT_SCREEN_CONTENT_TOOLS
    } else {
      seq_params->force_screen_content_tools = avm_rb_read_bit(rb);
    }

    if (seq_params->force_screen_content_tools > 0) {
      if (avm_rb_read_bit(rb)) {
        seq_params->force_integer_mv = 2;  // SELECT_INTEGER_MV
      } else {
        seq_params->force_integer_mv = avm_rb_read_bit(rb);
      }
    } else {
      seq_params->force_integer_mv = 2;  // SELECT_INTEGER_MV
    }
  }
}

void read_sequence_filter_group_tool_flags(struct SequenceHeader *seq_params,
                                           struct avm_read_bit_buffer *rb) {
  seq_params->disable_loopfilters_across_tiles = avm_rb_read_bit(rb);
  seq_params->enable_cdef = avm_rb_read_bit(rb);
  seq_params->enable_gdf = avm_rb_read_bit(rb);
  if (seq_params->enable_gdf && seq_params->sb_size != BLOCK_256X256 &&
      seq_params->sb_size != BLOCK_128X128) {
    seq_params->gdf_unit_matches_sb_size = avm_rb_read_bit(rb);
  } else {
    seq_params->gdf_unit_matches_sb_size = 0;
  }
  seq_params->enable_restoration = avm_rb_read_bit(rb);
  seq_params->lr_tools_disable_mask[0] = 0;
  seq_params->lr_tools_disable_mask[1] = 0;
  if (seq_params->enable_restoration) {
    for (int i = 1; i < RESTORE_SWITCHABLE_TYPES; ++i) {
      seq_params->lr_tools_disable_mask[0] |= (avm_rb_read_bit(rb) << i);
    }
    if (avm_rb_read_bit(rb)) {
      seq_params->lr_tools_disable_mask[1] = DEF_UV_LR_TOOLS_DISABLE_MASK;
      for (int i = 1; i < RESTORE_SWITCHABLE_TYPES; ++i) {
        if (DEF_UV_LR_TOOLS_DISABLE_MASK & (1 << i)) continue;
        seq_params->lr_tools_disable_mask[1] |= (avm_rb_read_bit(rb) << i);
      }
    } else {
      seq_params->lr_tools_disable_mask[1] =
          (seq_params->lr_tools_disable_mask[0] | DEF_UV_LR_TOOLS_DISABLE_MASK);
    }
  }
  seq_params->enable_ccso = avm_rb_read_bit(rb);
  if (seq_params->enable_ccso) {
    seq_params->ccso_unit_matches_sb_size = avm_rb_read_bit(rb);
  } else {
    seq_params->ccso_unit_matches_sb_size = 0;
  }
  if (seq_params->single_picture_header_flag) {
    seq_params->enable_cdef_on_skip_txfm = CDEF_ON_SKIP_TXFM_ADAPTIVE;
  } else {
    if (avm_rb_read_bit(rb)) {
      seq_params->enable_cdef_on_skip_txfm = CDEF_ON_SKIP_TXFM_ALWAYS_ON;
    } else {
      seq_params->enable_cdef_on_skip_txfm = avm_rb_read_bit(rb)
                                                 ? CDEF_ON_SKIP_TXFM_DISABLED
                                                 : CDEF_ON_SKIP_TXFM_ADAPTIVE;
    }
  }
  seq_params->df_par_bits_minus2 = avm_rb_read_literal(rb, 2);
}

void read_sequence_transform_quant_entropy_group_tool_flags(
    struct SequenceHeader *seq_params, struct avm_read_bit_buffer *rb) {
  seq_params->enable_fsc = avm_rb_read_bit(rb);
  if (!seq_params->enable_fsc) {
    seq_params->enable_idtx_intra = avm_rb_read_bit(rb);
  } else {
    seq_params->enable_idtx_intra = 1;
  }
  seq_params->enable_ist = avm_rb_read_bit(rb);
  seq_params->enable_inter_ist = avm_rb_read_bit(rb);
  seq_params->enable_chroma_dctonly =
      seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_inter_ddt =
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
  seq_params->reduced_tx_part_set = avm_rb_read_bit(rb);
  seq_params->enable_cctx = seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
  seq_params->enable_tcq = 0;
  int enable_tcq = avm_rb_read_bit(rb);
  if (enable_tcq) {
    if (!seq_params->single_picture_header_flag)
      enable_tcq += avm_rb_read_bit(rb);
    seq_params->enable_tcq = enable_tcq;
  }

  if (seq_params->enable_tcq == TCQ_DISABLE ||
      seq_params->enable_tcq >= TCQ_8ST_FR) {
    seq_params->enable_parity_hiding = avm_rb_read_bit(rb);
  } else {
    seq_params->enable_parity_hiding = 0;
  }

  if (seq_params->single_picture_header_flag) {
    // Setting both enable_avg_cdf and avg_cdf_type to 1 allows us to omit the
    // context_update_tile_id syntax element in tile_info(), which is part of
    // uncompressed_header().
    seq_params->enable_avg_cdf = 1;
    seq_params->avg_cdf_type = 1;
  } else {
    seq_params->enable_avg_cdf = avm_rb_read_bit(rb);
    if (seq_params->enable_avg_cdf) {
      seq_params->avg_cdf_type = avm_rb_read_bit(rb);
    }
  }
  const int is_monochrome = seq_params->monochrome;
  if (is_monochrome) {
    seq_params->separate_uv_delta_q = 0;
  } else {
    seq_params->separate_uv_delta_q = avm_rb_read_bit(rb);
  }

  seq_params->equal_ac_dc_q = avm_rb_read_bit(rb);
  if (!seq_params->equal_ac_dc_q) {
    seq_params->base_y_dc_delta_q =
        DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
    seq_params->y_dc_delta_q_enabled = avm_rb_read_bit(rb);
  } else {
    seq_params->base_y_dc_delta_q = 0;
    seq_params->y_dc_delta_q_enabled = 0;
  }
  if (!is_monochrome) {
    if (!seq_params->equal_ac_dc_q) {
      seq_params->base_uv_dc_delta_q =
          DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
      seq_params->uv_dc_delta_q_enabled = avm_rb_read_bit(rb);
    } else {
      seq_params->uv_dc_delta_q_enabled = 0;
    }
    seq_params->base_uv_ac_delta_q =
        DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
    seq_params->uv_ac_delta_q_enabled = avm_rb_read_bit(rb);
    if (seq_params->equal_ac_dc_q)
      seq_params->base_uv_dc_delta_q = seq_params->base_uv_ac_delta_q;
  } else {
    seq_params->base_uv_dc_delta_q = 0;
    seq_params->base_uv_ac_delta_q = 0;
    seq_params->uv_dc_delta_q_enabled = 0;
    seq_params->uv_ac_delta_q_enabled = 0;
  }
}

void read_sequence_segment_tool_flags(struct SequenceHeader *seq_params,
                                      struct avm_read_bit_buffer *rb) {
  seq_params->enable_ext_seg = avm_rb_read_bit(rb);
  seq_params->seq_seg_info_present_flag = avm_rb_read_bit(rb);
  if (seq_params->seq_seg_info_present_flag) {
    seq_params->seg_params.enable_ext_seg = seq_params->enable_ext_seg;
    read_seg_syntax_info(&seq_params->seg_params, rb);
  }
}

void av2_read_sequence_header(struct avm_read_bit_buffer *rb,
                              SequenceHeader *seq_params) {
  seq_params->seq_tile_info_present_flag = 0;
  seq_params->tile_params.allow_tile_info_change = 0;
  read_sequence_partition_group_tool_flags(seq_params, rb);
  read_sequence_segment_tool_flags(seq_params, rb);
  read_sequence_intra_group_tool_flags(seq_params, rb);
  read_sequence_inter_group_tool_flags(seq_params, rb);
  read_sequence_scc_group_tool_flags(seq_params, rb);
  read_sequence_transform_quant_entropy_group_tool_flags(seq_params, rb);
  read_sequence_filter_group_tool_flags(seq_params, rb);
  read_sequence_tile_config(seq_params, rb);
}

static AVM_INLINE void read_multi_frame_header_seg_info(
    MultiFrameHeader *mfh_param, struct avm_read_bit_buffer *rb) {
  mfh_param->mfh_seg_info_present_flag = avm_rb_read_bit(rb);
  if (mfh_param->mfh_seg_info_present_flag) {
    mfh_param->mfh_ext_seg_flag = avm_rb_read_bit(rb);
    mfh_param->mfh_seg_params.enable_ext_seg = mfh_param->mfh_ext_seg_flag;
    read_seg_syntax_info(&mfh_param->mfh_seg_params, rb);
  }
}

uint32_t av2_read_multi_frame_header(AV2_COMMON *cm,
                                     struct avm_read_bit_buffer *rb) {
  const uint32_t mfh_seq_header_id = avm_rb_read_uvlc(rb);
  if (mfh_seq_header_id >= MAX_SEQ_NUM) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Unsupported Sequence Header ID in MFH");
  }
  const uint32_t cur_mfh_id = avm_rb_read_uvlc(rb) + 1;
  if (cur_mfh_id >= MAX_MFH_NUM) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "multi-frame header id is greater than or equal to the "
                       "maximum multi-frame header number");
  }

  MultiFrameHeader *mfh_param = &cm->mfh_params[cur_mfh_id];
  mfh_param->mfh_seq_header_id = (int)mfh_seq_header_id;
  mfh_param->mfh_mlayer_id = cm->mlayer_id;
  mfh_param->mfh_tlayer_id = cm->tlayer_id;
  mfh_param->mfh_frame_width = cm->seq_params.max_frame_width;
  mfh_param->mfh_frame_height = cm->seq_params.max_frame_height;
  mfh_param->mfh_frame_size_present_flag = avm_rb_read_bit(rb);
  if (mfh_param->mfh_frame_size_present_flag) {
    mfh_param->mfh_frame_width_bits_minus1 = avm_rb_read_literal(rb, 4);
    int num_bits_width = mfh_param->mfh_frame_width_bits_minus1 + 1;
    mfh_param->mfh_frame_height_bits_minus1 = avm_rb_read_literal(rb, 4);
    int num_bits_height = mfh_param->mfh_frame_height_bits_minus1 + 1;
    av2_read_frame_size(rb, num_bits_width, num_bits_height,
                        &mfh_param->mfh_frame_width,
                        &mfh_param->mfh_frame_height);
  }
  mfh_param->mfh_deblocking_filter_update_flag = avm_rb_read_bit(rb);
  if (mfh_param->mfh_deblocking_filter_update_flag) {
    for (int i = 0; i < 4; i++) {
      mfh_param->mfh_apply_deblocking_filter[i] = avm_rb_read_bit(rb);
    }
  } else {
    for (int i = 0; i < 4; i++) {
      mfh_param->mfh_apply_deblocking_filter[i] = 0;
    }
  }

  read_multi_frame_header_seg_info(mfh_param, rb);

  cm->mfh_valid[cur_mfh_id] = true;
  return cur_mfh_id;
}

static void read_global_motion_params(WarpedMotionParams *params,
                                      const WarpedMotionParams *ref_params,
                                      struct avm_read_bit_buffer *rb,

                                      const struct scale_factors *sf,

                                      MvSubpelPrecision precision) {
  const int precision_loss = get_gm_precision_loss(precision);
  (void)precision_loss;
  TransformationType type = avm_rb_read_bit(rb);
  if (type != IDENTITY) {
    if (avm_rb_read_bit(rb)) {
      type = ROTZOOM;
    } else {
      type = AFFINE;
    }
  }

  *params = default_warp_params;
  params->wmtype = type;

  if (type >= ROTZOOM) {
    params->wmmat[2] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
                               (1 << GM_ALPHA_PREC_BITS)) *
                           GM_ALPHA_DECODE_FACTOR +
                       (1 << WARPEDMODEL_PREC_BITS);
    params->wmmat[3] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)) *
                       GM_ALPHA_DECODE_FACTOR;
  }

  if (type >= AFFINE) {
    params->wmmat[4] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)) *
                       GM_ALPHA_DECODE_FACTOR;
    params->wmmat[5] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
                               (1 << GM_ALPHA_PREC_BITS)) *
                           GM_ALPHA_DECODE_FACTOR +
                       (1 << WARPEDMODEL_PREC_BITS);
  } else {
    params->wmmat[4] = -params->wmmat[3];
    params->wmmat[5] = params->wmmat[2];
  }

  if (type >= TRANSLATION) {
    const int trans_dec_factor = GM_TRANS_DECODE_FACTOR;
    const int trans_prec_diff = GM_TRANS_PREC_DIFF;
    const int trans_max = GM_TRANS_MAX;

    params->wmmat[0] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, trans_max + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[0] >> trans_prec_diff)) *
                       trans_dec_factor;
    params->wmmat[1] = avm_rb_read_signed_primitive_refsubexpfin(
                           rb, trans_max + 1, SUBEXPFIN_K,
                           (ref_params->wmmat[1] >> trans_prec_diff)) *
                       trans_dec_factor;
  }

  if (params->wmtype <= AFFINE) {
    av2_reduce_warp_model(params);
    av2_get_shear_params(params

                         ,
                         sf

    );
  }
}

static AVM_INLINE void read_global_motion(AV2_COMMON *cm,
                                          struct avm_read_bit_buffer *rb) {
  const SequenceHeader *const seq_params = &cm->seq_params;
  int num_total_refs = cm->ref_frames_info.num_total_refs;
  bool use_global_motion = false;
  if (seq_params->enable_global_motion) {
    use_global_motion = avm_rb_read_bit(rb);
  }
  if (!use_global_motion) {
    for (int frame = 0; frame < INTER_REFS_PER_FRAME; ++frame) {
      cm->global_motion[frame] = default_warp_params;
      cm->cur_frame->global_motion[frame] = default_warp_params;
    }
    return;
  }

  int our_ref = num_total_refs;
  if (!frame_is_sframe(cm))
    our_ref = avm_rb_read_primitive_quniform(rb, num_total_refs + 1);
  if (our_ref == num_total_refs) {
    // Special case: Use IDENTITY model
    cm->base_global_motion_model = default_warp_params;
    cm->base_global_motion_distance = 1;
  } else {
    RefCntBuffer *buf = get_ref_frame_buf(cm, our_ref);
    assert(buf);
    if (buf->is_restricted) {
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                         "Invalid our_ref: restricted reference buffer");
    }
    int their_num_refs = buf->num_ref_frames;
    if (their_num_refs == 0) {
      // Special case: if an intra/key frame is used as a ref, use an
      // IDENTITY model
      cm->base_global_motion_model = default_warp_params;
      cm->base_global_motion_distance = 1;
    } else {
      const int their_ref = avm_rb_read_primitive_quniform(rb, their_num_refs);
      if (buf->refs_restricted_status[their_ref]) {
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                           "Invalid their_ref: restricted reference buffer");
      }
      const int our_ref_order_hint = buf->display_order_hint;
      const int their_ref_order_hint = buf->ref_display_order_hint[their_ref];
      cm->base_global_motion_model = buf->global_motion[their_ref];
      cm->base_global_motion_distance =
          get_relative_dist(&seq_params->order_hint_info, our_ref_order_hint,
                            their_ref_order_hint);
    }
  }

  for (int frame = 0; frame < cm->ref_frames_info.num_total_refs; ++frame) {
    int temporal_distance;
    const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, frame);
    if (ref_buf->is_restricted) {
      cm->global_motion[frame].invalid = 1;
      continue;
    }
    const int ref_order_hint = ref_buf->display_order_hint;
    const int cur_order_hint = cm->cur_frame->display_order_hint;
    temporal_distance = get_relative_dist(&seq_params->order_hint_info,
                                          cur_order_hint, ref_order_hint);

    if (temporal_distance == 0) {
      // Don't code global motion for frames at the same temporal instant
      cm->global_motion[frame] = default_warp_params;
      continue;
    }

    WarpedMotionParams ref_params_;
    av2_scale_warp_model(&cm->base_global_motion_model,
                         cm->base_global_motion_distance, &ref_params_,
                         temporal_distance);
    WarpedMotionParams *ref_params = &ref_params_;
    read_global_motion_params(&cm->global_motion[frame], ref_params, rb,

                              get_ref_scale_factors_const(cm, frame),

                              cm->features.fr_mv_precision);

    // TODO(sarahparker, debargha): The logic in the commented out code below
    // does not work currently and causes mismatches when resize is on. Fix it
    // before turning the optimization back on.
    /*
    YV12_BUFFER_CONFIG *ref_buf = get_ref_frame(cm, frame);
    if (cm->width == ref_buf->y_crop_width &&
        cm->height == ref_buf->y_crop_height) {
      read_global_motion_params(&cm->global_motion[frame],
                                &cm->prev_frame->global_motion[frame], rb,
                                cm->features.allow_high_precision_mv);
    } else {
      cm->global_motion[frame] = default_warp_params;
    }
    */
    /*
    printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
           frame, cm->current_frame.frame_number, cm->immediate_output_picture,
           cm->global_motion[frame].wmmat[0],
           cm->global_motion[frame].wmmat[1],
           cm->global_motion[frame].wmmat[2],
           cm->global_motion[frame].wmmat[3]);
           */
  }
  memcpy(cm->cur_frame->global_motion, cm->global_motion,
         INTER_REFS_PER_FRAME * sizeof(WarpedMotionParams));
}

// Release the references to the frame buffers in cm->ref_frame_map and reset
// all elements of cm->ref_frame_map to NULL.
static AVM_INLINE void reset_ref_frame_map(AV2_COMMON *const cm) {
  BufferPool *const pool = cm->buffer_pool;
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
    decrease_ref_count(cm->ref_frame_map[i], pool);
    cm->ref_frame_map[i] = NULL;
  }
}

// If the refresh_frame_flags bitmask is set, update reference frame id values
// and mark frames as valid for reference.
static AVM_INLINE void validate_references(AV2Decoder *const pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const int refresh_frame_flags = cm->current_frame.refresh_frame_flags;
  int first_ref_index;
  const bool clear_multiple_insert_in_one =
      av2_frame_clears_multiple_inserted_in_one(
          refresh_frame_flags, cm->current_frame.frame_type, &first_ref_index);

  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
    if ((refresh_frame_flags >> i) & 1) {
      if (av2_skip_reference_buffer_update(clear_multiple_insert_in_one, i,
                                           first_ref_index)) {
        pbi->valid_for_referencing[i] = 0;
      } else {
        pbi->valid_for_referencing[i] = 1;
      }
    }
  }
}

static INLINE void reset_frame_buffers(AV2_COMMON *cm) {
  RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
  int i;

  lock_buffer_pool(cm->buffer_pool);
  assert(cm->cur_frame->ref_count == 1);
  for (i = 0; i < FRAME_BUFFERS; ++i) {
    // Reset all unreferenced frame buffers. We can also reset cm->cur_frame
    // because we are the sole owner of cm->cur_frame.
    if (frame_bufs[i].ref_count > 0 && &frame_bufs[i] != cm->cur_frame) {
      continue;
    }
    frame_bufs[i].order_hint = 0;
    frame_bufs[i].display_order_hint = 0;
    av2_zero(frame_bufs[i].ref_display_order_hint);
    av2_zero(frame_bufs[i].ref_order_hints);
  }
  av2_zero_unused_internal_frame_buffers(&cm->buffer_pool->int_frame_buffers);
  unlock_buffer_pool(cm->buffer_pool);
}

// This function is used to dervie DOH to check the first keyobu of the temporal
// unit. This function must be updated with the get_disp_order_hint()
int get_disp_order_hint_keyobu(SequenceHeader *seq_params, OBU_TYPE obu_type,
                               int order_hint, int tlayer_id, int mlayer_id,
                               RefCntBuffer **ref_frame_map,
                               bool random_accessed, bool is_op_constrained,
                               const int mlayer_mask, const int tlayer_mask) {
  if (is_op_constrained) {
    // This configuration is only used for conformance checking in the AVM
    // reference software.
    assert(mlayer_mask >= 0 && mlayer_mask < (1 << MAX_NUM_MLAYERS));
    assert(tlayer_mask >= 0 && tlayer_mask < (1 << MAX_NUM_TLAYERS));
  } else {
    // This configuration is used in actual decoding process. Thus,
    // op_max_mlayer_id and op_max_tlayer_id are not needed and should be set to
    // -1 if is_op_constrained is false.
    assert(mlayer_mask == -1 && mlayer_mask == -1);
  }

  if (obu_type == OBU_CLOSED_LOOP_KEY) {
    return order_hint;
  } else if (obu_type == OBU_OPEN_LOOP_KEY) {
    if (random_accessed) return order_hint;
  }

  // Derive the exact display order hint from the signaled order_hint.
  // This requires scaling up order_hints corresponding to frame
  // numbers that exceed the number of bits available to send the order_hints.

  // Find the reference frame with the largest order_hint
  int max_disp_order_hint = 0;
  for (int map_idx = 0; map_idx < seq_params->ref_frames; map_idx++) {
    // Get reference frame buffer
    const RefCntBuffer *const buf = ref_frame_map[map_idx];
    if (buf == NULL ||
        (!buf->implicit_output_picture && !buf->immediate_output_picture) ||
        buf->is_restricted ||
        !is_tlayer_scalable_and_dependent(seq_params, tlayer_id, buf->tlayer_id,
                                          mlayer_id) ||
        !is_mlayer_scalable_and_dependent(seq_params, mlayer_id,
                                          buf->mlayer_id))
      continue;
    // Note: Exercising this condition is only used for the bitstream
    // conformance check in the AVM reference software. Decoder implementations
    // may skip this check since this conditional check shall not change the
    // display order hint derivation.
    if (is_op_constrained && (is_layer_dropped(buf->mlayer_id, mlayer_mask) ||
                              is_layer_dropped(buf->tlayer_id, tlayer_mask)))
      continue;

    if ((int)buf->display_order_hint > max_disp_order_hint)
      max_disp_order_hint = buf->display_order_hint;
  }

  int cur_disp_order_hint = order_hint;
  int display_order_hint_factor =
      1 << (seq_params->order_hint_info.order_hint_bits_minus_1 + 1);

  while (abs(max_disp_order_hint - cur_disp_order_hint) >=
         (display_order_hint_factor >> 1)) {
    if (cur_disp_order_hint > max_disp_order_hint) return cur_disp_order_hint;
    cur_disp_order_hint += display_order_hint_factor;
  }
  // We restrict the derived display order hint to a range, to avoid 32 bit
  // integer overflow and some corner cases when display order hint operations
  // are performed in DISPLAY_ORDER_HINT_BITS bit range
  struct avm_internal_error_info error_info;
  error_info.error_code = AVM_CODEC_OK;
  if (cur_disp_order_hint >= (1 << (DISPLAY_ORDER_HINT_BITS - 1)))
    avm_internal_error(&error_info, AVM_CODEC_ERROR,
                       "Derived display order hint is invalid");
  return cur_disp_order_hint;
}

static INLINE int get_disp_order_hint(AV2_COMMON *const cm, OBU_TYPE obu_type,
                                      bool random_accessed,
                                      bool is_op_constrained,
                                      const int mlayer_mask,
                                      const int tlayer_mask) {
  // NOTE: when this function is updated, get_disp_order_hint_keyobu() must be
  // updated.
  if (is_op_constrained) {
    // This configuration is only used for conformance checking in the AVM
    // reference software.
    assert(mlayer_mask >= 0 && mlayer_mask < (1 << MAX_NUM_MLAYERS));
    assert(tlayer_mask >= 0 && tlayer_mask < (1 << MAX_NUM_TLAYERS));
  } else {
    // This configuration is used in actual decoding process. Thus,
    // op_max_mlayer_id and op_max_tlayer_id are not needed and should be set to
    // -1 if is_op_constrained is false.
    assert(mlayer_mask == -1 && mlayer_mask == -1);
  }
  CurrentFrame *const current_frame = &cm->current_frame;
  if (obu_type == OBU_CLOSED_LOOP_KEY) {
    return current_frame->order_hint;
  } else if (obu_type == OBU_OPEN_LOOP_KEY) {
    if (random_accessed) return current_frame->order_hint;
  }
  if (current_frame->frame_type == S_FRAME &&
      cm->restricted_prediction_switch && !cm->show_existing_frame) {
    return current_frame->order_hint;
  }
  // Derive the exact display order hint from the signaled order_hint.
  // This requires scaling up order_hints corresponding to frame
  // numbers that exceed the number of bits available to send the order_hints.

  // Find the reference frame with the largest order_hint
  int max_disp_order_hint = 0;
  for (int map_idx = 0; map_idx < cm->seq_params.ref_frames; map_idx++) {
    // Get reference frame buffer
    const RefCntBuffer *const buf = cm->ref_frame_map[map_idx];
    if (buf == NULL ||
        (!buf->implicit_output_picture && !buf->immediate_output_picture) ||
        buf->is_restricted ||
        !is_tlayer_scalable_and_dependent(&cm->seq_params, cm->tlayer_id,
                                          buf->tlayer_id, cm->mlayer_id) ||
        !is_mlayer_scalable_and_dependent(&cm->seq_params, cm->mlayer_id,
                                          buf->mlayer_id))
      continue;
    // Note: Exercising this condition is only used for the bitstream
    // conformance check in the AVM reference software. Decoder implementations
    // may skip this check since this conditional check shall not change the
    // display order hint derivation.
    if (is_op_constrained && (is_layer_dropped(buf->mlayer_id, mlayer_mask) ||
                              is_layer_dropped(buf->tlayer_id, tlayer_mask)))
      continue;

    if ((int)buf->display_order_hint > max_disp_order_hint)
      max_disp_order_hint = buf->display_order_hint;
  }

  int cur_disp_order_hint = current_frame->order_hint;
  int display_order_hint_factor =
      1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1);

  while (abs(max_disp_order_hint - cur_disp_order_hint) >=
         (display_order_hint_factor >> 1)) {
    if (cur_disp_order_hint > max_disp_order_hint) return cur_disp_order_hint;
    cur_disp_order_hint += display_order_hint_factor;
  }
  // We restrict the derived display order hint to a range, to avoid 32 bit
  // integer overflow and some corner cases when display order hint operations
  // are performed in DISPLAY_ORDER_HINT_BITS bit range
  if (cur_disp_order_hint >= (1 << (DISPLAY_ORDER_HINT_BITS - 1)))
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                       "Derived display order hint is invalid");
  return cur_disp_order_hint;
}

static void read_frame_max_bvp_drl_bits(AV2_COMMON *const cm,
                                        struct avm_read_bit_buffer *rb) {
  FeatureFlags *const features = &cm->features;
  const SequenceHeader *const seq_params = &cm->seq_params;
  features->max_bvp_drl_bits = seq_params->def_max_bvp_drl_bits;
  if (seq_params->allow_frame_max_bvp_drl_bits) {
    features->max_bvp_drl_bits =
        avm_rb_read_primitive_ref_quniform(
            rb, MAX_MAX_IBC_DRL_BITS - MIN_MAX_IBC_DRL_BITS + 1,
            seq_params->def_max_bvp_drl_bits - MIN_MAX_IBC_DRL_BITS) +
        MIN_MAX_IBC_DRL_BITS;
  }
}
static INLINE void read_intrabc_params(AV2_COMMON *const cm,
                                       struct avm_read_bit_buffer *rb) {
  CurrentFrame *const current_frame = &cm->current_frame;
  FeatureFlags *const features = &cm->features;
  features->allow_intrabc = avm_rb_read_bit(rb);

  if (features->allow_intrabc) {
    if (current_frame->frame_type == KEY_FRAME ||
        current_frame->frame_type == INTRA_ONLY_FRAME) {
      features->allow_global_intrabc = avm_rb_read_bit(rb);
      features->allow_local_intrabc =
          features->allow_global_intrabc ? avm_rb_read_bit(rb) : 1;
    } else {
      features->allow_global_intrabc = 0;
      features->allow_local_intrabc = features->allow_intrabc;
    }
    read_frame_max_bvp_drl_bits(cm, rb);
  }
}
static INLINE void read_screen_content_params(AV2_COMMON *const cm,
                                              struct avm_read_bit_buffer *rb) {
  const SequenceHeader *const seq_params = &cm->seq_params;
  FeatureFlags *const features = &cm->features;

  if (seq_params->force_screen_content_tools == 2) {
    features->allow_screen_content_tools = avm_rb_read_bit(rb);
  } else {
    features->allow_screen_content_tools =
        seq_params->force_screen_content_tools;
  }

  if (features->allow_screen_content_tools) {
    if (seq_params->force_integer_mv == 2) {
      features->cur_frame_force_integer_mv = avm_rb_read_bit(rb);
    } else {
      features->cur_frame_force_integer_mv = seq_params->force_integer_mv;
    }
  } else {
    features->cur_frame_force_integer_mv = 0;
  }
}

static void set_primary_ref_frame_and_ctx(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  CurrentFrame *const current_frame = &cm->current_frame;
  FeatureFlags *const features = &cm->features;

  if (!seq_params->single_picture_header_flag) {
    int tmp_ref_frame[2] = { 0 };
    choose_primary_secondary_ref_frame(cm, tmp_ref_frame,
                                       pbi->signal_primary_ref_frame);
    features->derived_primary_ref_frame = tmp_ref_frame[0];
    features->derived_secondary_ref_frame = tmp_ref_frame[1];

    if (!pbi->signal_primary_ref_frame) {
      features->primary_ref_frame = features->derived_primary_ref_frame;
    }
  }

  // For primary_ref_frame and derived_primary_ref_frame, if one of them is
  // PRIMARY_REF_NONE, the other one is also PRIMARY_REF_NONE.
  if (features->derived_primary_ref_frame == PRIMARY_REF_NONE ||
      features->primary_ref_frame == PRIMARY_REF_NONE) {
    features->primary_ref_frame = PRIMARY_REF_NONE;
    features->derived_primary_ref_frame = PRIMARY_REF_NONE;
    features->cross_frame_context = CROSS_FRAME_CONTEXT_DISABLED;
  }
  assert(IMPLIES(features->derived_primary_ref_frame == PRIMARY_REF_NONE,
                 features->primary_ref_frame == PRIMARY_REF_NONE));
  assert(IMPLIES(features->primary_ref_frame == PRIMARY_REF_NONE,
                 features->derived_primary_ref_frame == PRIMARY_REF_NONE));

  if (features->primary_ref_frame >= cm->ref_frames_info.num_total_refs &&
      features->primary_ref_frame != PRIMARY_REF_NONE) {
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                       "Invalid primary_ref_frame");
  }
  if (get_ref_frame_buf(cm, features->primary_ref_frame) != NULL &&
      get_ref_frame_buf(cm, features->primary_ref_frame)->is_restricted) {
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                       "primary_ref_frame points a restricted reference");
  }
  if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
      cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
    // use the default frame context values
    av2_setup_past_independence(cm);
  } else {
    *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
                  ->frame_context;
  }

  if (!cm->fc->initialized) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Uninitialized entropy context.");
  }

  if (current_frame->frame_type != KEY_FRAME) {
    cm->prev_frame =
        get_primary_ref_frame_buf(cm, features->derived_primary_ref_frame);
    if (features->derived_primary_ref_frame != PRIMARY_REF_NONE &&
        get_primary_ref_frame_buf(cm, features->derived_primary_ref_frame) ==
            NULL) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Reference frame containing this frame's initial "
                         "frame context is unavailable.");
    }
  }
}

static void read_frame_max_drl_bits(AV2_COMMON *const cm,
                                    struct avm_read_bit_buffer *rb) {
  FeatureFlags *const features = &cm->features;
  const SequenceHeader *const seq_params = &cm->seq_params;
  features->max_drl_bits = seq_params->def_max_drl_bits;
  if (seq_params->allow_frame_max_drl_bits) {
    features->max_drl_bits =
        avm_rb_read_primitive_ref_quniform(
            rb, MAX_MAX_DRL_BITS - MIN_MAX_DRL_BITS + 1,
            seq_params->def_max_drl_bits - MIN_MAX_DRL_BITS) +
        MIN_MAX_DRL_BITS;
  }
}

static void reset_buffer_other_than_OLK(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  BufferPool *const pool = cm->buffer_pool;
  int ref_flags_to_keep = 0;
  for (int layer = 0; layer <= seq_params->max_mlayer_id; layer++) {
    if (cm->olk_refresh_frame_flags[layer] != -1)
      ref_flags_to_keep |= cm->olk_refresh_frame_flags[layer];
    if (cm->olk_co_vcl_refresh_frame_flags[layer] != -1)
      ref_flags_to_keep |= cm->olk_co_vcl_refresh_frame_flags[layer];
  }
  for (int ref_index = 0; ref_index < seq_params->ref_frames; ref_index++) {
    if (!((ref_flags_to_keep >> ref_index) & 1u) &&
        cm->ref_frame_map[ref_index] != NULL &&
        cm->ref_frame_map[ref_index]->long_term_id == -1) {
      decrease_ref_count(cm->ref_frame_map[ref_index], pool);
      cm->ref_frame_map[ref_index] = NULL;
      if (pbi->random_accessed) pbi->valid_for_referencing[ref_index] = 1;
    }
  }

  for (int layer = 0; layer <= seq_params->max_mlayer_id; layer++) {
    cm->olk_refresh_frame_flags[layer] = -1;
    cm->olk_co_vcl_refresh_frame_flags[layer] = -1;
    cm->prev_olk_co_vcl_refresh_frame_flags[layer] = -1;
  }
}

int av2_is_regular_non_olk_obu(OBU_TYPE obu_type) {
  return obu_type == OBU_REGULAR_SEF || obu_type == OBU_REGULAR_TIP ||
         obu_type == OBU_SWITCH || obu_type == OBU_RAS_FRAME ||
         obu_type == OBU_BRIDGE_FRAME || obu_type == OBU_REGULAR_TILE_GROUP;
}

int av2_is_regular_vcl_obu(OBU_TYPE obu_type) {
  return (obu_type == OBU_REGULAR_SEF || obu_type == OBU_REGULAR_TIP ||
          obu_type == OBU_REGULAR_TILE_GROUP || obu_type == OBU_BRIDGE_FRAME ||
          obu_type == OBU_SWITCH || obu_type == OBU_RAS_FRAME ||
          obu_type == OBU_OPEN_LOOP_KEY);
}
// Check if the current frame's layer is within the selected operating point
// using the DecOperatingPointParams structure.
static int is_layer_within_op_profiles(AV2Decoder *pbi,
                                       const int current_tlayer_id,
                                       const int current_mlayer_id) {
  const DecOperatingPointParams *params = &pbi->dec_op_params;
  if (!params->isValid || !params->dec_op) return 0;
  const int xlayer_id = pbi->common.xlayer_id;
  const OpsMLayerInfo *info = &params->dec_op->mlayer_info;
  // Check if mlayer is in the OP
  if (!((info->ops_mlayer_map[xlayer_id] >> current_mlayer_id) & 1)) return 0;
  // Check if tlayer is in the OP for this mlayer
  if (!((info->ops_tlayer_map[xlayer_id][current_mlayer_id] >>
         current_tlayer_id) &
        1))
    return 0;
  return 1;
}

// Derive operating point masks for mlayer and tlayer from the selected
// operating point in DecOperatingPointParams.
static void create_op_masks_from_profiles(AV2Decoder *pbi, int *tlayer_op_mask,
                                          int *mlayer_op_mask) {
  const DecOperatingPointParams *params = &pbi->dec_op_params;
  const int xlayer_id = pbi->common.xlayer_id;
  *mlayer_op_mask = params->dec_op->mlayer_info.ops_mlayer_map[xlayer_id];
  // Compute combined tlayer mask: union of all per-mlayer tlayer maps
  *tlayer_op_mask = 0;
  for (int j = 0; j < MAX_NUM_MLAYERS; j++) {
    if (*mlayer_op_mask & (1 << j)) {
      *tlayer_op_mask |=
          params->dec_op->mlayer_info.ops_tlayer_map[xlayer_id][j];
    }
  }
}

// Returns 1 if the given layer subset has a missing dependency, i.e. a
// retained layer depends on a dropped layer according to the dependency maps.
static int check_missing_layer_dependency(const AV2_COMMON *cm, int mlayer_mask,
                                          int tlayer_mask) {
  for (int cur_mlayer_id = 0; cur_mlayer_id <= cm->mlayer_id; cur_mlayer_id++) {
    if (!is_layer_dropped(cur_mlayer_id, mlayer_mask)) {
      for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
           ref_mlayer_id++) {
        if (cm->seq_params
                .mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] &&
            is_layer_dropped(ref_mlayer_id, mlayer_mask)) {
          return 1;
        }
      }
      for (int cur_tlayer_id = 0; cur_tlayer_id <= cm->tlayer_id;
           cur_tlayer_id++) {
        if (!is_layer_dropped(cur_tlayer_id, tlayer_mask)) {
          for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
               ref_tlayer_id++) {
            if (cm->seq_params
                    .tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
                                          [ref_tlayer_id] &&
                is_layer_dropped(ref_tlayer_id, tlayer_mask)) {
              return 1;
            }
          }
        }
      }
    }
  }
  return 0;
}

static void check_consistent_disp_order_hint_derivation(AV2Decoder *pbi,
                                                        OBU_TYPE obu_type,
                                                        bool random_accessed) {
  AV2_COMMON *const cm = &pbi->common;

  // Note: The following if block implements bitstream constraint checks for
  // consistent display order hint derivation when (embedded or temporal)
  // layers are selectively dropped based on operating points. The following
  // code provides checks for all the possible operating point combinations
  // and decoders may choose to simplify this check depending on the desired
  // operating point(s) specified in the operating point set (OPS).
  if (pbi->dec_op_params.isValid &&
      is_layer_within_op_profiles(pbi, cm->tlayer_id, cm->mlayer_id)) {
    CurrentFrame *const current_frame = &cm->current_frame;
    const int disp_order_unconstrained = current_frame->display_order_hint;
    int disp_order_op_constrained = 0;
    // number of layer-drop masks
    const int num_mlayer_masks = 1 << (cm->mlayer_id + 1);
    const int num_tlayer_masks = 1 << (cm->tlayer_id + 1);
    // derive operating point masks for mlayer and tlayer
    int op_mlayer_mask, op_tlayer_mask;
    create_op_masks_from_profiles(pbi, &op_tlayer_mask, &op_mlayer_mask);
    // Check consistency for subsets of OPs that would include the current
    // frame. Skip subsets where the current frame's layer would be dropped,
    // as those do not correspond to valid operating points for this frame.
    for (int ml = 0; ml < num_mlayer_masks; ml++) {
      for (int tl = 0; tl < num_tlayer_masks; tl++) {
        int mlayer_mask = ml & op_mlayer_mask;
        int tlayer_mask = tl & op_tlayer_mask;
        // Skip subsets that would drop the current frame's layer.
        if (is_layer_dropped(cm->mlayer_id, mlayer_mask) ||
            is_layer_dropped(cm->tlayer_id, tlayer_mask))
          continue;
        // Skip subsets with unsatisfied layer dependencies.
        if (check_missing_layer_dependency(cm, mlayer_mask, tlayer_mask))
          continue;
        disp_order_op_constrained = get_disp_order_hint(
            cm, obu_type, random_accessed, /*is_op_constrained=*/true,
            mlayer_mask, tlayer_mask);
        if (disp_order_unconstrained != disp_order_op_constrained) {
          avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                             "Inconsistent display order hint derivation "
                             "accross different operating points.");
        }
      }
    }
  }
}

static int read_show_existing_frame(AV2Decoder *pbi, bool is_regular_obu,
                                    struct avm_read_bit_buffer *rb) {
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  CurrentFrame *const current_frame = &cm->current_frame;
  BufferPool *const pool = cm->buffer_pool;
  cm->show_existing_frame = 1;
  init_bru_params(cm);

  if (is_regular_obu && pbi->olk_encountered &&
      pbi->this_is_first_vcl_obu_in_tu) {
    lock_buffer_pool(pool);
    reset_buffer_other_than_OLK(pbi);
    unlock_buffer_pool(pool);
  }

  // Show an existing frame directly.
  const int existing_frame_idx = cm->sef_ref_fb_idx =
      avm_rb_read_literal(rb, seq_params->ref_frames_log2);

  if (existing_frame_idx >= seq_params->ref_frames) {
    avm_internal_error(
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
        "Existing frame idx must be less than %d but is set to %d",
        seq_params->ref_frames, existing_frame_idx);
  }
  if (existing_frame_idx >= seq_params->ref_frames) {
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                       "SEF existing_frame_idx %d points restricted "
                       "reference",
                       existing_frame_idx);
  }
  RefCntBuffer *const frame_to_show = cm->ref_frame_map[existing_frame_idx];
  if (frame_to_show == NULL) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "Buffer does not contain a decoded frame");
  }
  if (frame_to_show->is_restricted) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid SEF Ref: restricted reference buffer");
  }
  cm->sef_ref_fb_idx = existing_frame_idx;
  cm->derive_sef_order_hint = avm_rb_read_bit(rb);
  cm->cur_frame->mlayer_id = cm->mlayer_id;
  cm->cur_frame->xlayer_id = cm->xlayer_id;
  cm->cur_frame->stream_id = av2_get_stream_index(cm, cm->xlayer_id);

  if (!cm->derive_sef_order_hint) {
    current_frame->order_hint = avm_rb_read_literal(
        rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);

    current_frame->display_order_hint = get_disp_order_hint(
        cm, is_regular_obu ? OBU_REGULAR_SEF : OBU_LEADING_SEF, false, false,
        -1, -1);
    check_consistent_disp_order_hint_derivation(
        pbi, is_regular_obu ? OBU_REGULAR_SEF : OBU_LEADING_SEF,
        /*random_accessed=*/false);
    current_frame->frame_number = current_frame->order_hint;
    // Since a SEF frame is not used as a reference frame, its display order
    // hint cannot be used to derive display order hints of subsequent frames.
    // To guarantee that, the display order hint of the SEF frame should not be
    // bigger than the max_disp_order_hint
    unsigned int max_disp_order_hint = 0;
    for (int map_idx = 0; map_idx < cm->seq_params.ref_frames; map_idx++) {
      // Get reference frame buffer
      const RefCntBuffer *const buf = cm->ref_frame_map[map_idx];
      if (buf == NULL ||
          !is_tlayer_scalable_and_dependent(&cm->seq_params, cm->tlayer_id,
                                            buf->tlayer_id, cm->mlayer_id) ||
          !is_mlayer_scalable_and_dependent(&cm->seq_params, cm->mlayer_id,
                                            buf->mlayer_id))
        continue;
      if (buf->display_order_hint > max_disp_order_hint)
        max_disp_order_hint = buf->display_order_hint;
    }
    cm->cur_frame->order_hint = current_frame->order_hint;
    cm->cur_frame->display_order_hint = current_frame->display_order_hint;
    resize_context_buffers(cm, frame_to_show->width, frame_to_show->height);
    setup_buffer_pool(cm);
    avm_yv12_copy_frame(&frame_to_show->buf, &cm->cur_frame->buf,
                        av2_num_planes(cm));
  } else {
    if (frame_to_show->implicit_output_picture ||
        frame_to_show->immediate_output_picture) {
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                         "the reference frame should be a hidden frame when "
                         "derive_sef_order_hint is true");
      return 0;
    }
    current_frame->order_hint = cm->cur_frame->order_hint =
        frame_to_show->order_hint;
    current_frame->display_order_hint = cm->cur_frame->display_order_hint =
        frame_to_show->display_order_hint;
  }

  if (is_regular_obu && pbi->olk_encountered) {
    if (pbi->last_olk_tu_display_order_hint == -1 &&
        !pbi->this_is_first_vcl_obu_in_tu) {
      // First non-hidden regular frame after a hidden OLK is this SEF (SEFs
      // are always shown).
      pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
    }
    if (pbi->this_is_first_vcl_obu_in_tu) pbi->olk_encountered = 0;
  }

  lock_buffer_pool(pool);
  assert(frame_to_show->ref_count > 0);
  // cm->cur_frame should be the buffer referenced by the return value
  // of the get_free_fb() call in assign_cur_frame_new_fb() (called by
  // av2_receive_compressed_data()), so the ref_count should be 1.
  assert(cm->cur_frame->ref_count == 1);
  // assign_frame_buffer_p() decrements ref_count directly rather than
  // call decrease_ref_count(). If cm->cur_frame->raw_frame_buffer has
  // already been allocated, it will not be released by
  // assign_frame_buffer_p()!
  assert(IMPLIES(cm->derive_sef_order_hint,
                 !cm->cur_frame->raw_frame_buffer.data));

  FrameHash raw_frame_hash = cm->cur_frame->raw_frame_hash;
  FrameHash grain_frame_hash = cm->cur_frame->grain_frame_hash;
  if (cm->derive_sef_order_hint)
    assign_frame_buffer_p(&cm->cur_frame, frame_to_show);

  // Combine any Decoded Frame Header metadata that was parsed before
  // the referenced frame with any parsed before this
  // show_existing_frame header, e.g. raw frame hash values before the
  // referenced coded frame and post film grain hash values before this
  // header.
  if (raw_frame_hash.is_present) cm->cur_frame->raw_frame_hash = raw_frame_hash;
  if (grain_frame_hash.is_present)
    cm->cur_frame->grain_frame_hash = grain_frame_hash;
  unlock_buffer_pool(pool);

  cm->lf.apply_deblocking_filter[0] = 0;
  cm->lf.apply_deblocking_filter[1] = 0;
  cm->immediate_output_picture = 1;
  // It is a requirement of bitstream conformance that when
  // show_existing_frame is used to show a previous frame with derived display
  // order hint, the frame is output via the show_existing_frame mechanism at
  // most once.
  if (cm->derive_sef_order_hint && frame_to_show->frame_output_done) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "Buffer does not contain a showable frame");
  }
  setup_film_grain(pbi, rb);
  current_frame->refresh_frame_flags = 0;
  return 0;
}

static void read_frame_opfl_refine_type(AV2_COMMON *const cm,
                                        struct avm_read_bit_buffer *rb) {
  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    cm->features.opfl_refine_type =
        (cm->seq_params.enable_opfl_refine == AVM_OPFL_REFINE_NONE ||
         !cm->seq_params.enable_tip_refinemv)
            ? REFINE_NONE
            : REFINE_ALL;
    return;
  }

  if (cm->seq_params.enable_opfl_refine == AVM_OPFL_REFINE_AUTO) {
    if (avm_rb_read_bit(rb)) {
      cm->features.opfl_refine_type = REFINE_SWITCHABLE;
    } else {
      cm->features.opfl_refine_type =
          avm_rb_read_bit(rb) ? REFINE_ALL : REFINE_NONE;
    }
  } else {
    cm->features.opfl_refine_type = cm->seq_params.enable_opfl_refine;
  }
}

int ras_frame_refresh_frame_flags_derivation(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  int refresh_frame_flags = (1 << cm->seq_params.ref_frames) - 1;
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
    if (cm->ref_frame_map[i] == NULL) continue;
    for (int j = 0; j < cm->num_ref_key_frames; j++) {
      if (cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id) {
        refresh_frame_flags &= ~(1 << i);
      }
    }
  }
  return refresh_frame_flags;
}

// This function marks reference frames as valid for referencing if they are
// present in the current RAS frame's long term ids.
// Note that we handle the case where there are multiple RAS frames (at
// different embedded layers) in a temporal unit, by clearing the
// valid_for_referencing flags and current and dependent mlayer reference frames
// only.
void mark_reference_frames_with_long_term_ids(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
    if (cm->ref_frame_map[i] != NULL &&
        !is_mlayer_transitively_dependent(
            &cm->seq_params, cm->ref_frame_map[i]->mlayer_id, cm->mlayer_id)) {
      continue;
    }
    pbi->valid_for_referencing[i] = 0;
    for (int j = 0; j < cm->num_ref_key_frames; j++) {
      if (cm->ref_frame_map[i] != NULL &&
          cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id)
        pbi->valid_for_referencing[i] = 1;
    }
  }
}

void check_long_term_ids_exist(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  for (int j = 0; j < cm->num_ref_key_frames; j++) {
    int found = 0;
    for (int i = 0; i < cm->seq_params.ref_frames; i++) {
      if (cm->ref_frame_map[i] != NULL &&
          cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id) {
        found = 1;
        break;
      }
    }
    if (found == 0) {
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                         "Required long term reference not available");
    }
  }
}

static void activate_atlas_segment(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  bool atlas_found = false;
  int xlayer_id;
  int atlas_lcr_id;
  xlayer_id = cm->lcr_params.xlayer_id;
  if (cm->lcr_params.is_global) {
    atlas_lcr_id = cm->lcr_params.global_lcr.lcr_global_atlas_id;
  } else {
    atlas_lcr_id = cm->lcr_params.local_lcr.lcr_local_atlas_id;
  }
  for (int i = 0; i < pbi->atlas_counter[xlayer_id]; i++) {
    if (pbi->atlas_list[xlayer_id][i].atlas_segment_id == atlas_lcr_id) {
      pbi->active_atlas_segment_info = &pbi->atlas_list[xlayer_id][i];
      atlas_found = true;
      break;
    }
  }
  if (atlas_found) {
    cm->atlas_params = *pbi->active_atlas_segment_info;
  } else {
    memset(&cm->atlas_params, 0, sizeof(struct AtlasSegmentInfo));
  }
}

// Find the active LCR for the given xlayer_id and seq_lcr_id.
// First searches for a local LCR whose lcr_local_id matches seq_lcr_id,
// then falls back to the global LCR.
static LayerConfigurationRecord *find_active_lcr(AV2Decoder *pbi, int xlayer_id,
                                                 int seq_lcr_id) {
  LayerConfigurationRecord *lcr = NULL;
  // Option 1: search for a local LCR for the current layer whose
  // lcr_global_id matches seq_lcr_id. seq_lcr_id is a global LCR ID, and
  // local LCRs are linked to a global LCR via local_lcr->lcr_global_id.
  if (xlayer_id < GLOBAL_XLAYER_ID) {
    for (int i = 0; i < MAX_NUM_LCR; i++) {
      LayerConfigurationRecord *candidate = &pbi->lcr_list[xlayer_id][i];
      if (candidate->valid && !candidate->is_global &&
          candidate->local_lcr.lcr_local_id == seq_lcr_id) {
        lcr = candidate;
        break;
      }
    }
  }
  // Option 2: no local LCR found for this layer; use the global LCR whose
  // lcr_global_config_record_id matches seq_lcr_id directly.
  if (lcr == NULL) {
    LayerConfigurationRecord *global_lcr =
        &pbi->lcr_list[GLOBAL_XLAYER_ID][seq_lcr_id];
    if (global_lcr->valid && global_lcr->is_global) {
      lcr = global_lcr;
    }
  }
  return lcr;
}

static void activate_layer_configuration_record(AV2Decoder *pbi,
                                                int seq_lcr_id) {
  AV2_COMMON *const cm = &pbi->common;
  LayerConfigurationRecord *lcr =
      find_active_lcr(pbi, cm->xlayer_id, seq_lcr_id);
  if (lcr != NULL) {
    if (lcr->lcr_from_leading) {
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                         "LCR was signalled in a leading temporal "
                         "unit and not re-signalled");
    }
    pbi->active_lcr = lcr;
    cm->lcr_params = *pbi->active_lcr;

    // Conformance: when monotonic_output_order_flag is 0 in any activated
    // sequence header, lcr_doh_constraint_flag shall be 1.
    if (lcr->is_global && !cm->seq_params.monotonic_output_order_flag &&
        !lcr->global_lcr.lcr_doh_constraint_flag) {
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                         "lcr_doh_constraint_flag must be 1 when "
                         "monotonic_output_order_flag is 0");
    }

    // If the activated LCR is a local LCR, also store the parent global LCR
    // so that embedded layer info can fall back to it.
    if (!lcr->is_global) {
      int global_id = lcr->local_lcr.lcr_global_id;
      if (global_id != LCR_ID_UNSPECIFIED) {
        LayerConfigurationRecord *parent_glcr =
            &pbi->lcr_list[GLOBAL_XLAYER_ID][global_id];
        if (parent_glcr->valid && parent_glcr->is_global) {
          cm->global_lcr_params = *parent_glcr;
          // Conformance: when a local LCR is present and its parent global LCR
          // has xlayer_info for the same extended layer, the local LCR's
          // xlayer_info shall be the same as the global LCR's xlayer_info.
          const GlobalLayerConfigurationRecord *glcr = &parent_glcr->global_lcr;
          for (int i = 0; i < glcr->LcrMaxNumXLayerCount; i++) {
            if (glcr->LcrXLayerID[i] == lcr->xlayer_id) {
              if (memcmp(&lcr->local_lcr.xlayer_info, &glcr->xlayer_info[i],
                         sizeof(lcr->local_lcr.xlayer_info)) != 0) {
                avm_internal_error(
                    &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                    "Local LCR xlayer_info for xlayer_id %d does not match "
                    "the parent global LCR xlayer_info",
                    lcr->xlayer_id);
              }
              break;
            }
          }
        } else {
          memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
        }
      } else {
        // No Global LCR associated with this Local LCR.
        memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
      }
    } else {
      memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
    }
    activate_atlas_segment(pbi);
  } else {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "Unsupported LCR id in the Sequence Header.\n");
  }
}

// This function provides conformance checks for the LCR, where the mlayer and
// tlayer presence information in lcr_mlayer_map and lcr_tlayer_map do not
// contradict with the dependency map information from the sequence header.
static void check_lcr_mlayer_tlayer_conformance(
    const struct SequenceHeader *const seq_header,
    const struct EmbeddedLayerInfo *mlayer_params,
    struct avm_internal_error_info *info) {
  const int mlayer_map = mlayer_params->lcr_mlayer_map;
  for (int cur_mlayer_id = 0; cur_mlayer_id < MAX_NUM_MLAYERS;
       cur_mlayer_id++) {
    for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
         ref_mlayer_id++) {
      if (seq_header->mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] ==
          1) {
        if ((mlayer_map & (1 << cur_mlayer_id)) &&
            (mlayer_map & (1 << ref_mlayer_id)) == 0) {
          avm_internal_error(
              info, AVM_CODEC_UNSUP_BITSTREAM,
              "Inconsistent mlayer dependency: In the activated sequence "
              "header, mlayer_dependency_map[%d][%d] is equal to 1, indicating "
              "an mlayer with ID=%d depends on an mlayer with ID=%d, while "
              "lcr_mlayer_map indicates that an mlayer with ID=%d is "
              "not present.",
              cur_mlayer_id, ref_mlayer_id, cur_mlayer_id, ref_mlayer_id,
              ref_mlayer_id);
        }
      }
    }
    const int tlayer_map = mlayer_params->lcr_tlayer_map[cur_mlayer_id];
    for (int cur_tlayer_id = 0; cur_tlayer_id < MAX_NUM_TLAYERS;
         cur_tlayer_id++) {
      for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
           ref_tlayer_id++) {
        if (seq_header->tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
                                             [ref_tlayer_id] == 1) {
          if ((tlayer_map & (1 << cur_tlayer_id)) &&
              (tlayer_map & (1 << ref_tlayer_id)) == 0) {
            avm_internal_error(
                info, AVM_CODEC_UNSUP_BITSTREAM,
                "Inconsistent tlayer dependency: In the activated sequence "
                "header, tlayer_dependency_map[%d][%d][%d] is equal to 1, "
                "indicating a tlayer with ID=%d depends on a tlayer with "
                "ID=%d, while lcr_tlayer_map[%d] indicates that a "
                "tlayer with ID=%d is not present.",
                cur_mlayer_id, cur_tlayer_id, ref_tlayer_id, cur_tlayer_id,
                ref_tlayer_id, cur_mlayer_id, ref_tlayer_id);
          }
        }
      }
    }
  }
}

// This function calls check_lcr_mlayer_tlayer_conformance function to perform
// conformance checks accross the LCRs and xlayers present in the bitstream.
static void check_lcr_layer_map_conformance(struct AV2Decoder *pbi,
                                            const int xlayer_id) {
  AV2_COMMON *const cm = &pbi->common;
  SequenceHeader *const seq_header = &cm->seq_params;
  const int seq_lcr_id = seq_header->seq_lcr_id;

  if (seq_lcr_id == LCR_ID_UNSPECIFIED) return;

  LayerConfigurationRecord *lcr_params =
      find_active_lcr(pbi, xlayer_id, seq_lcr_id);

  if (lcr_params == NULL) return;

  const LCRXLayerInfo *lcr_xlayer_info;
  if (lcr_params->is_global) {
    const GlobalLayerConfigurationRecord *glb_lcr = &lcr_params->global_lcr;
    if (glb_lcr == NULL) return;
    for (int i = 0; i < glb_lcr->LcrMaxNumXLayerCount; i++) {
      int xLId = glb_lcr->LcrXLayerID[i];
      lcr_xlayer_info = &glb_lcr->xlayer_info[xLId];
      check_lcr_mlayer_tlayer_conformance(
          seq_header, &lcr_xlayer_info->mlayer_params, &cm->error);
    }
  } else {
    const LocalLayerConfigurationRecord *loc_lcr = &lcr_params->local_lcr;
    if (loc_lcr == NULL) return;
    lcr_xlayer_info = &loc_lcr->xlayer_info;
    check_lcr_mlayer_tlayer_conformance(
        seq_header, &lcr_xlayer_info->mlayer_params, &cm->error);
  }
}

// This function provides conformance checks for the OPS, where the mlayer and
// tlayer presence information in ops_mlayer_map and ops_tlayer_map do not
// contradict with the dependency map information from the sequence header.
static void check_ops_mlayer_tlayer_conformance(
    const struct SequenceHeader *const seq_header,
    const struct OpsMLayerInfo *const ops_mlayer_info, int xLId,
    struct avm_internal_error_info *info) {
  const int mlayer_map = ops_mlayer_info->ops_mlayer_map[xLId];
  for (int cur_mlayer_id = 0; cur_mlayer_id < MAX_NUM_MLAYERS;
       cur_mlayer_id++) {
    for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
         ref_mlayer_id++) {
      if (seq_header->mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] ==
          1) {
        if ((mlayer_map & (1 << cur_mlayer_id)) &&
            (mlayer_map & (1 << ref_mlayer_id)) == 0) {
          avm_internal_error(
              info, AVM_CODEC_UNSUP_BITSTREAM,
              "Inconsistent mlayer dependency: In the activated sequence "
              "header, mlayer_dependency_map[%d][%d] is equal to 1, indicating "
              "an mlayer with ID=%d depends on an mlayer with ID=%d, while "
              "ops_mlayer_map[%d] indicates that an mlayer with ID=%d is not "
              "present.",
              cur_mlayer_id, ref_mlayer_id, cur_mlayer_id, ref_mlayer_id, xLId,
              ref_mlayer_id);
        }
      }
    }
    // Only check ops_tlayer_map for embedded layers present in ops_mlayer_map,
    // as ops_tlayer_map is only read from the bitstream for those layers.
    if (!(mlayer_map & (1 << cur_mlayer_id))) continue;
    const int tlayer_map = ops_mlayer_info->ops_tlayer_map[xLId][cur_mlayer_id];
    for (int cur_tlayer_id = 0; cur_tlayer_id < MAX_NUM_TLAYERS;
         cur_tlayer_id++) {
      for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
           ref_tlayer_id++) {
        if (seq_header->tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
                                             [ref_tlayer_id] == 1) {
          if ((tlayer_map & (1 << cur_tlayer_id)) &&
              (tlayer_map & (1 << ref_tlayer_id)) == 0) {
            avm_internal_error(
                info, AVM_CODEC_UNSUP_BITSTREAM,
                "Inconsistent tlayer dependency: In the activated sequence "
                "header, tlayer_dependency_map[%d][%d][%d] is equal to 1, "
                "indicating a tlayer with ID=%d depends on a tlayer with "
                "ID=%d, while ops_tlayer_map[%d][%d] indicates that a tlayer "
                "with ID=%d is not present.",
                cur_mlayer_id, cur_tlayer_id, ref_tlayer_id, cur_tlayer_id,
                ref_tlayer_id, xLId, cur_mlayer_id, ref_tlayer_id);
          }
        }
      }
    }
  }
}

// This function calls check_ops_mlayer_tlayer_conformance function to perform
// conformance checks accross the OPSes and xlayers present in the bitstream.
static void check_ops_layer_map_conformance(struct AV2Decoder *pbi,
                                            const int xlayer_id) {
  AV2_COMMON *const cm = &pbi->common;
  struct SequenceHeader *const seq_header = &cm->seq_params;
  for (int ops_id = 0; ops_id < MAX_NUM_OPS_ID; ops_id++) {
    struct OperatingPointSet *ops = &pbi->ops_list[xlayer_id][ops_id];
    if (ops == NULL) continue;
    for (int i = 0; i < ops->ops_cnt; i++) {
      OperatingPoint *op = &ops->op[i];
      if (op == NULL) continue;
      if (xlayer_id == GLOBAL_XLAYER_ID) {
        for (int xLId = 0; xLId < MAX_NUM_XLAYERS - 1; xLId++) {
          if ((op->ops_xlayer_map & (1 << xLId))) {
            if (ops->ops_mlayer_info_idc == 1 ||
                (ops->ops_mlayer_info_idc == 2 &&
                 op->ops_mlayer_explicit_info_flag[xLId])) {
              check_ops_mlayer_tlayer_conformance(seq_header, &op->mlayer_info,
                                                  xLId, &cm->error);
            }
          }
        }
      } else {
        check_ops_mlayer_tlayer_conformance(seq_header, &op->mlayer_info,
                                            xlayer_id, &cm->error);
      }
    }
  }
}

static void reset_qm_list(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  // reset QM to default: for both OLK and CLK
  const int num_planes = av2_num_planes(cm);
  for (int qm_pos = 0; qm_pos < NUM_CUSTOM_QMS; qm_pos++) {
    if ((pbi->obu_type == OBU_SWITCH || pbi->obu_type == OBU_RAS_FRAME) &&
        pbi->qm_list[qm_pos].qm_mlayer_id != -1 &&
        !is_mlayer_transitively_dependent(
            &cm->seq_params, pbi->qm_list[qm_pos].qm_mlayer_id, cm->mlayer_id))
      continue;

    // qm_protected[qm_pos] == 1 indicates the pbi->qm_list[qm_pos] is signalled
    // with CLK/OLK. those quantizer matrices are not reset to the predefined.
    if (pbi->qm_protected[qm_pos]) continue;
    // copy from predefined
    struct quantization_matrix_set *qmset = &pbi->qm_list[qm_pos];
    qmset->qm_id = qm_pos;
    qmset->qm_mlayer_id = -1;
    qmset->qm_tlayer_id = -1;
    qmset->quantizer_matrix_num_planes = num_planes;
    qmset->is_user_defined_qm = false;
  }
}

static void handle_sequence_header(AV2Decoder *pbi, OBU_TYPE obu_type,
                                   int xlayer_id, int seq_header_id) {
  AV2_COMMON *const cm = &pbi->common;
  bool keyframe_unit_in_tu =
      ((obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
        obu_type == OBU_RAS_FRAME) &&
       pbi->this_is_first_vcl_obu_in_tu);

  if (pbi->decoding_first_frame &&
      !(obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
        obu_type == OBU_RAS_FRAME)) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "the first frame of a bitstream shall be a keyframe");
  }

  struct SequenceHeader *seq_from_uch =
      &pbi->seq_list[xlayer_id][seq_header_id];

  if (seq_from_uch->seq_header_id == -1) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "No sequence header found with id = %d", seq_header_id);
  }

  if (seq_from_uch->sh_from_leading && !av2_is_leading_vcl_obu(obu_type)) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "Sequence header %d was signalled in a "
                       "leading temporal unit and not re-signalled",
                       seq_header_id);
  }

  // SH activation
  if (obu_type == OBU_CLOSED_LOOP_KEY ||
      (obu_type == OBU_OPEN_LOOP_KEY && pbi->random_accessed)) {
    pbi->active_seq[xlayer_id] = *seq_from_uch;
    // Reset malyer_id_map
    for (int i = 0; i < MAX_NUM_MLAYERS; i++)
      pbi->mlayer_id_map[xlayer_id][i] = 0;
    // Restore
    pbi->mlayer_id_map[xlayer_id][cm->mlayer_id] = 1;
  }

  // NOTE: cm->seq_params is a intermediate variable not to change the code too
  // much
  cm->seq_params = pbi->active_seq[xlayer_id];

  if (!keyframe_unit_in_tu) {
    if (!are_seq_headers_consistent(&cm->seq_params, seq_from_uch)) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Sequence Header changed at %s",
                         avm_obu_type_to_string(obu_type));
    }
    return;
  }

  // NOTE: at this point, the current obu is first CLK/OLK in the temporal unit
  // cm->seq_params is the currently active sequence header
  assert(obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
         obu_type == OBU_RAS_FRAME);

  if (obu_type == OBU_OPEN_LOOP_KEY && !pbi->random_accessed) {
    if (!are_seq_headers_consistent(&cm->seq_params, seq_from_uch)) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Sequence Header changed at OBU_OPEN_LOOP_KEY when "
                         "pbi->random_accessed %d",
                         pbi->random_accessed);
      return;
    }
  }

  // Empty referece list
  // NOTE: Should olk + random access reset reference list? It will be
  // redundant but will it harm?
  if (obu_type == OBU_CLOSED_LOOP_KEY) {
    reset_ref_frame_map(cm);
    for (int layer = 0; layer < MAX_NUM_MLAYERS; layer++) {
      cm->olk_refresh_frame_flags[layer] = -1;
      cm->olk_co_vcl_refresh_frame_flags[layer] = -1;
      cm->prev_olk_co_vcl_refresh_frame_flags[layer] = -1;
    }
  }

  // check bitstream conformance if sequence header is parsed
  // bitstream constraint for tlayer_id
  if (cm->tlayer_id > cm->seq_params.max_tlayer_id) {
    avm_internal_error(
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
        "Inconsistent tlayer_id information: OBU header indicates "
        "tlayer_id is "
        "%d, yet max_tlayer_id in the current active sequence header is %d.",
        cm->tlayer_id, cm->seq_params.max_tlayer_id);
  }
  // bitstream constraint for mlayer_id
  if (cm->mlayer_id > cm->seq_params.max_mlayer_id) {
    avm_internal_error(
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
        "Inconsistent mlayer_id information: OBU header indicates "
        "mlayer_id is "
        "%d, yet max_mlayer_id in the sequence header is %d.",
        cm->mlayer_id, cm->seq_params.max_mlayer_id);
  }

  // At this point, obu_type is OBU_CLOSED_LOOP_KEY or OBU_OPEN_LOOP_KEY.
  // When OBU_CONTENT_INTERPRETATION is not accompanied with the current obu,
  // cm->ci_params_per_layer[cm->mlayer_id] is reset to default values.
  const bool is_ci_present =
      pbi->obus_in_frame_unit_data[cm->tlayer_id][cm->mlayer_id]
                                  [OBU_CONTENT_INTERPRETATION];
  if (!is_ci_present && obu_type == OBU_CLOSED_LOOP_KEY) {
    // Initialize to default first
    av2_initialize_ci_params(&cm->ci_params_per_layer[cm->mlayer_id]);

    // Then, if there is any CI OBUs in the previous mlayer, copy the ci_params
    for (int ref_layer_id = 0; ref_layer_id < cm->mlayer_id; ref_layer_id++) {
      if (cm->seq_params.mlayer_dependency_map[cm->mlayer_id][ref_layer_id]) {
        cm->ci_params_per_layer[cm->mlayer_id] =
            cm->ci_params_per_layer[ref_layer_id];
        break;
      }
    }
  }

  // check dependency map consistency for LCR
  check_lcr_layer_map_conformance(pbi, xlayer_id);
  // check dependency map consistency for OPS
  check_ops_layer_map_conformance(pbi, xlayer_id);
}

static int is_reference_mapping_consistent(
    int ref_list1[INTER_REFS_PER_FRAME], int ref_list2[INTER_REFS_PER_FRAME]) {
  for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
    if (ref_list1[i] != ref_list2[i]) {
      return 0;
    }
  }
  return 1;
}

void update_num_restricted_ref(AV2_COMMON *const cm) {
  int num_total_refs = cm->ref_frames_info.num_total_refs;
  int num_restricted_ref = 0;
  for (int i = 0; i < num_total_refs; i++) {
    int dpb_idx = cm->remapped_ref_idx[i];
    assert(cm->ref_frame_map[dpb_idx] != NULL);
    if (cm->ref_frame_map[dpb_idx]->is_restricted) {
      num_restricted_ref++;
    }
  }
  cm->ref_frames_info.num_valid_refs_without_restricted_ref =
      cm->ref_frames_info.num_total_refs - num_restricted_ref;
  cm->ref_frames_info.num_valid_refs_with_restricted_ref =
      cm->ref_frames_info.num_total_refs;
  const int max_num_ref_frames =
      AVMMIN(cm->seq_params.ref_frames, INTER_REFS_PER_FRAME);
  if (cm->ref_frames_info.num_valid_refs_with_restricted_ref >
      max_num_ref_frames)
    cm->ref_frames_info.num_valid_refs_with_restricted_ref = max_num_ref_frames;
}

// Called if the cm->cur_mfh_id is zero.
static void handle_zero_cur_mfh_id(AV2_COMMON *const cm) {
  const SequenceHeader *const seq_params = &cm->seq_params;
  cm->mfh_params[cm->cur_mfh_id].mfh_frame_width = seq_params->max_frame_width;
  cm->mfh_params[cm->cur_mfh_id].mfh_frame_height =
      seq_params->max_frame_height;
  cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag = 0;
  for (int i = 0; i < 4; i++) {
    cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[i] = 0;
  }
  cm->mfh_params[cm->cur_mfh_id].mfh_mlayer_id = cm->mlayer_id;
  cm->mfh_params[cm->cur_mfh_id].mfh_tlayer_id = cm->tlayer_id;
  cm->mfh_valid[cm->cur_mfh_id] = true;
}

static int setup_multiframe_header_id(AV2_COMMON *const cm, OBU_TYPE obu_type,
                                      struct avm_read_bit_buffer *rb) {
  uint32_t cur_mfh_id = obu_type == OBU_BRIDGE_FRAME ? 0 : avm_rb_read_uvlc(rb);
  if (cur_mfh_id >= MAX_MFH_NUM) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "multi-frame header id is greater than or equal to "
                       "the maximum multi-frame header number");
  }
  return cur_mfh_id;
}

static int setup_sequence_header_id(AV2_COMMON *const cm,
                                    struct avm_read_bit_buffer *rb) {
  int seq_header_id_in_frame_header = -1;
  if (cm->cur_mfh_id == 0) {
    seq_header_id_in_frame_header = avm_rb_read_uvlc(rb);
    if (seq_header_id_in_frame_header >= MAX_SEQ_NUM) {
      avm_internal_error(
          &cm->error, AVM_CODEC_CORRUPT_FRAME,
          "Unsupported Sequence Header ID in uncompressed_header()");
    }
    cm->mfh_params[cm->cur_mfh_id].mfh_seq_header_id =
        (int)seq_header_id_in_frame_header;
  } else {
    if (!cm->mfh_valid[cm->cur_mfh_id]) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "No multi-frame header with mfh_id %d",
                         cm->cur_mfh_id);
    }
    seq_header_id_in_frame_header =
        cm->mfh_params[cm->cur_mfh_id].mfh_seq_header_id;
  }

  return seq_header_id_in_frame_header;
}

static int av1_get_obu_trailing_bits_count(const uint8_t *obu_payload,
                                           size_t payload_size) {
  assert(payload_size != 0);

  int trailing_bits = 0;

  // Step 1: Get the last nonzero byte of the payload
  int i;
  for (i = (int)payload_size - 1; i >= 0; i--) {
    if (obu_payload[i] != 0) {
      break;
    }
    trailing_bits += 8;
  }

  // Step 2: If all bytes are 0, then is invalid: there should be at least 1
  if (i < 0) return -1;

  // Step 3: Read backwards from bit 0 to find the first one
  uint8_t last_nonzero_byte = obu_payload[i];
  for (int bit_pos = 0; bit_pos < 8; bit_pos++) {
    if (last_nonzero_byte & (1 << bit_pos)) {
      // Found the trailing "1" bit marker
      trailing_bits += bit_pos + 1;
      break;
    }
  }
  return trailing_bits;
}

int read_obu_extension_bits(const uint8_t *obu_payload, size_t payload_size,
                            size_t bits_read_before_extension,
                            struct avm_internal_error_info *error_info) {
  // Get trailing bits count
  int num_trailing_bits =
      av1_get_obu_trailing_bits_count(obu_payload, payload_size);
  if (num_trailing_bits < 0) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Trailing bits are not found when OBU extension data is present.");
  }

  // Calculate total bits in payload
  size_t total_payload_bits = payload_size * 8;

  // Extension data bits = total - bits_read_before_extension -1 (ext flag) -
  // trailing bits
  if (total_payload_bits - bits_read_before_extension - 1 <
      (size_t)num_trailing_bits) {
    avm_internal_error(
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
        "Trailing bits are not found when OBU extension data is present.");
  }
  size_t extension_data_bits =
      total_payload_bits - bits_read_before_extension - 1 - num_trailing_bits;

  return (int)extension_data_bits;
}

// On success, returns 0. On failure, calls avm_internal_error and does not
// return.
static int read_uncompressed_header(AV2Decoder *pbi, OBU_TYPE obu_type,
                                    int obu_xlayer_id,
                                    struct avm_read_bit_buffer *rb) {
  AV2_COMMON *const cm = &pbi->common;
  const SequenceHeader *const seq_params = &cm->seq_params;
  const ContentInterpretation *const ci_params =
      &cm->ci_params_per_layer[cm->mlayer_id];
  const ColorInfo *const color_info = &ci_params->color_info;
  CurrentFrame *const current_frame = &cm->current_frame;
  FeatureFlags *const features = &cm->features;
  MACROBLOCKD *const xd = &pbi->dcb.xd;
  BufferPool *const pool = cm->buffer_pool;
  avm_s_frame_info *sframe_info = &pbi->sframe_info;
  init_bru_params(cm);
#if CONFIG_PARAKIT_COLLECT_DATA
  for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++) {
    cm->prob_models[i].frameNumber = current_frame->frame_number;
    cm->prob_models[i].frameType = current_frame->frame_type;
    for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
      for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
        for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
          for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
            beginningFrameFlag[i][j][k][l][h] = 1;
  }
#endif

  cm->cur_mfh_id = setup_multiframe_header_id(cm, obu_type, rb);

  int seq_header_id_for_frame_header = setup_sequence_header_id(cm, rb);
  assert(seq_header_id_for_frame_header >= 0);

  handle_sequence_header(pbi, obu_type, obu_xlayer_id,
                         seq_header_id_for_frame_header);

  if (cm->cur_mfh_id == 0) {
    handle_zero_cur_mfh_id(cm);
  } else {
    // Validate MFH frame dimensions when a MFH is present
    assert(cm->mfh_valid[cm->cur_mfh_id]);
    const MultiFrameHeader *mfh_param = &cm->mfh_params[cm->cur_mfh_id];
    if (mfh_param->mfh_frame_size_present_flag) {
      if (mfh_param->mfh_frame_width > seq_params->max_frame_width ||
          mfh_param->mfh_frame_height > seq_params->max_frame_height) {
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "MFH frame dimensions are larger than the sequence "
                           "header values.\n");
      }
    }
    // Check conformance for MFH according to dependency maps
    const int ref_mfh_mlayer_id = cm->mfh_params[cm->cur_mfh_id].mfh_mlayer_id;
    const int ref_mfh_tlayer_id = cm->mfh_params[cm->cur_mfh_id].mfh_tlayer_id;
    if (!seq_params->mlayer_dependency_map[cm->mlayer_id][ref_mfh_mlayer_id] ||
        !seq_params->tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
                                          [ref_mfh_tlayer_id]) {
      avm_internal_error(
          &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
          "The MFH selection for the current layer with mlayer_id=%d, "
          "tlayer_id=%d shall not depend on the MFH with mlayer_id=%d, "
          "tlayer_id=%d according to the layer dependency maps.",
          cm->mlayer_id, cm->tlayer_id, ref_mfh_mlayer_id, ref_mfh_tlayer_id);
    }
  }

  if (obu_type == OBU_RAS_FRAME &&
      seq_params->number_of_bits_for_lt_frame_id == 0) {
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                       "no OBU_RAS_FRAME shall be present when "
                       "number_of_bits_for_lt_frame_id == 0");
  }

  if (obu_type == OBU_BRIDGE_FRAME) {
    cm->bridge_frame_info.is_bridge_frame = 1;
    cm->bridge_frame_info.bridge_frame_ref_idx =
        avm_rb_read_literal(rb, seq_params->ref_frames_log2);
  } else {
    cm->bridge_frame_info.is_bridge_frame = 0;
    cm->bridge_frame_info.bridge_frame_ref_idx = INVALID_IDX;
  }

  if (obu_type == OBU_OPEN_LOOP_KEY || obu_type == OBU_CLOSED_LOOP_KEY) {
    if (seq_params->seq_lcr_id != LCR_ID_UNSPECIFIED) {
      activate_layer_configuration_record(pbi, seq_params->seq_lcr_id);
    } else {
      memset(&cm->lcr_params, 0, sizeof(struct LayerConfigurationRecord));
      memset(&cm->atlas_params, 0, sizeof(struct AtlasSegmentInfo));
    }
  }

  if (color_info->matrix_coefficients == AVM_CICP_MC_IDENTITY &&
      (seq_params->subsampling_x || seq_params->subsampling_y)) {
    avm_internal_error(
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
        "Matrix coefficients incompatible with non 4:4:4 color sampling.");
  }

  if (seq_params->single_picture_header_flag) {
    cm->show_existing_frame = 0;
    cm->immediate_output_picture = 1;
    cm->implicit_output_picture = 0;
    cm->cur_frame->immediate_output_picture = 1;
    cm->cur_frame->implicit_output_picture = 0;
    current_frame->frame_type = KEY_FRAME;
    pbi->decoding_first_frame = 1;
    reset_frame_buffers(cm);
    cm->cur_frame->frame_output_done = 0;
    if (pbi->this_is_first_vcl_obu_in_tu) reset_qm_list(pbi);
  } else {
    pbi->reset_decoder_state = 0;
    cm->show_existing_frame = 0;
    if (obu_type == OBU_LEADING_SEF || obu_type == OBU_REGULAR_SEF)
      return read_show_existing_frame(pbi, obu_type == OBU_REGULAR_SEF, rb);
    if (obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY) {
      current_frame->frame_type = KEY_FRAME;
      if (pbi->this_is_first_vcl_obu_in_tu) reset_qm_list(pbi);
    } else if (obu_type == OBU_RAS_FRAME || obu_type == OBU_SWITCH) {
      current_frame->frame_type = S_FRAME;
      cm->restricted_prediction_switch = avm_rb_read_bit(rb);
      if (cm->restricted_prediction_switch) {
        for (int i = 0; i < REF_FRAMES; i++) {
          if (cm->ref_frame_map[i] != NULL) {
            if (is_mlayer_transitively_dependent(
                    &cm->seq_params, cm->ref_frame_map[i]->mlayer_id,
                    cm->mlayer_id)) {
              if (is_frame_eligible_for_output(cm->ref_frame_map[i])) {
                const int doh_error = av2_output_frame_buffers(pbi, i);
                if (doh_error) {
                  avm_internal_error(
                      &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                      "Display order hint of an output picture is not unique"
                      " in the same (xlayer_id %d) layer.",
                      cm->xlayer_id);
                }
              }
              cm->ref_frame_map[i]->is_restricted = true;
              cm->ref_frame_map[i]->display_order_hint = REF_RESTRICTED_DOH;
            }
          }
        }

        // A restricted switch frame resets the DOH epoch for this layer.
        // This marks a CVS-internal epoch boundary where DOH derivation is
        // restarted.
        for (int ml = 0; ml <= cm->seq_params.max_mlayer_id; ml++) {
          if (is_mlayer_transitively_dependent(&cm->seq_params, ml,
                                               cm->mlayer_id)) {
            pbi->last_output_doh[cm->xlayer_id][ml] = -1;
          }
        }
        memset(&pbi->last_frame_unit, -1, sizeof(pbi->last_frame_unit));
        memset(&pbi->last_displayable_frame_unit, -1,
               sizeof(pbi->last_displayable_frame_unit));
      }
      if (obu_type == OBU_RAS_FRAME || cm->restricted_prediction_switch)
        reset_qm_list(pbi);
    } else if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP ||
               cm->bridge_frame_info.is_bridge_frame) {
      current_frame->frame_type = INTER_FRAME;
    } else {
      current_frame->frame_type =
          avm_rb_read_bit(rb) ? INTER_FRAME : INTRA_ONLY_FRAME;
    }
    current_frame->long_term_id = -1;
    if (current_frame->frame_type == KEY_FRAME) {
      const int long_term_id_plus_1 =
          avm_rb_read_literal(rb, seq_params->number_of_bits_for_lt_frame_id);
      current_frame->long_term_id = long_term_id_plus_1 - 1;
    }

    if (obu_type == OBU_RAS_FRAME || obu_type == OBU_OPEN_LOOP_KEY) {
      cm->num_ref_key_frames = 0;
      if (seq_params->number_of_bits_for_lt_frame_id != 0) {
        cm->num_ref_key_frames = avm_rb_read_literal(rb, 3);
        for (int i = 0; i < cm->num_ref_key_frames; i++) {
          cm->ref_long_term_ids[i] = avm_rb_read_literal(
              rb, seq_params->number_of_bits_for_lt_frame_id);
        }
      }
    }

    if (cm->bridge_frame_info.is_bridge_frame) {
      cm->immediate_output_picture = 0;
    } else {
      if (obu_type == OBU_OPEN_LOOP_KEY)
        cm->immediate_output_picture = 0;
      else
        cm->immediate_output_picture = avm_rb_read_bit(rb);
    }

    if (cm->immediate_output_picture == 0) pbi->is_arf_frame_present = 1;
    if (obu_type == OBU_OPEN_LOOP_KEY) pbi->is_fwd_kf_present = 1;
    if (cm->current_frame.frame_type == S_FRAME) {
      sframe_info->is_s_frame = 1;
      sframe_info->is_s_frame_at_altref = cm->immediate_output_picture ? 0 : 1;
    }
    if (seq_params->still_picture && (current_frame->frame_type != KEY_FRAME ||
                                      !cm->immediate_output_picture)) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Still pictures must be coded as shown keyframes");
    }
    if (!cm->immediate_output_picture) {
      if (cm->bridge_frame_info.is_bridge_frame) {
        cm->implicit_output_picture = 0;
      } else if (!seq_params->monotonic_output_order_flag) {
        cm->implicit_output_picture = avm_rb_read_bit(rb);
      } else {
        cm->implicit_output_picture = 0;
      }
    } else {
      cm->implicit_output_picture = 0;
    }

    cm->cur_frame->immediate_output_picture = cm->immediate_output_picture;
    cm->cur_frame->implicit_output_picture = cm->implicit_output_picture;
    cm->cur_frame->frame_output_done = 0;
  }
  av2_set_frame_sb_size(cm, cm->seq_params.sb_size);

  int frame_size_override_flag = 0;
  features->allow_intrabc = 0;
  features->allow_global_intrabc = 0;
  features->allow_local_intrabc = 0;
  features->primary_ref_frame = PRIMARY_REF_NONE;

  int signal_primary_ref_frame = -1;
  features->derived_primary_ref_frame = PRIMARY_REF_NONE;
  pbi->signal_primary_ref_frame = -1;

  features->cross_frame_context = CROSS_FRAME_CONTEXT_FORWARD;

  if (!seq_params->single_picture_header_flag) {
    if (obu_type == OBU_CLOSED_LOOP_KEY) {
      pbi->olk_encountered = 0;
    } else if (obu_type == OBU_OPEN_LOOP_KEY) {
      if (pbi->olk_encountered && pbi->this_is_first_vcl_obu_in_tu) {
        // This is the case when the first regular frame is another OLK
        // (0-4(K)-2-1-3-8(K)...
        lock_buffer_pool(pool);
        reset_buffer_other_than_OLK(pbi);
        unlock_buffer_pool(pool);
      }
      pbi->olk_encountered = 1;
    } else if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type) &&
               pbi->this_is_first_vcl_obu_in_tu) {
      lock_buffer_pool(pool);
      reset_buffer_other_than_OLK(pbi);
      unlock_buffer_pool(pool);
      pbi->olk_encountered = 0;
    }
    if (cm->bridge_frame_info.is_bridge_frame) {
      frame_size_override_flag = 1;
    } else {
      frame_size_override_flag = frame_is_sframe(cm) ? 1 : avm_rb_read_bit(rb);
      current_frame->order_hint = avm_rb_read_literal(
          rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
      current_frame->display_order_hint = get_disp_order_hint(
          cm, obu_type, pbi->random_accessed, false, -1, -1);
      check_consistent_disp_order_hint_derivation(pbi, obu_type,
                                                  pbi->random_accessed);
      current_frame->frame_number = current_frame->order_hint;
      current_frame->display_order_hint_restricted =
          current_frame->display_order_hint;

      // DOH constraint checks
      const int msdo_doh = pbi->common.msdo_params.msdo_doh_constraint_flag;
      const int lcr_doh =
          (pbi->active_lcr != NULL && pbi->active_lcr->is_global &&
           pbi->active_lcr->global_lcr.lcr_doh_constraint_flag);

      // Conformance: when monotonic_output_order_flag is 0 in any activated
      // sequence header, msdo_doh_constraint_flag shall be 1.
      // Only applies when an MSDO OBU is present (multistream decoder mode).
      // The equivalent lcr_doh_constraint_flag check is in
      // av2_decode_frame_headers_obu() at LCR activation time.
      if (pbi->multistream_decoder_mode &&
          !seq_params->monotonic_output_order_flag && !msdo_doh) {
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                           "msdo_doh_constraint_flag must be 1 when "
                           "monotonic_output_order_flag is 0");
      }

      const int doh_active = (msdo_doh || lcr_doh);
      if (doh_active) {
        const int order_hint_bits =
            seq_params->order_hint_info.order_hint_bits_minus_1 + 1;

        // All pictures in a TU must use the same OrderHintBits
        if (!pbi->doh_tu_order_hint_bits_set) {
          pbi->doh_tu_order_hint_bits = order_hint_bits;
          pbi->doh_tu_order_hint_bits_set = 1;
        } else if (pbi->doh_tu_order_hint_bits != order_hint_bits) {
          avm_internal_error(
              &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
              "DOH constraint: all pictures in a TU must use the same "
              "OrderHintBits");
        }
      }
    }

    if (obu_type == OBU_OPEN_LOOP_KEY) {
      if (cm->implicit_output_picture) {
        pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
      } else {
        // prevent resetting it to -1 when {OLK(s) - OLK(h)} when a hidden OLK
        // comes after a shown OLK
        if (pbi->this_is_first_vcl_obu_in_tu ||
            pbi->last_olk_tu_display_order_hint == -1) {
          pbi->last_olk_tu_display_order_hint = -1;
        }
      }
    } else if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type)) {
      if (pbi->last_olk_tu_display_order_hint == -1 &&
          !pbi->this_is_first_vcl_obu_in_tu &&
          (cm->implicit_output_picture || cm->immediate_output_picture)) {
        // regular frame in the same temporal unit with a hidden olk
        pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
      }
    }

    if (!frame_is_sframe(cm) && !frame_is_intra_only(cm)) {
      if (!cm->bridge_frame_info.is_bridge_frame) {
        signal_primary_ref_frame = avm_rb_read_bit(rb);
        if (obu_type != OBU_REGULAR_TIP && obu_type != OBU_LEADING_TIP)
          features->cross_frame_context = avm_rb_read_bit(rb)
                                              ? CROSS_FRAME_CONTEXT_DISABLED
                                              : CROSS_FRAME_CONTEXT_FORWARD;
        pbi->signal_primary_ref_frame = signal_primary_ref_frame;
        if (signal_primary_ref_frame) {
          features->primary_ref_frame =
              avm_rb_read_literal(rb, PRIMARY_REF_BITS);
          features->derived_primary_ref_frame = features->primary_ref_frame;
        }
      }
    }
  }

  if (obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY) {
    if (obu_type == OBU_CLOSED_LOOP_KEY && seq_params->max_mlayer_id == 0) {
      current_frame->refresh_frame_flags = ((1 << seq_params->ref_frames) - 1);
    } else if (obu_type == OBU_OPEN_LOOP_KEY ||
               seq_params->max_mlayer_id != 0) {
      const int short_refresh_frame_flags =
          cm->seq_params.enable_short_refresh_frame_flags;
      const int refresh_frame_flags_bits = short_refresh_frame_flags
                                               ? seq_params->ref_frames_log2
                                               : seq_params->ref_frames;

      if (short_refresh_frame_flags) {
        const int refresh_idx =
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
        current_frame->refresh_frame_flags = 1 << refresh_idx;
      } else {
        current_frame->refresh_frame_flags =
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
      }
    }
    if (obu_type == OBU_CLOSED_LOOP_KEY && pbi->this_is_first_vcl_obu_in_tu) {
      for (int ref_pos = 0; ref_pos < seq_params->ref_frames; ref_pos++) {
        if (!(current_frame->refresh_frame_flags >> ref_pos & 1u)) {
          decrease_ref_count(cm->ref_frame_map[ref_pos], pool);
          cm->ref_frame_map[ref_pos] = NULL;
        }
      }
    }
    if (obu_type == OBU_OPEN_LOOP_KEY) {
      cm->olk_refresh_frame_flags[cm->mlayer_id] =
          current_frame->refresh_frame_flags;
    }
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
      cm->remapped_ref_idx[i] = INVALID_IDX;
    }
    if (pbi->need_resync) {
      reset_ref_frame_map(cm);
      pbi->need_resync = 0;
    }
  } else {
    const int short_refresh_frame_flags =
        cm->seq_params.enable_short_refresh_frame_flags && !frame_is_sframe(cm);
    const int refresh_frame_flags_bits = short_refresh_frame_flags
                                             ? seq_params->ref_frames_log2
                                             : seq_params->ref_frames;

    if (current_frame->frame_type == INTRA_ONLY_FRAME) {
      if (short_refresh_frame_flags) {
        const bool has_refresh_frame_flags = avm_rb_read_bit(rb);
        if (has_refresh_frame_flags) {
          const int refresh_idx =
              avm_rb_read_literal(rb, refresh_frame_flags_bits);
          if (refresh_idx >= seq_params->ref_frames) {
            avm_internal_error(
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                "refresh_idx must be less than %d but is set to %d",
                seq_params->ref_frames, refresh_idx);
          }
          current_frame->refresh_frame_flags = 1 << refresh_idx;
        } else {
          current_frame->refresh_frame_flags = 0;
        }
      } else {
        current_frame->refresh_frame_flags =
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
      }
      assert(seq_params->ref_frames >= 1);
      if (seq_params->ref_frames > 1 &&
          current_frame->refresh_frame_flags ==
              ((1 << seq_params->ref_frames) - 1)) {
        avm_internal_error(
            &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
            "Intra only frames cannot refresh all the available entries in "
            "the decoded picture buffer (DPB) if the DPB size is larger than "
            "1. A key-frame should be inserted to refresh all entries.");
      }
      if (pbi->need_resync) {
        reset_ref_frame_map(cm);
        pbi->need_resync = 0;
      }
    } else if (pbi->need_resync != 1) { /* Skip if need resync */
      if (pbi->obu_type == OBU_RAS_FRAME && seq_params->max_mlayer_id == 0) {
        current_frame->refresh_frame_flags =
            ras_frame_refresh_frame_flags_derivation(pbi);
      } else if (frame_is_sframe(cm)) {
        current_frame->refresh_frame_flags =
            avm_rb_read_literal(rb, seq_params->ref_frames);
      } else {
        if (cm->bridge_frame_info.is_bridge_frame) {
          cm->bridge_frame_info.bridge_frame_overwrite_flag =
              avm_rb_read_bit(rb);
          if (!cm->bridge_frame_info.bridge_frame_overwrite_flag) {
            current_frame->refresh_frame_flags =
                1 << cm->bridge_frame_info.bridge_frame_ref_idx;
          }
        }

        if (!cm->bridge_frame_info.is_bridge_frame ||
            cm->bridge_frame_info.bridge_frame_overwrite_flag) {
          if (short_refresh_frame_flags) {
            const bool has_refresh_frame_flags = avm_rb_read_bit(rb);
            if (has_refresh_frame_flags) {
              const int refresh_idx =
                  avm_rb_read_literal(rb, refresh_frame_flags_bits);
              if (refresh_idx >= seq_params->ref_frames) {
                avm_internal_error(
                    &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                    "refresh_idx must be less than %d but is set to %d",
                    seq_params->ref_frames, refresh_idx);
              }
              current_frame->refresh_frame_flags = 1 << refresh_idx;
            } else {
              current_frame->refresh_frame_flags = 0;
            }
          } else {
            current_frame->refresh_frame_flags =
                avm_rb_read_literal(rb, refresh_frame_flags_bits);
          }
        }
      }
    }
  }

  if (cm->immediate_output_picture == 0 &&
      current_frame->refresh_frame_flags == 0) {
    avm_internal_error(
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
        "If immediate_output_frame is equal to 0, it is a requirement "
        "of bitstream conformance that refresh_frame_flags is not equal to 0.");
  }

  if (cm->is_leading_picture == 1) {
    // other obu_types cannot overwrite the slots OBU_OPEN_LOOP_KEY is stored
    for (int idx = 0; idx <= seq_params->max_mlayer_id; idx++) {
      if (cm->olk_refresh_frame_flags[idx] == -1) continue;
      if (current_frame->refresh_frame_flags &
          cm->olk_refresh_frame_flags[idx]) {
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                           "refresh_frame_flags(%d) of this frame(%s, doh=%d "
                           "layerid=%d) overwrites "
                           "one or more OLKs of mlyaer id, %d at %d in the "
                           "reference list",
                           current_frame->refresh_frame_flags,
                           avm_obu_type_to_string(obu_type),
                           cm->current_frame.display_order_hint, cm->mlayer_id,
                           idx, cm->olk_refresh_frame_flags[idx]);
      }
    }
  }

  // Record the refresh slots of regular VCL OBUs co-signalled with OLK in the
  // same temporal unit so that reset_buffer_other_than_OLK() preserves them
  // when the first regular temporal unit begins.
  if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type) &&
      pbi->this_is_first_vcl_obu_in_tu == 0) {
    memcpy(&cm->prev_olk_co_vcl_refresh_frame_flags[0],
           &cm->olk_co_vcl_refresh_frame_flags[0],
           MAX_NUM_MLAYERS * sizeof(cm->olk_co_vcl_refresh_frame_flags[0]));
    if (cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] == -1)
      cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] = 0;
    cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] |=
        current_frame->refresh_frame_flags;
  }

  if (pbi->obu_type == OBU_RAS_FRAME || pbi->obu_type == OBU_OPEN_LOOP_KEY) {
    check_long_term_ids_exist(pbi);
  }

  if (pbi->obu_type == OBU_RAS_FRAME) {
    mark_reference_frames_with_long_term_ids(pbi);
  }

  features->allow_lf_sub_pu = 0;
  if (current_frame->frame_type == KEY_FRAME) {
    cm->current_frame.pyramid_level = 1;
    cm->current_frame.tlayer_id = cm->tlayer_id;
    cm->current_frame.mlayer_id = cm->mlayer_id;
    cm->current_frame.xlayer_id = cm->xlayer_id;
    features->tip_frame_mode = TIP_FRAME_DISABLED;
    setup_frame_size(cm, frame_size_override_flag, rb);
    read_screen_content_params(cm, rb);
    read_intrabc_params(cm, rb);
    features->allow_ref_frame_mvs = 0;
    cm->prev_frame = NULL;

    cm->cur_frame->num_ref_frames = 0;
  } else {
    cm->current_frame.tlayer_id = cm->tlayer_id;
    cm->current_frame.mlayer_id = cm->mlayer_id;
    cm->current_frame.xlayer_id = cm->xlayer_id;

    features->allow_ref_frame_mvs = 0;
    features->tip_frame_mode = TIP_FRAME_DISABLED;
    if (current_frame->frame_type == INTRA_ONLY_FRAME) {
      setup_frame_size(cm, frame_size_override_flag, rb);
      read_screen_content_params(cm, rb);
      read_intrabc_params(cm, rb);

      cm->cur_frame->num_ref_frames = 0;

    } else if (pbi->need_resync != 1) { /* Skip if need resync */
      int use_olk_ref_only = pbi->olk_encountered &&
                             av2_is_regular_non_olk_obu(obu_type) &&
                             pbi->this_is_first_vcl_obu_in_tu == 0;
      // Implicitly derive the reference mapping
      init_ref_map_pair(cm, cm->ref_frame_map_pairs,
                        current_frame->frame_type == KEY_FRAME,
                        pbi->obu_type == OBU_RAS_FRAME, use_olk_ref_only);

      if (cm->bridge_frame_info.is_bridge_frame) {
        current_frame->order_hint =
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
                ->order_hint;
        current_frame->display_order_hint =
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
                ->display_order_hint;
        current_frame->frame_number =
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
                ->order_hint;
      }

      // For implicit reference mode, the reference mapping is derived without
      // considering the resolution first. Later, setup_frame_size_with_refs
      // uses the reference information to obtain the resolution.
      av2_get_ref_frames(cm, current_frame->display_order_hint, 0, 0,
                         cm->ref_frame_map_pairs);

      // Reference rankings will be implicitly derived in av2_get_ref_frames,
      // but if the explicit mode is used, reference indices will be signaled,
      // which overwrites the implictly derived ones.
      int explicit_ref_frame_map = -1;
      // explicit_ref_frame_map is always true when frame_type is s_frame.
      // explicit_ref_frame_map is always false when frame_type is key_frame or
      // intra_only frame. explicit_ref_frame_map is always false when
      // seq_params->explicit_ref_frame_map is false and frame_type is not
      // s_frame.
      if (frame_is_sframe(cm))
        explicit_ref_frame_map = 1;
      else if (frame_is_intra_only(cm))
        explicit_ref_frame_map = 0;
      else if (cm->bridge_frame_info.is_bridge_frame)
        explicit_ref_frame_map = 0;
      else {
        if (seq_params->enable_explicit_ref_frame_map)
          explicit_ref_frame_map = avm_rb_read_bit(rb);
        else
          explicit_ref_frame_map = 0;
      }

      if (explicit_ref_frame_map) {
        cm->ref_frames_info.num_total_refs =
            avm_rb_read_literal(rb, MAX_REFS_PER_FRAME_LOG2);
        const int max_num_ref_frames =
            AVMMIN(seq_params->ref_frames, INTER_REFS_PER_FRAME);
        // Check whether num_total_refs read is valid
        if (current_frame->frame_type != S_FRAME)
          if (cm->ref_frames_info.num_total_refs < 0 ||
              cm->ref_frames_info.num_total_refs > max_num_ref_frames)
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                               "Invalid num_total_refs");
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
          int ref = avm_rb_read_literal(rb, seq_params->ref_frames_log2);
          if (ref >= seq_params->ref_frames) {
            avm_internal_error(
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                "Explicit ref frame idx must be less than %d but is set to %d",
                seq_params->ref_frames, ref);
          }

          // Most of the time, streams start with a keyframe. In that case,
          // ref_frame_map will have been filled in at that point and will not
          // contain any NULLs. However, streams are explicitly allowed to start
          // with an intra-only frame, so long as they don't then signal a
          // reference to a slot that hasn't been set yet. That's what we are
          // checking here.
          if (cm->ref_frame_map[ref] == NULL)
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                               "Inter frame requests nonexistent reference");
          // mlayer and tlayer scalability related bitstream constraints for the
          // explicit reference frame signaling
          const int cur_mlayer_id = current_frame->mlayer_id;
          const int ref_mlayer_id = cm->ref_frame_map[ref]->mlayer_id;
          if (!is_mlayer_scalable_and_dependent(seq_params, cur_mlayer_id,
                                                ref_mlayer_id)) {
            avm_internal_error(
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                "Unsupported bitstream: embedded layer scalability shall be "
                "maintained in explicit reference map signaling.");
          }
          const int cur_tlayer_id = current_frame->tlayer_id;
          const int ref_tlayer_id = cm->ref_frame_map[ref]->tlayer_id;
          if (!is_tlayer_scalable_and_dependent(seq_params, cur_tlayer_id,
                                                ref_tlayer_id, cur_mlayer_id)) {
            avm_internal_error(
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                "Unsupported bitstream: temporal layer scalability shall be "
                "maintained in explicit reference map signaling.");
          }
          cm->remapped_ref_idx[i] = ref;
        }
      }
      if (!frame_is_sframe(cm) && frame_size_override_flag &&
          !cm->bridge_frame_info.is_bridge_frame) {
        setup_frame_size_with_refs(cm, explicit_ref_frame_map, rb);
      } else {
        setup_frame_size(cm, frame_size_override_flag, rb);
      }

      // Overwrite the reference mapping considering the resolution
      if (!explicit_ref_frame_map) {
        av2_get_ref_frames(cm, current_frame->display_order_hint, 1, 0,
                           cm->ref_frame_map_pairs);

        // Note: The following if block implements bitstream constraint checks
        // for consistent reference frame mapping when (embedded or temporal)
        // layers are selectively dropped based on operating points. The
        // following code provides checks for possible operating point
        // combinations and decoders may choose to simplify this check depending
        // on the desired operating point(s) specified in the operating point
        // set (OPS).
        if (pbi->dec_op_params.isValid &&
            is_layer_within_op_profiles(pbi, cm->tlayer_id, cm->mlayer_id)) {
          int ref_index_list[INTER_REFS_PER_FRAME];
          int constrained_ref_index_list[INTER_REFS_PER_FRAME];
          // number of layer-drop masks
          const int num_mlayer_masks = 1 << (cm->mlayer_id + 1);
          const int num_tlayer_masks = 1 << (cm->tlayer_id + 1);
          // derive operating point masks for mlayer and tlayer
          int op_mlayer_mask, op_tlayer_mask;
          create_op_masks_from_profiles(pbi, &op_tlayer_mask, &op_mlayer_mask);
          // Check consistency for subsets of OPs that would include the current
          // frame. Skip subsets where the current frame's layer would be
          // dropped.
          for (int ml = 0; ml < num_mlayer_masks; ml++) {
            for (int tl = 0; tl < num_tlayer_masks; tl++) {
              int mlayer_mask = ml & op_mlayer_mask;
              int tlayer_mask = tl & op_tlayer_mask;
              // Skip subsets that would drop the current frame's layer.
              if (is_layer_dropped(cm->mlayer_id, mlayer_mask) ||
                  is_layer_dropped(cm->tlayer_id, tlayer_mask))
                continue;
              // Skip subsets with unsatisfied layer dependencies.
              if (check_missing_layer_dependency(cm, mlayer_mask, tlayer_mask))
                continue;
              // derive OP constrained mapping and store in
              // cm->op_remapped_ref_idx[]
              const int default_map_idx = av2_get_op_constrained_ref_frames(
                  cm, current_frame->display_order_hint, 0,
                  cm->ref_frame_map_pairs, mlayer_mask, tlayer_mask);
              for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
                // get constrained mapped reference list
                constrained_ref_index_list[i] = cm->op_remapped_ref_idx[i];
                // set ref_index_list for lower operating points
                const int map_idx = cm->remapped_ref_idx[i];
                ref_index_list[i] = map_idx;
                const RefFrameMapPair ref_info =
                    cm->ref_frame_map_pairs[map_idx];
                if (is_layer_dropped(ref_info.mlayer_id, mlayer_mask) ||
                    is_layer_dropped(ref_info.tlayer_id, tlayer_mask)) {
                  ref_index_list[i] = default_map_idx;
                }
              }
              // check if reference mapping is consistent accross possible
              // operating points
              if (!is_reference_mapping_consistent(
                      ref_index_list, constrained_ref_index_list)) {
                avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                                   "Inconsistent reference index mapping "
                                   "accross different operating points.");
              }
            }
          }
        }
      }
      // Check to make sure all reference frames have valid dimensions.
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
        const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i);
        int valid_ref_frame = valid_ref_frame_size(ref_frame->buf.y_crop_width,
                                                   ref_frame->buf.y_crop_height,
                                                   cm->width, cm->height);
        if (!valid_ref_frame && !ref_frame->is_restricted)
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                             "Referenced frame has invalid size");
      }
      if (obu_type != OBU_LEADING_TIP && obu_type != OBU_REGULAR_TIP &&
          current_frame->frame_type == INTER_FRAME) {
        setup_bru_active_info(cm, rb);
        if (cm->bru.enabled) {
          const RefCntBuffer *const bru_ref =
              get_ref_frame_buf(cm, cm->bru.update_ref_idx);
          if (bru_ref != NULL && bru_ref->is_restricted) {
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                               "Invalid BRU Ref: restricted reference buffer");
          }
          if (bru_ref == NULL) {
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                               "Invalid BRU Ref: invalid reference buffer");
          } else {
            if (bru_ref->width != cm->width || bru_ref->height != cm->height) {
              avm_internal_error(
                  &cm->error, AVM_CODEC_CORRUPT_FRAME,
                  "BRU reference frame size is not the same as current frame");
            }
          }
        }
      }
      if (cm->bru.frame_inactive_flag ||
          cm->bridge_frame_info.is_bridge_frame) {
        cm->features.disable_cdf_update = 1;
      }
      cm->ref_frames_info.num_same_ref_compound =
          AVMMIN(cm->seq_params.num_same_ref_compound,
                 cm->ref_frames_info.num_total_refs);
      if (features->primary_ref_frame >= cm->ref_frames_info.num_total_refs &&
          features->primary_ref_frame != PRIMARY_REF_NONE) {
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                           "Invalid primary_ref_frame");
      }
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
        int ref = 0;
        if (!explicit_ref_frame_map) {
          if (cm->bridge_frame_info.is_bridge_frame) {
            const int ref_frame =
                cm->bridge_frame_info.bridge_frame_ref_idx_remapped;
            assert(!is_tip_ref_frame(
                ref_frame));  // TIP frame reference is not allowed
            ref = get_ref_frame_map_idx(cm, ref_frame);
          } else {
            ref = cm->remapped_ref_idx[i];
            if (cm->ref_frame_map[ref] == NULL)
              avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                                 "Inter frame requests nonexistent reference");
          }
        } else {
          ref = cm->remapped_ref_idx[i];
        }
        // find corresponding bru ref idx given explicit_bru_idx
        if (cm->bru.enabled && cm->bru.update_ref_idx == i) {
          cm->bru.ref_disp_order = cm->ref_frame_map[ref]->display_order_hint;
          cm->bru.explicit_ref_idx = ref;
        }
        // Check valid for referencing
        if (pbi->valid_for_referencing[ref] == 0)
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                             "Reference frame not valid for referencing");
        // Check that co-VCL frames in an OLK TU only reference frames written
        // in the current TU.
        if (pbi->olk_encountered && !pbi->this_is_first_vcl_obu_in_tu &&
            av2_is_regular_non_olk_obu(obu_type)) {
          const RefCntBuffer *const ref_buf = cm->ref_frame_map[ref];
          const int ref_mlayer_id = ref_buf->mlayer_id;
          const int ref_tlayer_id = ref_buf->tlayer_id;
          const int cur_mlayer_id = current_frame->mlayer_id;
          const int cur_tlayer_id = current_frame->tlayer_id;
          // Only check references from layers the current frame depends on.
          if (is_mlayer_scalable_and_dependent(&cm->seq_params, cur_mlayer_id,
                                               ref_mlayer_id) &&
              is_tlayer_scalable_and_dependent(&cm->seq_params, cur_tlayer_id,
                                               ref_tlayer_id, cur_mlayer_id)) {
            // Build a bitmask of DPB slots written in the current TU from all
            // mlayers that the current frame depends on.
            int current_tu_ref_flags = 0;
            for (int layer = 0; layer <= cm->seq_params.max_mlayer_id;
                 layer++) {
              if (!is_mlayer_scalable_and_dependent(&cm->seq_params,
                                                    cur_mlayer_id, layer))
                continue;
              if (cm->olk_refresh_frame_flags[layer] != -1)
                current_tu_ref_flags |= cm->olk_refresh_frame_flags[layer];
              if (cm->prev_olk_co_vcl_refresh_frame_flags[layer] != -1)
                current_tu_ref_flags |=
                    cm->prev_olk_co_vcl_refresh_frame_flags[layer];
            }
            if (!((current_tu_ref_flags >> ref) & 1)) {
              avm_internal_error(
                  &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                  "Co-VCL frame (doh=%d, mlayer=%d) in OLK TU references DPB "
                  "slot %d (mlayer=%d, tlayer=%d) which was not written in the "
                  "current temporal unit",
                  current_frame->display_order_hint, cur_mlayer_id, ref,
                  ref_mlayer_id, ref_tlayer_id);
            }
          }
        }
      }
      if (cm->bru.update_ref_idx != -1) {
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
          if (cm->bru.update_ref_idx != i) {
            if (cm->ref_frame_map[cm->bru.explicit_ref_idx] ==
                cm->ref_frame_map[cm->remapped_ref_idx[i]]) {
              avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                                 "Only one reference can be updated for BRU");
            }
          }
        }
        // The BRU reference buffer slot must be refreshed by this frame;
        if (!(current_frame->refresh_frame_flags &
              (1 << cm->bru.explicit_ref_idx))) {
          avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                             "BRU ref (explicit_ref_idx=%d) must be included "
                             "in refresh_frame_flags (0x%x)",
                             cm->bru.explicit_ref_idx,
                             current_frame->refresh_frame_flags);
        }
      }
      if (cm->bru.enabled) {
        int n_future = 0;
        int cur_frame_disp = (int)current_frame->display_order_hint;
        for (int i = 0; i < cm->seq_params.ref_frames; i++) {
          const RefCntBuffer *const buf = cm->ref_frame_map[i];
          if (buf) {
            if (buf->is_restricted) continue;
            int ref_disp = (int)buf->display_order_hint;
            const int disp_diff = get_relative_dist(
                &cm->seq_params.order_hint_info, cur_frame_disp, ref_disp);
            if (disp_diff < 0) {
              n_future++;
              break;
            }
          }
        }
        if (n_future > 0) {
          avm_internal_error(&cm->error, AVM_CODEC_ERROR,
                             "BRU can only use in LD");
        }
      }
      // With explicit_ref_frame_map, cm->remapped_ref_idx has been
      // overwritten. The reference lists also needs to be reset.
      if (explicit_ref_frame_map) {
        RefScoreData scores[REF_FRAMES];
        for (int i = 0; i < seq_params->ref_frames; i++)
          scores[i].score = INT_MAX;
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; i++) {
          if (cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted) {
            scores[i].distance = (1 << (RELATIVE_DIST_BITS - 1)) - 1;
          } else {
            scores[i].score = i;
            int ref = cm->remapped_ref_idx[i];
            scores[i].distance =
                get_relative_dist(&seq_params->order_hint_info,
                                  (int)current_frame->display_order_hint,
                                  (int)cm->ref_frame_map_pairs[ref].disp_order);
          }
          cm->ref_frames_info.ref_frame_distance[i] = scores[i].distance;
        }
        update_num_restricted_ref(cm);
        av2_get_past_future_cur_ref_lists(cm, scores);
      }
      cm->cur_frame->num_ref_frames = cm->ref_frames_info.num_total_refs;

      if (frame_might_allow_ref_frame_mvs(cm))
        features->allow_ref_frame_mvs = avm_rb_read_bit(rb);
      else
        features->allow_ref_frame_mvs = 0;
      if (features->allow_ref_frame_mvs &&
          cm->ref_frames_info.num_total_refs > 1 &&
          block_size_high[seq_params->sb_size] > 64) {
        // Get the TMVP sampling mode
        cm->tmvp_sample_step = avm_rb_read_bit(rb) + 1;
        cm->tmvp_sample_stepl2 = cm->tmvp_sample_step == 1 ? 0 : 1;
      } else {
        cm->tmvp_sample_step = 1;
        cm->tmvp_sample_stepl2 = 0;
      }

      cm->tip_global_motion.as_int = 0;
      cm->tip_interp_filter = MULTITAP_SHARP;
      cm->tip_global_wtd_index = 0;
      cm->has_both_sides_refs = (cm->ref_frames_info.num_future_refs > 0) &&
                                (cm->ref_frames_info.num_past_refs > 0);
      if (cm->seq_params.enable_tip && features->allow_ref_frame_mvs &&
          cm->ref_frames_info.num_total_refs >= 2 &&
          !cm->bridge_frame_info.is_bridge_frame &&
          !cm->bru.frame_inactive_flag) {
        if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP) {
          features->tip_frame_mode = TIP_FRAME_AS_OUTPUT;
        } else {
          features->tip_frame_mode =
              avm_rb_read_bit(rb) ? TIP_FRAME_AS_REF : TIP_FRAME_DISABLED;
        }

        read_frame_opfl_refine_type(cm, rb);

        if (features->tip_frame_mode && cm->seq_params.enable_tip_hole_fill) {
          features->allow_tip_hole_fill = avm_rb_read_bit(rb);
        } else {
          features->allow_tip_hole_fill = false;
        }

        if (features->tip_frame_mode && is_unequal_weighted_tip_allowed(cm)) {
          cm->tip_global_wtd_index = avm_rb_read_literal(rb, 3);
        }

        if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
          int all_zero = avm_rb_read_bit(rb);
          if (!all_zero) {
            cm->tip_global_motion.as_mv.row = avm_rb_read_literal(rb, 4);
            cm->tip_global_motion.as_mv.col = avm_rb_read_literal(rb, 4);
            if (cm->tip_global_motion.as_mv.row != 0) {
              int sign = avm_rb_read_bit(rb);
              if (sign) cm->tip_global_motion.as_mv.row *= -1;
            }
            if (cm->tip_global_motion.as_mv.col != 0) {
              int sign = avm_rb_read_bit(rb);
              if (sign) cm->tip_global_motion.as_mv.col *= -1;
            }
          }

          if (avm_rb_read_bit(rb)) {
            cm->tip_interp_filter = MULTITAP_SHARP;
          } else if (avm_rb_read_bit(rb)) {
            cm->tip_interp_filter = EIGHTTAP_REGULAR;
          } else {
            cm->tip_interp_filter = EIGHTTAP_SMOOTH;
          }
        }
      } else {
        features->tip_frame_mode = TIP_FRAME_DISABLED;
        if (!cm->bru.frame_inactive_flag &&
            !cm->bridge_frame_info.is_bridge_frame)
          read_frame_opfl_refine_type(cm, rb);
      }

      if (features->tip_frame_mode != TIP_FRAME_AS_OUTPUT &&
          !cm->bridge_frame_info.is_bridge_frame &&
          !cm->bru.frame_inactive_flag) {
        read_screen_content_params(cm, rb);
        read_intrabc_params(cm, rb);
        read_frame_max_drl_bits(cm, rb);
        if (features->cur_frame_force_integer_mv) {
          features->fr_mv_precision = MV_PRECISION_ONE_PEL;
        } else {
          if (avm_rb_read_bit(rb)) {
            features->fr_mv_precision = MV_PRECISION_QTR_PEL;
          } else {
            features->fr_mv_precision = avm_rb_read_bit(rb)
                                            ? MV_PRECISION_ONE_EIGHTH_PEL
                                            : MV_PRECISION_HALF_PEL;
          }

          features->most_probable_fr_mv_precision = features->fr_mv_precision;
        }
        if (features->fr_mv_precision == MV_PRECISION_ONE_PEL) {
          features->use_pb_mv_precision = 0;
        } else {
          features->use_pb_mv_precision = cm->seq_params.enable_flex_mvres;
        }

        features->interp_filter = read_frame_interp_filter(rb);
        int seq_enabled_motion_modes = cm->seq_params.seq_enabled_motion_modes;

        if (cm->seq_params.seq_frame_motion_modes_present_flag) {
          int frame_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
          for (int motion_mode = INTERINTRA; motion_mode < MOTION_MODES;
               motion_mode++) {
            if (seq_enabled_motion_modes & (1 << motion_mode)) {
              int enabled = avm_rb_read_bit(rb);
              if (enabled) {
                frame_enabled_motion_modes |= (1 << motion_mode);
              }
            }
          }
          features->enabled_motion_modes = frame_enabled_motion_modes;
        } else {
          features->enabled_motion_modes =
              cm->seq_params.seq_enabled_motion_modes;
        }
      }
    }

    if (!(current_frame->frame_type == INTRA_ONLY_FRAME) &&
        pbi->need_resync != 1) {
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
        const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, i);
        if (!ref_buf) continue;
        struct scale_factors *const ref_scale_factors =
            get_ref_scale_factors(cm, i);
        av2_setup_scale_factors_for_frame(
            ref_scale_factors, ref_buf->buf.y_crop_width,
            ref_buf->buf.y_crop_height, cm->width, cm->height);
        if ((!av2_is_valid_scale(ref_scale_factors)))
          avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                             "Reference frame has invalid dimensions");
      }

      if (cm->seq_params.enable_tip) {
        const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, TIP_FRAME);
        if (ref_buf) {
          struct scale_factors *const ref_scale_factors =
              get_ref_scale_factors(cm, TIP_FRAME);
          av2_setup_scale_factors_for_frame(
              ref_scale_factors, ref_buf->buf.y_crop_width,
              ref_buf->buf.y_crop_height, cm->width, cm->height);
          if ((!av2_is_valid_scale(ref_scale_factors)))
            avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
                               "Reference frame has invalid dimensions");
        }
      }
    }
  }

  av2_setup_frame_buf_refs(cm);

  av2_setup_frame_sign_bias(cm);

  cm->cur_frame->frame_type = current_frame->frame_type;
  cm->cur_frame->is_restricted_switch_frame =
      (current_frame->frame_type == S_FRAME &&
       cm->restricted_prediction_switch);
  cm->cur_frame->mlayer_id = cm->mlayer_id;
  cm->cur_frame->xlayer_id = cm->xlayer_id;
  cm->cur_frame->stream_id = av2_get_stream_index(cm, cm->xlayer_id);
  validate_references(pbi);

  cm->cur_frame->buf.bit_depth = seq_params->bit_depth;
  cm->cur_frame->buf.color_primaries = color_info->color_primaries;
  cm->cur_frame->buf.transfer_characteristics =
      color_info->transfer_characteristics;
  cm->cur_frame->buf.matrix_coefficients = color_info->matrix_coefficients;
  cm->cur_frame->buf.monochrome = seq_params->monochrome;
  if (ci_params->ci_chroma_sample_position_present_flag)
    cm->cur_frame->buf.chroma_sample_position =
        ci_params->ci_chroma_sample_position[0];
  else
    cm->cur_frame->buf.chroma_sample_position = AVM_CSP_UNSPECIFIED;
  cm->cur_frame->buf.color_range = color_info->full_range_flag;
  cm->cur_frame->buf.render_width = cm->render_width;
  cm->cur_frame->buf.render_height = cm->render_height;

  YV12_BUFFER_CONFIG *tip_frame_buf = &cm->tip_ref.tmp_tip_frame->buf;
  tip_frame_buf->bit_depth = seq_params->bit_depth;
  tip_frame_buf->color_primaries = color_info->color_primaries;
  tip_frame_buf->transfer_characteristics =
      color_info->transfer_characteristics;
  tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
  tip_frame_buf->monochrome = seq_params->monochrome;
  if (ci_params->ci_chroma_sample_position_present_flag)
    tip_frame_buf->chroma_sample_position =
        ci_params->ci_chroma_sample_position[0];
  else
    tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
  tip_frame_buf->color_range = color_info->full_range_flag;
  tip_frame_buf->render_width = cm->render_width;
  tip_frame_buf->render_height = cm->render_height;

  if (pbi->need_resync) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Keyframe / intra-only frame required to reset decoder"
                       " state");
  }
  xd->bd = (int)seq_params->bit_depth;
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
    // Set parameters corresponding to no filtering.
    struct loopfilter *lf = &cm->lf;
    lf->apply_deblocking_filter[0] = 0;
    lf->apply_deblocking_filter[1] = 0;
    cm->cdef_info.cdef_frame_enable = 0;
    cm->gdf_info.gdf_mode = 0;
    // set cm->rst_info and copy it to cur_frame->rst_info
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
      cm->rst_info[plane].frame_restoration_type = RESTORE_NONE;
      cm->rst_info[plane].frame_filters_on = 0;
      av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[plane],
                                 &cm->rst_info[plane]);
      cm->cur_frame->rst_info[plane].num_filter_classes = 0;
      cm->cur_frame->rst_info[plane].rst_ref_pic_idx = 0;
      cm->cur_frame->rst_info[plane].temporal_pred_flag = 0;
    }
    features->disable_cdf_update = 1;
    const RefCntBuffer *ref_buf;
    if (cm->bridge_frame_info.is_bridge_frame) {
      ref_buf = get_ref_frame_buf(
          cm, cm->bridge_frame_info.bridge_frame_ref_idx_remapped);
    } else {
      ref_buf = get_ref_frame_buf(cm, cm->bru.update_ref_idx);
    }
    // set cm->ccso_info and copy to cur_frame->ccso_info
    // doing once in uncompred header
    cm->ccso_info.ccso_frame_flag = 0;
    for (int plane = 0; plane < CCSO_NUM_COMPONENTS; plane++) {
      if (cm->bru.frame_inactive_flag ||
          cm->bridge_frame_info.is_bridge_frame) {
        cm->ccso_info.reuse_ccso[plane] = 0;
        cm->ccso_info.sb_reuse_ccso[plane] = 0;
        cm->ccso_info.ccso_ref_idx[plane] = UINT8_MAX;
        cm->ccso_info.ccso_enable[plane] = 0;
        av2_copy_ccso_filters(&cm->cur_frame->ccso_info, &cm->ccso_info, plane,
                              1, 0, 0);
        continue;
      }
    }
    cm->quant_params.base_qindex = ref_buf->base_qindex;
    if (av2_num_planes(cm) > 1) {
      cm->quant_params.u_ac_delta_q = ref_buf->u_ac_delta_q;
      cm->quant_params.v_ac_delta_q = ref_buf->v_ac_delta_q;
    } else {
      cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q = 0;
    }
    cm->cur_frame->base_qindex = cm->quant_params.base_qindex;
    cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q;
    cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q;

    // Bridge frames should inherit the restricted status from their reference
    cm->cur_frame->is_restricted = ref_buf->is_restricted;

    set_primary_ref_frame_and_ctx(pbi);

    CommonContexts *const above_contexts = &cm->above_contexts;
    if (above_contexts->num_planes < av2_num_planes(cm) ||
        above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
        above_contexts->num_tile_rows < cm->tiles.rows) {
      av2_free_above_context_buffers(above_contexts);
      if (av2_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
                                          cm->mi_params.mi_cols,
                                          av2_num_planes(cm))) {
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                           "Failed to allocate context buffers");
      }
    }

    setup_film_grain(pbi, rb);
    return 0;
  }

  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    // Set parameters corresponding to no filtering.
    struct loopfilter *lf = &cm->lf;
    lf->apply_deblocking_filter[0] = 0;
    lf->apply_deblocking_filter[1] = 0;

    cm->gdf_info.gdf_mode = 0;

    cm->cdef_info.cdef_frame_enable = 0;
    cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
    cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
    cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
  }

  if (features->tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
    if (!cm->bridge_frame_info.is_bridge_frame) {
      features->disable_cdf_update = avm_rb_read_bit(rb);
    } else {
      features->disable_cdf_update = 1;
    }

    read_tile_info(pbi, rb);
    if (!av2_is_min_tile_width_satisfied(cm)) {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Minimum tile width requirement not satisfied");
    }

    CommonQuantParams *const quant_params = &cm->quant_params;
    setup_quantization(quant_params, av2_num_planes(cm), &cm->seq_params, rb);
    cm->cur_frame->base_qindex = quant_params->base_qindex;
    cm->cur_frame->u_ac_delta_q = quant_params->u_ac_delta_q;
    cm->cur_frame->v_ac_delta_q = quant_params->v_ac_delta_q;

    set_primary_ref_frame_and_ctx(pbi);

    CommonContexts *const above_contexts = &cm->above_contexts;
    if (above_contexts->num_planes < av2_num_planes(cm) ||
        above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
        above_contexts->num_tile_rows < cm->tiles.rows) {
      av2_free_above_context_buffers(above_contexts);
      if (av2_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
                                          cm->mi_params.mi_cols,
                                          av2_num_planes(cm))) {
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
                           "Failed to allocate context buffers");
      }
    }

    setup_segmentation(cm, rb);

    setup_qm_params(pbi, quant_params, cm->seg.enabled, av2_num_planes(cm), rb);
    cm->delta_q_info.delta_q_res = 1;
    cm->delta_q_info.delta_q_present_flag =
        quant_params->base_qindex > 0 ? avm_rb_read_bit(rb) : 0;
    if (cm->delta_q_info.delta_q_present_flag) {
      xd->current_base_qindex = quant_params->base_qindex;
      cm->delta_q_info.delta_q_res = 1 << avm_rb_read_literal(rb, 2);
    }

    xd->cur_frame_force_integer_mv = features->cur_frame_force_integer_mv;
    features->has_lossless_segment = 0;

    const int max_seg_num =
        cm->seg.enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
    for (int i = 0; i < max_seg_num; i++) {
      const int qindex = av2_get_qindex(&cm->seg, i, quant_params->base_qindex,
                                        cm->seq_params.bit_depth);
      xd->lossless[i] =
          qindex == 0 && cm->delta_q_info.delta_q_present_flag == 0 &&
          (quant_params->y_dc_delta_q + cm->seq_params.base_y_dc_delta_q <=
           0) &&
          (quant_params->u_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <=
           0) &&
          (quant_params->v_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <=
           0) &&
          (quant_params->u_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <=
           0) &&
          (quant_params->v_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0);

      features->lossless_segment[i] = xd->lossless[i];
      if (xd->lossless[i]) features->has_lossless_segment = 1;

      xd->qindex[i] = qindex;
      if (av2_use_qmatrix(quant_params, xd, i)) {
        if (quant_params->qm_index_bits > 0) {
          quant_params->qm_index[i] =
              avm_rb_read_literal(rb, quant_params->qm_index_bits);
#if CONFIG_QM_DEBUG
          printf("[DEC-FRM] qm_index[%d]: %d\n", i, quant_params->qm_index[i]);
#endif
          if (quant_params->qm_index[i] >= quant_params->pic_qm_num) {
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                               "Invalid qm_index[%d]=%d >= %d", i,
                               quant_params->qm_index[i],
                               quant_params->pic_qm_num);
          }
        } else {
          quant_params->qm_index[i] = 0;
        }
      }
    }
    features->coded_lossless = is_coded_lossless(cm, xd);
    features->all_lossless = features->coded_lossless;

    // Decode frame-level TCQ flag, if applicable.
    if (features->coded_lossless) {
      features->tcq_mode = 0;
    } else if (seq_params->enable_tcq >= TCQ_8ST_FR) {
      features->tcq_mode = avm_rb_read_bit(rb);
    } else {
      features->tcq_mode = seq_params->enable_tcq;
    }

    if (features->coded_lossless || !cm->seq_params.enable_parity_hiding ||
        features->tcq_mode)
      features->allow_parity_hiding = false;
    else
      features->allow_parity_hiding = avm_rb_read_bit(rb);

    setup_segmentation_dequant(pbi, xd);

    if (features->coded_lossless) {
      cm->lf.apply_deblocking_filter[0] = 0;
      cm->lf.apply_deblocking_filter[1] = 0;
    }
    if (features->coded_lossless || !seq_params->enable_cdef) {
      cm->cdef_info.cdef_frame_enable = 0;
    }
    if (features->all_lossless || !seq_params->enable_restoration) {
      cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
      cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
      cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
      cm->rst_info[0].frame_filters_on = 0;
      cm->rst_info[1].frame_filters_on = 0;
      cm->rst_info[2].frame_filters_on = 0;
    }
  } else {
    if (cm->seq_params.enable_tip_explicit_qp) {
      cm->quant_params.base_qindex = avm_rb_read_literal(
          rb, cm->seq_params.bit_depth == AVM_BITS_8 ? QINDEX_BITS_UNEXT
                                                     : QINDEX_BITS);
      if (av2_num_planes(cm) > 1 && cm->seq_params.uv_ac_delta_q_enabled) {
        int diff_uv_delta = 0;
        if (cm->seq_params.separate_uv_delta_q) {
          diff_uv_delta = avm_rb_read_bit(rb);
        }
        cm->quant_params.u_ac_delta_q = read_delta_q(rb);
        if (diff_uv_delta) {
          cm->quant_params.v_ac_delta_q = read_delta_q(rb);
        } else {
          cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q;
        }
      } else {
        cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q = 0;
      }
      cm->cur_frame->base_qindex = cm->quant_params.base_qindex;
      cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q;
      cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q;
    }
    features->disable_cdf_update = 1;
    features->coded_lossless = 0;
    features->all_lossless = 0;
  }
  setup_loopfilter(cm, rb);

  if (!features->coded_lossless && seq_params->enable_gdf) {
    setup_gdf(cm, rb);
  } else {
    cm->gdf_info.gdf_mode = 0;
  }
  if (!features->coded_lossless && seq_params->enable_cdef) {
    setup_cdef(cm, rb);
  }
  if (!features->all_lossless && seq_params->enable_restoration) {
    decode_restoration_mode(cm, rb);
  }
  for (int plane = 0; plane < CCSO_NUM_COMPONENTS; plane++) {
    cm->ccso_info.ccso_enable[plane] = false;
  }
  if (!features->coded_lossless && seq_params->enable_ccso) {
    setup_ccso(cm, rb);
  }
  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    if (cm->seq_params.enable_lf_sub_pu && cm->features.allow_lf_sub_pu &&
        cm->lf.apply_deblocking_filter_tip) {
      read_tile_info(pbi, rb);
    }
    setup_film_grain(pbi, rb);
    features->enable_imp_msk_bld = seq_params->enable_imp_msk_bld;
    // TIP frame will be output for displaying
    // No futher processing needed
    return 0;
  }
  features->tx_mode = read_tx_mode(rb, features->coded_lossless);
  current_frame->reference_mode = read_frame_reference_mode(cm, rb);

  av2_setup_skip_mode_allowed(cm);
  current_frame->skip_mode_info.skip_mode_flag =
      current_frame->skip_mode_info.skip_mode_allowed ? avm_rb_read_bit(rb) : 0;

  if (!frame_is_intra_only(cm) && seq_params->enable_bawp)
    features->enable_bawp = avm_rb_read_bit(rb);
  else
    features->enable_bawp = 0;

  features->enable_intra_bawp = seq_params->enable_bawp;

  features->enable_cwp = seq_params->enable_cwp;
  features->allow_warpmv_mode = 0;
  if (!frame_is_intra_only(cm) &&
      (features->enabled_motion_modes & (1 << WARP_DELTA)) != 0) {
    features->allow_warpmv_mode = avm_rb_read_bit(rb);
  }

  features->enable_imp_msk_bld = seq_params->enable_imp_msk_bld;

  features->reduced_tx_set_used = avm_rb_read_literal(rb, 2);

  if (features->allow_ref_frame_mvs && !frame_might_allow_ref_frame_mvs(cm)) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Frame wrongly requests reference frame MVs");
  }

  if (features->tip_frame_mode && !cm->seq_params.enable_tip) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Frame wrongly requests TIP mode");
  }

  if (!frame_is_intra_only(cm)) read_global_motion(cm, rb);
  setup_film_grain(pbi, rb);
  features->enable_ext_seg = seq_params->enable_ext_seg;
  return 0;
}

struct avm_read_bit_buffer *av2_init_read_bit_buffer(
    AV2Decoder *pbi, struct avm_read_bit_buffer *rb, const uint8_t *data,
    const uint8_t *data_end) {
  rb->bit_offset = 0;
  rb->error_handler = error_handler;
  rb->error_handler_data = &pbi->common;
  rb->bit_buffer = data;
  rb->bit_buffer_end = data_end;
  return rb;
}

void av2_read_frame_size(struct avm_read_bit_buffer *rb, int num_bits_width,
                         int num_bits_height, int *width, int *height) {
  *width = avm_rb_read_literal(rb, num_bits_width) + 1;
  *height = avm_rb_read_literal(rb, num_bits_height) + 1;
}
BITSTREAM_PROFILE av2_read_profile(struct avm_read_bit_buffer *rb) {
  int profile = avm_rb_read_literal(rb, PROFILE_BITS);
  return (BITSTREAM_PROFILE)profile;
}
static AVM_INLINE void tip_mode_legal_check(AV2Decoder *const pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const bool is_tip_frame =
      pbi->obu_type == OBU_LEADING_TIP || pbi->obu_type == OBU_REGULAR_TIP;
  if (is_tip_frame && cm->features.tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
    avm_internal_error(
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
        "tip_frame_mode is not equal to TIP_FRAME_AS_OUTPUT for a TIP frame");
  }

  if (cm->features.tip_frame_mode == TIP_FRAME_DISABLED) return;

  if (cm->current_frame.frame_type == KEY_FRAME ||
      cm->current_frame.frame_type == INTRA_ONLY_FRAME ||
      cm->current_frame.frame_type == S_FRAME) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }

  if (!cm->features.allow_ref_frame_mvs) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }

  if (!cm->seq_params.enable_tip) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }

  if (!cm->has_both_sides_refs && cm->ref_frames_info.num_past_refs < 2) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }

  TIP *tip_ref = &cm->tip_ref;
  if (tip_ref->ref_frame[0] == NONE_FRAME ||
      tip_ref->ref_frame[1] == NONE_FRAME) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }

  const int tip_mode_allowed =
      tip_ref->ref_frame[0] != NONE_FRAME &&
      tip_ref->ref_frame[1] != NONE_FRAME &&
      is_ref_motion_field_eligible_by_frame_size(
          cm, get_ref_frame_buf(cm, tip_ref->ref_frame[0])) &&
      is_ref_motion_field_eligible_by_frame_size(
          cm, get_ref_frame_buf(cm, tip_ref->ref_frame[1]));

  if (!tip_mode_allowed ||
      (!is_ref_motion_field_eligible_by_frame_type(
           get_ref_frame_buf(cm, tip_ref->ref_frame[0])) &&
       !is_ref_motion_field_eligible_by_frame_type(
           get_ref_frame_buf(cm, tip_ref->ref_frame[1])))) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "Invalid TIP mode.");
  }
}

static AVM_INLINE void process_tip_mode(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const int num_planes = av2_num_planes(cm);
  MACROBLOCKD *const xd = &pbi->dcb.xd;

  tip_mode_legal_check(pbi);

  if (!cm->features.allow_ref_frame_mvs) return;

  if (cm->features.tip_frame_mode == TIP_FRAME_DISABLED) {
    // TPL mvs at non-sampled locations will be filled after it is hole-filled
    // and smoothed.
    av2_fill_tpl_mvs_sample_gap(cm);
    return;
  }

  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    av2_dec_setup_tip_frame(pbi, cm, xd);
  } else if (cm->features.tip_frame_mode == TIP_FRAME_AS_REF) {
    av2_setup_tip_motion_field(cm);
  }

  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
      cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
    }
    avm_yv12_copy_frame(&cm->tip_ref.tip_frame->buf, &cm->cur_frame->buf,
                        num_planes);
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
      cm->global_motion[i] = default_warp_params;
      cm->cur_frame->global_motion[i] = default_warp_params;
    }

    set_primary_ref_frame_and_ctx(pbi);
    cm->seg.enabled = 0;
    if (cm->cur_frame->seg_map) {
      memset(cm->cur_frame->seg_map, 0,
             (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
    }
    memset(&cm->seg, 0, sizeof(cm->seg));
    cm->seg.enable_ext_seg = cm->seq_params.enable_ext_seg;
    segfeatures_copy(&cm->cur_frame->seg, &cm->seg);

    cm->cur_frame->frame_context = *cm->fc;
  }
}

static int32_t read_tile_indices_in_tilegroup(AV2Decoder *pbi,
                                              struct avm_read_bit_buffer *rb,
                                              int *start_tile, int *end_tile) {
  AV2_COMMON *const cm = &pbi->common;
  CommonTileParams *const tiles = &cm->tiles;
  uint32_t saved_bit_offset = rb->bit_offset;
  int tile_start_and_end_present_flag = 0;
  const int num_tiles = tiles->rows * tiles->cols;

  if (num_tiles > 1) {
    tile_start_and_end_present_flag = avm_rb_read_bit(rb);
  }
  if (num_tiles == 1 || !tile_start_and_end_present_flag) {
    *start_tile = 0;
    *end_tile = num_tiles - 1;
  } else {
    int tile_bits = tiles->log2_rows + tiles->log2_cols;
    *start_tile = avm_rb_read_literal(rb, tile_bits);
    *end_tile = avm_rb_read_literal(rb, tile_bits);
  }
  if (*start_tile != pbi->next_start_tile) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "tg_start (%d) must be equal to %d", *start_tile,
                       pbi->next_start_tile);
    return -1;
  }
  if (*start_tile > *end_tile) {
    avm_internal_error(
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
        "tg_end (%d) must be greater than or equal to tg_start (%d)", *end_tile,
        *start_tile);
    return -1;
  }
  if (*end_tile >= num_tiles) {
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                       "tg_end (%d) must be less than NumTiles (%d)", *end_tile,
                       num_tiles);
    return -1;
  }
  pbi->next_start_tile = (*end_tile == num_tiles - 1) ? 0 : *end_tile + 1;

  if (cm->bru.enabled) {
    if (num_tiles > 1) {
      for (int tile_idx = *start_tile; tile_idx <= *end_tile; tile_idx++) {
        const int active_bitmap_byte = tile_idx >> 3;
        const int active_bitmap_bit = tile_idx & 7;
        tiles->tile_active_bitmap[active_bitmap_byte] +=
            (avm_rb_read_bit(rb) << active_bitmap_bit);
      }
    } else {
      tiles->tile_active_bitmap[0] = 1;
    }
  }
  return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
}

int32_t av2_read_tilegroup_header(
    AV2Decoder *pbi, struct avm_read_bit_buffer *rb, const uint8_t *data,
    const uint8_t **p_data_end, int *first_tile_group_in_frame, int *start_tile,
    int *end_tile, OBU_TYPE obu_type, int obu_xlayer_id) {
#if CONFIG_COLLECT_COMPONENT_TIMING
  start_timing(pbi, av2_read_tilegroup_header_time);
#endif

  assert(rb->bit_offset == 0);

  AV2_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->dcb.xd;

  int is_first_tile_group = 1;
  int send_uncompressed_header_flag = 1;
  bool send_first_tile_group_indication = true;
  send_first_tile_group_indication &= obu_type != OBU_LEADING_SEF;
  send_first_tile_group_indication &= obu_type != OBU_REGULAR_SEF;
  send_first_tile_group_indication &= obu_type != OBU_LEADING_TIP;
  send_first_tile_group_indication &= obu_type != OBU_REGULAR_TIP;
  send_first_tile_group_indication &= obu_type != OBU_BRIDGE_FRAME;
  if (send_first_tile_group_indication)
    is_first_tile_group = avm_rb_read_bit(rb);
  *first_tile_group_in_frame = is_first_tile_group;

  if (is_first_tile_group) {
#if CONFIG_MISMATCH_DEBUG
    mismatch_move_frame_idx_r(1);
#endif  // CONFIG_MISMATCH_DEBUG
    pbi->seen_frame_header = 1;
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
      cm->global_motion[i] = default_warp_params;
      cm->cur_frame->global_motion[i] = default_warp_params;
    }

    for (int p = 0; p < MAX_MB_PLANE; ++p) {
      cm->cur_frame->rst_info[p].frame_filters_on = 0;
    }

    xd->global_motion = cm->global_motion;
  } else {
    send_uncompressed_header_flag = avm_rb_read_bit(rb);
  }

  if (send_uncompressed_header_flag) {
    if (!is_first_tile_group) {
      rb->bit_offset += pbi->uncomp_hdr_size_in_bits;
    } else {
      uint32_t uncomp_hdr_start_point = rb->bit_offset;
      read_uncompressed_header(pbi, obu_type, obu_xlayer_id, rb);

      // Conformance check for the number of reference frames
      if (cm->seq_params.seq_max_level_idx < SEQ_LEVELS) {
        const int max_legal_ref_frames = av2_get_max_level_ref_frames(
            cm, obu_type, cm->seq_params.seq_max_level_idx);
        if (cm->seq_params.ref_frames > max_legal_ref_frames) {
          avm_internal_error(
              &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
              "The maximum number of reference frames shall not be "
              "greater than %d, yet the bitstream indicates that the "
              "maximum decoded picture buffer size is equal to %d.\n",
              max_legal_ref_frames, cm->seq_params.ref_frames);
        }
      }

      pbi->uncomp_hdr_size_in_bits = rb->bit_offset - uncomp_hdr_start_point;
    }
  }

  if (is_first_tile_group) {
#if CONFIG_BITSTREAM_DEBUG
    avm_bitstream_queue_set_frame_read(
        (int)(derive_output_order_idx(cm, cm->cur_frame) * 2 +
              cm->immediate_output_picture));
#endif

    // avm_rb_bytes_read()= (rb->bit_offset + 7) >> 3;
    const uint32_t uncomp_hdr_size =
        (uint32_t)avm_rb_bytes_read(rb);  // Size of the uncompressed header
    const YV12_BUFFER_CONFIG *new_fb =
        (cm->show_existing_frame && !cm->derive_sef_order_hint)
            ? &cm->ref_frame_map[cm->sef_ref_fb_idx]->buf
            : &cm->cur_frame->buf;
    xd->cur_buf = new_fb;
    if (av2_allow_intrabc(cm, xd, BLOCK_4X4) && xd->tree_type != CHROMA_PART) {
      av2_setup_scale_factors_for_frame(
          &cm->sf_identity, xd->cur_buf->y_crop_width,
          xd->cur_buf->y_crop_height, xd->cur_buf->y_crop_width,
          xd->cur_buf->y_crop_height);
    }
    if (obu_type == OBU_REGULAR_SEF || obu_type == OBU_LEADING_SEF) {
      // showing a frame directly
      *p_data_end = data + uncomp_hdr_size;
      if (pbi->reset_decoder_state) {
        // Use the default frame context values.
        *cm->fc = *cm->default_frame_context;
        if (!cm->fc->initialized)
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                             "Uninitialized entropy context.");
      }
#if CONFIG_COLLECT_COMPONENT_TIMING
      end_timing(pbi, av2_read_tilegroup_header_time);
#endif
      return uncomp_hdr_size;
    }

    cm->mi_params.setup_mi(&cm->mi_params);

    av2_setup_block_planes(xd, cm->seq_params.subsampling_x,
                           cm->seq_params.subsampling_y, av2_num_planes(cm));

    if (cm->features.allow_ref_frame_mvs)
      av2_setup_motion_field(cm);
    else
      av2_setup_ref_frame_sides(cm);

    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
      for (int plane = 0; plane < av2_num_planes(cm); plane++) {
        cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
      }
      MV_REF *frame_mvs = cm->cur_frame->mvs;
      const int mvs_rows =
          ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
      const int mvs_cols =
          ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
      const int mvs_stride = mvs_cols;

      for (int h = 0; h < mvs_rows; h++) {
        MV_REF *mv = frame_mvs;
        for (int w = 0; w < mvs_cols; w++) {
          if (cm->bridge_frame_info.is_bridge_frame) {
            mv->ref_frame[0] =
                cm->bridge_frame_info.bridge_frame_ref_idx_remapped;
          } else {
            mv->ref_frame[0] = cm->bru.update_ref_idx;
          }
          mv->ref_frame[1] = NONE_FRAME;
          mv->mv[0].as_int = 0;
          mv->mv[1].as_int = 0;
          mv++;
        }
        frame_mvs += mvs_stride;
      }
      for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
        cm->global_motion[i] = default_warp_params;
        cm->cur_frame->global_motion[i] = default_warp_params;
      }

      set_primary_ref_frame_and_ctx(pbi);
      cm->seg.enabled = 0;
      if (cm->cur_frame->seg_map) {
        memset(cm->cur_frame->seg_map, 0,
               (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
      }
      memset(&cm->seg, 0, sizeof(cm->seg));
      cm->seg.enable_ext_seg = cm->seq_params.enable_ext_seg;
      segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
      if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
          cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
        // use the default frame context values
        *cm->fc = *cm->default_frame_context;
      } else {
        *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
                      ->frame_context;
        int ref_frame_used = PRIMARY_REF_NONE;
        int map_idx = INVALID_IDX;
        get_secondary_reference_frame_idx(cm, &ref_frame_used, &map_idx);
        avg_primary_secondary_references(cm, ref_frame_used, map_idx);
      }
      *p_data_end = data + uncomp_hdr_size;
#if CONFIG_COLLECT_COMPONENT_TIMING
      end_timing(pbi, av2_read_tilegroup_header_time);
#endif
      return uncomp_hdr_size;
    }

    process_tip_mode(pbi);
    if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP) {
      *p_data_end = data + uncomp_hdr_size;
#if CONFIG_COLLECT_COMPONENT_TIMING
      end_timing(pbi, av2_read_tilegroup_header_time);
#endif
      return uncomp_hdr_size;
    }

    if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
        cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
      // use the default frame context values
      *cm->fc = *cm->default_frame_context;
    } else {
      *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
                    ->frame_context;
      int ref_frame_used = PRIMARY_REF_NONE;
      int map_idx = INVALID_IDX;
      get_secondary_reference_frame_idx(cm, &ref_frame_used, &map_idx);
      avg_primary_secondary_references(cm, ref_frame_used, map_idx);
    }
    if (!cm->fc->initialized)
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Uninitialized entropy context.");

    pbi->dcb.corrupted = 0;
  }

  bool tile_indices_present_flag = true;
  tile_indices_present_flag &= obu_type != OBU_LEADING_SEF;
  tile_indices_present_flag &= obu_type != OBU_REGULAR_SEF;
  tile_indices_present_flag &= obu_type != OBU_LEADING_TIP;
  tile_indices_present_flag &= obu_type != OBU_REGULAR_TIP;
  tile_indices_present_flag &=
      (!cm->bru.frame_inactive_flag && !cm->bridge_frame_info.is_bridge_frame);
  if (tile_indices_present_flag)
    read_tile_indices_in_tilegroup(pbi, rb, start_tile, end_tile);
#if CONFIG_COLLECT_COMPONENT_TIMING
  end_timing(pbi, av2_read_tilegroup_header_time);
#endif
  return (int32_t)avm_rb_bytes_read(rb);
}

// Once-per-frame initialization
static AVM_INLINE void setup_frame_info(AV2Decoder *pbi) {
  AV2_COMMON *const cm = &pbi->common;

  if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
      cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
      cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
    av2_alloc_restoration_buffers(cm);
  } else {
    if (cm->gdf_info.gdf_mode) {
      av2_alloc_restoration_boundary_buffers(cm, 1);
    }
  }
  const int buf_size = MC_TEMP_BUF_PELS << 1;
  if (pbi->td.mc_buf_size != buf_size) {
    av2_free_mc_tmp_buf(&pbi->td);
    av2_free_opfl_tmp_bufs(&pbi->td);

    allocate_mc_tmp_buf(cm, &pbi->td, buf_size);
    allocate_opfl_tmp_bufs(cm, &pbi->td);
  }
}

// 1) For multiple tiles-based coding, calculate the average CDFs from the
// allowed tiles, and use the average CDFs of the tiles as the frame's CDFs
// 2) For one tile coding, directly use that tile's CDFs as the frame's CDFs
void decoder_avg_tiles_cdfs(AV2Decoder *const pbi) {
  AV2_COMMON *const cm = &pbi->common;
  const CommonTileParams *const tiles = &cm->tiles;
  const int total_tiles = tiles->rows * tiles->cols;
  if (total_tiles == 1) {
    *cm->fc = pbi->tile_data[0].tctx;
  } else {
    const unsigned int total_tiles_log2 = av2_compute_allowed_tiles_log2(cm);
    const unsigned int used_tiles = (1 << total_tiles_log2);
    *cm->fc = pbi->tile_data[0].tctx;
    av2_shift_cdf_symbols(cm->fc, total_tiles_log2);
    for (unsigned int tile_idx = 1; tile_idx < used_tiles; ++tile_idx) {
      av2_cumulative_avg_cdf_symbols(cm->fc, &pbi->tile_data[tile_idx].tctx,
                                     total_tiles_log2);
    }
  }
}

void av2_gdf_frame_dec(AV2_COMMON *cm) { gdf_filter_frame(cm); }

void av2_decode_tg_tiles_and_wrapup(AV2Decoder *pbi, const uint8_t *data,
                                    const uint8_t *data_end,
                                    const uint8_t **p_data_end, int start_tile,
                                    int end_tile, int initialize_flag) {
#if CONFIG_COLLECT_COMPONENT_TIMING
  start_timing(pbi, av2_decode_tg_tiles_and_wrapup_time);
#endif

  AV2_COMMON *const cm = &pbi->common;
  CommonTileParams *const tiles = &cm->tiles;
  MACROBLOCKD *const xd = &pbi->dcb.xd;
  const int tile_count_tg = end_tile - start_tile + 1;

  if (!cm->wedge_mask_initialized &&
      cm->current_frame.frame_type != KEY_FRAME) {
    av2_init_wedge_masks();
    cm->wedge_mask_initialized = true;
  }
  if (initialize_flag) setup_frame_info(pbi);
  const int num_planes = av2_num_planes(cm);
#if CONFIG_INSPECTION
  avm_realloc_frame_buffer(
      &cm->predicted_pixels, cm->width, cm->height,
      cm->seq_params.subsampling_x, cm->seq_params.subsampling_y,
      AVM_DEC_BORDER_IN_PIXELS, cm->features.byte_alignment, NULL, NULL, NULL,
      false);
  avm_realloc_frame_buffer(
      &cm->prefiltered_pixels, cm->width, cm->height,
      cm->seq_params.subsampling_x, cm->seq_params.subsampling_y,
      AVM_DEC_BORDER_IN_PIXELS, cm->features.byte_alignment, NULL, NULL, NULL,
      false);
#endif  // CONFIG_INSPECTION
  if (pbi->max_threads > 1 && pbi->row_mt)
    *p_data_end =
        decode_tiles_row_mt(pbi, data, data_end, start_tile, end_tile);
  else if (pbi->max_threads > 1 && tile_count_tg > 1)
    *p_data_end = decode_tiles_mt(pbi, data, data_end, start_tile, end_tile);
  else
    *p_data_end = decode_tiles(pbi, data, data_end, start_tile, end_tile);

  // If the bit stream is monochrome, set the U and V buffers to a constant.
  if (num_planes < 3) {
    set_planes_to_neutral_grey(&cm->seq_params, xd->cur_buf, 1);
  }

#if CONFIG_INSPECTION
  memcpy(cm->prefiltered_pixels.buffer_alloc, cm->cur_frame->buf.buffer_alloc,
         cm->prefiltered_pixels.frame_size);
#endif  // CONFIG_INSPECTION

  if (end_tile != tiles->rows * tiles->cols - 1) {
    return;
  }

  av2_alloc_cdef_buffers(cm, &pbi->cdef_worker, &pbi->cdef_sync,
                         pbi->num_workers);
  av2_alloc_cdef_sync(cm, &pbi->cdef_sync, pbi->num_workers);

  // verify active region
  if (!bru_active_map_validation(cm)) {
    avm_internal_error(&cm->error, AVM_CODEC_ERROR, "Invalid active region");
  }
  // bru swap in mode 0, in mode 1, still use cur frame and then drop bru ref
  // after filtering
  // backward reference frame update
  // check if any active block
  // 1. intra frames do not have backward update
  // 2. if no active block in the frame and bru enabled, no need to update, just
  // drop the recon
  // 3. if any inactive block exists and bru enabled, update ref and drop the
  // if enabled flag signaled == 1, do swap
  if (cm->bru.enabled && pbi->bru_opt_mode &&
      cm->current_frame.frame_type != KEY_FRAME) {
    dec_bru_swap_stage(cm, xd);
    if (cm->bru.frame_inactive_flag) {
      cm->cur_frame->frame_context = *cm->fc;
#if CONFIG_PARAKIT_COLLECT_DATA
      for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++)
        for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
          for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
            for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
              for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
                beginningFrameFlag[i][j][k][l][h] = 1;
#endif
      return;
    }
  }

  if (!cm->bru.frame_inactive_flag) {
    if (cm->lf.apply_deblocking_filter[0] ||
        cm->lf.apply_deblocking_filter[1]) {
      if (pbi->num_workers > 1) {
        av2_loop_filter_frame_mt(&cm->cur_frame->buf, cm, &pbi->dcb.xd, 0,
                                 num_planes, 0, pbi->tile_workers,
                                 pbi->num_workers, &pbi->lf_row_sync);
      } else {
        av2_loop_filter_frame(&cm->cur_frame->buf, cm, &pbi->dcb.xd, 0,
                              num_planes, 0);
      }
    }

    const int use_ccso =
        !pbi->skip_loop_filter && !cm->features.coded_lossless &&
        (cm->ccso_info.ccso_enable[0] || cm->ccso_info.ccso_enable[1] ||
         cm->ccso_info.ccso_enable[2]);
    uint16_t *ext_rec_y = NULL;
    if (use_ccso) {
      const int pic_height = cm->cur_frame->buf.y_height;
      const int pic_width = cm->cur_frame->buf.y_width;
      const int dst_stride = cm->cur_frame->buf.y_stride;
      const uint16_t *rec_y = cm->cur_frame->buf.y_buffer;
      const int ccso_stride_ext = pic_width + (CCSO_PADDING_SIZE << 1);
      ext_rec_y = avm_malloc(sizeof(*ext_rec_y) *
                             (pic_height + (CCSO_PADDING_SIZE << 1)) *
                             (pic_width + (CCSO_PADDING_SIZE << 1)));
      for (int r = 0; r < pic_height; ++r) {
        for (int c = 0; c < pic_width; ++c) {
          ext_rec_y[(r + CCSO_PADDING_SIZE) * ccso_stride_ext + c +
                    CCSO_PADDING_SIZE] = rec_y[r * dst_stride + c];
        }
      }
      extend_ccso_border(&cm->cur_frame->buf, ext_rec_y, CCSO_PADDING_SIZE);
    }

    const int do_loop_restoration =
        cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
        (cm->rst_info[1].frame_restoration_type != RESTORE_NONE &&
         !cm->seq_params.monochrome) ||
        (cm->rst_info[2].frame_restoration_type != RESTORE_NONE &&
         !cm->seq_params.monochrome);
    const int do_cdef = !pbi->skip_loop_filter &&
                        !cm->features.coded_lossless &&
                        cm->cdef_info.cdef_frame_enable;
    const int do_gdf = is_gdf_enabled(cm);
    const int optimized_loop_restoration =
        !cm->seq_params.disable_loopfilters_across_tiles && !do_gdf &&
        !use_ccso && !do_cdef;

    if (!optimized_loop_restoration) {
      if (do_loop_restoration)
        av2_loop_restoration_save_boundary_lines(&pbi->common.cur_frame->buf,
                                                 cm, 0);
      else {
        if (do_gdf)
          save_tile_row_boundary_lines(&pbi->common.cur_frame->buf, 0, cm, 0);
      }

      if (do_cdef) {
        if (pbi->num_workers > 1 &&
            !cm->seq_params.disable_loopfilters_across_tiles) {
          av2_cdef_frame_mt(cm, &pbi->dcb.xd, pbi->cdef_worker,
                            pbi->tile_workers, &pbi->cdef_sync,
                            pbi->num_workers, av2_cdef_init_fb_row_mt);
        } else {
          av2_cdef_frame(&pbi->common.cur_frame->buf, cm, &pbi->dcb.xd,
                         av2_cdef_init_fb_row);
        }
      }
      if (use_ccso) {
        if (pbi->num_workers > 1 &&
            !cm->seq_params.disable_loopfilters_across_tiles) {
          av2_ccso_frame_mt(&cm->cur_frame->buf, cm, xd, pbi->tile_workers,
                            pbi->num_workers, ext_rec_y, &pbi->ccso_sync);
        } else {
          ccso_frame(&cm->cur_frame->buf, cm, xd, ext_rec_y);
        }
        avm_free(ext_rec_y);
      }
      if (do_gdf) {
        gdf_copy_guided_frame(cm);
      }
      if (do_loop_restoration) {
        av2_loop_restoration_save_boundary_lines(&pbi->common.cur_frame->buf,
                                                 cm, 1);
      } else {
        if (do_gdf)
          save_tile_row_boundary_lines(&pbi->common.cur_frame->buf, 0, cm, 1);
      }
      if (do_loop_restoration) {
        copy_frame_filters_to_runits_if_needed(cm);
        if (pbi->num_workers > 1 &&
            !cm->seq_params.disable_loopfilters_across_tiles) {
          av2_loop_restoration_filter_frame_mt(
              (YV12_BUFFER_CONFIG *)xd->cur_buf, cm, optimized_loop_restoration,
              pbi->tile_workers, pbi->num_workers, &pbi->lr_row_sync,
              &pbi->lr_ctxt);
        } else {
          av2_loop_restoration_filter_frame((YV12_BUFFER_CONFIG *)xd->cur_buf,
                                            cm, optimized_loop_restoration,
                                            &pbi->lr_ctxt);
        }
      }
      if (do_gdf) {
        av2_gdf_frame_dec(cm);
        gdf_free_guided_frame(cm);
      }

    } else {
      if (do_loop_restoration) {
        copy_frame_filters_to_runits_if_needed(cm);
        if (pbi->num_workers > 1 &&
            !cm->seq_params.disable_loopfilters_across_tiles) {
          av2_loop_restoration_filter_frame_mt(
              (YV12_BUFFER_CONFIG *)xd->cur_buf, cm, optimized_loop_restoration,
              pbi->tile_workers, pbi->num_workers, &pbi->lr_row_sync,
              &pbi->lr_ctxt);
        } else {
          av2_loop_restoration_filter_frame((YV12_BUFFER_CONFIG *)xd->cur_buf,
                                            cm, optimized_loop_restoration,
                                            &pbi->lr_ctxt);
        }
      }
    }
    if (!pbi->dcb.corrupted) {
      if (!cm->bridge_frame_info.is_bridge_frame) {
        if (cm->seq_params.enable_avg_cdf && cm->seq_params.avg_cdf_type &&
            cm->tiles.rows * cm->tiles.cols > 1) {
          decoder_avg_tiles_cdfs(pbi);
        } else {
          assert(pbi->context_update_tile_id < pbi->allocated_tiles);
          *cm->fc = pbi->tile_data[pbi->context_update_tile_id].tctx;
        }
        av2_reset_cdf_symbol_counters(cm->fc);
      }
    } else {
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
                         "Decode failed. Frame data is corrupted.");
    }
  }

#if CONFIG_INSPECTION
  if (pbi->inspect_cb != NULL) {
    (*pbi->inspect_cb)(pbi, pbi->inspect_ctx);
  }
#endif  // CONFIG_INSPECTION

  // Non frame parallel update frame context here.
  cm->cur_frame->frame_context = *cm->fc;
#if CONFIG_PARAKIT_COLLECT_DATA
  for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++)
    for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
      for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
        for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
          for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
            beginningFrameFlag[i][j][k][l][h] = 1;
#endif

#if CONFIG_COLLECT_COMPONENT_TIMING
  end_timing(pbi, av2_decode_tg_tiles_and_wrapup_time);
#endif
}
