Support Separate qmatrix for U and V planes

This commit adds support of a separate qmatrix and iqmatrix for each
of the U and V planes. Currently the separate matrices are intialized
to the same ones, then the commit does not have any coding impact
yet.

Change-Id: I5c4045fe1879db262c6ec1567d8d7dfd9a98fbed
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 4199ed4..b163aa6 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -331,16 +331,18 @@
 
 #if CONFIG_AOM_QM
   // Global quant matrix tables
-  qm_val_t *giqmatrix[NUM_QM_LEVELS][2][TX_SIZES_ALL];
-  qm_val_t *gqmatrix[NUM_QM_LEVELS][2][TX_SIZES_ALL];
+  qm_val_t *giqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
+  qm_val_t *gqmatrix[NUM_QM_LEVELS][3][TX_SIZES_ALL];
 
   // Local quant matrix tables for each frame
   qm_val_t *y_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-  qm_val_t *uv_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  qm_val_t *u_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  qm_val_t *v_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
 
   // Encoder
   qm_val_t *y_qmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
-  qm_val_t *uv_qmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  qm_val_t *u_qmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
+  qm_val_t *v_qmatrix[MAX_SEGMENTS][TX_SIZES_ALL];
 
   int using_qmatrix;
   int min_qmlevel;
@@ -724,8 +726,7 @@
       memcpy(xd->plane[i].seg_dequant_QTX, cm->u_dequant_QTX,
              sizeof(cm->u_dequant_QTX));
 #if CONFIG_AOM_QM
-      memcpy(xd->plane[i].seg_iqmatrix, cm->uv_iqmatrix,
-             sizeof(cm->uv_iqmatrix));
+      memcpy(xd->plane[i].seg_iqmatrix, cm->u_iqmatrix, sizeof(cm->u_iqmatrix));
 #endif
 #if CONFIG_NEW_QUANT
       memcpy(xd->plane[i].seg_dequant_nuq_QTX, cm->u_dequant_nuq_QTX,
@@ -735,8 +736,7 @@
       memcpy(xd->plane[i].seg_dequant_QTX, cm->v_dequant_QTX,
              sizeof(cm->v_dequant_QTX));
 #if CONFIG_AOM_QM
-      memcpy(xd->plane[i].seg_iqmatrix, cm->uv_iqmatrix,
-             sizeof(cm->uv_iqmatrix));
+      memcpy(xd->plane[i].seg_iqmatrix, cm->v_iqmatrix, sizeof(cm->v_iqmatrix));
 #endif
 #if CONFIG_NEW_QUANT
       memcpy(xd->plane[i].seg_dequant_nuq_QTX, cm->v_dequant_nuq_QTX,
diff --git a/av1/common/quant_common.c b/av1/common/quant_common.c
index 3590ba3..2ba2da8 100644
--- a/av1/common/quant_common.c
+++ b/av1/common/quant_common.c
@@ -352,13 +352,12 @@
 }
 
 #if CONFIG_AOM_QM
-qm_val_t *aom_iqmatrix(AV1_COMMON *cm, int qmlevel, int is_chroma,
+qm_val_t *aom_iqmatrix(AV1_COMMON *cm, int qmlevel, int plane,
                        TX_SIZE tx_size) {
-  return &cm->giqmatrix[qmlevel][!!is_chroma][tx_size][0];
+  return &cm->giqmatrix[qmlevel][plane][tx_size][0];
 }
-qm_val_t *aom_qmatrix(AV1_COMMON *cm, int qmlevel, int is_chroma,
-                      TX_SIZE tx_size) {
-  return &cm->gqmatrix[qmlevel][!!is_chroma][tx_size][0];
+qm_val_t *aom_qmatrix(AV1_COMMON *cm, int qmlevel, int plane, TX_SIZE tx_size) {
+  return &cm->gqmatrix[qmlevel][plane][tx_size][0];
 }
 
 #define QM_TOTAL_SIZE 3344
@@ -369,7 +368,7 @@
   int q, c, t;
   int current;
   for (q = 0; q < NUM_QM_LEVELS; ++q) {
-    for (c = 0; c < 2; ++c) {
+    for (c = 0; c < av1_num_planes(cm); ++c) {
       current = 0;
       for (t = 0; t < TX_SIZES_ALL; ++t) {
         const int size = tx_size_2d[t];
@@ -379,8 +378,8 @@
           cm->giqmatrix[q][c][t] = NULL;
         } else {
           assert(current + size <= QM_TOTAL_SIZE);
-          cm->gqmatrix[q][c][t] = &wt_matrix_ref[q][c][current];
-          cm->giqmatrix[q][c][t] = &iwt_matrix_ref[q][c][current];
+          cm->gqmatrix[q][c][t] = &wt_matrix_ref[q][c >= 1][current];
+          cm->giqmatrix[q][c][t] = &iwt_matrix_ref[q][c >= 1][current];
           current += size;
         }
       }
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 7cc9c84..c380243 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1422,8 +1422,9 @@
                             ? NUM_QM_LEVELS - 1
                             : aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
     for (int j = 0; j < TX_SIZES_ALL; ++j) {
-      cm->y_iqmatrix[i][j] = aom_iqmatrix(cm, qmlevel, 0, j);
-      cm->uv_iqmatrix[i][j] = aom_iqmatrix(cm, qmlevel, 1, j);
+      cm->y_iqmatrix[i][j] = aom_iqmatrix(cm, qmlevel, AOM_PLANE_Y, j);
+      cm->u_iqmatrix[i][j] = aom_iqmatrix(cm, qmlevel, AOM_PLANE_U, j);
+      cm->v_iqmatrix[i][j] = aom_iqmatrix(cm, qmlevel, AOM_PLANE_V, j);
     }
 #endif  // CONFIG_AOM_QM
 #if CONFIG_NEW_QUANT
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c
index f985a42..8c4a5db 100644
--- a/av1/encoder/av1_quantize.c
+++ b/av1/encoder/av1_quantize.c
@@ -1745,10 +1745,10 @@
     x->plane[2].round_QTX = quants->v_round[qindex];
     x->plane[2].dequant_QTX = cpi->dequants.v_dequant_QTX[qindex];
 #if CONFIG_AOM_QM
-    memcpy(&xd->plane[2].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel][1],
-           sizeof(cm->gqmatrix[qmlevel][1]));
-    memcpy(&xd->plane[2].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel][1],
-           sizeof(cm->giqmatrix[qmlevel][1]));
+    memcpy(&xd->plane[2].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel][2],
+           sizeof(cm->gqmatrix[qmlevel][2]));
+    memcpy(&xd->plane[2].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel][2],
+           sizeof(cm->giqmatrix[qmlevel][2]));
 #endif
     x->plane[2].dequant_QTX = cpi->dequants.v_dequant_QTX[qindex];
     xd->plane[2].dequant_Q3 = cpi->dequants.v_dequant_Q3[qindex];