shithub: libvpx

Download patch

ref: 5b984b36ca1e45171e0c4be49c6909696ab068e3
parent: acf0d56f0bb2fc51508f07e38147044539138517
author: Guillaume Martres <gmartres@google.com>
date: Fri Oct 11 12:14:29 EDT 2013

Use a separate MODE_INFO stream for each tile column

This should make parallel tiles decoding easier to implement.

Change-Id: I6226456dd11f275fa991e4a7a930549da6675915

--- a/vp9/common/vp9_blockd.h
+++ b/vp9/common/vp9_blockd.h
@@ -198,8 +198,6 @@
   MODE_INFO *last_mi;
   int mode_info_stride;
 
-  MODE_INFO *mic_stream_ptr;
-
   // A NULL indicates that the 8x8 is not part of the image
   MODE_INFO **mi_8x8;
   MODE_INFO **prev_mi_8x8;
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -174,6 +174,7 @@
 }
 
 static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE bsize,
+                        int tile_col,
                         int mi_row, int mi_col) {
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
@@ -187,9 +188,9 @@
   xd->prev_mi_8x8 = cm->prev_mi_grid_visible + offset;
 
   // we are using the mode info context stream here
-  xd->mi_8x8[0] = xd->mic_stream_ptr;
+  xd->mi_8x8[0] = pbi->mi_streams[tile_col];
   xd->mi_8x8[0]->mbmi.sb_type = bsize;
-  xd->mic_stream_ptr++;
+  pbi->mi_streams[tile_col]++;
 
   // Special case: if prev_mi is NULL, the previous mode info context
   // cannot be used.
@@ -221,7 +222,8 @@
   xd->corrupted |= cfg->corrupted;
 }
 
-static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col,
+static void decode_modes_b(VP9D_COMP *pbi, int tile_col,
+                           int mi_row, int mi_col,
                            vp9_reader *r, BLOCK_SIZE bsize) {
   MACROBLOCKD *const xd = &pbi->mb;
   const int less8x8 = bsize < BLOCK_8X8;
@@ -232,7 +234,7 @@
     if (xd->ab_index > 0)
       return;
 
-  set_offsets(pbi, bsize, mi_row, mi_col);
+  set_offsets(pbi, bsize, tile_col, mi_row, mi_col);
   vp9_read_mode_info(pbi, mi_row, mi_col, r);
 
   if (less8x8)
@@ -269,7 +271,8 @@
   xd->corrupted |= vp9_reader_has_error(r);
 }
 
-static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col,
+static void decode_modes_sb(VP9D_COMP *pbi, int tile_col,
+                            int mi_row, int mi_col,
                             vp9_reader* r, BLOCK_SIZE bsize) {
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
@@ -307,19 +310,19 @@
 
   switch (partition) {
     case PARTITION_NONE:
-      decode_modes_b(pbi, mi_row, mi_col, r, subsize);
+      decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize);
       break;
     case PARTITION_HORZ:
-      decode_modes_b(pbi, mi_row, mi_col, r, subsize);
+      decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize);
       *get_sb_index(xd, subsize) = 1;
       if (mi_row + hbs < cm->mi_rows)
-        decode_modes_b(pbi, mi_row + hbs, mi_col, r, subsize);
+        decode_modes_b(pbi, tile_col, mi_row + hbs, mi_col, r, subsize);
       break;
     case PARTITION_VERT:
-      decode_modes_b(pbi, mi_row, mi_col, r, subsize);
+      decode_modes_b(pbi, tile_col, mi_row, mi_col, r, subsize);
       *get_sb_index(xd, subsize) = 1;
       if (mi_col + hbs < cm->mi_cols)
-        decode_modes_b(pbi, mi_row, mi_col + hbs, r, subsize);
+        decode_modes_b(pbi, tile_col, mi_row, mi_col + hbs, r, subsize);
       break;
     case PARTITION_SPLIT: {
       int n;
@@ -326,7 +329,8 @@
       for (n = 0; n < 4; n++) {
         const int j = n >> 1, i = n & 1;
         *get_sb_index(xd, subsize) = n;
-        decode_modes_sb(pbi, mi_row + j * hbs, mi_col + i * hbs, r, subsize);
+        decode_modes_sb(pbi, tile_col, mi_row + j * hbs, mi_col + i * hbs,
+                        r, subsize);
       }
     } break;
     default:
@@ -582,7 +586,7 @@
   setup_display_size(cm, rb);
 }
 
-static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) {
+static void decode_tile(VP9D_COMP *pbi, vp9_reader *r, int tile_col) {
   const int num_threads = pbi->oxcf.max_threads;
   VP9_COMMON *const cm = &pbi->common;
   int mi_row, mi_col;
@@ -607,7 +611,7 @@
     vp9_zero(cm->left_seg_context);
     for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end;
          mi_col += MI_BLOCK_SIZE)
-      decode_modes_sb(pbi, mi_row, mi_col, r, BLOCK_64X64);
+      decode_modes_sb(pbi, tile_col, mi_row, mi_col, r, BLOCK_64X64);
 
     if (pbi->do_loopfilter_inline) {
       // delay the loopfilter by 1 macroblock row.
@@ -709,7 +713,7 @@
         setup_token_decoder(pbi, data_ptr2[tile_row][tile_col],
                             data_end - data_ptr2[tile_row][tile_col],
                             &residual_bc);
-        decode_tile(pbi, &residual_bc);
+        decode_tile(pbi, &residual_bc, tile_col);
         if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1)
           bc_bak = residual_bc;
       }
@@ -738,7 +742,7 @@
         }
 
         setup_token_decoder(pbi, data, size, &residual_bc);
-        decode_tile(pbi, &residual_bc);
+        decode_tile(pbi, &residual_bc, tile_col);
         data += size;
       }
     }
@@ -954,6 +958,8 @@
   const size_t first_partition_size = read_uncompressed_header(pbi, &rb);
   const int keyframe = cm->frame_type == KEY_FRAME;
   YV12_BUFFER_CONFIG *new_fb = &cm->yv12_fb[cm->new_fb_idx];
+  const int tile_cols = 1 << cm->log2_tile_cols;
+  int tile_col;
 
   if (!first_partition_size) {
     if (!keyframe) {
@@ -982,8 +988,16 @@
   setup_plane_dequants(cm, &pbi->mb, cm->base_qindex);
 
   xd->mi_8x8 = cm->mi_grid_visible;
-  xd->mic_stream_ptr = cm->mi;
   xd->mode_info_stride = cm->mode_info_stride;
+
+  CHECK_MEM_ERROR(cm, pbi->mi_streams,
+                  vpx_realloc(pbi->mi_streams, tile_cols *
+                              sizeof(*pbi->mi_streams)));
+  for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
+    vp9_get_tile_col_offsets(cm, tile_col);
+    pbi->mi_streams[tile_col] =
+        &cm->mi[cm->mi_rows * cm->cur_tile_mi_col_start];
+  }
 
   cm->fc = cm->frame_contexts[cm->frame_context_idx];
 
--- a/vp9/decoder/vp9_onyxd_if.c
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -163,6 +163,7 @@
   vp9_remove_common(&pbi->common);
   vp9_worker_end(&pbi->lf_worker);
   vpx_free(pbi->lf_worker.data1);
+  vpx_free(pbi->mi_streams);
   vpx_free(pbi);
 }
 
--- a/vp9/decoder/vp9_onyxd_int.h
+++ b/vp9/decoder/vp9_onyxd_int.h
@@ -39,6 +39,10 @@
 
   int do_loopfilter_inline;  // apply loopfilter to available rows immediately
   VP9Worker lf_worker;
+
+  /* Each tile column has its own MODE_INFO stream. This array indexes them by
+     tile column index. */
+  MODE_INFO **mi_streams;
 } VP9D_COMP;
 
 #endif  // VP9_DECODER_VP9_ONYXD_INT_H_
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1942,7 +1942,6 @@
   xd->mi_8x8 = cm->mi_grid_visible;
   // required for vp9_frame_init_quantizer
   xd->mi_8x8[0] = cm->mi;
-  xd->mic_stream_ptr = cm->mi;
 
   xd->last_mi = cm->prev_mi;
 
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -519,7 +519,6 @@
   xd->mi_8x8 = cm->mi_grid_visible;
   // required for vp9_frame_init_quantizer
   xd->mi_8x8[0] = cm->mi;
-  xd->mic_stream_ptr = cm->mi;
 
   setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);