shithub: libvpx

Download patch

ref: 2be50a1c9cf62c046c668669f5a224d2fc8c3f45
parent: bfce02971e59e3439d576774772a13c5349d6c76
parent: afcb62b414fef7669bb69ffaa214395b195aeb81
author: Frank Galligan <fgalligan@google.com>
date: Tue Apr 28 12:12:09 EDT 2015

Merge "WIP: Use LUT for y_dequant/uv_dequant"

--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -184,6 +184,8 @@
   int y_dc_delta_q;
   int uv_dc_delta_q;
   int uv_ac_delta_q;
+  int16_t y_dequant[MAX_SEGMENTS][2];
+  int16_t uv_dequant[MAX_SEGMENTS][2];
 
   /* We allocate a MODE_INFO struct for each macroblock, together with
      an extra row on top and column on the left to simplify prediction. */
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -293,8 +293,7 @@
   MACROBLOCKD *xd;
   FRAME_COUNTS *counts;
   vp9_reader *r;
-  const int16_t *const y_dequant;
-  const int16_t *const uv_dequant;
+  int seg_id;
 };
 
 static void predict_and_reconstruct_intra_block(int plane, int block,
@@ -307,8 +306,6 @@
   MODE_INFO *const mi = xd->mi[0];
   const PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block)
                                             : mi->mbmi.uv_mode;
-  const int16_t *const dequant = (plane == 0) ? args->y_dequant
-                                              : args->uv_dequant;
   int x, y;
   uint8_t *dst;
   txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
@@ -322,7 +319,7 @@
   if (!mi->mbmi.skip) {
     const int eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block,
                                             plane_bsize, x, y, tx_size,
-                                            args->r, dequant);
+                                            args->r, args->seg_id);
     inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride,
                             eob);
   }
@@ -334,8 +331,7 @@
   vp9_reader *r;
   FRAME_COUNTS *counts;
   int *eobtotal;
-  const int16_t *const y_dequant;
-  const int16_t *const uv_dequant;
+  int seg_id;
 };
 
 static void reconstruct_inter_block(int plane, int block,
@@ -345,12 +341,10 @@
   VP9_COMMON *const cm = args->cm;
   MACROBLOCKD *const xd = args->xd;
   struct macroblockd_plane *const pd = &xd->plane[plane];
-  const int16_t *const dequant = (plane == 0) ? args->y_dequant
-                                              : args->uv_dequant;
   int x, y, eob;
   txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
   eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block, plane_bsize,
-                                x, y, tx_size, args->r, dequant);
+                                x, y, tx_size, args->r, args->seg_id);
   inverse_transform_block(xd, plane, block, tx_size,
                           &pd->dst.buf[4 * y * pd->dst.stride + 4 * x],
                           pd->dst.stride, eob);
@@ -392,8 +386,6 @@
                          vp9_reader *r, BLOCK_SIZE bsize) {
   VP9_COMMON *const cm = &pbi->common;
   const int less8x8 = bsize < BLOCK_8X8;
-  int16_t y_dequant[2], uv_dequant[2];
-  int qindex = cm->base_qindex;
   MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col);
   vp9_read_mode_info(pbi, xd, counts, tile, mi_row, mi_col, r);
 
@@ -402,17 +394,10 @@
 
   if (mbmi->skip) {
     reset_skip_context(xd, bsize);
-  } else if (cm->seg.enabled) {
-    qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex);
   }
 
