]> granicus.if.org Git - libvpx/commitdiff
Add support for tile rows.
authorRonald S. Bultje <rbultje@google.com>
Fri, 8 Feb 2013 19:33:11 +0000 (11:33 -0800)
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>
Wed, 13 Feb 2013 20:31:00 +0000 (12:31 -0800)
These allow sending partial bitstream packets over the network before
encoding a complete frame is completed, thus lowering end-to-end
latency. The tile-rows are not independent.

Change-Id: I99986595cbcbff9153e2a14f49b4aa7dee4768e2

13 files changed:
vp9/common/vp9_onyx.h
vp9/common/vp9_onyxc_int.h
vp9/common/vp9_tile_common.c
vp9/common/vp9_tile_common.h
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_segmentation.c
vp9/vp9_cx_iface.c
vpx/vp8cx.h
vpxenc.c

index 0b7d98a583d7e2058ec733d9c1a54c0b933f0c22..d93b7d5fb91c8f6942b240ce015c180be6deed4c 100644 (file)
@@ -177,6 +177,7 @@ extern "C"
     int arnr_type;
 
     int tile_columns;
+    int tile_rows;
 
     struct vpx_fixed_buf         two_pass_stats_in;
     struct vpx_codec_pkt_list  *output_pkt_list;
index a333a4b02ee3f3ddfc25aefbf12e40495a8fcc00..6295514eaee34e32578e390dacc4c5e1d0630252 100644 (file)
@@ -280,7 +280,9 @@ typedef struct VP9Common {
   int frame_parallel_decoding_mode;
 
   int tile_columns, log2_tile_columns;
-  int cur_tile_mb_col_start, cur_tile_mb_col_end, cur_tile_idx;
+  int cur_tile_mb_col_start, cur_tile_mb_col_end, cur_tile_col_idx;
+  int tile_rows, log2_tile_rows;
+  int cur_tile_mb_row_start, cur_tile_mb_row_end, cur_tile_row_idx;
 } VP9_COMMON;
 
 static int get_free_fb(VP9_COMMON *cm) {
index 02e0d146198f18c458c761233d7e714611d4731e..29f89b618d8d728afd94747b5b59d1cf231046c3 100644 (file)
 
 #include "vp9/common/vp9_tile_common.h"
 
-void vp9_get_tile_offsets(VP9_COMMON *cm, int *min_tile_off,
-                          int *max_tile_off) {
-  const int log2_n_tiles = cm->log2_tile_columns;
-  const int tile_idx = cm->cur_tile_idx;
-  const int mb_cols = cm->mb_cols;
-  const int sb_cols = (mb_cols + 3) >> 2;
-  const int sb_off1 = (tile_idx * sb_cols) >> log2_n_tiles;
-  const int sb_off2 = ((tile_idx + 1) * sb_cols) >> log2_n_tiles;
-
-  *min_tile_off = (sb_off1 << 2) > mb_cols ? mb_cols : (sb_off1 << 2);
-  *max_tile_off = (sb_off2 << 2) > mb_cols ? mb_cols : (sb_off2 << 2);
+static void vp9_get_tile_offsets(VP9_COMMON *cm, int *min_tile_off,
+                                 int *max_tile_off, int tile_idx,
+                                 int log2_n_tiles, int n_mbs) {
+  const int n_sbs = (n_mbs + 3) >> 2;
+  const int sb_off1 =  (tile_idx      * n_sbs) >> log2_n_tiles;
+  const int sb_off2 = ((tile_idx + 1) * n_sbs) >> log2_n_tiles;
+
+  *min_tile_off = (sb_off1 << 2) > n_mbs ? n_mbs : (sb_off1 << 2);
+  *max_tile_off = (sb_off2 << 2) > n_mbs ? n_mbs : (sb_off2 << 2);
+}
+
+void vp9_get_tile_col_offsets(VP9_COMMON *cm, int tile_col_idx) {
+  cm->cur_tile_col_idx = tile_col_idx;
+  vp9_get_tile_offsets(cm, &cm->cur_tile_mb_col_start,
+                       &cm->cur_tile_mb_col_end, tile_col_idx,
+                       cm->log2_tile_columns, cm->mb_cols);
+}
+
+void vp9_get_tile_row_offsets(VP9_COMMON *cm, int tile_row_idx) {
+  cm->cur_tile_row_idx = tile_row_idx;
+  vp9_get_tile_offsets(cm, &cm->cur_tile_mb_row_start,
+                       &cm->cur_tile_mb_row_end, tile_row_idx,
+                       cm->log2_tile_rows, cm->mb_rows);
 }
 
 #define MIN_TILE_WIDTH_SBS (MIN_TILE_WIDTH >> 6)
index 653b6b4f622887c4a7b60cbb21da38c7f6c9df41..92bf508971e0fd6789356f594f6b0defef30a3e3 100644 (file)
@@ -16,8 +16,9 @@
 #define MIN_TILE_WIDTH 256
 #define MAX_TILE_WIDTH 4096
 
-extern void vp9_get_tile_offsets(VP9_COMMON *cm, int *min_tile_off,
-                                 int *max_tile_off);
+extern void vp9_get_tile_col_offsets(VP9_COMMON *cm, int tile_col_idx);
+
+extern void vp9_get_tile_row_offsets(VP9_COMMON *cm, int tile_row_idx);
 
 extern void vp9_get_tile_n_bits(VP9_COMMON *cm, int *min_log2_n_tiles,
                                 int *delta_log2_n_tiles);
index bcdb262077cfb49926f9bdffc2d510dd40a5f187..04e3fe5b3b794175b78e4ac6100cd9765ea0b49a 100644 (file)
@@ -1770,7 +1770,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
   /* tile info */
   {
     const unsigned char *data_ptr = data + first_partition_length_in_bytes;
-    int tile, delta_log2_tiles;
+    int tile_row, tile_col, delta_log2_tiles;
 
     vp9_get_tile_n_bits(pc, &pc->log2_tile_columns, &delta_log2_tiles);
     while (delta_log2_tiles--) {
@@ -1780,55 +1780,80 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
         break;
       }
     }
+    pc->log2_tile_rows = vp9_read_bit(&header_bc);
+    if (pc->log2_tile_rows)
+      pc->log2_tile_rows += vp9_read_bit(&header_bc);
     pc->tile_columns = 1 << pc->log2_tile_columns;
+    pc->tile_rows    = 1 << pc->log2_tile_rows;
 
     vpx_memset(pc->above_context, 0,
                sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols);
 
     if (pbi->oxcf.inv_tile_order) {
-      const unsigned char *data_ptr2[4];
+      const int n_cols = pc->tile_columns;
+      const unsigned char *data_ptr2[4][1 << 6];
       BOOL_DECODER UNINITIALIZED_IS_SAFE(bc_bak);
 
-      data_ptr2[0] = data_ptr;
-      for (tile = 1; tile < pc->tile_columns; tile++) {
-        int size = data_ptr2[tile - 1][0] + (data_ptr2[tile - 1][1] << 8) +
-                (data_ptr2[tile - 1][2] << 16) + (data_ptr2[tile - 1][3] << 24);
-        data_ptr2[tile - 1] += 4;
-        data_ptr2[tile] = data_ptr2[tile - 1] + size;
+      // pre-initialize the offsets, we're going to read in inverse order
+      data_ptr2[0][0] = data_ptr;
+      for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+        if (tile_row) {
+          int size = data_ptr2[tile_row - 1][n_cols - 1][0] +
+                    (data_ptr2[tile_row - 1][n_cols - 1][1] << 8) +
+                    (data_ptr2[tile_row - 1][n_cols - 1][2] << 16) +
+                    (data_ptr2[tile_row - 1][n_cols - 1][3] << 24);
+          data_ptr2[tile_row - 1][n_cols - 1] += 4;
+          data_ptr2[tile_row][0] = data_ptr2[tile_row - 1][n_cols - 1] + size;
+        }
+
+        for (tile_col = 1; tile_col < n_cols; tile_col++) {
+          int size = data_ptr2[tile_row][tile_col - 1][0] +
+                    (data_ptr2[tile_row][tile_col - 1][1] << 8) +
+                    (data_ptr2[tile_row][tile_col - 1][2] << 16) +
+                    (data_ptr2[tile_row][tile_col - 1][3] << 24);
+          data_ptr2[tile_row][tile_col - 1] += 4;
+          data_ptr2[tile_row][tile_col] =
+              data_ptr2[tile_row][tile_col - 1] + size;
+        }
       }
-      for (tile = pc->tile_columns - 1; tile >= 0; tile--) {
-        pc->cur_tile_idx = tile;
-        vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start,
-                             &pc->cur_tile_mb_col_end);
-        setup_token_decoder(pbi, data_ptr2[tile], &residual_bc);
-
-        /* Decode a row of superblocks */
-        for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 4) {
-          decode_sb_row(pbi, pc, mb_row, xd, &residual_bc);
+
+      for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+        vp9_get_tile_row_offsets(pc, tile_row);
+        for (tile_col = n_cols - 1; tile_col >= 0; tile_col--) {
+          vp9_get_tile_col_offsets(pc, tile_col);
+          setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], &residual_bc);
+
+          /* Decode a row of superblocks */
+          for (mb_row = pc->cur_tile_mb_row_start;
+               mb_row < pc->cur_tile_mb_row_end; mb_row += 4) {
+            decode_sb_row(pbi, pc, mb_row, xd, &residual_bc);
+          }
+          if (tile_row == pc->tile_rows - 1 && tile_col == n_cols - 1)
+            bc_bak = residual_bc;
         }
-        if (tile == pc->tile_columns - 1)
-          bc_bak = residual_bc;
       }
       residual_bc = bc_bak;
     } else {
-      for (tile = 0; tile < pc->tile_columns; tile++) {
-        pc->cur_tile_idx = tile;
-        vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start,
-                             &pc->cur_tile_mb_col_end);
-
-        if (tile < pc->tile_columns - 1)
-          setup_token_decoder(pbi, data_ptr + 4, &residual_bc);
-        else
-          setup_token_decoder(pbi, data_ptr, &residual_bc);
-
-        /* Decode a row of superblocks */
-        for (mb_row = 0; mb_row < pc->mb_rows; mb_row += 4) {
-          decode_sb_row(pbi, pc, mb_row, xd, &residual_bc);
-        }
-        if (tile < pc->tile_columns - 1) {
-          int size = data_ptr[0] + (data_ptr[1] << 8) + (data_ptr[2] << 16) +
-                    (data_ptr[3] << 24);
-          data_ptr += 4 + size;
+      for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+        vp9_get_tile_row_offsets(pc, tile_row);
+        for (tile_col = 0; tile_col < pc->tile_columns; tile_col++) {
+          vp9_get_tile_col_offsets(pc, tile_col);
+
+          if (tile_col < pc->tile_columns - 1 || tile_row < pc->tile_rows - 1)
+            setup_token_decoder(pbi, data_ptr + 4, &residual_bc);
+          else
+            setup_token_decoder(pbi, data_ptr, &residual_bc);
+
+          /* Decode a row of superblocks */
+          for (mb_row = pc->cur_tile_mb_row_start;
+               mb_row < pc->cur_tile_mb_row_end; mb_row += 4) {
+            decode_sb_row(pbi, pc, mb_row, xd, &residual_bc);
+          }
+          if (tile_col < pc->tile_columns - 1 || tile_row < pc->tile_rows - 1) {
+            int size = data_ptr[0] + (data_ptr[1] << 8) + (data_ptr[2] << 16) +
+                      (data_ptr[3] << 24);
+            data_ptr += 4 + size;
+          }
         }
       }
     }
