Refactor CommonQuantParams from AV1_COMMON struct.

BUG=aomedia:2610

Change-Id: Ib2346b445946d3c2275c866b222313c2d0db659f
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index 15a9ed2..0006c1f 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -994,7 +994,8 @@
                                                va_list args) {
   int *const arg = va_arg(args, int *);
   if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
-  *arg = ((FrameWorkerData *)ctx->frame_worker->data1)->pbi->common.base_qindex;
+  *arg = ((FrameWorkerData *)ctx->frame_worker->data1)
+             ->pbi->common.quant_params.base_qindex;
   return AOM_CODEC_OK;
 }
 
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 4e8cdb0..d56f629 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -419,6 +419,41 @@
                     int height);
 };
 
+// Parameters related to quantization.
+typedef struct CommonQuantParams CommonQuantParams;
+struct CommonQuantParams {
+  // Base qIndex of the frame in the range 0 to 255.
+  // The qindex per block may have a delta from this: see 'delta_q_info' below.
+  int base_qindex;
+
+  int y_dc_delta_q;
+  int u_dc_delta_q;
+  int v_dc_delta_q;
+  int u_ac_delta_q;
+  int v_ac_delta_q;
+
+  // The dequantizers below are true dequantizers used only in the
+  // dequantization process.  They have the same coefficient
+  // shift/scale as TX.
+  int16_t y_dequant_QTX[MAX_SEGMENTS][2];
+  int16_t u_dequant_QTX[MAX_SEGMENTS][2];
+  int16_t v_dequant_QTX[MAX_SEGMENTS][2];
+
+  // Global quant matrix tables
+  const qm_val_t *giqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
+  const qm_val_t *gqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
+
+  // Local quant matrix tables for each frame
+  const qm_val_t *y_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  const qm_val_t *u_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  const qm_val_t *v_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+
+  int using_qmatrix;
+  int qm_y;
+  int qm_u;
+  int qm_v;
+};
+
 typedef struct AV1Common {
   // Information about the current frame that is being coded.
   CurrentFrame current_frame;
@@ -535,34 +570,8 @@
 #if CONFIG_ENTROPY_STATS
   int coef_cdf_category;
 #endif
-
-  int base_qindex;
-  int y_dc_delta_q;
-  int u_dc_delta_q;
-  int v_dc_delta_q;
-  int u_ac_delta_q;
-  int v_ac_delta_q;
-
-  // The dequantizers below are true dequantizers used only in the
-  // dequantization process.  They have the same coefficient
-  // shift/scale as TX.
-  int16_t y_dequant_QTX[MAX_SEGMENTS][2];
-  int16_t u_dequant_QTX[MAX_SEGMENTS][2];
-  int16_t v_dequant_QTX[MAX_SEGMENTS][2];
-
-  // Global quant matrix tables
-  const qm_val_t *giqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
-  const qm_val_t *gqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
-
-  // Local quant matrix tables for each frame
-  const qm_val_t *y_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-  const qm_val_t *u_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-  const qm_val_t *v_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-
-  int using_qmatrix;
-  int qm_y;
-  int qm_u;
-  int qm_v;
+  // Quantization params.
+  CommonQuantParams quant_params;
 
   uint8_t *last_frame_seg_map;
 
@@ -836,25 +845,28 @@
 static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd,
                                         tran_low_t *dqcoeff) {
   const int num_planes = av1_num_planes(cm);
+  const CommonQuantParams *const quant_params = &cm->quant_params;
+
   for (int i = 0; i < num_planes; ++i) {
     xd->plane[i].dqcoeff = dqcoeff;
 
     if (xd->plane[i].plane_type == PLANE_TYPE_Y) {
-      memcpy(xd->plane[i].seg_dequant_QTX, cm->y_dequant_QTX,
-             sizeof(cm->y_dequant_QTX));
-      memcpy(xd->plane[i].seg_iqmatrix, cm->y_iqmatrix, sizeof(cm->y_iqmatrix));
+      memcpy(xd->plane[i].seg_dequant_QTX, quant_params->y_dequant_QTX,
+             sizeof(quant_params->y_dequant_QTX));
+      memcpy(xd->plane[i].seg_iqmatrix, quant_params->y_iqmatrix,
+             sizeof(quant_params->y_iqmatrix));
 
     } else {
       if (i == AOM_PLANE_U) {
-        memcpy(xd->plane[i].seg_dequant_QTX, cm->u_dequant_QTX,
-               sizeof(cm->u_dequant_QTX));
-        memcpy(xd->plane[i].seg_iqmatrix, cm->u_iqmatrix,
-               sizeof(cm->u_iqmatrix));
+        memcpy(xd->plane[i].seg_dequant_QTX, quant_params->u_dequant_QTX,
+               sizeof(quant_params->u_dequant_QTX));
+        memcpy(xd->plane[i].seg_iqmatrix, quant_params->u_iqmatrix,
+               sizeof(quant_params->u_iqmatrix));
       } else {
-        memcpy(xd->plane[i].seg_dequant_QTX, cm->v_dequant_QTX,
-               sizeof(cm->v_dequant_QTX));
-        memcpy(xd->plane[i].seg_iqmatrix, cm->v_iqmatrix,
-               sizeof(cm->v_iqmatrix));
+        memcpy(xd->plane[i].seg_dequant_QTX, quant_params->v_dequant_QTX,
+               sizeof(quant_params->v_dequant_QTX));
+        memcpy(xd->plane[i].seg_iqmatrix, quant_params->v_iqmatrix,
+               sizeof(quant_params->v_iqmatrix));
       }
     }
   }
diff --git a/av1/common/debugmodes.c b/av1/common/debugmodes.c
index 7e1ab12..ff02ddd 100644
--- a/av1/common/debugmodes.c
+++ b/av1/common/debugmodes.c
@@ -18,7 +18,7 @@
 static void log_frame_info(AV1_COMMON *cm, const char *str, FILE *f) {
   fprintf(f, "%s", str);
   fprintf(f, "(Frame %d, Show:%d, Q:%d): \n", cm->current_frame.frame_number,
-          cm->show_frame, cm->base_qindex);
+          cm->show_frame, cm->quant_params.base_qindex);
 }
 /* This function dereferences a pointer to the mbmi structure
  * and uses the passed in member offset to print out the value of an integer
diff --git a/av1/common/entropy.c b/av1/common/entropy.c
index cd63fd2..1f7a0ef 100644
--- a/av1/common/entropy.c
+++ b/av1/common/entropy.c
@@ -29,7 +29,7 @@
 }
 
 void av1_default_coef_probs(AV1_COMMON *cm) {
-  const int index = get_q_ctx(cm->base_qindex);
+  const int index = get_q_ctx(cm->quant_params.base_qindex);
 #if CONFIG_ENTROPY_STATS
   cm->coef_cdf_category = index;
 #endif
diff --git a/av1/common/quant_common.c b/av1/common/quant_common.c
index 327948c..804eb6a 100644
--- a/av1/common/quant_common.c
+++ b/av1/common/quant_common.c
@@ -225,23 +225,23 @@
   }
 }
 
-bool av1_use_qmatrix(const AV1_COMMON *cm, const MACROBLOCKD *const xd,
-                     int segment_id) {
+bool av1_use_qmatrix(const CommonQuantParams *quant_params,
+                     const MACROBLOCKD *const xd, int segment_id) {
   // True if we are using Q matrix and this is not a lossless segment.
-  return cm->using_qmatrix && !xd->lossless[segment_id];
+  return quant_params->using_qmatrix && !xd->lossless[segment_id];
 }
 
-const qm_val_t *av1_iqmatrix(AV1_COMMON *cm, int qmlevel, int plane,
-                             TX_SIZE tx_size) {
-  assert(cm->giqmatrix[qmlevel][plane][tx_size] != NULL ||
+const qm_val_t *av1_iqmatrix(const CommonQuantParams *quant_params, int qmlevel,
+                             int plane, TX_SIZE tx_size) {
+  assert(quant_params->giqmatrix[qmlevel][plane][tx_size] != NULL ||
          qmlevel == NUM_QM_LEVELS - 1);
-  return cm->giqmatrix[qmlevel][plane][tx_size];
+  return quant_params->giqmatrix[qmlevel][plane][tx_size];
 }
-const qm_val_t *av1_qmatrix(AV1_COMMON *cm, int qmlevel, int plane,
-                            TX_SIZE tx_size) {
-  assert(cm->gqmatrix[qmlevel][plane][tx_size] != NULL ||
+const qm_val_t *av1_qmatrix(const CommonQuantParams *quant_params, int qmlevel,
+                            int plane, TX_SIZE tx_size) {
+  assert(quant_params->gqmatrix[qmlevel][plane][tx_size] != NULL ||
          qmlevel == NUM_QM_LEVELS - 1);
-  return cm->gqmatrix[qmlevel][plane][tx_size];
+  return quant_params->gqmatrix[qmlevel][plane][tx_size];
 }
 
 #define QM_TOTAL_SIZE 3344
@@ -250,27 +250,27 @@
 static const qm_val_t wt_matrix_ref[NUM_QM_LEVELS - 1][2][QM_TOTAL_SIZE];
 static const qm_val_t iwt_matrix_ref[NUM_QM_LEVELS - 1][2][QM_TOTAL_SIZE];
 
-void av1_qm_init(AV1_COMMON *cm) {
-  const int num_planes = av1_num_planes(cm);
-  int q, c, t;
-  int current;
-  for (q = 0; q < NUM_QM_LEVELS; ++q) {
-    for (c = 0; c < num_planes; ++c) {
-      current = 0;
-      for (t = 0; t < TX_SIZES_ALL; ++t) {
+void av1_qm_init(CommonQuantParams *quant_params, int num_planes) {
+  for (int q = 0; q < NUM_QM_LEVELS; ++q) {
+    for (int c = 0; c < num_planes; ++c) {
+      int current = 0;
+      for (int t = 0; t < TX_SIZES_ALL; ++t) {
         const int size = tx_size_2d[t];
         const int qm_tx_size = av1_get_adjusted_tx_size(t);
         if (q == NUM_QM_LEVELS - 1) {
-          cm->gqmatrix[q][c][t] = NULL;
-          cm->giqmatrix[q][c][t] = NULL;
+          quant_params->gqmatrix[q][c][t] = NULL;
+          quant_params->giqmatrix[q][c][t] = NULL;
         } else if (t != qm_tx_size) {  // Reuse matrices for 'qm_tx_size'
           assert(t > qm_tx_size);
-          cm->gqmatrix[q][c][t] = cm->gqmatrix[q][c][qm_tx_size];
-          cm->giqmatrix[q][c][t] = cm->giqmatrix[q][c][qm_tx_size];
+          quant_params->gqmatrix[q][c][t] =
+              quant_params->gqmatrix[q][c][qm_tx_size];
+          quant_params->giqmatrix[q][c][t] =
+              quant_params->giqmatrix[q][c][qm_tx_size];
         } else {
           assert(current + size <= QM_TOTAL_SIZE);
-          cm->gqmatrix[q][c][t] = &wt_matrix_ref[q][c >= 1][current];
-          cm->giqmatrix[q][c][t] = &iwt_matrix_ref[q][c >= 1][current];
+          quant_params->gqmatrix[q][c][t] = &wt_matrix_ref[q][c >= 1][current];
+          quant_params->giqmatrix[q][c][t] =
+              &iwt_matrix_ref[q][c >= 1][current];
           current += size;
         }
       }
diff --git a/av1/common/quant_common.h b/av1/common/quant_common.h
index 7556669..8dc0419 100644
--- a/av1/common/quant_common.h
+++ b/av1/common/quant_common.h
@@ -38,6 +38,7 @@
 #define DEFAULT_QM_LAST 9
 
 struct AV1Common;
+struct CommonQuantParams;
 struct macroblockd;
 
 int16_t av1_dc_quant_QTX(int qindex, int delta, aom_bit_depth_t bit_depth);
@@ -47,19 +48,22 @@
                    int base_qindex);
 
 // Returns true if we should use quantization matrix.
-bool av1_use_qmatrix(const struct AV1Common *cm,
-                     const struct macroblockd *const xd, int segment_id);
+bool av1_use_qmatrix(const struct CommonQuantParams *quant_params,
+                     const struct macroblockd *xd, int segment_id);
 
 // Reduce the large number of quantizers to a smaller number of levels for which
 // different matrices may be defined
 static INLINE int aom_get_qmlevel(int qindex, int first, int last) {
   return first + (qindex * (last + 1 - first)) / QINDEX_RANGE;
 }
-void av1_qm_init(struct AV1Common *cm);
-const qm_val_t *av1_iqmatrix(struct AV1Common *cm, int qmlevel, int plane,
-                             TX_SIZE tx_size);
-const qm_val_t *av1_qmatrix(struct AV1Common *cm, int qmlevel, int plane,
-                            TX_SIZE tx_size);
+
+// Initialize all global quant/dequant matrices.
+void av1_qm_init(struct CommonQuantParams *quant_params, int num_planes);
+
+const qm_val_t *av1_iqmatrix(const struct CommonQuantParams *quant_params,
+                             int qmlevel, int plane, TX_SIZE tx_size);
+const qm_val_t *av1_qmatrix(const struct CommonQuantParams *quant_params,
+                            int qmlevel, int plane, TX_SIZE tx_size);
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 75f88be..2e16afe 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1450,12 +1450,14 @@
     for (int i = 0; i < MAX_SEGMENTS; i++) {
       const int current_qindex =
           av1_get_qindex(&cm->seg, i, xd->current_qindex);
+      const CommonQuantParams *const quant_params = &cm->quant_params;
       for (int j = 0; j < num_planes; ++j) {
-        const int dc_delta_q =
-            j == 0 ? cm->y_dc_delta_q
-                   : (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q);
-        const int ac_delta_q =
-            j == 0 ? 0 : (j == 1 ? cm->u_ac_delta_q : cm->v_ac_delta_q);
+        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] = av1_dc_quant_QTX(
             current_qindex, dc_delta_q, cm->seq_params.bit_depth);
         xd->plane[j].seg_dequant_QTX[i][1] = av1_ac_quant_QTX(
@@ -2036,42 +2038,42 @@
   return aom_rb_read_bit(rb) ? aom_rb_read_inv_signed_literal(rb, 6) : 0;
 }
 
-static AOM_INLINE void setup_quantization(AV1_COMMON *const cm,
+static AOM_INLINE void setup_quantization(CommonQuantParams *quant_params,
+                                          int num_planes,
+                                          bool separate_uv_delta_q,
                                           struct aom_read_bit_buffer *rb) {
-  const SequenceHeader *const seq_params = &cm->seq_params;
-  const int num_planes = av1_num_planes(cm);
-  cm->base_qindex = aom_rb_read_literal(rb, QINDEX_BITS);
-  cm->y_dc_delta_q = read_delta_q(rb);
+  quant_params->base_qindex = aom_rb_read_literal(rb, QINDEX_BITS);
+  quant_params->y_dc_delta_q = read_delta_q(rb);
   if (num_planes > 1) {
     int diff_uv_delta = 0;
-    if (seq_params->separate_uv_delta_q) diff_uv_delta = aom_rb_read_bit(rb);
-    cm->u_dc_delta_q = read_delta_q(rb);
-    cm->u_ac_delta_q = read_delta_q(rb);
+    if (separate_uv_delta_q) diff_uv_delta = aom_rb_read_bit(rb);
+    quant_params->u_dc_delta_q = read_delta_q(rb);
+    quant_params->u_ac_delta_q = read_delta_q(rb);
     if (diff_uv_delta) {
-      cm->v_dc_delta_q = read_delta_q(rb);
-      cm->v_ac_delta_q = read_delta_q(rb);
+      quant_params->v_dc_delta_q = read_delta_q(rb);
+      quant_params->v_ac_delta_q = read_delta_q(rb);
     } else {
-      cm->v_dc_delta_q = cm->u_dc_delta_q;
-      cm->v_ac_delta_q = cm->u_ac_delta_q;
+      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 {
-    cm->u_dc_delta_q = 0;
-    cm->u_ac_delta_q = 0;
-    cm->v_dc_delta_q = 0;
-    cm->v_ac_delta_q = 0;
+    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;
   }
-  cm->using_qmatrix = aom_rb_read_bit(rb);
-  if (cm->using_qmatrix) {
-    cm->qm_y = aom_rb_read_literal(rb, QM_LEVEL_BITS);
-    cm->qm_u = aom_rb_read_literal(rb, QM_LEVEL_BITS);
-    if (!seq_params->separate_uv_delta_q)
-      cm->qm_v = cm->qm_u;
+  quant_params->using_qmatrix = aom_rb_read_bit(rb);
+  if (quant_params->using_qmatrix) {
+    quant_params->qm_y = aom_rb_read_literal(rb, QM_LEVEL_BITS);
+    quant_params->qm_u = aom_rb_read_literal(rb, QM_LEVEL_BITS);
+    if (!separate_uv_delta_q)
+      quant_params->qm_v = quant_params->qm_u;
     else
-      cm->qm_v = aom_rb_read_literal(rb, QM_LEVEL_BITS);
+      quant_params->qm_v = aom_rb_read_literal(rb, QM_LEVEL_BITS);
   } else {
-    cm->qm_y = 0;
-    cm->qm_u = 0;
-    cm->qm_v = 0;
+    quant_params->qm_y = 0;
+    quant_params->qm_u = 0;
+    quant_params->qm_v = 0;
   }
 }
 
@@ -2082,33 +2084,37 @@
   // When segmentation is disabled, only the first value is used.  The
   // remaining are don't cares.
   const int max_segments = cm->seg.enabled ? MAX_SEGMENTS : 1;
+  CommonQuantParams *const quant_params = &cm->quant_params;
   for (int i = 0; i < max_segments; ++i) {
     const int qindex = xd->qindex[i];
-    cm->y_dequant_QTX[i][0] =
-        av1_dc_quant_QTX(qindex, cm->y_dc_delta_q, bit_depth);
-    cm->y_dequant_QTX[i][1] = av1_ac_quant_QTX(qindex, 0, bit_depth);
-    cm->u_dequant_QTX[i][0] =
-        av1_dc_quant_QTX(qindex, cm->u_dc_delta_q, bit_depth);
-    cm->u_dequant_QTX[i][1] =
-        av1_ac_quant_QTX(qindex, cm->u_ac_delta_q, bit_depth);
-    cm->v_dequant_QTX[i][0] =
-        av1_dc_quant_QTX(qindex, cm->v_dc_delta_q, bit_depth);
-    cm->v_dequant_QTX[i][1] =
-        av1_ac_quant_QTX(qindex, cm->v_ac_delta_q, bit_depth);
-    const int use_qmatrix = av1_use_qmatrix(cm, xd, i);
+    quant_params->y_dequant_QTX[i][0] =
+        av1_dc_quant_QTX(qindex, quant_params->y_dc_delta_q, bit_depth);
+    quant_params->y_dequant_QTX[i][1] = av1_ac_quant_QTX(qindex, 0, bit_depth);
+    quant_params->u_dequant_QTX[i][0] =
+        av1_dc_quant_QTX(qindex, quant_params->u_dc_delta_q, bit_depth);
+    quant_params->u_dequant_QTX[i][1] =
+        av1_ac_quant_QTX(qindex, quant_params->u_ac_delta_q, bit_depth);
+    quant_params->v_dequant_QTX[i][0] =
+        av1_dc_quant_QTX(qindex, quant_params->v_dc_delta_q, bit_depth);
+    quant_params->v_dequant_QTX[i][1] =
+        av1_ac_quant_QTX(qindex, quant_params->v_ac_delta_q, bit_depth);
+    const int use_qmatrix = av1_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 qmlevel_y = use_qmatrix ? cm->qm_y : NUM_QM_LEVELS - 1;
+    const int qmlevel_y = use_qmatrix ? quant_params->qm_y : NUM_QM_LEVELS - 1;
     for (int j = 0; j < TX_SIZES_ALL; ++j) {
-      cm->y_iqmatrix[i][j] = av1_iqmatrix(cm, qmlevel_y, AOM_PLANE_Y, j);
+      quant_params->y_iqmatrix[i][j] =
+          av1_iqmatrix(quant_params, qmlevel_y, AOM_PLANE_Y, j);
     }
-    const int qmlevel_u = use_qmatrix ? cm->qm_u : NUM_QM_LEVELS - 1;
+    const int qmlevel_u = use_qmatrix ? quant_params->qm_u : NUM_QM_LEVELS - 1;
     for (int j = 0; j < TX_SIZES_ALL; ++j) {
-      cm->u_iqmatrix[i][j] = av1_iqmatrix(cm, qmlevel_u, AOM_PLANE_U, j);
+      quant_params->u_iqmatrix[i][j] =
+          av1_iqmatrix(quant_params, qmlevel_u, AOM_PLANE_U, j);
     }
-    const int qmlevel_v = use_qmatrix ? cm->qm_v : NUM_QM_LEVELS - 1;
+    const int qmlevel_v = use_qmatrix ? quant_params->qm_v : NUM_QM_LEVELS - 1;
     for (int j = 0; j < TX_SIZES_ALL; ++j) {
-      cm->v_iqmatrix[i][j] = av1_iqmatrix(cm, qmlevel_v, AOM_PLANE_V, j);
+      quant_params->v_iqmatrix[i][j] =
+          av1_iqmatrix(quant_params, qmlevel_v, AOM_PLANE_V, j);
     }
   }
 }
@@ -3053,7 +3059,7 @@
       td->bit_reader = &tile_data->bit_reader;
       av1_zero(td->cb_buffer_base.dqcoeff);
       av1_tile_init(&td->xd.tile, cm, row, col);
-      td->xd.current_qindex = cm->base_qindex;
+      td->xd.current_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
@@ -3123,7 +3129,7 @@
   td->bit_reader = &tile_data->bit_reader;
   av1_zero(td->cb_buffer_base.dqcoeff);
   av1_tile_init(&td->xd.tile, cm, tile_row, tile_col);
-  td->xd.current_qindex = cm->base_qindex;
+  td->xd.current_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);
@@ -5173,7 +5179,9 @@
                        "Minimum tile width requirement not satisfied");
   }
 
-  setup_quantization(cm, rb);
+  CommonQuantParams *const quant_params = &cm->quant_params;
+  setup_quantization(quant_params, av1_num_planes(cm),
+                     cm->seq_params.separate_uv_delta_q, rb);
   xd->bd = (int)seq_params->bit_depth;
 
   if (cm->num_allocated_above_context_planes < av1_num_planes(cm) ||
@@ -5196,9 +5204,9 @@
   cm->delta_q_info.delta_lf_present_flag = 0;
   cm->delta_q_info.delta_lf_multi = 0;
   cm->delta_q_info.delta_q_present_flag =
-      cm->base_qindex > 0 ? aom_rb_read_bit(rb) : 0;
+      quant_params->base_qindex > 0 ? aom_rb_read_bit(rb) : 0;
   if (cm->delta_q_info.delta_q_present_flag) {
-    xd->current_qindex = cm->base_qindex;
+    xd->current_qindex = quant_params->base_qindex;
     cm->delta_q_info.delta_q_res = 1 << aom_rb_read_literal(rb, 2);
     if (!features->allow_intrabc)
       cm->delta_q_info.delta_lf_present_flag = aom_rb_read_bit(rb);
@@ -5212,10 +5220,11 @@
   xd->cur_frame_force_integer_mv = features->cur_frame_force_integer_mv;
 
   for (int i = 0; i < MAX_SEGMENTS; ++i) {
-    const int qindex = av1_get_qindex(&cm->seg, i, cm->base_qindex);
-    xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
-                      cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 &&
-                      cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0;
+    const int qindex = av1_get_qindex(&cm->seg, i, quant_params->base_qindex);
+    xd->lossless[i] =
+        qindex == 0 && quant_params->y_dc_delta_q == 0 &&
+        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;
     xd->qindex[i] = qindex;
   }
   features->coded_lossless = is_coded_lossless(cm, xd);
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 7cfe1ed..fc5f2cd 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -137,7 +137,7 @@
 
   av1_loop_filter_init(cm);
 
-  av1_qm_init(cm);
+  av1_qm_init(&cm->quant_params, av1_num_planes(cm));
   av1_loop_restoration_precal();
 #if CONFIG_ACCOUNTING
   pbi->acct_enabled = 1;
diff --git a/av1/decoder/decodetxb.c b/av1/decoder/decodetxb.c
index 116b64c..aa08022 100644
--- a/av1/decoder/decodetxb.c
+++ b/av1/decoder/decodetxb.c
@@ -165,7 +165,7 @@
   const qm_val_t *iqmatrix =
       IS_2D_TRANSFORM(tx_type)
           ? pd->seg_iqmatrix[mbmi->segment_id][qm_tx_size]
-          : cm->giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
+          : cm->quant_params.giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
   const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
   const int16_t *const scan = scan_order->scan;
   int eob_extra = 0;
diff --git a/av1/decoder/inspection.c b/av1/decoder/inspection.c
index 72ced47..d121a70 100644
--- a/av1/decoder/inspection.c
+++ b/av1/decoder/inspection.c
@@ -37,6 +37,7 @@
   struct AV1Decoder *pbi = (struct AV1Decoder *)decoder;
   AV1_COMMON *const cm = &pbi->common;
   const CommonModeInfoParams *const mi_params = &cm->mi_params;
+  const CommonQuantParams *quant_params = &cm->quant_params;
 
   if (fd->mi_rows != mi_params->mi_rows || fd->mi_cols != mi_params->mi_cols) {
     ifd_clear(fd);
@@ -46,7 +47,7 @@
   fd->frame_number = cm->current_frame.frame_number;
   fd->show_frame = cm->show_frame;
   fd->frame_type = cm->current_frame.frame_type;
-  fd->base_qindex = cm->base_qindex;
+  fd->base_qindex = quant_params->base_qindex;
   // Set width and height of the first tile until generic support can be added
   TileInfo tile_info;
   av1_tile_set_row(&tile_info, cm, 0);
@@ -62,9 +63,9 @@
   int i, j;
   for (i = 0; i < MAX_SEGMENTS; i++) {
     for (j = 0; j < 2; j++) {
-      fd->y_dequant[i][j] = cm->y_dequant_QTX[i][j];
-      fd->u_dequant[i][j] = cm->u_dequant_QTX[i][j];
-      fd->v_dequant[i][j] = cm->v_dequant_QTX[i][j];
+      fd->y_dequant[i][j] = quant_params->y_dequant_QTX[i][j];
+      fd->u_dequant[i][j] = quant_params->u_dequant_QTX[i][j];
+      fd->v_dequant[i][j] = quant_params->v_dequant_QTX[i][j];
     }
   }
   for (j = 0; j < mi_params->mi_rows; j++) {
diff --git a/av1/encoder/aq_complexity.c b/av1/encoder/aq_complexity.c
index 936eddc..1756f46 100644
--- a/av1/encoder/aq_complexity.c
+++ b/av1/encoder/aq_complexity.c
@@ -61,8 +61,9 @@
 
 void av1_setup_in_frame_q_adj(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  const int base_qindex = cm->quant_params.base_qindex;
   struct segmentation *const seg = &cm->seg;
-  int resolution_change =
+  const int resolution_change =
       cm->prev_frame && (cm->width != cm->prev_frame->width ||
                          cm->height != cm->prev_frame->height);
 
@@ -80,7 +81,7 @@
   if (is_frame_aq_enabled(cpi)) {
     int segment;
     const int aq_strength =
-        get_aq_c_strength(cm->base_qindex, cm->seq_params.bit_depth);
+        get_aq_c_strength(base_qindex, cm->seq_params.bit_depth);
 
     // Clear down the segment map.
     memset(cpi->segmentation_map, DEFAULT_AQ2_SEG,
@@ -105,17 +106,17 @@
       if (segment == DEFAULT_AQ2_SEG) continue;
 
       qindex_delta = av1_compute_qdelta_by_rate(
-          &cpi->rc, cm->current_frame.frame_type, cm->base_qindex,
+          &cpi->rc, cm->current_frame.frame_type, base_qindex,
           aq_c_q_adj_factor[aq_strength][segment], cm->seq_params.bit_depth);
 
       // For AQ complexity mode, we dont allow Q0 in a segment if the base
       // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment
       // Q delta is sometimes applied without going back around the rd loop.
       // This could lead to an illegal combination of partition size and q.
-      if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
-        qindex_delta = -cm->base_qindex + 1;
+      if ((base_qindex != 0) && ((base_qindex + qindex_delta) == 0)) {
+        qindex_delta = -base_qindex + 1;
       }
-      if ((cm->base_qindex + qindex_delta) > 0) {
+      if ((base_qindex + qindex_delta) > 0) {
         av1_enable_segfeature(seg, segment, SEG_LVL_ALT_Q);
         av1_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta);
       }
@@ -152,8 +153,8 @@
     const int target_rate = (int)(num / denom);
     double logvar;
     double low_var_thresh;
-    const int aq_strength =
-        get_aq_c_strength(cm->base_qindex, cm->seq_params.bit_depth);
+    const int aq_strength = get_aq_c_strength(cm->quant_params.base_qindex,
+                                              cm->seq_params.bit_depth);
 
     aom_clear_system_state();
     low_var_thresh =
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c
index 3866411..835998b 100644
--- a/av1/encoder/aq_cyclicrefresh.c
+++ b/av1/encoder/aq_cyclicrefresh.c
@@ -96,28 +96,27 @@
 int av1_cyclic_refresh_estimate_bits_at_q(const AV1_COMP *cpi,
                                           double correction_factor) {
   const AV1_COMMON *const cm = &cpi->common;
+  const FRAME_TYPE frame_type = cm->current_frame.frame_type;
+  const int base_qindex = cm->quant_params.base_qindex;
+  const int bit_depth = cm->seq_params.bit_depth;
   const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
-  int estimated_bits;
-  int mbs = cm->mi_params.MBs;
-  int num4x4bl = mbs << 4;
+  const int mbs = cm->mi_params.MBs;
+  const int num4x4bl = mbs << 4;
   // Weight for non-base segments: use actual number of blocks refreshed in
   // previous/just encoded frame. Note number of blocks here is in 4x4 units.
-  double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
-  double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
+  const double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
+  const double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
   // Take segment weighted average for estimated bits.
-  estimated_bits =
+  const int estimated_bits =
       (int)((1.0 - weight_segment1 - weight_segment2) *
-                av1_estimate_bits_at_q(cm->current_frame.frame_type,
-                                       cm->base_qindex, mbs, correction_factor,
-                                       cm->seq_params.bit_depth) +
+                av1_estimate_bits_at_q(frame_type, base_qindex, mbs,
+                                       correction_factor, bit_depth) +
             weight_segment1 * av1_estimate_bits_at_q(
-                                  cm->current_frame.frame_type,
-                                  cm->base_qindex + cr->qindex_delta[1], mbs,
-                                  correction_factor, cm->seq_params.bit_depth) +
+                                  frame_type, base_qindex + cr->qindex_delta[1],
+                                  mbs, correction_factor, bit_depth) +
             weight_segment2 * av1_estimate_bits_at_q(
-                                  cm->current_frame.frame_type,
-                                  cm->base_qindex + cr->qindex_delta[2], mbs,
-                                  correction_factor, cm->seq_params.bit_depth));
+                                  frame_type, base_qindex + cr->qindex_delta[2],
+                                  mbs, correction_factor, bit_depth));
   return estimated_bits;
 }
 
@@ -293,10 +292,10 @@
     // TODO(any): Ensure the population of
     // cpi->common.features.allow_screen_content_tools and use the same instead
     // of cpi->oxcf.content == AOM_CONTENT_SCREEN
-    int qindex_thresh =
-        cpi->oxcf.content == AOM_CONTENT_SCREEN
-            ? av1_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2, cm->base_qindex)
-            : 0;
+    int qindex_thresh = cpi->oxcf.content == AOM_CONTENT_SCREEN
+                            ? av1_get_qindex(&cm->seg, CR_SEGMENT_ID_BOOST2,
+                                             cm->quant_params.base_qindex)
+                            : 0;
     assert(mi_row >= 0 && mi_row < mi_params->mi_rows);
     assert(mi_col >= 0 && mi_col < mi_params->mi_cols);
     bl_index = mi_row * mi_params->mi_cols + mi_col;
@@ -431,8 +430,8 @@
     }
     return;
   } else {
-    const double q =
-        av1_convert_qindex_to_q(cm->base_qindex, cm->seq_params.bit_depth);
+    const double q = av1_convert_qindex_to_q(cm->quant_params.base_qindex,
+                                             cm->seq_params.bit_depth);
     aom_clear_system_state();
     // Set rate threshold to some multiple (set to 2 for now) of the target
     // rate (target is given by sb64_target_rate and scaled by 256).
@@ -463,20 +462,22 @@
     av1_enable_segfeature(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q);
 
     // Set the q delta for segment BOOST1.
+    const CommonQuantParams *const quant_params = &cm->quant_params;
     int qindex_delta =
-        compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta);
+        compute_deltaq(cpi, quant_params->base_qindex, cr->rate_ratio_qdelta);
     cr->qindex_delta[1] = qindex_delta;
 
     // Compute rd-mult for segment BOOST1.
-    const int qindex2 =
-        clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ);
+    const int qindex2 = clamp(
+        quant_params->base_qindex + quant_params->y_dc_delta_q + qindex_delta,
+        0, MAXQ);
     cr->rdmult = av1_compute_rd_mult(cpi, qindex2);
 
     av1_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta);
 
     // Set a more aggressive (higher) q delta for segment BOOST2.
     qindex_delta = compute_deltaq(
-        cpi, cm->base_qindex,
+        cpi, quant_params->base_qindex,
         AOMMIN(CR_MAX_RATE_TARGET_RATIO,
                0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta));
     cr->qindex_delta[2] = qindex_delta;
diff --git a/av1/encoder/aq_variance.c b/av1/encoder/aq_variance.c
index 6e3cc3c..89e444d 100644
--- a/av1/encoder/aq_variance.c
+++ b/av1/encoder/aq_variance.c
@@ -44,6 +44,7 @@
 
 void av1_vaq_frame_setup(AV1_COMP *cpi) {
   AV1_COMMON *cm = &cpi->common;
+  const int base_qindex = cm->quant_params.base_qindex;
   struct segmentation *seg = &cm->seg;
   int i;
 
@@ -78,15 +79,15 @@
       // Set up avg segment id to be 1.0 and adjust the other segments around
       // it.
       int qindex_delta = av1_compute_qdelta_by_rate(
-          &cpi->rc, cm->current_frame.frame_type, cm->base_qindex,
+          &cpi->rc, cm->current_frame.frame_type, base_qindex,
           rate_ratio[i] / avg_ratio, cm->seq_params.bit_depth);
 
       // We don't allow qindex 0 in a segment if the base value is not 0.
       // Q index 0 (lossless) implies 4x4 encoding only and in AQ mode a segment
       // Q delta is sometimes applied without going back around the rd loop.
       // This could lead to an illegal combination of partition size and q.
-      if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
-        qindex_delta = -cm->base_qindex + 1;
+      if ((base_qindex != 0) && ((base_qindex + qindex_delta) == 0)) {
+        qindex_delta = -base_qindex + 1;
       }
 
       av1_set_segdata(seg, i, SEG_LVL_ALT_Q, qindex_delta);
@@ -193,12 +194,13 @@
   } else {
     rate_level = block_var_level;
   }
+  const int base_qindex = cm->quant_params.base_qindex;
   int qindex_delta = av1_compute_qdelta_by_rate(
-      &cpi->rc, cm->current_frame.frame_type, cm->base_qindex,
+      &cpi->rc, cm->current_frame.frame_type, base_qindex,
       deltaq_rate_ratio[rate_level], cm->seq_params.bit_depth);
 
-  if ((cm->base_qindex != 0) && ((cm->base_qindex + qindex_delta) == 0)) {
-    qindex_delta = -cm->base_qindex + 1;
+  if ((base_qindex != 0) && ((base_qindex + qindex_delta) == 0)) {
+    qindex_delta = -base_qindex + 1;
   }
-  return cm->base_qindex + qindex_delta;
+  return base_qindex + qindex_delta;
 }
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c
index bf649d2..995c90b 100644
--- a/av1/encoder/av1_quantize.c
+++ b/av1/encoder/av1_quantize.c
@@ -649,30 +649,35 @@
 }
 
 void av1_init_quantizer(AV1_COMP *cpi) {
-  AV1_COMMON *const cm = &cpi->common;
+  const AV1_COMMON *const cm = &cpi->common;
+  const CommonQuantParams *const quant_params = &cm->quant_params;
   QUANTS *const quants = &cpi->quants;
   Dequants *const dequants = &cpi->dequants;
-  av1_build_quantizer(cm->seq_params.bit_depth, cm->y_dc_delta_q,
-                      cm->u_dc_delta_q, cm->u_ac_delta_q, cm->v_dc_delta_q,
-                      cm->v_ac_delta_q, quants, dequants);
+  av1_build_quantizer(cm->seq_params.bit_depth, quant_params->y_dc_delta_q,
+                      quant_params->u_dc_delta_q, quant_params->u_ac_delta_q,
+                      quant_params->v_dc_delta_q, quant_params->v_ac_delta_q,
+                      quants, dequants);
 }
 
 void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
                                int segment_id) {
   const AV1_COMMON *const cm = &cpi->common;
+  const CommonQuantParams *const quant_params = &cm->quant_params;
   MACROBLOCKD *const xd = &x->e_mbd;
   const QUANTS *const quants = &cpi->quants;
 
-  const int current_qindex = AOMMAX(
-      0, AOMMIN(QINDEX_RANGE - 1, cm->delta_q_info.delta_q_present_flag
-                                      ? cm->base_qindex + xd->delta_qindex
-                                      : cm->base_qindex));
+  const int current_qindex =
+      AOMMAX(0, AOMMIN(QINDEX_RANGE - 1,
+                       cm->delta_q_info.delta_q_present_flag
+                           ? quant_params->base_qindex + xd->delta_qindex
+                           : quant_params->base_qindex));
   const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex);
-  const int rdmult = av1_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
-  const int use_qmatrix = av1_use_qmatrix(cm, xd, segment_id);
+  const int rdmult =
+      av1_compute_rd_mult(cpi, qindex + quant_params->y_dc_delta_q);
+  const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id);
 
   // Y
-  const int qmlevel_y = use_qmatrix ? cm->qm_y : NUM_QM_LEVELS - 1;
+  const int qmlevel_y = use_qmatrix ? quant_params->qm_y : NUM_QM_LEVELS - 1;
   x->plane[0].quant_QTX = quants->y_quant[qindex];
   x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
   x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
@@ -680,13 +685,15 @@
   x->plane[0].zbin_QTX = quants->y_zbin[qindex];
   x->plane[0].round_QTX = quants->y_round[qindex];
   x->plane[0].dequant_QTX = cpi->dequants.y_dequant_QTX[qindex];
-  memcpy(&xd->plane[0].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel_y][0],
-         sizeof(cm->gqmatrix[qmlevel_y][0]));
-  memcpy(&xd->plane[0].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel_y][0],
-         sizeof(cm->giqmatrix[qmlevel_y][0]));
+  memcpy(&xd->plane[0].seg_qmatrix[segment_id],
+         quant_params->gqmatrix[qmlevel_y][0],
+         sizeof(quant_params->gqmatrix[qmlevel_y][0]));
+  memcpy(&xd->plane[0].seg_iqmatrix[segment_id],
+         quant_params->giqmatrix[qmlevel_y][0],
+         sizeof(quant_params->giqmatrix[qmlevel_y][0]));
 
   // U
-  const int qmlevel_u = use_qmatrix ? cm->qm_u : NUM_QM_LEVELS - 1;
+  const int qmlevel_u = use_qmatrix ? quant_params->qm_u : NUM_QM_LEVELS - 1;
   x->plane[1].quant_QTX = quants->u_quant[qindex];
   x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
   x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
@@ -694,12 +701,14 @@
   x->plane[1].zbin_QTX = quants->u_zbin[qindex];
   x->plane[1].round_QTX = quants->u_round[qindex];
   x->plane[1].dequant_QTX = cpi->dequants.u_dequant_QTX[qindex];
-  memcpy(&xd->plane[1].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel_u][1],
-         sizeof(cm->gqmatrix[qmlevel_u][1]));
-  memcpy(&xd->plane[1].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel_u][1],
-         sizeof(cm->giqmatrix[qmlevel_u][1]));
+  memcpy(&xd->plane[1].seg_qmatrix[segment_id],
+         quant_params->gqmatrix[qmlevel_u][1],
+         sizeof(quant_params->gqmatrix[qmlevel_u][1]));
+  memcpy(&xd->plane[1].seg_iqmatrix[segment_id],
+         quant_params->giqmatrix[qmlevel_u][1],
+         sizeof(quant_params->giqmatrix[qmlevel_u][1]));
   // V
-  const int qmlevel_v = use_qmatrix ? cm->qm_v : NUM_QM_LEVELS - 1;
+  const int qmlevel_v = use_qmatrix ? quant_params->qm_v : NUM_QM_LEVELS - 1;
   x->plane[2].quant_QTX = quants->v_quant[qindex];
   x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
   x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
@@ -707,10 +716,12 @@
   x->plane[2].zbin_QTX = quants->v_zbin[qindex];
   x->plane[2].round_QTX = quants->v_round[qindex];
   x->plane[2].dequant_QTX = cpi->dequants.v_dequant_QTX[qindex];
-  memcpy(&xd->plane[2].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel_v][2],
-         sizeof(cm->gqmatrix[qmlevel_v][2]));
-  memcpy(&xd->plane[2].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel_v][2],
-         sizeof(cm->giqmatrix[qmlevel_v][2]));
+  memcpy(&xd->plane[2].seg_qmatrix[segment_id],
+         quant_params->gqmatrix[qmlevel_v][2],
+         sizeof(quant_params->gqmatrix[qmlevel_v][2]));
+  memcpy(&xd->plane[2].seg_iqmatrix[segment_id],
+         quant_params->giqmatrix[qmlevel_v][2],
+         sizeof(quant_params->giqmatrix[qmlevel_v][2]));
   x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
   x->qindex = qindex;
 
@@ -729,22 +740,25 @@
   // quantizer has to be reinitialized with av1_init_quantizer() if any
   // delta_q changes.
   AV1_COMMON *const cm = &cpi->common;
-  cm->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
-  cm->y_dc_delta_q = 0;
-  cm->u_dc_delta_q = 0;
-  cm->u_ac_delta_q = 0;
-  cm->v_dc_delta_q = 0;
-  cm->v_ac_delta_q = 0;
-  cm->qm_y =
-      aom_get_qmlevel(cm->base_qindex, cpi->min_qmlevel, cpi->max_qmlevel);
-  cm->qm_u = aom_get_qmlevel(cm->base_qindex + cm->u_ac_delta_q,
-                             cpi->min_qmlevel, cpi->max_qmlevel);
+  CommonQuantParams *quant_params = &cm->quant_params;
+  quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
+  quant_params->y_dc_delta_q = 0;
+  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;
+  quant_params->qm_y = aom_get_qmlevel(quant_params->base_qindex,
+                                       cpi->min_qmlevel, cpi->max_qmlevel);
+  quant_params->qm_u =
+      aom_get_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q,
+                      cpi->min_qmlevel, cpi->max_qmlevel);
 
   if (!cm->seq_params.separate_uv_delta_q)
-    cm->qm_v = cm->qm_u;
+    quant_params->qm_v = quant_params->qm_u;
   else
-    cm->qm_v = aom_get_qmlevel(cm->base_qindex + cm->v_ac_delta_q,
-                               cpi->min_qmlevel, cpi->max_qmlevel);
+    quant_params->qm_v =
+        aom_get_qmlevel(quant_params->base_qindex + quant_params->v_ac_delta_q,
+                        cpi->min_qmlevel, cpi->max_qmlevel);
 }
 
 // Table that converts 0-63 Q-range values passed in outside to the Qindex
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index fc8a1de..a7f1cf5 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -794,7 +794,7 @@
   const FeatureFlags *const features = &cm->features;
   const int is_inter = is_inter_block(mbmi);
   if (get_ext_tx_types(tx_size, is_inter, features->reduced_tx_set_used) > 1 &&
-      ((!cm->seg.enabled && cm->base_qindex > 0) ||
+      ((!cm->seg.enabled && cm->quant_params.base_qindex > 0) ||
        (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
       !mbmi->skip &&
       !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
@@ -1691,7 +1691,7 @@
   av1_init_above_context(cm, xd, tile->tile_row);
 
   if (cpi->common.delta_q_info.delta_q_present_flag) {
-    xd->current_qindex = cpi->common.base_qindex;
+    xd->current_qindex = cpi->common.quant_params.base_qindex;
     if (cpi->common.delta_q_info.delta_lf_present_flag) {
       av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
     }
@@ -2026,31 +2026,31 @@
   }
 }
 
-static AOM_INLINE void encode_quantization(const AV1_COMMON *const cm,
-                                           struct aom_write_bit_buffer *wb) {
-  const int num_planes = av1_num_planes(cm);
-
-  aom_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS);
-  write_delta_q(wb, cm->y_dc_delta_q);
+static AOM_INLINE void encode_quantization(
+    const CommonQuantParams *const quant_params, int num_planes,
+    bool separate_uv_delta_q, struct aom_write_bit_buffer *wb) {
+  aom_wb_write_literal(wb, quant_params->base_qindex, QINDEX_BITS);
+  write_delta_q(wb, quant_params->y_dc_delta_q);
   if (num_planes > 1) {
-    int diff_uv_delta = (cm->u_dc_delta_q != cm->v_dc_delta_q) ||
-                        (cm->u_ac_delta_q != cm->v_ac_delta_q);
-    if (cm->seq_params.separate_uv_delta_q) aom_wb_write_bit(wb, diff_uv_delta);
-    write_delta_q(wb, cm->u_dc_delta_q);
-    write_delta_q(wb, cm->u_ac_delta_q);
+    int diff_uv_delta =
+        (quant_params->u_dc_delta_q != quant_params->v_dc_delta_q) ||
+        (quant_params->u_ac_delta_q != quant_params->v_ac_delta_q);
+    if (separate_uv_delta_q) aom_wb_write_bit(wb, diff_uv_delta);
+    write_delta_q(wb, quant_params->u_dc_delta_q);
+    write_delta_q(wb, quant_params->u_ac_delta_q);
     if (diff_uv_delta) {
-      write_delta_q(wb, cm->v_dc_delta_q);
-      write_delta_q(wb, cm->v_ac_delta_q);
+      write_delta_q(wb, quant_params->v_dc_delta_q);
+      write_delta_q(wb, quant_params->v_ac_delta_q);
     }
   }
-  aom_wb_write_bit(wb, cm->using_qmatrix);
-  if (cm->using_qmatrix) {
-    aom_wb_write_literal(wb, cm->qm_y, QM_LEVEL_BITS);
-    aom_wb_write_literal(wb, cm->qm_u, QM_LEVEL_BITS);
-    if (!cm->seq_params.separate_uv_delta_q)
-      assert(cm->qm_u == cm->qm_v);
+  aom_wb_write_bit(wb, quant_params->using_qmatrix);
+  if (quant_params->using_qmatrix) {
+    aom_wb_write_literal(wb, quant_params->qm_y, QM_LEVEL_BITS);
+    aom_wb_write_literal(wb, quant_params->qm_u, QM_LEVEL_BITS);
+    if (!separate_uv_delta_q)
+      assert(quant_params->qm_u == quant_params->qm_v);
     else
-      aom_wb_write_literal(wb, cm->qm_v, QM_LEVEL_BITS);
+      aom_wb_write_literal(wb, quant_params->qm_v, QM_LEVEL_BITS);
   }
 }
 
@@ -2826,6 +2826,7 @@
     struct aom_write_bit_buffer *wb) {
   AV1_COMMON *const cm = &cpi->common;
   const SequenceHeader *const seq_params = &cm->seq_params;
+  const CommonQuantParams *quant_params = &cm->quant_params;
   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   CurrentFrame *const current_frame = &cm->current_frame;
   FeatureFlags *const features = &cm->features;
@@ -3067,16 +3068,17 @@
   }
 
   write_tile_info(cm, saved_wb, wb);
-  encode_quantization(cm, wb);
+  encode_quantization(quant_params, av1_num_planes(cm),
+                      cm->seq_params.separate_uv_delta_q, wb);
   encode_segmentation(cm, xd, wb);
 
   const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
-  if (delta_q_info->delta_q_present_flag) assert(cm->base_qindex > 0);
-  if (cm->base_qindex > 0) {
+  if (delta_q_info->delta_q_present_flag) assert(quant_params->base_qindex > 0);
+  if (quant_params->base_qindex > 0) {
     aom_wb_write_bit(wb, delta_q_info->delta_q_present_flag);
     if (delta_q_info->delta_q_present_flag) {
       aom_wb_write_literal(wb, get_msb(delta_q_info->delta_q_res), 2);
-      xd->current_qindex = cm->base_qindex;
+      xd->current_qindex = quant_params->base_qindex;
       if (features->allow_intrabc)
         assert(delta_q_info->delta_lf_present_flag == 0);
       else
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index d00dafc..4791e55 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -1260,7 +1260,7 @@
   cpi->td.mb.e_mbd.delta_qindex = 0;
 
   if (!frame_params.show_existing_frame) {
-    cm->using_qmatrix = cpi->oxcf.using_qm;
+    cm->quant_params.using_qmatrix = cpi->oxcf.using_qm;
     cpi->min_qmlevel = cpi->oxcf.qm_minlevel;
     cpi->max_qmlevel = cpi->oxcf.qm_maxlevel;
 #if !CONFIG_REALTIME_ONLY
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 4533204..ccf66d6 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -240,9 +240,9 @@
 
 static int set_deltaq_rdmult(const AV1_COMP *const cpi, MACROBLOCKD *const xd) {
   const AV1_COMMON *const cm = &cpi->common;
-
-  return av1_compute_rd_mult(
-      cpi, cm->base_qindex + xd->delta_qindex + cm->y_dc_delta_q);
+  const CommonQuantParams *quant_params = &cm->quant_params;
+  return av1_compute_rd_mult(cpi, quant_params->base_qindex + xd->delta_qindex +
+                                      quant_params->y_dc_delta_q);
 }
 
 static AOM_INLINE void set_ssim_rdmult(const AV1_COMP *const cpi,
@@ -336,8 +336,10 @@
   const AV1_COMMON *const cm = &cpi->common;
   av1_init_plane_quantizers(cpi, x, segment_id);
   aom_clear_system_state();
-  int segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
-  return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
+  const int segment_qindex =
+      av1_get_qindex(&cm->seg, segment_id, cm->quant_params.base_qindex);
+  return av1_compute_rd_mult(cpi,
+                             segment_qindex + cm->quant_params.y_dc_delta_q);
 }
 
 static AOM_INLINE void setup_block_rdmult(const AV1_COMP *const cpi,
@@ -4028,12 +4030,13 @@
   int64_t mc_dep_cost = 0;
   const int mi_wide = mi_size_wide[bsize];
   const int mi_high = mi_size_high[bsize];
+  const int base_qindex = cm->quant_params.base_qindex;
 
-  if (tpl_frame->is_valid == 0) return cm->base_qindex;
+  if (tpl_frame->is_valid == 0) return base_qindex;
 
-  if (!is_frame_tpl_eligible(cpi)) return cm->base_qindex;
+  if (!is_frame_tpl_eligible(cpi)) return base_qindex;
 
-  if (cpi->gf_group.index >= MAX_LAG_BUFFERS) return cm->base_qindex;
+  if (cpi->gf_group.index >= MAX_LAG_BUFFERS) return base_qindex;
 
 #if !USE_TPL_CLASSIC_MODEL
   int64_t mc_count = 0, mc_saved = 0;
@@ -4073,13 +4076,13 @@
     beta = (r0 / rk);
     assert(beta > 0.0);
   }
-  offset = av1_get_deltaq_offset(cpi, cm->base_qindex, beta);
+  offset = av1_get_deltaq_offset(cpi, base_qindex, beta);
   aom_clear_system_state();
 
   const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
   offset = AOMMIN(offset, delta_q_info->delta_q_res * 9 - 1);
   offset = AOMMAX(offset, -delta_q_info->delta_q_res * 9 + 1);
-  int qindex = cm->base_qindex + offset;
+  int qindex = cm->quant_params.base_qindex + offset;
   qindex = AOMMIN(qindex, MAXQ);
   qindex = AOMMAX(qindex, MINQ);
 
@@ -4099,7 +4102,7 @@
   // Delta-q modulation based on variance
   av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
 
-  int current_qindex = cm->base_qindex;
+  int current_qindex = cm->quant_params.base_qindex;
   if (cpi->oxcf.deltaq_mode == DELTA_Q_PERCEPTUAL) {
     if (DELTA_Q_PERCEPTUAL_MODULATION == 1) {
       const int block_wavelet_energy_level =
@@ -4126,7 +4129,7 @@
     current_qindex =
         clamp(current_qindex, delta_q_res, 256 - delta_q_info->delta_q_res);
   } else {
-    current_qindex = cm->base_qindex;
+    current_qindex = cm->quant_params.base_qindex;
   }
 
   MACROBLOCKD *const xd = &x->e_mbd;
@@ -4140,7 +4143,7 @@
   current_qindex = AOMMAX(current_qindex, MINQ + 1);
   assert(current_qindex > 0);
 
-  xd->delta_qindex = current_qindex - cm->base_qindex;
+  xd->delta_qindex = current_qindex - cm->quant_params.base_qindex;
   set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
   xd->mi[0]->current_qindex = current_qindex;
   av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id);
@@ -4869,7 +4872,7 @@
   // Reset delta for every tile
   if (mi_row == tile_info->mi_row_start || cpi->row_mt) {
     if (cm->delta_q_info.delta_q_present_flag)
-      xd->current_qindex = cm->base_qindex;
+      xd->current_qindex = cm->quant_params.base_qindex;
     if (cm->delta_q_info.delta_lf_present_flag) {
       av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
     }
@@ -5686,13 +5689,15 @@
     }
   }
 
+  const CommonQuantParams *quant_params = &cm->quant_params;
   for (i = 0; i < MAX_SEGMENTS; ++i) {
-    const int qindex = cm->seg.enabled
-                           ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
-                           : cm->base_qindex;
-    xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
-                      cm->u_dc_delta_q == 0 && cm->u_ac_delta_q == 0 &&
-                      cm->v_dc_delta_q == 0 && cm->v_ac_delta_q == 0;
+    const int qindex =
+        cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex)
+                        : quant_params->base_qindex;
+    xd->lossless[i] =
+        qindex == 0 && quant_params->y_dc_delta_q == 0 &&
+        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;
     if (xd->lossless[i]) cpi->has_lossless_segment = 1;
     xd->qindex[i] = qindex;
     if (xd->lossless[i]) {
@@ -5733,12 +5738,12 @@
 
   // update delta_q_present_flag and delta_lf_present_flag based on
   // base_qindex
-  cm->delta_q_info.delta_q_present_flag &= cm->base_qindex > 0;
-  cm->delta_q_info.delta_lf_present_flag &= cm->base_qindex > 0;
+  cm->delta_q_info.delta_q_present_flag &= quant_params->base_qindex > 0;
+  cm->delta_q_info.delta_lf_present_flag &= quant_params->base_qindex > 0;
 
   av1_frame_init_quantizer(cpi);
   av1_initialize_rd_consts(cpi);
-  av1_initialize_me_consts(cpi, x, cm->base_qindex);
+  av1_initialize_me_consts(cpi, x, quant_params->base_qindex);
 
   init_encode_frame_mb_context(cpi);
   set_default_interp_skip_flags(cpi);
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index d855d2f..95b4e03 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -338,21 +338,23 @@
   qparam->qmatrix = NULL;
   qparam->iqmatrix = NULL;
 }
-void av1_setup_qmatrix(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
-                       TX_SIZE tx_size, TX_TYPE tx_type, QUANT_PARAM *qparam) {
-  MACROBLOCKD *const xd = &x->e_mbd;
+void av1_setup_qmatrix(const CommonQuantParams *quant_params,
+                       const MACROBLOCK *x, int plane, TX_SIZE tx_size,
+                       TX_TYPE tx_type, QUANT_PARAM *qparam) {
+  const MACROBLOCKD *const xd = &x->e_mbd;
   const struct macroblockd_plane *const pd = &xd->plane[plane];
-  MB_MODE_INFO *const mbmi = xd->mi[0];
-  int seg_id = mbmi->segment_id;
+  const MB_MODE_INFO *const mbmi = xd->mi[0];
+  const int seg_id = mbmi->segment_id;
   const TX_SIZE qm_tx_size = av1_get_adjusted_tx_size(tx_size);
   // Use a flat matrix (i.e. no weighting) for 1D and Identity transforms
   const qm_val_t *qmatrix =
-      IS_2D_TRANSFORM(tx_type) ? pd->seg_qmatrix[seg_id][qm_tx_size]
-                               : cm->gqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
+      IS_2D_TRANSFORM(tx_type)
+          ? pd->seg_qmatrix[seg_id][qm_tx_size]
+          : quant_params->gqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
   const qm_val_t *iqmatrix =
       IS_2D_TRANSFORM(tx_type)
           ? pd->seg_iqmatrix[seg_id][qm_tx_size]
-          : cm->giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
+          : quant_params->giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
   qparam->qmatrix = qmatrix;
   qparam->iqmatrix = iqmatrix;
 }
@@ -396,7 +398,8 @@
     av1_setup_xform(cm, x, tx_size, tx_type, &txfm_param);
     av1_setup_quant(tx_size, use_trellis, quant_idx, cpi->use_quant_b_adapt,
                     &quant_param);
-    av1_setup_qmatrix(cm, x, plane, tx_size, tx_type, &quant_param);
+    av1_setup_qmatrix(&cm->quant_params, x, plane, tx_size, tx_type,
+                      &quant_param);
     av1_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, &txfm_param,
                     &quant_param);
 
@@ -413,7 +416,8 @@
                      args->cpi->sf.rd_sf.trellis_eob_fast, &dummy_rate_cost);
     }
     if (!quant_param.use_optimize_b && do_dropout) {
-      av1_dropout_qcoeff(x, plane, block, tx_size, tx_type, cm->base_qindex);
+      av1_dropout_qcoeff(x, plane, block, tx_size, tx_type,
+                         cm->quant_params.base_qindex);
     }
   } else {
     p->eobs[block] = 0;
@@ -585,7 +589,8 @@
   av1_setup_xform(cm, x, tx_size, DCT_DCT, &txfm_param);
   av1_setup_quant(tx_size, 0, AV1_XFORM_QUANT_B, cpi->use_quant_b_adapt,
                   &quant_param);
-  av1_setup_qmatrix(cm, x, plane, tx_size, DCT_DCT, &quant_param);
+  av1_setup_qmatrix(&cm->quant_params, x, plane, tx_size, DCT_DCT,
+                    &quant_param);
 
   av1_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, &txfm_param,
                   &quant_param);
@@ -726,7 +731,8 @@
     av1_setup_xform(cm, x, tx_size, tx_type, &txfm_param);
     av1_setup_quant(tx_size, use_trellis, quant_idx, cpi->use_quant_b_adapt,
                     &quant_param);
-    av1_setup_qmatrix(cm, x, plane, tx_size, tx_type, &quant_param);
+    av1_setup_qmatrix(&cm->quant_params, x, plane, tx_size, tx_type,
+                      &quant_param);
 
     av1_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, &txfm_param,
                     &quant_param);
@@ -753,7 +759,8 @@
                      args->cpi->sf.rd_sf.trellis_eob_fast, &dummy_rate_cost);
     }
     if (do_dropout) {
-      av1_dropout_qcoeff(x, plane, block, tx_size, tx_type, cm->base_qindex);
+      av1_dropout_qcoeff(x, plane, block, tx_size, tx_type,
+                         cm->quant_params.base_qindex);
     }
   }
 
diff --git a/av1/encoder/encodemb.h b/av1/encoder/encodemb.h
index 2abe8ff..e05f4ce 100644
--- a/av1/encoder/encodemb.h
+++ b/av1/encoder/encodemb.h
@@ -68,8 +68,9 @@
                      TX_TYPE tx_type, TxfmParam *txfm_param);
 void av1_setup_quant(TX_SIZE tx_size, int use_optimize_b, int xform_quant_idx,
                      int use_quant_b_adapt, QUANT_PARAM *qparam);
-void av1_setup_qmatrix(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
-                       TX_SIZE tx_size, TX_TYPE tx_type, QUANT_PARAM *qparam);
+void av1_setup_qmatrix(const CommonQuantParams *quant_params,
+                       const MACROBLOCK *x, int plane, TX_SIZE tx_size,
+                       TX_TYPE tx_type, QUANT_PARAM *qparam);
 
 void av1_xform_quant(MACROBLOCK *x, int plane, int block, int blk_row,
                      int blk_col, BLOCK_SIZE plane_bsize, TxfmParam *txfm_param,
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 0e25acc..f7864e9 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3430,7 +3430,7 @@
    * av1_init_quantizer() for every frame.
    */
   av1_init_quantizer(cpi);