-  y_dequant[0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
-  y_dequant[1] = vp9_ac_quant(qindex, 0, cm->bit_depth);
-  uv_dequant[0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
-  uv_dequant[1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
-
   if (!is_inter_block(mbmi)) {
-    struct intra_args arg = {cm, xd, counts, r , y_dequant, uv_dequant};
+    struct intra_args arg = {cm, xd, counts, r, mbmi->segment_id};
     vp9_foreach_transformed_block(xd, bsize,
                                   predict_and_reconstruct_intra_block, &arg);
   } else {
@@ -422,8 +407,7 @@
     // Reconstruction
     if (!mbmi->skip) {
       int eobtotal = 0;
-      struct inter_args arg = {cm, xd, r, counts, &eobtotal, y_dequant,
-                               uv_dequant};
+      struct inter_args arg = {cm, xd, r, counts, &eobtotal, mbmi->segment_id};
       vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg);
       if (!less8x8 && eobtotal == 0)
         mbmi->skip = 1;  // skip loopfilter
@@ -647,11 +631,39 @@
                  cm->y_dc_delta_q == 0 &&
                  cm->uv_dc_delta_q == 0 &&
                  cm->uv_ac_delta_q == 0;
+
 #if CONFIG_VP9_HIGHBITDEPTH
   xd->bd = (int)cm->bit_depth;
 #endif
 }
 
+static void setup_segmentation_dequant(VP9_COMMON *const cm) {
+  // Build y/uv dequant values based on segmentation.
+  if (cm->seg.enabled) {
+    int i;
+    for (i = 0; i < MAX_SEGMENTS; ++i) {
+      const int qindex = vp9_get_qindex(&cm->seg, i, cm->base_qindex);
+      cm->y_dequant[i][0] = vp9_dc_quant(qindex, cm->y_dc_delta_q,
+                                         cm->bit_depth);
+      cm->y_dequant[i][1] = vp9_ac_quant(qindex, 0, cm->bit_depth);
+      cm->uv_dequant[i][0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q,
+                                          cm->bit_depth);
+      cm->uv_dequant[i][1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q,
+                                          cm->bit_depth);
+    }
+  } else {
+    const int qindex = cm->base_qindex;
+    // When segmentation is disabled, only the first value is used.  The
+    // remaining are don't cares.
+    cm->y_dequant[0][0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
+    cm->y_dequant[0][1] = vp9_ac_quant(qindex, 0, cm->bit_depth);
+    cm->uv_dequant[0][0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q,
+                                        cm->bit_depth);
+    cm->uv_dequant[0][1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q,
+                                        cm->bit_depth);
+  }
+}
+
 static INTERP_FILTER read_interp_filter(struct vp9_read_bit_buffer *rb) {
   const INTERP_FILTER literal_to_filter[] = { EIGHTTAP_SMOOTH,
                                               EIGHTTAP,
@@ -1486,6 +1498,7 @@
   setup_loopfilter(&cm->lf, rb);
   setup_quantization(cm, &pbi->mb, rb);
   setup_segmentation(&cm->seg, rb);
+  setup_segmentation_dequant(cm);
 
   setup_tile_info(cm, rb);
   sz = vp9_rb_read_literal(rb, 16);
--- a/vp9/decoder/vp9_detokenize.c
+++ b/vp9/decoder/vp9_detokenize.c
@@ -205,8 +205,10 @@
                             FRAME_COUNTS *counts, int plane, int block,
                             BLOCK_SIZE plane_bsize, int x, int y,
                             TX_SIZE tx_size, vp9_reader *r,
-                            const int16_t *const dequant) {
+                            int seg_id) {
   struct macroblockd_plane *const pd = &xd->plane[plane];
+  const int16_t *const dequant = (plane == 0) ? cm->y_dequant[seg_id]
+                                              : cm->uv_dequant[seg_id];
   const int ctx = get_entropy_context(tx_size, pd->above_context + x,
                                                pd->left_context + y);
   const scan_order *so = get_scan(xd, tx_size, pd->plane_type, block);
--- a/vp9/decoder/vp9_detokenize.h
+++ b/vp9/decoder/vp9_detokenize.h
@@ -23,7 +23,7 @@
                             FRAME_COUNTS *counts, int plane, int block,
                             BLOCK_SIZE plane_bsize, int x, int y,
                             TX_SIZE tx_size, vp9_reader *r,
-                            const int16_t *const dequant);
+                            int seg_id);
 
 #ifdef __cplusplus
 }  // extern "C"