]> granicus.if.org Git - libvpx/commitdiff
Add decoder support to recursive transform block partition
authorJingning Han <jingning@google.com>
Thu, 8 Oct 2015 19:05:03 +0000 (12:05 -0700)
committerJingning Han <jingning@google.com>
Thu, 8 Oct 2015 23:16:41 +0000 (16:16 -0700)
This commit allows the decoder to recursively parse and rebuild
the pixel blocks.

Change-Id: I510f3a30ae7cdad5b70725c66882b00a0594e96f

vp10/decoder/decodeframe.c
vp10/decoder/decodemv.c
vp10/encoder/bitstream.c
vp10/encoder/encodemb.c
vp10/encoder/rdopt.c
vp10/encoder/tokenize.c

index 0e15ad624b4aa4ae58fc629a21b6279bd1528f53..80c07dee4bd48f454c3d47f93ec983e10b4bcc7e 100644 (file)
@@ -390,9 +390,12 @@ static void decode_reconstruct_tx(MACROBLOCKD *const xd, vpx_reader *r,
                                   int block, int blk_row, int blk_col,
                                   TX_SIZE tx_size, int *eob_total) {
   const 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, mbmi->sb_type,
-                          pd->subsampling_x, pd->subsampling_y) : mbmi->tx_size;
+      get_uv_tx_size_impl(mbmi->inter_tx_size[tx_idx], mbmi->sb_type,
+                          pd->subsampling_x, pd->subsampling_y) :
+      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];
 
@@ -935,7 +938,7 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd,
         const BLOCK_SIZE plane_bsize =
             get_plane_block_size(VPXMAX(bsize, BLOCK_8X8), pd);
         const TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
-        const int txb_size = txsize_to_bsize[max_tx_size];
+        const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
         int bw = num_4x4_blocks_wide_lookup[txb_size];
         int block = 0;
         const int step = 1 << (max_tx_size << 1);
@@ -2178,6 +2181,7 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
 #if !CONFIG_MISC_FIXES
   cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r);
 #endif
+
   if (cm->tx_mode == TX_MODE_SELECT)
     read_tx_mode_probs(&fc->tx_probs, &r);
   read_coef_probs(fc, cm->tx_mode, &r);
index 92ebbb6c7ca0be1495c53a87f9642ddd6f7bc5ef..870ab154f86306b002b9e9aef86da77ffbb240f8 100644 (file)
@@ -65,31 +65,44 @@ static int read_segment_id(vpx_reader *r, const struct segmentation *seg) {
 }
 
 #if CONFIG_VAR_TX
-static void read_tx_size_inter(VP10_COMMON *cm, MB_MODE_INFO *mbmi,
-                               TX_SIZE tx_size, int mi_row, int mi_col,
+static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
+                               MB_MODE_INFO *mbmi,
+                               TX_SIZE tx_size, int blk_row, int blk_col,
                                vpx_reader *r) {
-  int is_split = vpx_read_bit(r);
+  int is_split = 0;
+  const int tx_idx = (blk_row >> 1) * 8 + (blk_col >> 1);
+  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)
+    max_blocks_high += xd->mb_to_bottom_edge >> 5;
+  if (xd->mb_to_right_edge < 0)
+     max_blocks_wide += xd->mb_to_right_edge >> 5;
+
+  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
+     return;
+
+  is_split = vpx_read_bit(r);
 
   if (is_split) {
     BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
-    int bsl = mi_width_log2_lookup[bsize];
+    int bsl = b_width_log2_lookup[bsize];
     int i;
     if (tx_size == TX_8X8) {
-      mbmi->tx_size = TX_4X4;
+      mbmi->inter_tx_size[tx_idx] = TX_4X4;
+      mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
       return;
     }
 
     assert(bsl > 0);
     --bsl;
     for (i = 0; i < 4; ++i) {
-      int offsetr = mi_row + ((i >> 1) << bsl);
-      int offsetc = mi_col + ((i & 0x01) << bsl);
-      if (offsetr >= cm->mi_rows || offsetc >= cm->mi_cols)
-        continue;
-      read_tx_size_inter(cm, mbmi, tx_size - 1, offsetr, offsetc, r);
+      int offsetr = blk_row + ((i >> 1) << bsl);
+      int offsetc = blk_col + ((i & 0x01) << bsl);
+      read_tx_size_inter(cm, xd, mbmi, tx_size - 1, offsetr, offsetc, r);
     }
   } else {
-    mbmi->tx_size = tx_size;
+    mbmi->inter_tx_size[tx_idx] = tx_size;
+    mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
   }
 }
 #endif