-  av1_qm_init(cm);
+  av1_qm_init(&cm->quant_params, av1_num_planes(cm));
 
   av1_loop_filter_init(cm);
   cm->superres_scale_denominator = SCALE_NUMERATOR;
@@ -5837,7 +5837,7 @@
 
   // Note: Both use common rdmult based on base qindex of fullres.
   const int64_t rdmult =
-      av1_compute_rd_mult_based_on_qindex(cpi, cm->base_qindex);
+      av1_compute_rd_mult_based_on_qindex(cpi, cm->quant_params.base_qindex);
 
 #if SUPERRES_RECODE_ALL_RATIOS
   // Find the best rdcost among all superres denoms.
@@ -6904,7 +6904,9 @@
   return 0;
 }
 
-int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
+int av1_get_quantizer(AV1_COMP *cpi) {
+  return cpi->common.quant_params.base_qindex;
+}
 
 int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *frame_size) {
   size_t output_size = 0;
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index c2941a5..697192e 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -1754,7 +1754,8 @@
   const qm_val_t *iqmatrix =
       IS_2D_TRANSFORM(tx_type)
           ? pd->seg_iqmatrix[xd->mi[0]->segment_id][qm_tx_size]
-          : cpi->common.giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
+          : cpi->common.quant_params
+                .giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
   const int block_offset = BLOCK_OFFSET(block);
   tran_low_t *qcoeff = p->qcoeff + block_offset;
   tran_low_t *dqcoeff = pd->dqcoeff + block_offset;
@@ -1951,7 +1952,7 @@
   const qm_val_t *iqmatrix =
       IS_2D_TRANSFORM(tx_type)
           ? pd->seg_iqmatrix[mbmi->segment_id][qm_tx_size]
-          : cm->giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
+          : cm->quant_params.giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
   assert(width == (1 << bwl));
   const int tx_type_cost =
       get_tx_type_cost(x, xd, plane, tx_size, tx_type, reduced_tx_set_used);
@@ -2036,7 +2037,7 @@
   }
 
   if (get_ext_tx_types(tx_size, is_inter, reduced_tx_set_used) > 1 &&
-      cm->base_qindex > 0 && !mbmi->skip &&
+      cm->quant_params.base_qindex > 0 && !mbmi->skip &&
       !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
     const int eset = get_ext_tx_set(tx_size, is_inter, reduced_tx_set_used);
     if (eset > 0) {
diff --git a/av1/encoder/intra_mode_search.c b/av1/encoder/intra_mode_search.c
index 5a85037..21fdfe0 100644
--- a/av1/encoder/intra_mode_search.c
+++ b/av1/encoder/intra_mode_search.c
@@ -1733,7 +1733,8 @@
   const int mode_cost =
       x->mbmode_cost[size_group_lookup[bsize]][mode] + ref_frame_cost;
   const int intra_cost_penalty = av1_get_intra_cost_penalty(
-      cm->base_qindex, cm->y_dc_delta_q, cm->seq_params.bit_depth);
+      cm->quant_params.base_qindex, cm->quant_params.y_dc_delta_q,
+      cm->seq_params.bit_depth);
   const int skip_ctx = av1_get_skip_context(xd);
 
   int known_rate = mode_cost;
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index d0eb08b..a6ab0ce 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -1536,11 +1536,13 @@
   const int bw = block_size_wide[bsize];
   const int pixels_in_block = bh * bw;
   struct buf_2d orig_dst = pd->dst;
+  const CommonQuantParams *quant_params = &cm->quant_params;
 #if COLLECT_PICK_MODE_STAT
   aom_usec_timer_start(&ms_stat.timer2);
 #endif
   int intra_cost_penalty = av1_get_intra_cost_penalty(
-      cm->base_qindex, cm->y_dc_delta_q, cm->seq_params.bit_depth);
+      quant_params->base_qindex, quant_params->y_dc_delta_q,
+      cm->seq_params.bit_depth);
   int64_t inter_mode_thresh = RDCOST(x->rdmult, intra_cost_penalty, 0);
   const int perform_intra_pred = cpi->sf.rt_sf.check_intra_pred_nonrd;
   int use_modeled_non_rd_cost = 0;
