]> granicus.if.org Git - libvpx/commitdiff
dpcm intra prediction for tx_skip
authorpunksu <huisu@google.com>
Wed, 17 Dec 2014 05:51:27 +0000 (13:51 +0800)
committerhui su <huisu@google.com>
Wed, 14 Jan 2015 22:54:09 +0000 (14:54 -0800)
Implements vertical, horizontal, and tm dpcm intra prediction for
blocks in tx_skip mode. Typical coding gain on screen content video
is 2%~5%.

Change-Id: Idd5bd84ac59daa586ec0cd724680cef695981651

vp9/common/vp9_idct.c
vp9/common/vp9_idct.h
vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_dct.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodemb.c
vp9/encoder/vp9_encodemb.h
vp9/encoder/vp9_quantize.c
vp9/encoder/vp9_quantize.h

index dd15d792040f6b711a8bf28afd74c90c1eace3c2..0ca3d60a6079c9ff14d97184491244d8999dc5b9 100644 (file)
@@ -1593,15 +1593,21 @@ void vp9_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input, uint8_t *dest,
 }
 
 #if CONFIG_TX_SKIP
-void vp9_tx_identity_add(const tran_low_t *input, uint8_t *dest,
-                         int stride, int bs, int shift) {
+void vp9_tx_identity_add_rect(const tran_low_t *input, uint8_t *dest,
+                              int row, int col,
+                              int stride_in, int stride_out, int shift) {
   int r, c, temp;
-  for (r = 0; r < bs; r++)
-    for (c = 0; c < bs; c++) {
-      temp = dest[r * stride + c] + (input[r * bs + c] >> shift);
-      dest[r * stride + c] = clip_pixel(temp);
+  for (r = 0; r < row; r++)
+    for (c = 0; c < col; c++) {
+      temp = dest[r * stride_out + c] + (input[r * stride_in + c] >> shift);
+      dest[r * stride_out + c] = clip_pixel(temp);
     }
 }
+
+void vp9_tx_identity_add(const tran_low_t *input, uint8_t *dest,
+                         int stride, int bs, int shift) {
+  vp9_tx_identity_add_rect(input, dest, bs, bs, bs, stride, shift);
+}
 #endif
 
 #if CONFIG_TX64X64
index 8b476ffdf7a6fc653c7be8ade9f32b3f55880549..fb468aed0b67d6f37a59745d22d3292778d7863c 100644 (file)
@@ -170,6 +170,9 @@ void vp9_highbd_iht16x16_add(TX_TYPE tx_type, const tran_low_t *input,
 
 #endif  // VP9_COMMON_VP9_IDCT_H_
 #if CONFIG_TX_SKIP
+void vp9_tx_identity_add_rect(const tran_low_t *input, uint8_t *dest,
+                              int row, int col, int stride_in,
+                              int stride_out, int shift);
 void vp9_tx_identity_add(const tran_low_t *input, uint8_t *dest,
                          int stride, int bs, int shift);
 #endif
index 57e4999d93f7fd2a756b19f292e28435b04d1d4b..0fd53f3d6b52a9770bbaeee51e3c6c2a2bcaac07 100644 (file)
@@ -202,6 +202,86 @@ static void setup_plane_dequants(VP9_COMMON *cm, MACROBLOCKD *xd, int q_index) {
     xd->plane[i].dequant = cm->uv_dequant[q_index];
 }
 
+#if CONFIG_TX_SKIP
+static void vp9_intra_dpcm_add(tran_low_t *dqcoeff, uint8_t *dst, int stride,
+                               PREDICTION_MODE mode, int bs, int shift) {
+  int r, c, temp;
+
+  switch (mode) {
+    case H_PRED:
+      for (r = 0; r < bs; r++) {
+        temp = dst[r * stride] + (dqcoeff[r * bs] >> shift);
+        dst[r * stride] = clip_pixel(temp);
+      }
+      for (r = 0; r < bs; r++)
+        for (c = 1; c < bs; c++) {
+          temp = dst[r * stride + c - 1] +
+              (dqcoeff[r * bs + c] >> shift);
+          dst[r * stride + c] = clip_pixel(temp);
+        }
+      break;
+    case V_PRED:
+      for (c = 0; c < bs; c++) {
+        temp = dst[c] + (dqcoeff[c] >> shift);
+        dst[c] = clip_pixel(temp);
+      }
+      for (r = 1; r < bs; r++)
+        for (c = 0; c < bs; c++) {
+          temp = dst[(r - 1) * stride + c] +
+              (dqcoeff[r * bs + c] >> shift);
+          dst[r * stride + c] = clip_pixel(temp);
+        }
+      break;
+    case TM_PRED:
+      for (c = 0; c < bs; c++) {
+        temp = dst[c] + (dqcoeff[c] >> shift);
+        dst[c] = clip_pixel(temp);
+      }
+      for (r = 1; r < bs; r++) {
+        temp = dst[r * stride] + (dqcoeff[r * bs] >> shift);
+        dst[r * stride] = clip_pixel(temp);
+      }
+      for (r = 1; r < bs; r++)
+        for (c = 1; c < bs; c++) {
+          temp = dst[stride * r + c - 1] + dst[stride * (r - 1) + c] -
+                 dst[stride * (r - 1) + c - 1];
+          temp = clip_pixel(temp);
+          temp = temp + (dqcoeff[r * bs + c] >> shift);
+          dst[stride * r + c] = clip_pixel(temp);
+        }
+      break;
+    default:
+      break;
+  }
+}
+
+static void vp9_intra_dpcm_add_nocoeff(uint8_t *dst, int stride,
+                                       PREDICTION_MODE mode, int bs) {
+  int r, c, temp;
+
+  switch (mode) {
+    case H_PRED:
+      for (r = 0; r < bs; r++)
+        memset(dst + r * stride + 1, dst[r * stride], bs - 1);
+      break;
+    case V_PRED:
+      for (r = 1; r < bs; r++)
+        memcpy(dst + r * stride, dst, bs * sizeof(*dst));
+      break;
+    case TM_PRED:
+      for (r = 1; r < bs; r++)
+        for (c = 1; c < bs; c++) {
+          temp = dst[stride * r + c - 1] + dst[stride * (r - 1) + c] -
+              dst[stride * (r - 1) + c - 1];
+          dst[stride * r + c] = clip_pixel(temp);
+        }
+      break;
+    default:
+      break;
+  }
+}
+#endif  // CONFIG_TX_SKIP
+
 static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
                                     TX_SIZE tx_size, uint8_t *dst, int stride,
                                     int eob) {
@@ -209,6 +289,8 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
 #if CONFIG_TX_SKIP
   MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
   int shift = mbmi->tx_skip_shift;
+  PREDICTION_MODE mode = (plane == 0) ? get_y_mode(xd->mi[0].src_mi, block):
+                                        mbmi->uv_mode;
 #endif
   if (eob > 0) {
     TX_TYPE tx_type = DCT_DCT;
@@ -386,7 +468,10 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
           tx_type = get_tx_type_4x4(plane_type, xd, block);
 #if CONFIG_TX_SKIP
           if (mbmi->tx_skip[plane != 0]) {
-            vp9_tx_identity_add(dqcoeff, dst, stride, 4, shift);
+            if (mode == V_PRED || mode == H_PRED || mode == TM_PRED)
+              vp9_intra_dpcm_add(dqcoeff, dst, stride, mode, 4, shift);
+            else
+              vp9_tx_identity_add(dqcoeff, dst, stride, 4, shift);
           } else {
             vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob);
           }
@@ -398,7 +483,10 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
           tx_type = get_tx_type(plane_type, xd);
 #if CONFIG_TX_SKIP
           if (mbmi->tx_skip[plane != 0]) {
-            vp9_tx_identity_add(dqcoeff, dst, stride, 8, shift);
+            if (mode == V_PRED || mode == H_PRED || mode == TM_PRED)
+              vp9_intra_dpcm_add(dqcoeff, dst, stride, mode, 8, shift);
+            else
+              vp9_tx_identity_add(dqcoeff, dst, stride, 8, shift);
           } else {
             vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
           }
@@ -410,7 +498,10 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
           tx_type = get_tx_type(plane_type, xd);
 #if CONFIG_TX_SKIP
           if (mbmi->tx_skip[plane != 0]) {
-            vp9_tx_identity_add(dqcoeff, dst, stride, 16, shift);
+            if (mode == V_PRED || mode == H_PRED || mode == TM_PRED)
+              vp9_intra_dpcm_add(dqcoeff, dst, stride, mode, 16, shift);
+            else
+              vp9_tx_identity_add(dqcoeff, dst, stride, 16, shift);
           } else {
             vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
           }
@@ -422,7 +513,10 @@ static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
           tx_type = DCT_DCT;
 #if CONFIG_TX_SKIP
           if (mbmi->tx_skip[plane != 0]) {
-            vp9_tx_identity_add(dqcoeff, dst, stride, 32, shift);
+            if (mode == V_PRED || mode == H_PRED || mode == TM_PRED)
+              vp9_intra_dpcm_add(dqcoeff, dst, stride, mode, 32, shift);
+            else
+              vp9_tx_identity_add(dqcoeff, dst, stride, 32, shift);
           } else {
             vp9_idct32x32_add(dqcoeff, dst, stride, eob);;
           }
@@ -482,6 +576,9 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
                                             : mi->mbmi.uv_mode;
   int x, y;
   uint8_t *dst;
+#if CONFIG_TX_SKIP
+  int no_coeff = 0;
+#endif
 #if CONFIG_FILTERINTRA
   int fbit;
   if (plane == 0)
@@ -508,7 +605,26 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
                                             args->r);
     inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride,
                             eob);
+#if CONFIG_TX_SKIP
+    no_coeff = !eob;
+#endif
+  }
+
+#if CONFIG_TX_SKIP
+  if ((mi->mbmi.skip || no_coeff) && mi->mbmi.tx_skip[plane != 0] &&
+      mode == TM_PRED && tx_size <= TX_32X32) {
+    int bs = 4 * (1 << tx_size);
+    vp9_intra_dpcm_add_nocoeff(dst, pd->dst.stride, mode, bs);
   }