index 02dc4edfc770d997c5d78d83b3d1246f0f6f2b13..257ddb2c546bac80fd411b185bc3bc8e600828df 100644 (file)
@@ -1089,14 +1089,15 @@ static void write_modes_b(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc,
 }
 
 static void write_modes(VP9_COMP *cpi, vp9_writer* const bc,
-                        TOKENEXTRA **tok) {
+                        TOKENEXTRA **tok, TOKENEXTRA *tok_end) {
   VP9_COMMON *const c = &cpi->common;
   const int mis = c->mode_info_stride;
-  MODE_INFO *m, *m_ptr = c->mi + c->cur_tile_mb_col_start;
+  MODE_INFO *m, *m_ptr = c->mi;
   int i, mb_row, mb_col;
-  TOKENEXTRA *tok_end = *tok + cpi->tok_count;
 
-  for (mb_row = 0; mb_row < c->mb_rows; mb_row += 4, m_ptr += 4 * mis) {
+  m_ptr += c->cur_tile_mb_col_start + c->cur_tile_mb_row_start * mis;
+  for (mb_row = c->cur_tile_mb_row_start;
+       mb_row < c->cur_tile_mb_row_end; mb_row += 4, m_ptr += 4 * mis) {
     m = m_ptr;
     for (mb_col = c->cur_tile_mb_col_start;
          mb_col < c->cur_tile_mb_col_end; mb_col += 4, m += 4) {
@@ -2046,6 +2047,9 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
         break;
       }
     }
+    vp9_write_bit(&header_bc, pc->log2_tile_rows != 0);
+    if (pc->log2_tile_rows != 0)
+      vp9_write_bit(&header_bc, pc->log2_tile_rows != 1);
   }
 
   vp9_stop_encode(&header_bc);
@@ -2075,33 +2079,45 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
   }
 
   {
-    int tile, total_size = 0;
+    int tile_row, tile_col, total_size = 0;
     unsigned char *data_ptr = cx_data + header_bc.pos;
-    TOKENEXTRA *tok = cpi->tok;
-
-    for (tile = 0; tile < pc->tile_columns; tile++) {
-      pc->cur_tile_idx = tile;
-      vp9_get_tile_offsets(pc, &pc->cur_tile_mb_col_start,
-                           &pc->cur_tile_mb_col_end);
-
-      if (tile < pc->tile_columns - 1)
-        vp9_start_encode(&residual_bc, data_ptr + total_size + 4);
-      else
-        vp9_start_encode(&residual_bc, data_ptr + total_size);
-      write_modes(cpi, &residual_bc, &tok);
-      vp9_stop_encode(&residual_bc);
-      if (tile < pc->tile_columns - 1) {
-        /* size of this tile */
-        data_ptr[total_size + 0] = residual_bc.pos;
-        data_ptr[total_size + 1] = residual_bc.pos >> 8;
-        data_ptr[total_size + 2] = residual_bc.pos >> 16;
-        data_ptr[total_size + 3] = residual_bc.pos >> 24;
-        total_size += 4;
-      }
+    TOKENEXTRA *tok[1 << 6], *tok_end;
+
+    tok[0] = cpi->tok;
+    for (tile_col = 1; tile_col < pc->tile_columns; tile_col++)
+      tok[tile_col] = tok[tile_col - 1] + cpi->tok_count[tile_col - 1];
+
+    for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) {
+      vp9_get_tile_row_offsets(pc, tile_row);
+      tok_end = cpi->tok + cpi->tok_count[0];
+      for (tile_col = 0; tile_col < pc->tile_columns;
+           tile_col++, tok_end += cpi->tok_count[tile_col]) {
+        vp9_get_tile_col_offsets(pc, tile_col);
+
+        if (tile_col < pc->tile_columns - 1 || tile_row < pc->tile_rows - 1)
+          vp9_start_encode(&residual_bc, data_ptr + total_size + 4);
+        else
+          vp9_start_encode(&residual_bc, data_ptr + total_size);
+        write_modes(cpi, &residual_bc, &tok[tile_col], tok_end);
+        vp9_stop_encode(&residual_bc);
+        if (tile_col < pc->tile_columns - 1 || tile_row < pc->tile_rows - 1) {
+          /* size of this tile */
+          data_ptr[total_size + 0] = residual_bc.pos;
+          data_ptr[total_size + 1] = residual_bc.pos >> 8;
+          data_ptr[total_size + 2] = residual_bc.pos >> 16;
+          data_ptr[total_size + 3] = residual_bc.pos >> 24;
+          total_size += 4;
+        }
 
-      total_size += residual_bc.pos;
+        total_size += residual_bc.pos;
+      }
     }
 
+    assert((unsigned int)(tok[0] - cpi->tok) == cpi->tok_count[0]);
+    for (tile_col = 1; tile_col < pc->tile_columns; tile_col++)
+      assert((unsigned int)(tok[tile_col] - tok[tile_col - 1]) ==
+                  cpi->tok_count[tile_col]);
+
     *size += total_size;
   }
 }