@@ -644,21 +657,31 @@ static void read_inter_frame_mode_info(VP10Decoder *const pbi,
   if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
       !mbmi->skip && inter_block) {
     const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
-    const int txb_size = txsize_to_bsize[max_tx_size];
-    const int bs = num_8x8_blocks_wide_lookup[txb_size];
-    const int width  = num_8x8_blocks_wide_lookup[bsize];
-    const int height = num_8x8_blocks_high_lookup[bsize];
+    const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
+    const int bs = num_4x4_blocks_wide_lookup[txb_size];
+    const int width  = num_4x4_blocks_wide_lookup[bsize];
+    const int height = num_4x4_blocks_high_lookup[bsize];
     int idx, idy;
     for (idy = 0; idy < height; idy += bs)
       for (idx = 0; idx < width; idx += bs)
-        read_tx_size_inter(cm, mbmi, max_tx_size,
-                           mi_row + idy, mi_col + idx, r);
+        read_tx_size_inter(cm, xd, mbmi, max_tx_size,
+                           idy, idx, r);
     if (xd->counts) {
       const int ctx = get_tx_size_context(xd);
       ++get_tx_counts(max_tx_size, ctx, &xd->counts->tx)[mbmi->tx_size];
     }
   } else {
     mbmi->tx_size = read_tx_size(cm, xd, !mbmi->skip || !inter_block, r);
+    if (inter_block) {
+      const BLOCK_SIZE txb_size = txsize_to_bsize[mbmi->tx_size];
+      const int bs = num_4x4_blocks_wide_lookup[txb_size];
+      const int width  = num_4x4_blocks_wide_lookup[bsize];
+      const int height = num_4x4_blocks_high_lookup[bsize];
+      int idx, idy;
+      for (idy = 0; idy < height; idy += bs)
+        for (idx = 0; idx < width; idx += bs)
+          mbmi->inter_tx_size[(idy >> 1) * 8 + (idx >> 1)] = mbmi->tx_size;
+    }
   }
 #else
   mbmi->tx_size = read_tx_size(cm, xd, !mbmi->skip || !inter_block, r);
