]> granicus.if.org Git - libvpx/commitdiff
Generalized intra 4x4 encoding for all sizes
authorYaowu Xu <yaowu@google.com>
Thu, 16 May 2013 00:21:15 +0000 (17:21 -0700)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 22 May 2013 10:44:12 +0000 (11:44 +0100)
Change-Id: I1b86744fa247233c8df031b3f4b87b212c8dd094

vp9/common/vp9_reconinter.h
vp9/common/vp9_reconintra.c
vp9/common/vp9_reconintra.h
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodeintra.c
vp9/encoder/vp9_encodeintra.h
vp9/encoder/vp9_encodemb.c

index af289d27ed2049e475a7546cb3faf6c141eab6c8..4e521850d738691a7f8de677c0df93d4f88bc6c7 100644 (file)
@@ -15,7 +15,6 @@
 #include "vp9/common/vp9_onyxc_int.h"
 
 struct subpix_fn_table;
-
 void vp9_build_inter_predictors_sby(MACROBLOCKD *xd,
                                     int mb_row,
                                     int mb_col,
index ea4805f3374822cdfd12549015bd3ae562ef356e..1588f33cef17de052aba709c82bd0c4270ed05c0 100644 (file)
@@ -13,6 +13,7 @@
 #include "./vpx_config.h"
 #include "vp9_rtcd.h"
 #include "vp9/common/vp9_reconintra.h"
+#include "vp9/common/vp9_onyxc_int.h"
 #include "vpx_mem/vpx_mem.h"
 
 static void d27_predictor(uint8_t *ypred_ptr, int y_stride,
@@ -378,38 +379,51 @@ void vp9_build_intra_predictors_sby_s(MACROBLOCKD *xd,
 
 void vp9_build_intra_predictors_sbuv_s(MACROBLOCKD *xd,
                                        BLOCK_SIZE_TYPE bsize) {
-  int p;
+  const int bwl = b_width_log2(bsize), bw = 2 << bwl;
+  const int bhl = b_height_log2(bsize), bh = 2 << bhl;
 
-  for (p = 1; p < MAX_MB_PLANE; p++) {
-    const struct macroblockd_plane* const pd = &xd->plane[p];
-    const int bwl = b_width_log2(bsize) - pd->subsampling_x;
-    const int bw = 4 << bwl;
-    const int bhl = b_height_log2(bsize) - pd->subsampling_y;
-    const int bh = 4 << bhl;
-
-    vp9_build_intra_predictors(pd->dst.buf, pd->dst.stride,
-                               pd->dst.buf, pd->dst.stride,
-                               xd->mode_info_context->mbmi.uv_mode,
-                               bw, bh, xd->up_available,
-                               xd->left_available, 0 /*xd->right_available*/);
-  }
+  vp9_build_intra_predictors(xd->plane[1].dst.buf, xd->plane[1].dst.stride,
+                             xd->plane[1].dst.buf, xd->plane[1].dst.stride,
+                             xd->mode_info_context->mbmi.uv_mode,
+                             bw, bh, xd->up_available,
+                             xd->left_available, 0 /*xd->right_available*/);
+  vp9_build_intra_predictors(xd->plane[2].dst.buf, xd->plane[1].dst.stride,
+                             xd->plane[2].dst.buf, xd->plane[1].dst.stride,
+                             xd->mode_info_context->mbmi.uv_mode,
+                             bw, bh, xd->up_available,
+                             xd->left_available, 0 /*xd->right_available*/);
 }
 
-void vp9_intra4x4_predict(MACROBLOCKD *xd,
-                          int block_idx,
-                          BLOCK_SIZE_TYPE bsize,
-                          int mode,
-                          uint8_t *predictor, int pre_stride) {
-  const int bwl = b_width_log2(bsize);
+void vp9_predict_intra_block(MACROBLOCKD *xd,
+                            int block_idx,
+                            BLOCK_SIZE_TYPE bsize,
+                            TX_SIZE tx_size,
+                            int mode,
+                            uint8_t *predictor, int pre_stride) {
+  const int bwl = b_width_log2(bsize) - tx_size;
   const int wmask = (1 << bwl) - 1;
   const int have_top =
       (block_idx >> bwl) || xd->up_available;
   const int have_left =
       (block_idx & wmask) || xd->left_available;
   const int have_right = ((block_idx & wmask) != wmask);
+  const int txfm_block_size = 4 << tx_size;
 
+  assert(bwl >= 0);
   vp9_build_intra_predictors(predictor, pre_stride,
                              predictor, pre_stride,
-                             mode, 4, 4, have_top, have_left,
+                             mode,
+                             txfm_block_size,
+                             txfm_block_size,
+                             have_top, have_left,
                              have_right);
 }
+
+void vp9_intra4x4_predict(MACROBLOCKD *xd,
+                          int block_idx,
+                          BLOCK_SIZE_TYPE bsize,
+                          int mode,
+                          uint8_t *predictor, int pre_stride) {
+  vp9_predict_intra_block(xd, block_idx, bsize, TX_4X4,
+                          mode, predictor, pre_stride);
+}
index 1a715c3ee70887b48cecb8ce199b1ccaf5c4039f..faecd6be73565165603c61a3e55848bbdc51314b 100644 (file)
@@ -21,4 +21,10 @@ B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr,
 B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block,
                                          uint8_t *ptr, int stride);
 
+void vp9_predict_intra_block(MACROBLOCKD *xd,
+                            int block_idx,
+                            BLOCK_SIZE_TYPE bsize,
+                            TX_SIZE tx_size,
+                            int mode,
+                            uint8_t *predictor, int pre_stride);
 #endif  // VP9_COMMON_VP9_RECONINTRA_H_
index b6f611c87625959a8ea262dd072c1bc3d0a5236c..277f92ce7770996c0aa47882936023257ba71187 100644 (file)
@@ -1707,7 +1707,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t,
   if (mbmi->mode == I4X4_PRED) {
     assert(bsize == BLOCK_SIZE_SB8X8 && mbmi->txfm_size == TX_4X4);
 #endif
-    vp9_encode_intra4x4mby(x, BLOCK_SIZE_SB8X8);
+    vp9_encode_intra4x4mby(cm, x, BLOCK_SIZE_SB8X8);
     vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_SB8X8);
     vp9_encode_sbuv(cm, x, BLOCK_SIZE_SB8X8);
 
index f8cf50f84fff7a636605aa2dbc9f4868671a3f3c..91866b28ffbca1803a3faf3da1d78ac957cd3691 100644 (file)
@@ -80,15 +80,6 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib,
   }
 }
 
-void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bsize) {
-  int i;
-  int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
-  int bc = 1 << (bwl + bhl);
-
-  for (i = 0; i < bc; i++)
-    encode_intra4x4block(mb, i, bsize);
-}
-
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) {
   MACROBLOCKD *xd = &x->e_mbd;
 
@@ -102,3 +93,5 @@ void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x) {
   vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16);
   vp9_encode_sbuv(cm, x, BLOCK_SIZE_MB16X16);
 }