index 96829449b57777705674814a9e457b609cc4b65d..fe33f2ebf37802dfe98ec41f504d77376da5e68f 100644 (file)
@@ -1231,8 +1231,6 @@ static void encode_frame_internal(VP9_COMP *cpi) {
   MACROBLOCK *const x = &cpi->mb;
   VP9_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &x->e_mbd;
-
-  TOKENEXTRA *tp = cpi->tok;
   int totalrate;
 
   // printf("encode_frame_internal frame %d (%d)\n",
@@ -1313,19 +1311,19 @@ static void encode_frame_internal(VP9_COMP *cpi) {
 
     {
       // Take tiles into account and give start/end MB
-      int tile;
+      int tile_col;
+      TOKENEXTRA *tp = cpi->tok;
+
+      for (tile_col = 0; tile_col < cm->tile_columns; tile_col++) {
+        TOKENEXTRA *tp_old = tp;
 
-      for (tile = 0; tile < cm->tile_columns; tile++) {
         // For each row of SBs in the frame
-        cm->cur_tile_idx = tile;
-        vp9_get_tile_offsets(cm, &cm->cur_tile_mb_col_start,
-                             &cm->cur_tile_mb_col_end);
+        vp9_get_tile_col_offsets(cm, tile_col);
         for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4) {
           encode_sb_row(cpi, mb_row, &tp, &totalrate);
         }
+        cpi->tok_count[tile_col] = (unsigned int)(tp - tp_old);
       }
-
-      cpi->tok_count = (unsigned int)(tp - cpi->tok);
     }
 
     vpx_usec_timer_mark(&emr_timer);
index b8993cf259f82713df35780f3a5a8080871d9cbf..3e5940f55fa1d8173eb891d214a63c22f0ea5409 100644 (file)
@@ -1105,9 +1105,13 @@ rescale(int val, int num, int denom) {
   return (int)(llval * llnum / llden);
 }
 
-static void set_tile_limits(VP9_COMMON *cm) {
+static void set_tile_limits(VP9_COMP *cpi) {
+  VP9_COMMON *const cm = &cpi->common;
   int min_log2_tiles, max_log2_tiles;
 
+  cm->log2_tile_columns = cpi->oxcf.tile_columns;
+  cm->log2_tile_rows = cpi->oxcf.tile_rows;
+
   vp9_get_tile_n_bits(cm, &min_log2_tiles, &max_log2_tiles);
   max_log2_tiles += min_log2_tiles;
   if (cm->log2_tile_columns < min_log2_tiles)
@@ -1115,6 +1119,7 @@ static void set_tile_limits(VP9_COMMON *cm) {
   else if (cm->log2_tile_columns > max_log2_tiles)
     cm->log2_tile_columns = max_log2_tiles;
   cm->tile_columns = 1 << cm->log2_tile_columns;
+  cm->tile_rows = 1 << cm->log2_tile_rows;
 }
 
 static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
@@ -1154,8 +1159,7 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
   cpi->gld_fb_idx = 1;
   cpi->alt_fb_idx = 2;
 
-  cm->log2_tile_columns = cpi->oxcf.tile_columns;
-  set_tile_limits(cm);
+  set_tile_limits(cpi);
 
 #if VP9_TEMPORAL_ALT_REF
   {
@@ -1382,8 +1386,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
   cpi->last_frame_distortion = 0;
 #endif
 
-  cm->log2_tile_columns = cpi->oxcf.tile_columns;
-  set_tile_limits(cm);
+  set_tile_limits(cpi);
 }
 
 #define M_LOG2_E 0.693147180559945309417
index 7acaef472edfa3527b8fa16520d690f5fc9f138e..1476de4daf062f7aa24792e21b5cd8eb4793fe91 100644 (file)
@@ -347,7 +347,7 @@ typedef struct VP9_COMP {
   YV12_BUFFER_CONFIG last_frame_uf;
 
   TOKENEXTRA *tok;
-  unsigned int tok_count;
+  unsigned int tok_count[1 << 6];
 
 
   unsigned int frames_since_key;
index 710ca7ea049d40e681403f7b85ba516dbfab4a90..b125a486e8c9e75445ab5b63be8ee3d191b849aa 100644 (file)
@@ -255,7 +255,7 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
   int t_pred_cost = INT_MAX;
 
   int i;
-  int tile, mb_row, mb_col;
+  int tile_col, mb_row, mb_col;
 
   int temporal_predictor_count[PREDICTION_PROBS][2];
   int no_pred_segcounts[MAX_MB_SEGMENTS];
@@ -283,10 +283,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
   // First of all generate stats regarding how well the last segment map
   // predicts this one
 
-  for (tile = 0; tile < cm->tile_columns; tile++) {
-    cm->cur_tile_idx = tile;
-    vp9_get_tile_offsets(cm, &cm->cur_tile_mb_col_start,
-                         &cm->cur_tile_mb_col_end);
+  for (tile_col = 0; tile_col < cm->tile_columns; tile_col++) {
+    vp9_get_tile_col_offsets(cm, tile_col);
     mi_ptr = cm->mi + cm->cur_tile_mb_col_start;
     for (mb_row = 0; mb_row < cm->mb_rows; mb_row += 4, mi_ptr += 4 * mis) {
       mi = mi_ptr;
index 80320c44a0d7e5aa831ca2427e458b6aeaa07a6e..81f02ee6bbd361f48c4315bc81dc52626d2e9e5e 100644 (file)
@@ -27,6 +27,7 @@ struct vp8_extracfg {
   unsigned int                Sharpness;
   unsigned int                static_thresh;
   unsigned int                tile_columns;
+  unsigned int                tile_rows;
   unsigned int                arnr_max_frames;    /* alt_ref Noise Reduction Max Frame Count */
   unsigned int                arnr_strength;    /* alt_ref Noise Reduction Strength */
   unsigned int                arnr_type;        /* alt_ref filter type */
@@ -55,6 +56,7 @@ static const struct extraconfig_map extracfg_map[] = {
       0,                          /* Sharpness */
       0,                          /* static_thresh */
       0,                          /* tile_columns */
+      0,                          /* tile_rows */
       0,                          /* arnr_max_frames */
       3,                          /* arnr_strength */
       3,                          /* arnr_type*/
@@ -172,6 +174,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t      *ctx,
   RANGE_CHECK_HI(vp8_cfg, noise_sensitivity,  6);
 
   RANGE_CHECK(vp8_cfg, tile_columns, 0, 6);
+  RANGE_CHECK(vp8_cfg, tile_rows, 0, 2);
   RANGE_CHECK_HI(vp8_cfg, Sharpness,       7);
   RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15);
   RANGE_CHECK_HI(vp8_cfg, arnr_strength,   6);
@@ -309,6 +312,7 @@ static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
   oxcf->tuning = vp8_cfg.tuning;
 
   oxcf->tile_columns = vp8_cfg.tile_columns;
+  oxcf->tile_rows = vp8_cfg.tile_rows;
 
 #if CONFIG_LOSSLESS
   oxcf->lossless = vp8_cfg.lossless;
@@ -416,6 +420,7 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
       MAP(VP8E_SET_SHARPNESS,             xcfg.Sharpness);
       MAP(VP8E_SET_STATIC_THRESHOLD,      xcfg.static_thresh);
       MAP(VP9E_SET_TILE_COLUMNS,          xcfg.tile_columns);
+      MAP(VP9E_SET_TILE_ROWS,             xcfg.tile_rows);
 
       MAP(VP8E_SET_ARNR_MAXFRAMES,        xcfg.arnr_max_frames);
       MAP(VP8E_SET_ARNR_STRENGTH,        xcfg.arnr_strength);
@@ -1006,6 +1011,7 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = {
   {VP8E_SET_SHARPNESS,                set_param},
   {VP8E_SET_STATIC_THRESHOLD,         set_param},
   {VP9E_SET_TILE_COLUMNS,             set_param},
+  {VP9E_SET_TILE_ROWS,                set_param},
   {VP8E_GET_LAST_QUANTIZER,           get_param},
   {VP8E_GET_LAST_QUANTIZER_64,        get_param},
   {VP8E_SET_ARNR_MAXFRAMES,           set_param},
index d483c47cc48277f060bf49da18ae2f51d151b240..0b910b99df5f17bc622263a9c9497ef92540034d 100644 (file)
@@ -188,7 +188,8 @@ enum vp8e_enc_control_id {
 
   /* TODO(jkoleszar): Move to vp9cx.h */
   VP9E_SET_LOSSLESS,
-  VP9E_SET_TILE_COLUMNS
+  VP9E_SET_TILE_COLUMNS,
+  VP9E_SET_TILE_ROWS,
 };
 
 /*!\brief vpx 1-D scaling mode
@@ -300,6 +301,7 @@ VPX_CTRL_USE_TYPE(VP8E_SET_TUNING,             int) /* vp8e_tuning */
 VPX_CTRL_USE_TYPE(VP8E_SET_CQ_LEVEL,      unsigned int)
 
 VPX_CTRL_USE_TYPE(VP9E_SET_TILE_COLUMNS,  int)
+VPX_CTRL_USE_TYPE(VP9E_SET_TILE_ROWS,  int)
 
 VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER,     int *)
 VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64,  int *)
index 10a6063301821730dcefc1631c8d82d31eb1bc86..ee2312e01ea56fbe4710a58e0419938a0820534c 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1084,6 +1084,8 @@ static const arg_def_t token_parts = ARG_DEF(NULL, "token-parts", 1,
                                      "Number of token partitions to use, log2");
 static const arg_def_t tile_cols = ARG_DEF(NULL, "tile-columns", 1,
                                          "Number of tile columns to use, log2");
+static const arg_def_t tile_rows = ARG_DEF(NULL, "tile-rows", 1,
+                                           "Number of tile rows to use, log2");
 static const arg_def_t auto_altref = ARG_DEF(NULL, "auto-alt-ref", 1,
                                              "Enable automatic alt reference frames");
 static const arg_def_t arnr_maxframes = ARG_DEF(NULL, "arnr-maxframes", 1,
@@ -1127,7 +1129,7 @@ static const int vp8_arg_ctrl_map[] = {
 #if CONFIG_VP9_ENCODER
 static const arg_def_t *vp9_args[] = {
   &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh,
-  &tile_cols, &arnr_maxframes, &arnr_strength, &arnr_type,
+  &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type,
   &tune_ssim, &cq_level, &max_intra_rate_pct,
 #if CONFIG_LOSSLESS
   &lossless,
@@ -1137,7 +1139,7 @@ static const arg_def_t *vp9_args[] = {
 static const int vp9_arg_ctrl_map[] = {
   VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF,
   VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD,
-  VP9E_SET_TILE_COLUMNS,
+  VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS,
   VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE,
   VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT,
 #if CONFIG_LOSSLESS