index e0db0c3336908739cde75f8090e174609f6595d4..545a9d8cba21d583878271040848395e8bc85e95 100644 (file)
@@ -119,14 +119,26 @@ static int prob_diff_update_savings(const vpx_tree_index *tree,
 
 #if CONFIG_VAR_TX
 static void write_tx_size_inter(const VP10_COMMON *cm,
+                                const MACROBLOCKD *xd,
                                 const MB_MODE_INFO *mbmi,
-                                TX_SIZE tx_size, int mi_row, int mi_col,
+                                TX_SIZE tx_size, int blk_row, int blk_col,
                                 vpx_writer *w) {
-  if (tx_size == mbmi->tx_size) {
+  const int tx_idx = (blk_row >> 1) * 8 + (blk_col >> 1);
+  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)
+    max_blocks_high += xd->mb_to_bottom_edge >> 5;
+  if (xd->mb_to_right_edge < 0)
+     max_blocks_wide += xd->mb_to_right_edge >> 5;
+
+  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
+     return;
+
+  if (tx_size == mbmi->inter_tx_size[tx_idx]) {
     vpx_write_bit(w, 0);
   } else {
     const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
-    int bsl = mi_width_log2_lookup[bsize];
+    int bsl = b_width_log2_lookup[bsize];
     int i;
     vpx_write_bit(w, 1);
 
@@ -136,11 +148,9 @@ static void write_tx_size_inter(const VP10_COMMON *cm,
     assert(bsl > 0);
     --bsl;
     for (i = 0; i < 4; ++i) {
-      int offsetr = mi_row + ((i >> 1) << bsl);
-      int offsetc = mi_col + ((i & 0x01) << bsl);
-      if (offsetr >= cm->mi_rows || offsetc >= cm->mi_cols)
-        continue;
-      write_tx_size_inter(cm, mbmi, tx_size - 1, offsetr, offsetc, w);
+      int offsetr = blk_row + ((i >> 1) << bsl);
+      int offsetc = blk_col + ((i & 0x01) << bsl);
+      write_tx_size_inter(cm, xd, mbmi, tx_size - 1, offsetr, offsetc, w);
     }
   }
 }
@@ -345,9 +355,6 @@ static void write_ref_frames(const VP10_COMMON *cm, const MACROBLOCKD *xd,
 }
 
 static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
-#if CONFIG_VAR_TX
-                                int mi_row, int mi_col,
-#endif
                                 vpx_writer *w) {
   VP10_COMMON *const cm = &cpi->common;
   const nmv_context *nmvc = &cm->fc->nmvc;
@@ -387,14 +394,13 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
     if (is_inter) {  // This implies skip flag is 0.
       const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
       const int txb_size = txsize_to_bsize[max_tx_size];
-      const int bs = num_8x8_blocks_wide_lookup[txb_size];
-      const int width  = num_8x8_blocks_wide_lookup[bsize];
-      const int height = num_8x8_blocks_high_lookup[bsize];
+      const int bs = num_4x4_blocks_wide_lookup[txb_size];
+      const int width  = num_4x4_blocks_wide_lookup[bsize];
+      const int height = num_4x4_blocks_high_lookup[bsize];
       int idx, idy;
       for (idy = 0; idy < height; idy += bs)
         for (idx = 0; idx < width; idx += bs)
-          write_tx_size_inter(cm, mbmi, max_tx_size,
-                              mi_row + idy, mi_col + idx, w);
+          write_tx_size_inter(cm, xd, mbmi, max_tx_size, idy, idx, w);
     } else {
       write_selected_tx_size(cm, xd, w);
     }
@@ -549,11 +555,7 @@ static void write_modes_b(VP10_COMP *cpi, const TileInfo *const tile,
   if (frame_is_intra_only(cm)) {
     write_mb_modes_kf(cm, xd, xd->mi, w);
   } else {
-#if CONFIG_VAR_TX
-    pack_inter_mode_mvs(cpi, m, mi_row, mi_col, w);
-#else
     pack_inter_mode_mvs(cpi, m, w);
-#endif
   }
 
   assert(*tok < tok_end);
index 437870ea5f1dd596221d2e85c581777404be6ab6..cdc30791ec171121d4c397caca6ab6c35232786f 100644 (file)
@@ -1500,9 +1500,11 @@ static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
   MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
 
   const struct macroblockd_plane *const pd = &xd->plane[plane];
+  const int blk_idx = ((blk_row >> 1) << 3) + (blk_col >> 1);
   TX_SIZE plane_tx_size = plane ?
-      get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type,
-                          pd->subsampling_x, pd->subsampling_y) : mbmi->tx_size;
+      get_uv_tx_size_impl(mbmi->inter_tx_size[blk_idx], mbmi->sb_type,
+                          pd->subsampling_x, pd->subsampling_y) :
+      mbmi->inter_tx_size[blk_idx];
 
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
@@ -1601,8 +1603,8 @@ void vp10_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) {
     const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
     const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
     const TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
-    int txb_size = txsize_to_bsize[max_tx_size];
-    int bh = num_4x4_blocks_wide_lookup[txb_size];
+    const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
+    const int bh = num_4x4_blocks_wide_lookup[txb_size];
     int idx, idy;
     int block = 0;
     int step = 1 << (max_tx_size * 2);
index 49d3700197e7ec7ff43dabb3f96de96b087ee52f..b44b036303205c2a93ec19849199ff3360bdf7ab 100644 (file)
@@ -2781,6 +2781,11 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
     super_block_yrd(cpi, x, rate_y, &distortion_y, &skippable_y, psse,
                     bsize, ref_best_rd);
 
+#if CONFIG_VAR_TX
+    for (i = 0; i < 64; ++i)
+      mbmi->inter_tx_size[i] = mbmi->tx_size;
+#endif
+
     if (*rate_y == INT_MAX) {
       *rate2 = INT_MAX;
       *distortion = INT64_MAX;
@@ -3932,6 +3937,11 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
         xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
     }
 
+#if CONFIG_VAR_TX
+    for (i = 0; i < 64; ++i)
+      mbmi->inter_tx_size[i] = mbmi->tx_size;
+#endif
+
     if (ref_frame == INTRA_FRAME) {
       int rate;
       if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
index f65e17fc25438e918403204bb5383744e0690d4a..d20196c028dbe09c88b32c455bb3995c5393e8a3 100644 (file)
@@ -622,9 +622,11 @@ void tokenize_tx(ThreadData *td, TOKENEXTRA **t,
   MACROBLOCKD *const xd = &x->e_mbd;
   MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
   const struct macroblockd_plane *const pd = &xd->plane[plane];
+  const int blk_idx = ((blk_row >> 1) << 3) + (blk_col >> 1);
   TX_SIZE plane_tx_size = plane ?
-      get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type,
-                          pd->subsampling_x, pd->subsampling_y) : mbmi->tx_size;
+      get_uv_tx_size_impl(mbmi->inter_tx_size[blk_idx], mbmi->sb_type,
+                          pd->subsampling_x, pd->subsampling_y) :
+      mbmi->inter_tx_size[blk_idx];
 
   int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
   int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
@@ -702,7 +704,7 @@ void vp10_tokenize_sb_inter(VP10_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
     const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
     const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
     const TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
-    int txb_size = txsize_to_bsize[max_tx_size];
+    const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
     int bh = num_4x4_blocks_wide_lookup[txb_size];
     int idx, idy;
     int block = 0;