]> granicus.if.org Git - libvpx/commitdiff
Add decoder support to recursive transform block partition
authorJingning Han <jingning@google.com>
Tue, 21 Apr 2015 18:56:43 +0000 (11:56 -0700)
committerJingning Han <jingning@google.com>
Fri, 22 May 2015 23:45:34 +0000 (16:45 -0700)
It allows the decoder to recursively parse and use the transform
block size for inter coded blocks.

Change-Id: I12ceea48ab35501ac1a3447142deb2a334eff3b8

vp9/common/vp9_blockd.h
vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodemb.c
vp9/encoder/vp9_tokenize.c

index 57fd3d599af2a70177dd83a1234970430bdf5699..d4b8e3fb10ce41a2eff5038d06cc8cd406e57b58 100644 (file)
@@ -266,13 +266,21 @@ static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
 
 void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);
 
-static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
+static TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
                                           int xss, int yss) {
   if (bsize < BLOCK_8X8) {
     return TX_4X4;
   } else {
     const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss];
-    return MIN(y_tx_size, max_txsize_lookup[plane_bsize]);
+    TX_SIZE uv_tx_size = TX_4X4;
+    if (y_tx_size == TX_32X32)
+      uv_tx_size = TX_16X16;
+    else if (y_tx_size == TX_16X16)
+      uv_tx_size = TX_8X8;
+    else if (y_tx_size == TX_8X8)
+      uv_tx_size = TX_4X4;
+
+    return MIN(uv_tx_size, max_txsize_lookup[plane_bsize]);
   }
 }
 
index f5f52f7d89dfa8bedb7713e25b511738509f8406..3a52015aded9ec6f9f375d30dd2b2a7c5d2b7754 100644 (file)
@@ -347,9 +347,11 @@ static void decode_reconstruct_tx(int blk_row, int blk_col,
   MACROBLOCKD *const xd = args->xd;
   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
   struct macroblockd_plane *const pd = &xd->plane[plane];
+  int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
+               (blk_col >> (1 - pd->subsampling_x));
   TX_SIZE plane_tx_size = plane ?
-      get_uv_tx_size_impl(mbmi->tx_size, plane_bsize,
-                          0, 0) : mbmi->tx_size;
+      get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
+      mbmi->inter_tx_size[tx_idx];
 
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
@@ -502,6 +504,7 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
         mbmi->skip = 1;  // skip loopfilter
     }
   }
+
   xd->corrupted |= vp9_reader_has_error(r);
 }
 
index 5fee95a30e88ade92be638567528e556d0380d34..b600d435d515359c845d385b71c4208b48f28730 100644 (file)
@@ -65,8 +65,13 @@ static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
                                vp9_reader *r) {
   MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
   int is_split = 0;
+  int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
   int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
+  BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
+  int bh = num_4x4_blocks_high_lookup[bsize];
+  int i, j;
+
   if (xd->mb_to_bottom_edge < 0)
     max_blocks_high += xd->mb_to_bottom_edge >> 5;
   if (xd->mb_to_right_edge < 0)
@@ -78,13 +83,14 @@ static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
   is_split = vp9_read_bit(r);
 
   if (!is_split) {
+    mbmi->inter_tx_size[tx_idx] = tx_size;
+    for (j = 0; j < bh / 2; ++j)
+      for (i = 0; i < bh / 2; ++i)
+        mbmi->inter_tx_size[tx_idx + j * 8 + i] = tx_size;
     mbmi->tx_size = tx_size;
   } else {
-    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
-    int bh = num_4x4_blocks_high_lookup[bsize];
-    int i;
-
     if (tx_size == TX_8X8) {
+      mbmi->inter_tx_size[tx_idx] = TX_4X4;
       mbmi->tx_size = TX_4X4;
       return;
     }
@@ -627,8 +633,11 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi,
         read_tx_size_inter(cm, xd, max_txsize_lookup[mbmi->sb_type],
                            idy, idx, r);
   } else {
+    int i;
     mbmi->tx_size = read_tx_size(cm, xd, counts,
                                  !mbmi->skip || !inter_block, r);
+    for (i = 0; i < 64; ++i)
+      mbmi->inter_tx_size[i] = mbmi->tx_size;
   }
 
   if (inter_block)
index 17e5c7fcbd7ce54b2771d23852c21c8bb9530bd6..8d4ebac08c41edffa077ff53df9e3bb6c8285adf 100644 (file)
@@ -80,6 +80,7 @@ static void write_tx_size_inter(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                                 TX_SIZE tx_size, int blk_row, int blk_col,
                                 vp9_writer *w) {
   MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
+  int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
   int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
   if (xd->mb_to_bottom_edge < 0)
@@ -91,7 +92,7 @@ static void write_tx_size_inter(const VP9_COMMON *cm, const MACROBLOCKD *xd,
     return;
 
   // TODO(jingning): this assumes support of the possible 64x64 transform.
-  if (tx_size == mbmi->tx_size) {
+  if (tx_size == mbmi->inter_tx_size[tx_idx]) {
     vp9_write_bit(w, 0);
   } else {  // further split
     BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
index ff33a463815f25760569f633bb21a7c5715a6379..0604b2cf4068f8696e8dbdecf3f12419b257cf41 100644 (file)
@@ -805,10 +805,11 @@ static void encode_block_inter(int blk_row, int blk_col,
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
   struct macroblockd_plane *const pd = &xd->plane[plane];
-  int blk_idx = (blk_row / 2) * 8 + (blk_col / 2);
+  int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
+               (blk_col >> (1 - pd->subsampling_x));
   TX_SIZE plane_tx_size = plane ?
-      get_uv_tx_size_impl(mbmi->inter_tx_size[blk_idx], plane_bsize, 0, 0) :
-      mbmi->inter_tx_size[blk_idx];
+      get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
+      mbmi->inter_tx_size[tx_idx];
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
   if (xd->mb_to_bottom_edge < 0)
index 7b3f8bef2d48872f5b21085e20fc738b753450ed..e930cf1f7bb8a4d0f6d93791e09646333d601bb6 100644 (file)
@@ -708,11 +708,11 @@ void tokenize_tx(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
   const struct macroblockd_plane *const pd = &xd->plane[plane];
-  int blk_idx = (blk_row / 2) * 8 + (blk_col / 2);
+  int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
+               (blk_col >> (1 - pd->subsampling_x));
   TX_SIZE plane_tx_size = plane ?
-      get_uv_tx_size_impl(mbmi->inter_tx_size[blk_idx],
-                          plane_bsize, 0, 0) :
-      mbmi->inter_tx_size[blk_idx];
+      get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], plane_bsize, 0, 0) :
+      mbmi->inter_tx_size[tx_idx];
 
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];