+
+
index c2620049425f35f8d82064c5ea96e3f747554c42..22a046e355a21679dc8021f5d13c5e588d9c1059 100644 (file)
@@ -16,5 +16,6 @@
 int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred);
 void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x);
 void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x);
-void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bs);
+void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *mb,
+                            BLOCK_SIZE_TYPE bs);
 #endif  // VP9_ENCODER_VP9_ENCODEINTRA_H_
index 5990773bb2fb0cdd11fb42701cb0e50eed12ac75..d9cd091632fa001857b895c62e2a2fd5b6060476 100644 (file)
@@ -604,3 +604,104 @@ void vp9_encode_sb(VP9_COMMON *const cm, MACROBLOCK *x,
 
   foreach_transformed_block(xd, bsize, encode_block, &arg);
 }
+
+static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize,
+                               int ss_txfrm_size, void *arg) {
+  struct encode_b_args* const args = arg;
+  MACROBLOCK* const x = args->x;
+  MACROBLOCKD* const xd = &x->e_mbd;
+  const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2);
+  const int bw = 4 << (b_width_log2(bsize) - xd->plane[plane].subsampling_x);
+  const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane,
+                                                       block, ss_txfrm_size);
+  uint8_t* const src =
+      raster_block_offset_uint8(xd, bsize, plane, raster_block,
+                                x->plane[plane].src.buf,
+                                x->plane[plane].src.stride);
+  uint8_t* const dst =
+      raster_block_offset_uint8(xd, bsize, plane, raster_block,
+                                xd->plane[plane].dst.buf,
+                                xd->plane[plane].dst.stride);
+  int16_t* const src_diff =
+      raster_block_offset_int16(xd, bsize, plane,
+                                raster_block, x->plane[plane].src_diff);
+
+  const int txfm_b_size = 4 << tx_size;
+  int ib = raster_block;
+
+  TX_TYPE tx_type;
+
+  if (tx_size <= TX_16X16)
+    tx_type = txfm_map(xd->mode_info_context->bmi[ib].as_mode.first);
+  else
+    tx_type = DCT_DCT;
+
+  vp9_predict_intra_block(&x->e_mbd, ib, bsize, tx_size,
+                          xd->mode_info_context->bmi[ib].as_mode.first,
+                          dst, xd->plane[plane].dst.stride);
+  vp9_subtract_block(txfm_b_size, txfm_b_size,
+                     src_diff, bw,
+                     src, x->plane[plane].src.stride,
+                     dst, xd->plane[plane].dst.stride);
+
+  xform_quant(plane, block, bsize, ss_txfrm_size, arg);
+
+  /*
+  if (x->optimize)
+    vp9_optimize_b(plane, block, bsize, ss_txfrm_size, args->cm, x, args->ctx);
+    */
+
+  switch (ss_txfrm_size / 2) {
+    case TX_32X32:
+        vp9_short_idct32x32_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
+                                block, 16), dst, xd->plane[plane].dst.stride);
+      break;
+    case TX_16X16:
+      tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT;
+      if (tx_type == DCT_DCT) {
+        vp9_short_idct16x16_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
+                                block, 16), dst, xd->plane[plane].dst.stride);
+      } else {
+        vp9_short_iht16x16_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
+                               block, 16), dst, xd->plane[plane].dst.stride,
+                               tx_type);
+      }
+      break;
+    case TX_8X8:
+      tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT;
+      if (tx_type == DCT_DCT) {
+        vp9_short_idct8x8_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
+                              block, 16), dst, xd->plane[plane].dst.stride);
+      } else {
+        vp9_short_iht8x8_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff,
+                             block, 16), dst, xd->plane[plane].dst.stride,
+                             tx_type);
+      }
+      break;
+    case TX_4X4:
+      tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT;
+      if (tx_type == DCT_DCT) {
+        // this is like vp9_short_idct4x4 but has a special case around eob<=1
+        // which is significant (not just an optimization) for the lossless
+        // case.
+        vp9_inverse_transform_b_4x4_add(xd, xd->plane[plane].eobs[block],
+            BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), dst,
+            xd->plane[plane].dst.stride);
+      } else {
+        vp9_short_iht4x4_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16),
+                             dst, xd->plane[plane].dst.stride, tx_type);
+      }
+      break;
+  }
+}
+
+void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x,
+                            BLOCK_SIZE_TYPE bsize) {
+  MACROBLOCKD* const xd = &x->e_mbd;
+  struct optimize_ctx ctx;
+  struct encode_b_args arg = {cm, x, &ctx};
+
+  foreach_transformed_block_in_plane(xd, bsize, 0,
+                                     encode_block_intra, &arg);
+}
+