@@ -1658,7 +1660,7 @@
   const int use_model_yrd_large =
       cpi->oxcf.rc_mode == AOM_CBR && large_block &&
       !cyclic_refresh_segment_id_boosted(xd->mi[0]->segment_id) &&
-      cm->base_qindex;
+      quant_params->base_qindex;
 
 #if COLLECT_PICK_MODE_STAT
   ms_stat.num_blocks[bsize]++;
@@ -1671,9 +1673,9 @@
 
   // TODO(marpan): Look into reducing these conditions. For now constrain
   // it to avoid significant bdrate loss.
-  if (cpi->sf.rt_sf.use_modeled_non_rd_cost && cm->base_qindex > 120 &&
-      x->source_variance > 100 && bsize <= BLOCK_16X16 &&
-      x->content_state_sb != kLowVarHighSumdiff &&
+  if (cpi->sf.rt_sf.use_modeled_non_rd_cost &&
+      quant_params->base_qindex > 120 && x->source_variance > 100 &&
+      bsize <= BLOCK_16X16 && x->content_state_sb != kLowVarHighSumdiff &&
       x->content_state_sb != kHighSad)
     use_modeled_non_rd_cost = 1;
 
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index c2d8620..32b98df 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -2780,7 +2780,7 @@
     const int pyramid_level = cpi->gf_group.layer_depth[cpi->gf_group.index];
     int i;
     for (i = pyramid_level; i <= MAX_ARF_LAYERS; ++i) {
-      rc->active_best_quality[i] = cpi->common.base_qindex;
+      rc->active_best_quality[i] = cpi->common.quant_params.base_qindex;
       // if (pyramid_level >= 2) {
       //   rc->active_best_quality[pyramid_level] =
       //     AOMMAX(rc->active_best_quality[pyramid_level],
@@ -2805,7 +2805,8 @@
             (double)twopass->rolling_arf_group_actual_bits /
                 (double)twopass->rolling_arf_group_target_bits,
             twopass->bpm_factor,
-            av1_convert_qindex_to_q(cm->base_qindex, cm->seq_params.bit_depth),
+            av1_convert_qindex_to_q(quant_params->base_qindex,
+                                    cm->seq_params.bit_depth),
             av1_convert_qindex_to_q(rc->active_worst_quality,
                                     cm->seq_params.bit_depth));
     fclose(fpfile);
diff --git a/av1/encoder/pickcdef.c b/av1/encoder/pickcdef.c
index cc323a2..c8b90e1 100644
--- a/av1/encoder/pickcdef.c
+++ b/av1/encoder/pickcdef.c
@@ -290,11 +290,12 @@
 
 static void pick_cdef_from_qp(AV1_COMMON *const cm) {
   const int bd = cm->seq_params.bit_depth;
-  const int q = av1_ac_quant_QTX(cm->base_qindex, 0, bd) >> (bd - 8);
+  const int q =
+      av1_ac_quant_QTX(cm->quant_params.base_qindex, 0, bd) >> (bd - 8);
   CdefInfo *const cdef_info = &cm->cdef_info;
   cdef_info->cdef_bits = 0;
   cdef_info->nb_cdef_strengths = 1;
-  cdef_info->cdef_damping = 3 + (cm->base_qindex >> 6);
+  cdef_info->cdef_damping = 3 + (cm->quant_params.base_qindex >> 6);
 
   int predicted_y_f1 = 0;
   int predicted_y_f2 = 0;
@@ -362,7 +363,7 @@
   const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
   const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
   int *sb_index = aom_malloc(nvfb * nhfb * sizeof(*sb_index));
-  const int damping = 3 + (cm->base_qindex >> 6);
+  const int damping = 3 + (cm->quant_params.base_qindex >> 6);
   const int fast = (pick_method == CDEF_FAST_SEARCH_LVL1 ||
                     pick_method == CDEF_FAST_SEARCH_LVL2);
   const int total_strengths = nb_cdef_strengths[pick_method];
diff --git a/av1/encoder/picklpf.c b/av1/encoder/picklpf.c
index 78cb1c8..17c9965 100644
--- a/av1/encoder/picklpf.c
+++ b/av1/encoder/picklpf.c
@@ -213,8 +213,8 @@
   } else if (method >= LPF_PICK_FROM_Q) {
     const int min_filter_level = 0;
     const int max_filter_level = av1_get_max_filter_level(cpi);
-    const int q =
-        av1_ac_quant_QTX(cm->base_qindex, 0, cm->seq_params.bit_depth);
+    const int q = av1_ac_quant_QTX(cm->quant_params.base_qindex, 0,
+                                   cm->seq_params.bit_depth);
     // based on tests result for rtc test set
     // 0.04590 boosted or 0.02295 non-booseted in 18-bit fixed point
     const int strength_boost_q_treshold = 700;
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 50d70a7..ccbe1cc 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -1464,7 +1464,7 @@
   if (rsc->sf->lpf_sf.prune_wiener_based_on_src_var) {
     const int scale[3] = { 0, 1, 2 };
     // Obtain the normalized Qscale
-    const int qs = av1_dc_quant_QTX(rsc->cm->base_qindex, 0,
+    const int qs = av1_dc_quant_QTX(rsc->cm->quant_params.base_qindex, 0,
                                     rsc->cm->seq_params.bit_depth) >>
                    3;
     // Derive threshold as sqr(normalized Qscale) * scale / 16,
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 1a045b5..992d1fb 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -492,7 +492,7 @@
         av1_cyclic_refresh_estimate_bits_at_q(cpi, rate_correction_factor);
   } else {
     projected_size_based_on_q = av1_estimate_bits_at_q(
-        cpi->common.current_frame.frame_type, cm->base_qindex, MBs,
+        cm->current_frame.frame_type, cm->quant_params.base_qindex, MBs,
         rate_correction_factor, cm->seq_params.bit_depth);
   }
   // Work out a size correction factor.
@@ -510,7 +510,7 @@
   }
 
   cpi->rc.q_2_frame = cpi->rc.q_1_frame;
-  cpi->rc.q_1_frame = cm->base_qindex;
+  cpi->rc.q_1_frame = cm->quant_params.base_qindex;
   cpi->rc.rc_2_frame = cpi->rc.rc_1_frame;
   if (correction_factor > 110)
     cpi->rc.rc_1_frame = -1;
@@ -1566,7 +1566,7 @@
   const int is_intrnl_arf =
       gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE;
 
-  const int qindex = cm->base_qindex;
+  const int qindex = cm->quant_params.base_qindex;
 
   // Update rate control heuristics
   rc->projected_frame_size = (int)(bytes_used << 3);
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 20e2ab2..727956c 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -391,23 +391,23 @@
 int av1_get_adaptive_rdmult(const AV1_COMP *cpi, double beta) {
   assert(beta > 0.0);
   const AV1_COMMON *cm = &cpi->common;
-  int64_t q =
-      av1_dc_quant_QTX(cm->base_qindex, 0, cpi->common.seq_params.bit_depth);
+  int64_t q = av1_dc_quant_QTX(cm->quant_params.base_qindex, 0,
+                               cm->seq_params.bit_depth);
   int64_t rdmult = 0;
 
-  switch (cpi->common.seq_params.bit_depth) {
+  switch (cm->seq_params.bit_depth) {
     case AOM_BITS_8: rdmult = (int)((88 * q * q / beta) / 24); break;
     case AOM_BITS_10:
       rdmult = ROUND_POWER_OF_TWO((int)((88 * q * q / beta) / 24), 4);
       break;
     default:
-      assert(cpi->common.seq_params.bit_depth == AOM_BITS_12);
+      assert(cm->seq_params.bit_depth == AOM_BITS_12);
       rdmult = ROUND_POWER_OF_TWO((int)((88 * q * q / beta) / 24), 8);
       break;
   }
 
   if (is_stat_consumption_stage(cpi) &&
-      (cpi->common.current_frame.frame_type != KEY_FRAME)) {
+      (cm->current_frame.frame_type != KEY_FRAME)) {
     const GF_GROUP *const gf_group = &cpi->gf_group;
     const FRAME_UPDATE_TYPE frame_type = gf_group->update_type[gf_group->index];
     const int boost_index = AOMMIN(15, (cpi->rc.gfu_boost / 100));
@@ -451,10 +451,10 @@
   int i, bsize, segment_id;
 
   for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
-    const int qindex =
-        clamp(av1_get_qindex(&cm->seg, segment_id, cm->base_qindex) +
-                  cm->y_dc_delta_q,
-              0, MAXQ);
+    const int qindex = clamp(
+        av1_get_qindex(&cm->seg, segment_id, cm->quant_params.base_qindex) +
+            cm->quant_params.y_dc_delta_q,
+        0, MAXQ);
     const int q = compute_rd_thresh_factor(qindex, cm->seq_params.bit_depth);
 
     for (bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) {
@@ -589,7 +589,8 @@
 
   aom_clear_system_state();
 
-  rd->RDMULT = av1_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
+  rd->RDMULT = av1_compute_rd_mult(
+      cpi, cm->quant_params.base_qindex + cm->quant_params.y_dc_delta_q);
 
   set_error_per_bit(x, rd->RDMULT);
 
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 8199875..827aec4 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1277,7 +1277,7 @@
   SPEED_FEATURES *const sf = &cpi->sf;
   const int is_720p_or_larger = AOMMIN(cm->width, cm->height) >= 720;
   if (is_720p_or_larger && cpi->oxcf.mode == GOOD && speed == 0) {
-    if (cm->base_qindex <= 80) {
+    if (cm->quant_params.base_qindex <= 80) {
       sf->rd_sf.perform_coeff_opt = 2;
       memcpy(cpi->coeff_opt_dist_threshold,
              coeff_opt_dist_thresholds[sf->rd_sf.perform_coeff_opt],
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 4a35fa3..b722c7b 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -737,7 +737,7 @@
 
   tpl_frame->is_valid = 1;
 
-  cm->base_qindex = base_qindex;
+  cm->quant_params.base_qindex = base_qindex;
   av1_frame_init_quantizer(cpi);
 
   tpl_frame->base_rdmult =
@@ -1157,10 +1157,12 @@
   }
 
   MACROBLOCKD *const xd = &x->e_mbd;
-  const int orig_rdmult =
-      av1_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
-  const int new_rdmult = av1_compute_rd_mult(
-      cpi, cm->base_qindex + xd->delta_qindex + cm->y_dc_delta_q);
+  const CommonQuantParams *quant_params = &cm->quant_params;
+  const int orig_rdmult = av1_compute_rd_mult(
+      cpi, quant_params->base_qindex + quant_params->y_dc_delta_q);
+  const int new_rdmult =
+      av1_compute_rd_mult(cpi, quant_params->base_qindex + xd->delta_qindex +
+                                   quant_params->y_dc_delta_q);
   const double scaling_factor = (double)new_rdmult / (double)orig_rdmult;
 
   double scale_adj = log(scaling_factor) - log_sum / base_block_count;
diff --git a/av1/encoder/tx_search.c b/av1/encoder/tx_search.c
index f65509d9..48cc47b 100644
--- a/av1/encoder/tx_search.c
+++ b/av1/encoder/tx_search.c
@@ -1102,7 +1102,7 @@
                                                     : AV1_XFORM_QUANT_FP)
                           : AV1_XFORM_QUANT_FP,
                       cpi->use_quant_b_adapt, &quant_param_intra);
-      av1_setup_qmatrix(cm, x, plane, tx_size, best_tx_type,
+      av1_setup_qmatrix(&cm->quant_params, x, plane, tx_size, best_tx_type,
                         &quant_param_intra);
       av1_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize,
                       &txfm_param_intra, &quant_param_intra);
@@ -2207,8 +2207,9 @@
     const TX_TYPE tx_type = (TX_TYPE)txk_map[idx];
     if (!(allowed_tx_mask & (1 << tx_type))) continue;
     txfm_param.tx_type = tx_type;
-    if (av1_use_qmatrix(cm, xd, mbmi->segment_id)) {
-      av1_setup_qmatrix(cm, x, plane, tx_size, tx_type, &quant_param);
+    if (av1_use_qmatrix(&cm->quant_params, xd, mbmi->segment_id)) {
+      av1_setup_qmatrix(&cm->quant_params, x, plane, tx_size, tx_type,
+                        &quant_param);
     }
     if (plane == 0) xd->tx_type_map[tx_type_map_idx] = tx_type;
     RD_STATS this_rd_stats;
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c
index b0fb2f0..9e7b264 100644
--- a/av1/encoder/var_based_part.c
+++ b/av1/encoder/var_based_part.c
@@ -684,10 +684,11 @@
   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
       cyclic_refresh_segment_id_boosted(segment_id) &&
       cpi->sf.rt_sf.use_nonrd_pick_mode) {
-    int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
+    int q = av1_get_qindex(&cm->seg, segment_id, cm->quant_params.base_qindex);
     set_vbp_thresholds(cpi, thresholds, q, content_state);
   } else {
-    set_vbp_thresholds(cpi, thresholds, cm->base_qindex, content_state);
+    set_vbp_thresholds(cpi, thresholds, cm->quant_params.base_qindex,
+                       content_state);
   }
 
   if (is_small_sb) {