+#endif
+
+#if CONFIG_TX_SKIP && CONFIG_FILTERINTRA
+  if ((mi->mbmi.skip || no_coeff) && mi->mbmi.tx_skip[plane != 0] &&
+      (mode == H_PRED || mode == V_PRED) && fbit) {
+    int bs = 4 * (1 << tx_size);
+    vp9_intra_dpcm_add_nocoeff(dst, pd->dst.stride, mode, bs);
+  }
+#endif
 }
 
 struct inter_args {
index 4d9665c9430b6a0ac2d194a7f1ff4e2209e34875..edf4e9098fe4b0bb7b06425856f288a7722e179f 100644 (file)
@@ -746,6 +746,9 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
     xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv, nearestmv,
                                 nearestmv, nearmv, is_compound, allow_hp, r);
   }
+#if CONFIG_TX_SKIP
+    mbmi->uv_mode = mbmi->mode;
+#endif
 }
 
 static void read_inter_frame_mode_info(VP9_COMMON *const cm,
@@ -859,7 +862,7 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
 #if CONFIG_SUPERTX
     if (try_tx_skip) {
 #else
-    if (try_tx_skip && !mbmi->skip) {
+    if (try_tx_skip && (!mbmi->skip || !inter_block)) {
 #endif  // CONFIG_SUPERTX
       if (xd->lossless) {
 #if CONFIG_SUPERTX
index 59dc6b5b7422903498ebdc30895c9bccf83d246e..e34f860379a824a4aa0f3bc5341b9fc803eaa38f 100644 (file)
@@ -439,7 +439,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
 #if CONFIG_SUPERTX
     if (try_tx_skip) {
 #else
-    if (try_tx_skip && !skip) {
+    if (try_tx_skip && (!skip || !is_inter)) {
 #endif  // CONFIG_SUPERTX
       if (xd->lossless) {
 #if CONFIG_SUPERTX
index 7f092b59f8dfc3cdb82ac2e197738ed988a188d3..706afb26eab88a64e1d3da1c9fd2567ec6b81a15 100644 (file)
@@ -1440,14 +1440,20 @@ void vp9_fdct32x32_rd_c(const int16_t *input, tran_low_t *out, int stride) {
 }
 
 #if CONFIG_TX_SKIP
-void vp9_tx_identity(const int16_t *input, tran_low_t *out, int stride,
-                     int bs, int shift) {
+void vp9_tx_identity_rect(const int16_t *input, tran_low_t *out,
+                          int row, int col,
+                          int stride_in, int stride_out, int shift) {
   int r, c;
-  for (r = 0; r < bs; r++)
-    for (c = 0; c < bs; c++) {
-      out[bs * r + c] = input[stride * r + c] << shift;
+  for (r = 0; r < row; r++)
+    for (c = 0; c < col; c++) {
+      out[stride_out * r + c] = input[stride_in * r + c] << shift;
     }
 }
+
+void vp9_tx_identity(const int16_t *input, tran_low_t *out, int stride,
+                     int bs, int shift) {
+  vp9_tx_identity_rect(input, out, bs, bs, stride, bs, shift);
+}
 #endif
 
 #if CONFIG_TX64X64
index dbca9b0f1ca1254b6594ab1e6f00f9097904fe38..255ac219170bfa6c9122033579dd01c239af9bb0 100644 (file)
@@ -4800,7 +4800,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
 #if CONFIG_SUPERTX
       if (try_tx_skip) {
 #else
-      if (try_tx_skip && !(mbmi->skip || seg_skip)) {
+      if (try_tx_skip && (!(mbmi->skip || seg_skip) || !is_inter_block(mbmi))) {
 #endif
         ++cm->counts.y_tx_skip[is_inter_block(mbmi)][mbmi->tx_skip[0]];
         ++cm->counts.uv_tx_skip[mbmi->tx_skip[0]][mbmi->tx_skip[1]];
index c35c504b7dd3fc2c5f0b1685016a687d06fa21fb..4b4f36b47df8bf3c4fe5560e86f1d2696e5aa27f 100644 (file)
@@ -1435,6 +1435,109 @@ void vp9_encode_sb_supertx(MACROBLOCK *x, BLOCK_SIZE bsize) {
 }
 #endif
 
+#if CONFIG_TX_SKIP
+static int vp9_dpcm_intra(uint8_t *src, int src_stride,
+                          uint8_t *dst, int dst_stride,
+                          int16_t *src_diff, int diff_stride,
+                          tran_low_t *coeff, tran_low_t *qcoeff,
+                          tran_low_t *dqcoeff, struct macroblock_plane *p,
+                          struct macroblockd_plane *pd,
+                          const scan_order *scan_order, PREDICTION_MODE mode,
+                          int bs, int shift, int logsizeby32) {
+  int i, j, eob, temp;
+  vpx_memset(qcoeff, 0, bs * bs * sizeof(*qcoeff));
+  vpx_memset(dqcoeff, 0, bs * bs * sizeof(*dqcoeff));
+
+  switch (mode) {
+    case H_PRED:
+      for (i = 0 ; i < bs; i++) {
+        vp9_subtract_block_c(bs, 1, src_diff + i, diff_stride,
+                             src + i, src_stride,
+                             dst + i, dst_stride);
+        vp9_tx_identity_rect(src_diff + i, coeff + i, bs, 1,
+                             diff_stride, bs, shift);
+        vp9_quantize_rect(coeff + i, bs, 1, p->zbin, p->round, p->quant,
+                          p->quant_shift, qcoeff + i, dqcoeff + i,
+                          pd->dequant, p->zbin_extra, logsizeby32, bs, i == 0);
+        vp9_tx_identity_add_rect(dqcoeff + i, dst + i, bs, 1,
+                                 bs, dst_stride, shift);
+        if ( i < bs - 1 && 1)
+          for (j = 0 ; j < bs; j++)
+            *(dst + j * dst_stride + i + 1) =
+                *(dst + j * dst_stride + i);
+      }
+      break;
+    case V_PRED:
+      for (i = 0 ; i < bs; i++) {
+        vp9_subtract_block_c(1, bs, src_diff + diff_stride * i,
+                             diff_stride,
+                             src + src_stride * i, src_stride,
+                             dst + dst_stride * i, dst_stride);
+        vp9_tx_identity_rect(src_diff + diff_stride * i,
+                             coeff + bs * i, 1, bs,
+                             diff_stride, bs, shift);
+        vp9_quantize_rect(coeff + bs * i, 1, bs, p->zbin, p->round, p->quant,
+                          p->quant_shift, qcoeff + bs * i, dqcoeff + bs * i,
+                          pd->dequant, p->zbin_extra, logsizeby32, bs, i == 0);
+        vp9_tx_identity_add_rect(dqcoeff + bs * i, dst + dst_stride * i,
+                                 1, bs, bs, dst_stride, shift);
+        if (i < bs - 1)
+          vpx_memcpy(dst + (i + 1) * dst_stride,
+                     dst + i * dst_stride, bs * sizeof(dst[0]));
+      }
+      break;
+    case TM_PRED:
+      vp9_subtract_block_c(1, bs, src_diff, diff_stride, src, src_stride,
+                           dst, dst_stride);
+      vp9_tx_identity_rect(src_diff, coeff, 1, bs, diff_stride, bs, shift);
+      vp9_quantize_rect(coeff, 1, bs, p->zbin, p->round, p->quant,
+                        p->quant_shift, qcoeff, dqcoeff, pd->dequant,
+                        p->zbin_extra, logsizeby32, bs, 1);
+      vp9_tx_identity_add_rect(dqcoeff, dst, 1, bs, bs, dst_stride, shift);
+
+      vp9_subtract_block_c(bs -1, 1, src_diff + diff_stride, diff_stride,
+                           src + src_stride, src_stride,
+                           dst + dst_stride, dst_stride);
+      vp9_tx_identity_rect(src_diff + diff_stride, coeff + bs, bs - 1, 1,
+                           diff_stride, bs, shift);
+      vp9_quantize_rect(coeff + bs, bs - 1, 1, p->zbin, p->round, p->quant,
+                        p->quant_shift, qcoeff + bs, dqcoeff + bs,
+                        pd->dequant, p->zbin_extra, logsizeby32, bs, 0);
+      vp9_tx_identity_add_rect(dqcoeff + bs, dst + dst_stride, bs - 1, 1,
+                               bs, dst_stride, shift);
+
+      for (i = 1 ; i < bs; i++) {
+        for (j = 1 ; j < bs; j++) {
+          temp = dst[(i - 1) * dst_stride + j] + dst[i * dst_stride + j - 1] -
+                 dst[(i - 1) * dst_stride + j - 1];
+          temp = clip_pixel(temp);
+          dst[i * dst_stride + j] = temp;
+          vp9_subtract_block_c(1, 1, src_diff + diff_stride * i + j,
+                               diff_stride, src + src_stride * i + j,
+                               src_stride, dst + dst_stride * i + j,
+                               dst_stride);
+          vp9_tx_identity_rect(src_diff + i * diff_stride + j,
+                               coeff + bs * i + j, 1, 1, diff_stride,
+                               bs, shift);
+          vp9_quantize_rect(coeff + bs * i + j, 1, 1, p->zbin, p->round,
+                            p->quant, p->quant_shift, qcoeff + bs * i + j,
+                            dqcoeff + bs * i + j, pd->dequant,
+                            p->zbin_extra, logsizeby32, bs, 0);
+          vp9_tx_identity_add_rect(dqcoeff + bs * i + j,
+                                   dst + dst_stride * i + j, 1, 1, bs,
+                                   dst_stride, shift);
+        }
+      }
+      break;
+    default:
+      break;
+  }
+
+  eob = get_eob(qcoeff, bs * bs, scan_order->scan);
+  return eob;
+}
+#endif  // CONFIG_TX_SKIP
+
 static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
                                TX_SIZE tx_size, void *arg) {
   struct encode_b_args* const args = arg;
@@ -1512,6 +1615,14 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
                                     dst, dst_stride, i, j, plane);
 
             if (!x->skip_recode) {
+              if (mode == V_PRED || mode == H_PRED || mode == TM_PRED) {
+                *eob = vp9_dpcm_intra(src, src_stride, dst, dst_stride,
+                                      src_diff, diff_stride,
+                                      coeff, qcoeff, dqcoeff, p, pd,
+                                      scan_order, mode, 32, shift, 0);
+                break;
+              }
+
               vp9_subtract_block(32, 32, src_diff, diff_stride,
                                  src, src_stride, dst, dst_stride);
               vp9_tx_identity(src_diff, coeff, diff_stride, 32, shift);
@@ -1537,6 +1648,14 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
                                     x->skip_encode ? src_stride : dst_stride,
                                     dst, dst_stride, i, j, plane);
             if (!x->skip_recode) {
+              if (mode == V_PRED || mode == H_PRED || mode == TM_PRED) {
+                *eob = vp9_dpcm_intra(src, src_stride, dst, dst_stride,
+                                      src_diff, diff_stride,
+                                      coeff, qcoeff, dqcoeff, p, pd,
+                                      scan_order, mode, 16, shift, -1);
+                break;
+              }
+
               vp9_subtract_block(16, 16, src_diff, diff_stride,
                                  src, src_stride, dst, dst_stride);
               vp9_tx_identity(src_diff, coeff, diff_stride, 16, shift);
@@ -1561,6 +1680,14 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
                                     x->skip_encode ? src_stride : dst_stride,
                                     dst, dst_stride, i, j, plane);
             if (!x->skip_recode) {
+              if (mode == V_PRED || mode == H_PRED || mode == TM_PRED) {
+                *eob = vp9_dpcm_intra(src, src_stride, dst, dst_stride,
+                                      src_diff, diff_stride,
+                                      coeff, qcoeff, dqcoeff, p, pd,
+                                      scan_order, mode, 8, shift, -1);
+                break;
+              }
+
               vp9_subtract_block(8, 8, src_diff, diff_stride,
                                  src, src_stride, dst, dst_stride);
               vp9_tx_identity(src_diff, coeff, diff_stride, 8, shift);
@@ -1587,6 +1714,14 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
                                     dst, dst_stride, i, j, plane);
 
             if (!x->skip_recode) {
+              if (mode == V_PRED || mode == H_PRED || mode == TM_PRED) {
+                *eob = vp9_dpcm_intra(src, src_stride, dst, dst_stride,
+                                      src_diff, diff_stride,
+                                      coeff, qcoeff, dqcoeff, p, pd,
+                                      scan_order, mode, 4, shift, -1);
+                break;
+              }
+
               vp9_subtract_block(4, 4, src_diff, diff_stride,
                                  src, src_stride, dst, dst_stride);
               vp9_tx_identity(src_diff, coeff, diff_stride, 4, shift);
index 0f0f584e7caae8926ccc710931956b6fb2b02a8c..8d11c35400f281c8f30ae7b1a3b77c7c6c921462 100644 (file)
@@ -39,6 +39,9 @@ void vp9_encode_block_intra(MACROBLOCK *x, int plane, int block,
 void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
 
 #if CONFIG_TX_SKIP
+void vp9_tx_identity_rect(const int16_t *input, tran_low_t *out,
+                          int row, int col,
+                          int stride_in, int stride_out, int shift);
 void vp9_tx_identity(const int16_t *input, tran_low_t *out, int stride,
                      int bs, int shift);
 #endif
index be6a41897b277e441bb7c82df9ff5e20172deaa4..93c7f76b8958b0752232752783a91ad09a2b829a 100644 (file)
@@ -495,6 +495,67 @@ void vp9_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
   *eob_ptr = eob + 1;
 }
 
+#if CONFIG_TX_SKIP
+void vp9_quantize_rect(const tran_low_t *coeff_ptr, int row, int col,
+                       const int16_t *zbin_ptr, const int16_t *round_ptr,
+                       const int16_t *quant_ptr,
+                       const int16_t *quant_shift_ptr,
+                       tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
+                       const int16_t *dequant_ptr, int zbin_oq_value,
+                       int logsizeby32, int stride, int has_dc) {
+  int r, c;
+  int zbins[2] = {ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value,
+                                     1 + (logsizeby32 < 0 ? -1 : logsizeby32)),
+                  ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value,
+                                     1 + (logsizeby32 < 0 ? -1 : logsizeby32))};
+  if (logsizeby32 < 0) {
+    logsizeby32 = -1;
+    zbins[0] = zbin_ptr[0] + zbin_oq_value;
+    zbins[1] = zbin_ptr[1] + zbin_oq_value;
+  }
+
+  for (r = 0; r < row; r++)
+    for (c = 0; c < col; c++) {
+      const int coeff = coeff_ptr[r * stride + c];
+      const int coeff_sign = (coeff >> 31);
+      int tmp;
+      int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
+      int idx = (r == 0 && c == 0 && has_dc) ? 0 : 1;
+      qcoeff_ptr[r * stride + c] = dqcoeff_ptr[r * stride + c] = 0;
+
+      if (abs_coeff >= zbins[idx]) {
+        if (logsizeby32 < 0)
+          abs_coeff += round_ptr[idx];
+        else
+          abs_coeff += ROUND_POWER_OF_TWO(round_ptr[idx], (1 + logsizeby32));
+        abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
+        tmp = ((((abs_coeff * quant_ptr[idx]) >> 16) + abs_coeff) *
+              quant_shift_ptr[idx]) >> (15 - logsizeby32);
+
+        qcoeff_ptr[r * stride + c] = (tmp ^ coeff_sign) - coeff_sign;
+        dqcoeff_ptr[r * stride + c] = qcoeff_ptr[r * stride + c] *
+                                      dequant_ptr[idx] /
+                                      (1 << (logsizeby32 + 1));
+      }
+    }
+}
+
+int get_eob(tran_low_t *qcoeff_ptr, intptr_t n_coeffs, const int16_t *scan) {
+  int i, rc, eob = -1;
+
+  for (i = (int)n_coeffs - 1; i >= 0; i--) {
+    rc = scan[i];
+    if (qcoeff_ptr[rc]) {
+      eob = i;
+      break;
+    }
+  }
+
+  eob += 1;
+  return eob;
+}
+#endif
+
 #if CONFIG_VP9_HIGHBITDEPTH
 void vp9_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
                              int skip_block, const int16_t *zbin_ptr,
index f454724bffb805807f95072b84ff57196bb0956d..fc7ccf7c866281d5a101c708e139691acb24ca18 100644 (file)
@@ -96,6 +96,17 @@ int vp9_quantizer_to_qindex(int quantizer);
 
 int vp9_qindex_to_quantizer(int qindex);
 
+#if CONFIG_TX_SKIP
+void vp9_quantize_rect(const tran_low_t *coeff_ptr, int row, int col,
+                       const int16_t *zbin_ptr, const int16_t *round_ptr,
+                       const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
+                       tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
+                       const int16_t *dequant_ptr, int zbin_oq_value,
+                       int logsizeby32, int stride, int has_dc);
+
+int get_eob(tran_low_t *qcoeff_ptr, intptr_t n_coeffs, const int16_t *scan);
+#endif
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif