summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r--vp9/encoder/vp9_encodeframe.c583
1 files changed, 246 insertions, 337 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 87fcd35ce..feaf7043a 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -48,33 +48,9 @@
#define SPLIT_MV_ZBIN_BOOST 0
#define INTRA_ZBIN_BOOST 0
-static INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) {
- switch (subsize) {
- case BLOCK_64X64:
- case BLOCK_64X32:
- case BLOCK_32X64:
- case BLOCK_32X32:
- return &x->sb_index;
- case BLOCK_32X16:
- case BLOCK_16X32:
- case BLOCK_16X16:
- return &x->mb_index;
- case BLOCK_16X8:
- case BLOCK_8X16:
- case BLOCK_8X8:
- return &x->b_index;
- case BLOCK_8X4:
- case BLOCK_4X8:
- case BLOCK_4X4:
- return &x->ab_index;
- default:
- assert(0);
- return NULL;
- }
-}
-
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
- int mi_row, int mi_col, BLOCK_SIZE bsize);
+ int mi_row, int mi_col, BLOCK_SIZE bsize,
+ PICK_MODE_CONTEXT *ctx);
// Motion vector component magnitude threshold for defining fast motion.
#define FAST_MOTION_MV_THRESH 24
@@ -743,7 +719,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, int mi_col,
int *totalrate, int64_t *totaldist,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
- int64_t best_rd) {
+ int64_t best_rd, int block) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -760,10 +736,13 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
// Use the lower precision, but faster, 32x32 fdct for mode selection.
x->use_lp32x32fdct = 1;
+ // TODO(JBB): Most other places in the code instead of calling the function
+ // and then checking if its not the first 8x8 we put the check in the
+ // calling function. Do that here.
if (bsize < BLOCK_8X8) {
// When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
// there is nothing to be done.
- if (x->ab_index != 0) {
+ if (block != 0) {
*totalrate = 0;
*totaldist = 0;
return;
@@ -886,22 +865,6 @@ static void update_stats(VP9_COMP *cpi) {
}
}
-static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
- switch (bsize) {
- case BLOCK_64X64:
- return &x->sb64_partitioning;
- case BLOCK_32X32:
- return &x->sb_partitioning[x->sb_index];
- case BLOCK_16X16:
- return &x->mb_partitioning[x->sb_index][x->mb_index];
- case BLOCK_8X8:
- return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
- default:
- assert(0);
- return NULL;
- }
-}
-
static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
@@ -967,19 +930,12 @@ static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row, int mi_col,
- int output_enabled, BLOCK_SIZE bsize) {
- MACROBLOCK *const x = &cpi->mb;
+ int output_enabled, BLOCK_SIZE bsize,
+ PICK_MODE_CONTEXT *ctx) {
- if (bsize < BLOCK_8X8) {
- // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
- // there is nothing to be done.
- if (x->ab_index > 0)
- return;
- }
set_offsets(cpi, tile, mi_row, mi_col, bsize);
- update_state(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize,
- output_enabled);
- encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
+ update_state(cpi, ctx, mi_row, mi_col, bsize, output_enabled);
+ encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize, ctx);
if (output_enabled) {
update_stats(cpi);
@@ -991,7 +947,8 @@ static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row, int mi_col,
- int output_enabled, BLOCK_SIZE bsize) {
+ int output_enabled, BLOCK_SIZE bsize,
+ PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -999,61 +956,58 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
int ctx;
PARTITION_TYPE partition;
- BLOCK_SIZE subsize;
+ BLOCK_SIZE subsize = bsize;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
if (bsize >= BLOCK_8X8) {
ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
- subsize = *get_sb_partitioning(x, bsize);
+ subsize = get_subsize(bsize, pc_tree->partitioning);
} else {
ctx = 0;
subsize = BLOCK_4X4;
}
partition = partition_lookup[bsl][subsize];
+ if (output_enabled && bsize != BLOCK_4X4)
+ cm->counts.partition[ctx][partition]++;
switch (partition) {
case PARTITION_NONE:
- if (output_enabled && bsize >= BLOCK_8X8)
- cm->counts.partition[ctx][PARTITION_NONE]++;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->none);
break;
case PARTITION_VERT:
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_VERT]++;
- *get_sb_index(x, subsize) = 0;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- if (mi_col + hbs < cm->mi_cols) {
- *get_sb_index(x, subsize) = 1;
- encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->vertical[0]);
+ if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
+ encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize,
+ &pc_tree->vertical[1]);
}
break;
case PARTITION_HORZ:
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_HORZ]++;
- *get_sb_index(x, subsize) = 0;
- encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- if (mi_row + hbs < cm->mi_rows) {
- *get_sb_index(x, subsize) = 1;
- encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->horizontal[0]);
+ if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
+ encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize,
+ &pc_tree->horizontal[1]);
}
break;
case PARTITION_SPLIT:
- subsize = get_subsize(bsize, PARTITION_SPLIT);
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_SPLIT]++;
-
- *get_sb_index(x, subsize) = 0;
- encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- *get_sb_index(x, subsize) = 1;
- encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
- *get_sb_index(x, subsize) = 2;
- encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
- *get_sb_index(x, subsize) = 3;
- encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
- subsize);
+ if (bsize == BLOCK_8X8) {
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ pc_tree->leaf_split[0]);
+ } else {
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ pc_tree->split[0]);
+ encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize,
+ pc_tree->split[1]);
+ encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize,
+ pc_tree->split[2]);
+ encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
+ subsize, pc_tree->split[3]);
+ }
break;
default:
assert("Invalid partition type.");
@@ -1406,20 +1360,14 @@ static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row, int mi_col,
- int output_enabled, BLOCK_SIZE bsize) {
- MACROBLOCK *const x = &cpi->mb;
+ int output_enabled, BLOCK_SIZE bsize,
+ PICK_MODE_CONTEXT *ctx) {
- if (bsize < BLOCK_8X8) {
- // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
- // there is nothing to be done.
- if (x->ab_index > 0)
- return;
- }
set_offsets(cpi, tile, mi_row, mi_col, bsize);
- update_state_rt(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize);
+ update_state_rt(cpi, ctx, mi_row, mi_col, bsize);
- encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
+ encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize, ctx);
update_stats(cpi);
(*tp)->token = EOSB_TOKEN;
@@ -1428,7 +1376,8 @@ static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row, int mi_col,
- int output_enabled, BLOCK_SIZE bsize) {
+ int output_enabled, BLOCK_SIZE bsize,
+ PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -1453,51 +1402,40 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
}
partition = partition_lookup[bsl][subsize];
+ if (output_enabled && bsize != BLOCK_4X4)
+ cm->counts.partition[ctx][partition]++;
switch (partition) {
case PARTITION_NONE:
- if (output_enabled && bsize >= BLOCK_8X8)
- cm->counts.partition[ctx][PARTITION_NONE]++;
- encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
+ encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->none);
break;
case PARTITION_VERT:
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_VERT]++;
- *get_sb_index(x, subsize) = 0;
- encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- if (mi_col + hbs < cm->mi_cols) {
- *get_sb_index(x, subsize) = 1;
+ encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->vertical[0]);
+ if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
encode_b_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
- subsize);
+ subsize, &pc_tree->vertical[1]);
}
break;
case PARTITION_HORZ:
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_HORZ]++;
- *get_sb_index(x, subsize) = 0;
- encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- if (mi_row + hbs < cm->mi_rows) {
- *get_sb_index(x, subsize) = 1;
+ encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ &pc_tree->horizontal[0]);
+ if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
encode_b_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
- subsize);
+ subsize, &pc_tree->horizontal[1]);
}
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
- if (output_enabled)
- cm->counts.partition[ctx][PARTITION_SPLIT]++;
-
- *get_sb_index(x, subsize) = 0;
- encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
- *get_sb_index(x, subsize) = 1;
+ encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize,
+ pc_tree->split[0]);
encode_sb_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
- subsize);
- *get_sb_index(x, subsize) = 2;
+ subsize, pc_tree->split[1]);
encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
- subsize);
- *get_sb_index(x, subsize) = 3;
+ subsize, pc_tree->split[2]);
encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
- subsize);
+ subsize, pc_tree->split[3]);
break;
default:
assert("Invalid partition type.");
@@ -1512,7 +1450,8 @@ static void rd_use_partition(VP9_COMP *cpi,
MODE_INFO **mi_8x8,
TOKENEXTRA **tp, int mi_row, int mi_col,
BLOCK_SIZE bsize, int *rate, int64_t *dist,
- int do_recon) {
+ int do_recon, PC_TREE *pc_tree,
+ int block) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -1538,6 +1477,7 @@ static void rd_use_partition(VP9_COMP *cpi,
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
int do_partition_search = 1;
+ PICK_MODE_CONTEXT *ctx = &pc_tree->none;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -1548,17 +1488,7 @@ static void rd_use_partition(VP9_COMP *cpi,
partition = partition_lookup[bsl][bs_type];
subsize = get_subsize(bsize, partition);
- if (bsize < BLOCK_8X8) {
- // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
- // there is nothing to be done.
- if (x->ab_index != 0) {
- *rate = 0;
- *dist = 0;
- return;
- }
- } else {
- *(get_sb_partitioning(x, bsize)) = subsize;
- }
+ pc_tree->partitioning = partition;
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
if (bsize == BLOCK_16X16) {
@@ -1572,7 +1502,7 @@ static void rd_use_partition(VP9_COMP *cpi,
do_partition_search = 0;
if (mi_row + (mi_step >> 1) < cm->mi_rows &&
mi_col + (mi_step >> 1) < cm->mi_cols) {
- *(get_sb_partitioning(x, bsize)) = bsize;
+ pc_tree->partitioning = PARTITION_NONE;
bs_type = mi_8x8[0]->mbmi.sb_type = bsize;
subsize = bsize;
partition = PARTITION_NONE;
@@ -1599,9 +1529,9 @@ static void rd_use_partition(VP9_COMP *cpi,
if (partition != PARTITION_NONE && !splits_below &&
mi_row + (mi_step >> 1) < cm->mi_rows &&
mi_col + (mi_step >> 1) < cm->mi_cols) {
- *(get_sb_partitioning(x, bsize)) = bsize;
+ pc_tree->partitioning = PARTITION_NONE;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
- get_block_context(x, bsize), INT64_MAX);
+ ctx, INT64_MAX, 0);
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
@@ -1612,31 +1542,28 @@ static void rd_use_partition(VP9_COMP *cpi,
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
mi_8x8[0]->mbmi.sb_type = bs_type;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = partition;
}
}
switch (partition) {
case PARTITION_NONE:
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, bsize,
- get_block_context(x, bsize), INT64_MAX);
+ &last_part_dist, bsize, ctx, INT64_MAX, 0);
break;
case PARTITION_HORZ:
- *get_sb_index(x, subsize) = 0;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, subsize,
- get_block_context(x, subsize), INT64_MAX);
+ &last_part_dist, subsize, &pc_tree->horizontal[0],
+ INT64_MAX, 0);
if (last_part_rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
int rt = 0;
int64_t dt = 0;
- update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
- subsize, 0);
- encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
- *get_sb_index(x, subsize) = 1;
+ PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
+ update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
- subsize, get_block_context(x, subsize), INT64_MAX);
+ subsize, &pc_tree->horizontal[1], INT64_MAX, 1);
if (rt == INT_MAX || dt == INT64_MAX) {
last_part_rate = INT_MAX;
last_part_dist = INT64_MAX;
@@ -1648,20 +1575,19 @@ static void rd_use_partition(VP9_COMP *cpi,
}
break;
case PARTITION_VERT:
- *get_sb_index(x, subsize) = 0;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, subsize,
- get_block_context(x, subsize), INT64_MAX);
+ &last_part_dist, subsize, &pc_tree->vertical[0],
+ INT64_MAX, 0);
if (last_part_rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
int rt = 0;
int64_t dt = 0;
- update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
- subsize, 0);
- encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
- *get_sb_index(x, subsize) = 1;
+ PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
+ update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
- subsize, get_block_context(x, subsize), INT64_MAX);
+ subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
+ INT64_MAX, 1);
if (rt == INT_MAX || dt == INT64_MAX) {
last_part_rate = INT_MAX;
last_part_dist = INT64_MAX;
@@ -1672,7 +1598,12 @@ static void rd_use_partition(VP9_COMP *cpi,
}
break;
case PARTITION_SPLIT:
- // Split partition.
+ if (bsize == BLOCK_8X8) {
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
+ &last_part_dist, subsize, pc_tree->leaf_split[0],
+ INT64_MAX, 0);
+ break;
+ }
last_part_rate = 0;
last_part_dist = 0;
for (i = 0; i < 4; i++) {
@@ -1685,11 +1616,9 @@ static void rd_use_partition(VP9_COMP *cpi,
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
- *get_sb_index(x, subsize) = i;
-
rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt,
- i != 3);
+ i != 3, pc_tree->split[i], i);
if (rt == INT_MAX || dt == INT64_MAX) {
last_part_rate = INT_MAX;
last_part_dist = INT64_MAX;
@@ -1721,6 +1650,7 @@ static void rd_use_partition(VP9_COMP *cpi,
chosen_rate = 0;
chosen_dist = 0;
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+ pc_tree->partitioning = PARTITION_SPLIT;
// Split partition.
for (i = 0; i < 4; i++) {
@@ -1734,15 +1664,11 @@ static void rd_use_partition(VP9_COMP *cpi,
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
- *get_sb_index(x, split_subsize) = i;
- *get_sb_partitioning(x, bsize) = split_subsize;
- *get_sb_partitioning(x, split_subsize) = split_subsize;
-
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
-
+ pc_tree->split[i]->partitioning = PARTITION_NONE;
rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
- split_subsize, get_block_context(x, split_subsize),
- INT64_MAX);
+ split_subsize, &pc_tree->split[i]->none,
+ INT64_MAX, i);
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -1757,7 +1683,7 @@ static void rd_use_partition(VP9_COMP *cpi,
if (i != 3)
encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
- split_subsize);
+ split_subsize, pc_tree->split[i]);
pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
split_subsize);
@@ -1770,19 +1696,19 @@ static void rd_use_partition(VP9_COMP *cpi,
}
}
- // If last_part is better set the partitioning to that...
+ // If last_part is better set the partitioning to that.
if (last_part_rd < chosen_rd) {
mi_8x8[0]->mbmi.sb_type = bsize;
if (bsize >= BLOCK_8X8)
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = partition;
chosen_rate = last_part_rate;
chosen_dist = last_part_dist;
chosen_rd = last_part_rd;
}
- // If none was better set the partitioning to that...
+ // If none was better set the partitioning to that.
if (none_rd < chosen_rd) {
if (bsize >= BLOCK_8X8)
- *(get_sb_partitioning(x, bsize)) = bsize;
+ pc_tree->partitioning = PARTITION_NONE;
chosen_rate = none_rate;
chosen_dist = none_dist;
}
@@ -1808,8 +1734,8 @@ static void rd_use_partition(VP9_COMP *cpi,
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
chosen_rate, chosen_dist);
-
- encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize,
+ pc_tree);
}
*rate = chosen_rate;
@@ -1953,7 +1879,8 @@ static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row,
int mi_col, BLOCK_SIZE bsize, int *rate,
- int64_t *dist, int do_recon, int64_t best_rd) {
+ int64_t *dist, int do_recon, int64_t best_rd,
+ PC_TREE *pc_tree, int block) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -1961,7 +1888,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
TOKENEXTRA *tp_orig = *tp;
- PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
+ PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i, pl;
BLOCK_SIZE subsize;
int this_rate, sum_rate = 0, best_rate = INT_MAX;
@@ -1982,15 +1909,6 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
bsize >= BLOCK_8X8;
(void) *tp_orig;
- if (bsize < BLOCK_8X8) {
- // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
- // there is nothing to be done.
- if (x->ab_index != 0) {
- *rate = 0;
- *dist = 0;
- return;
- }
- }
assert(num_8x8_blocks_wide_lookup[bsize] ==
num_8x8_blocks_high_lookup[bsize]);
@@ -2000,7 +1918,6 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
} else {
x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
}
-
// Determine partition types in search according to the speed features.
// The threshold set here has to be of square block size.
if (cpi->sf.auto_min_max_partition_size) {
@@ -2037,7 +1954,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// PARTITION_NONE
if (partition_none_allowed) {
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize,
- ctx, best_rd);
+ ctx, best_rd, 0);
if (this_rate != INT_MAX) {
if (bsize >= BLOCK_8X8) {
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
@@ -2052,7 +1969,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_dist = this_dist;
best_rd = sum_rd;
if (bsize >= BLOCK_8X8)
- *(get_sb_partitioning(x, bsize)) = bsize;
+ pc_tree->partitioning = PARTITION_NONE;
// Adjust threshold according to partition size.
stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
@@ -2084,29 +2001,47 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// the starting point of motion search in the following partition type check.
if (do_split) {
subsize = get_subsize(bsize, PARTITION_SPLIT);
- for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
- const int x_idx = (i & 1) * mi_step;
- const int y_idx = (i >> 1) * mi_step;
-
- if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
- continue;
-
- *get_sb_index(x, subsize) = i;
- if (cpi->sf.adaptive_motion_search)
- load_pred_mv(x, ctx);
- if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
- partition_none_allowed)
- get_block_context(x, subsize)->pred_interp_filter =
+ if (bsize == BLOCK_8X8) {
+ i = 4;
+ if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
+ pc_tree->leaf_split[0]->pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize,
- &this_rate, &this_dist, i != 3, best_rd - sum_rd);
- if (this_rate == INT_MAX) {
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
+ pc_tree->leaf_split[0], best_rd, 0);
+
+ if (sum_rate == INT_MAX) {
sum_rd = INT64_MAX;
} else {
- sum_rate += this_rate;
- sum_dist += this_dist;
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ if (sum_rd < best_rd) {
+ update_state(cpi, ctx, mi_row, mi_col, bsize, 0);
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
+ update_partition_context(xd, mi_row, mi_col, subsize, bsize);
+ }
+ }
+ } else {
+ for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
+ const int x_idx = (i & 1) * mi_step;
+ const int y_idx = (i >> 1) * mi_step;
+
+ if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
+ continue;
+
+ if (cpi->sf.adaptive_motion_search)
+ load_pred_mv(x, ctx);
+
+ rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
+ subsize, &this_rate, &this_dist, i != 3,
+ best_rd - sum_rd, pc_tree->split[i], i);
+
+ if (this_rate == INT_MAX) {
+ sum_rd = INT64_MAX;
+ } else {
+ sum_rate += this_rate;
+ sum_dist += this_dist;
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ }
}
}
if (sum_rd < best_rd && i == 4) {
@@ -2117,7 +2052,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rate = sum_rate;
best_dist = sum_dist;
best_rd = sum_rd;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_SPLIT;
}
} else {
// skip rectangular partition test when larger block size
@@ -2127,36 +2062,33 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
}
-
// PARTITION_HORZ
if (partition_horz_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_HORZ);
- *get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
- get_block_context(x, subsize)->pred_interp_filter =
+ pc_tree->horizontal[0].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
- get_block_context(x, subsize), best_rd);
+ &pc_tree->horizontal[0], best_rd, 0);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows) {
- update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
- subsize, 0);
- encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
+ PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
+ update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
- *get_sb_index(x, subsize) = 1;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
- get_block_context(x, subsize)->pred_interp_filter =
+ pc_tree->horizontal[1].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate,
- &this_dist, subsize, get_block_context(x, subsize),
- best_rd - sum_rd);
+ &this_dist, subsize, &pc_tree->horizontal[1],
+ best_rd - sum_rd, 1);
if (this_rate == INT_MAX) {
sum_rd = INT64_MAX;
} else {
@@ -2173,41 +2105,39 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rd = sum_rd;
best_rate = sum_rate;
best_dist = sum_dist;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_HORZ;
}
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
}
-
// PARTITION_VERT
if (partition_vert_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_VERT);
- *get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
- get_block_context(x, subsize)->pred_interp_filter =
+ pc_tree->vertical[0].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
- get_block_context(x, subsize), best_rd);
+ &pc_tree->vertical[0], best_rd, 0);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols) {
- update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
- subsize, 0);
- encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
+ update_state(cpi, &pc_tree->vertical[0], mi_row, mi_col, subsize, 0);
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize,
+ &pc_tree->vertical[0]);
- *get_sb_index(x, subsize) = 1;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
- get_block_context(x, subsize)->pred_interp_filter =
+ pc_tree->vertical[bsize > BLOCK_8X8].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate,
- &this_dist, subsize, get_block_context(x, subsize),
- best_rd - sum_rd);
+ &this_dist, subsize,
+ &pc_tree->vertical[bsize > BLOCK_8X8], best_rd - sum_rd,
+ 1);
if (this_rate == INT_MAX) {
sum_rd = INT64_MAX;
} else {
@@ -2224,12 +2154,11 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rate = sum_rate;
best_dist = sum_dist;
best_rd = sum_rd;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_VERT;
}
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
}
-
// TODO(jbb): This code added so that we avoid static analysis
// warning related to the fact that best_rd isn't used after this
// point. This code should be refactored so that the duplicate
@@ -2248,12 +2177,14 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
best_rate);
}
-
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
best_rate, best_dist);
+ if (bsize == BLOCK_4X4)
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, ctx);
+ else
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
- encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
}
if (bsize == BLOCK_64X64) {
assert(tp_orig < *tp);
@@ -2281,18 +2212,18 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int dummy_rate;
int64_t dummy_dist;
- BLOCK_SIZE i;
+ int i;
MACROBLOCK *x = &cpi->mb;
if (sf->adaptive_pred_interp_filter) {
- for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) {
- const int num_4x4_w = num_4x4_blocks_wide_lookup[i];
- const int num_4x4_h = num_4x4_blocks_high_lookup[i];
- const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h);
- for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index)
- for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index)
- for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index)
- get_block_context(x, i)->pred_interp_filter = SWITCHABLE;
+ for (i = 0; i < 64; ++i)
+ x->leaf_tree[i].pred_interp_filter = SWITCHABLE;
+
+ for (i = 0; i < 64; ++i) {
+ x->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
+ x->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
+ x->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
+ x->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
}
}
@@ -2312,18 +2243,18 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
sf->always_this_block_size);
rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1);
+ &dummy_rate, &dummy_dist, 1, x->pc_root, 0);
} else if (sf->partition_search_type == VAR_BASED_FIXED_PARTITION) {
BLOCK_SIZE bsize;
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1);
+ &dummy_rate, &dummy_dist, 1, x->pc_root, 0);
} else if (sf->partition_search_type == VAR_BASED_PARTITION) {
choose_partitioning(cpi, tile, mi_row, mi_col);
rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1);
+ &dummy_rate, &dummy_dist, 1, x->pc_root, 0);
} else {
if ((cm->current_video_frame
% sf->last_partitioning_redo_frequency) == 0
@@ -2342,7 +2273,8 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
&sf->max_partition_size);
}
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1, INT64_MAX);
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root,
+ 0);
} else {
if (sf->constrain_copy_partition &&
sb_has_motion(cm, prev_mi_8x8))
@@ -2351,7 +2283,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
else
copy_partitioning(cm, mi_8x8, prev_mi_8x8);
rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1);
+ &dummy_rate, &dummy_dist, 1, x->pc_root, 0);
}
}
} else {
@@ -2363,7 +2295,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
&sf->max_partition_size);
}
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1, INT64_MAX);
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root, 0);
}
}
}
@@ -2517,10 +2449,11 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
int mi_row, int mi_col,
- BLOCK_SIZE bsize, BLOCK_SIZE subsize) {
+ BLOCK_SIZE bsize, BLOCK_SIZE subsize,
+ PC_TREE *pc_tree) {
MACROBLOCKD *xd = &x->e_mbd;
int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
- PARTITION_TYPE partition = partition_lookup[bsl][subsize];
+ PARTITION_TYPE partition = pc_tree->partitioning;
assert(bsize >= BLOCK_8X8);
@@ -2530,48 +2463,42 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
switch (partition) {
case PARTITION_NONE:
set_modeinfo_offsets(cm, xd, mi_row, mi_col);
- *(xd->mi[0]) = get_block_context(x, subsize)->mic;
+ *(xd->mi[0]) = pc_tree->none.mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
break;
case PARTITION_VERT:
- *get_sb_index(x, subsize) = 0;
set_modeinfo_offsets(cm, xd, mi_row, mi_col);
- *(xd->mi[0]) = get_block_context(x, subsize)->mic;
+ *(xd->mi[0]) = pc_tree->vertical[0].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
if (mi_col + hbs < cm->mi_cols) {
- *get_sb_index(x, subsize) = 1;
set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs);
- *(xd->mi[0]) = get_block_context(x, subsize)->mic;
+ *(xd->mi[0]) = pc_tree->vertical[1].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize);
}
break;
case PARTITION_HORZ:
- *get_sb_index(x, subsize) = 0;
set_modeinfo_offsets(cm, xd, mi_row, mi_col);
- *(xd->mi[0]) = get_block_context(x, subsize)->mic;
+ *(xd->mi[0]) = pc_tree->horizontal[0].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
if (mi_row + hbs < cm->mi_rows) {
- *get_sb_index(x, subsize) = 1;
set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col);
- *(xd->mi[0]) = get_block_context(x, subsize)->mic;
+ *(xd->mi[0]) = pc_tree->horizontal[1].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
}
break;
- case PARTITION_SPLIT:
- *get_sb_index(x, subsize) = 0;
+ case PARTITION_SPLIT: {
+ BLOCK_SIZE subsubsize = get_subsize(subsize, PARTITION_SPLIT);
fill_mode_info_sb(cm, x, mi_row, mi_col, subsize,
- *(get_sb_partitioning(x, subsize)));
- *get_sb_index(x, subsize) = 1;
+ subsubsize, pc_tree->split[0]);
fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
- *(get_sb_partitioning(x, subsize)));
- *get_sb_index(x, subsize) = 2;
+ subsubsize, pc_tree->split[1]);
fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
- *(get_sb_partitioning(x, subsize)));
- *get_sb_index(x, subsize) = 3;
+ subsubsize, pc_tree->split[2]);
fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
- *(get_sb_partitioning(x, subsize)));
+ subsubsize, pc_tree->split[3]);
break;
+ }
default:
break;
}
@@ -2580,15 +2507,16 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
TOKENEXTRA **tp, int mi_row,
int mi_col, BLOCK_SIZE bsize, int *rate,
- int64_t *dist, int do_recon, int64_t best_rd) {
+ int64_t *dist, int do_recon, int64_t best_rd,
+ PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
TOKENEXTRA *tp_orig = *tp;
- PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
+ PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i;
- BLOCK_SIZE subsize;
+ BLOCK_SIZE subsize = bsize;
int this_rate, sum_rate = 0, best_rate = INT_MAX;
int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
int64_t sum_rd = 0;
@@ -2607,16 +2535,6 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
bsize >= BLOCK_8X8;
(void) *tp_orig;
- if (bsize < BLOCK_8X8) {
- // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
- // there is nothing to be done.
- if (x->ab_index != 0) {
- *rate = 0;
- *dist = 0;
- return;
- }
- }
-
assert(num_8x8_blocks_wide_lookup[bsize] ==
num_8x8_blocks_high_lookup[bsize]);
@@ -2661,7 +2579,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_dist = this_dist;
best_rd = sum_rd;
if (bsize >= BLOCK_8X8)
- *(get_sb_partitioning(x, bsize)) = bsize;
+ pc_tree->partitioning = PARTITION_NONE;
// Adjust threshold according to partition size.
stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
@@ -2698,12 +2616,11 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
continue;
- *get_sb_index(x, subsize) = i;
load_pred_mv(x, ctx);
nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
subsize, &this_rate, &this_dist, 0,
- best_rd - sum_rd);
+ best_rd - sum_rd, pc_tree->split[i]);
if (this_rate == INT_MAX) {
sum_rd = INT64_MAX;
@@ -2718,7 +2635,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rate = sum_rate;
best_dist = sum_dist;
best_rd = sum_rd;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_SPLIT;
} else {
// skip rectangular partition test when larger block size
// gives better rd cost
@@ -2730,26 +2647,22 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// PARTITION_HORZ
if (partition_horz_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_HORZ);
- *get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
&this_rate, &this_dist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->horizontal[0].mic.mbmi = xd->mi[0]->mbmi;
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
- *get_sb_index(x, subsize) = 1;
-
load_pred_mv(x, ctx);
-
nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
&this_rate, &this_dist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->horizontal[1].mic.mbmi = xd->mi[0]->mbmi;
if (this_rate == INT_MAX) {
sum_rd = INT64_MAX;
@@ -2765,7 +2678,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rd = sum_rd;
best_rate = sum_rate;
best_dist = sum_dist;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_HORZ;
}
}
@@ -2773,24 +2686,18 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (partition_vert_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_VERT);
- *get_sb_index(x, subsize) = 0;
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
&this_rate, &this_dist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->vertical[0].mic.mbmi = xd->mi[0]->mbmi;
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
- *get_sb_index(x, subsize) = 1;
-
load_pred_mv(x, ctx);
-
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
&this_rate, &this_dist, subsize);
-
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
-
+ pc_tree->vertical[1].mic.mbmi = xd->mi[0]->mbmi;
if (this_rate == INT_MAX) {
sum_rd = INT64_MAX;
} else {
@@ -2805,9 +2712,13 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
best_rate = sum_rate;
best_dist = sum_dist;
best_rd = sum_rd;
- *(get_sb_partitioning(x, bsize)) = subsize;
+ pc_tree->partitioning = PARTITION_VERT;
}
}
+ // TODO(JBB): The following line is here just to avoid a static warning
+ // that occurs because at this point we never again reuse best_rd
+ // despite setting it here. The code should be refactored to avoid this.
+ (void) best_rd;
*rate = best_rate;
*dist = best_dist;
@@ -2816,8 +2727,9 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
return;
// update mode info array
- fill_mode_info_sb(cm, x, mi_row, mi_col, bsize,
- *(get_sb_partitioning(x, bsize)));
+ subsize = get_subsize(bsize, pc_tree->partitioning);
+ fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, subsize,
+ pc_tree);
if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
@@ -2834,7 +2746,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
best_rate, best_dist);
- encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
+ encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
}
if (bsize == BLOCK_64X64) {
@@ -2852,7 +2764,8 @@ static void nonrd_use_partition(VP9_COMP *cpi,
TOKENEXTRA **tp,
int mi_row, int mi_col,
BLOCK_SIZE bsize, int output_enabled,
- int *totrate, int64_t *totdist) {
+ int *totrate, int64_t *totdist,
+ PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -2872,17 +2785,15 @@ static void nonrd_use_partition(VP9_COMP *cpi,
switch (partition) {
case PARTITION_NONE:
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->none.mic.mbmi = xd->mi[0]->mbmi;
break;
case PARTITION_VERT:
- *get_sb_index(x, subsize) = 0;
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->vertical[0].mic.mbmi = xd->mi[0]->mbmi;
if (mi_col + hbs < cm->mi_cols) {
- *get_sb_index(x, subsize) = 1;
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
&rate, &dist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->vertical[1].mic.mbmi = xd->mi[0]->mbmi;
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
@@ -2891,14 +2802,12 @@ static void nonrd_use_partition(VP9_COMP *cpi,
}
break;
case PARTITION_HORZ:
- *get_sb_index(x, subsize) = 0;
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
- get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
+ pc_tree->horizontal[0].mic.mbmi = xd->mi[0]->mbmi;
if (mi_row + hbs < cm->mi_rows) {
- *get_sb_index(x, subsize) = 1;
nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
&rate, &dist, subsize);
- get_block_context(x, subsize)->mic.mbmi = mi_8x8[0]->mbmi;
+ pc_tree->horizontal[1].mic.mbmi = mi_8x8[0]->mbmi;
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
@@ -2908,31 +2817,28 @@ static void nonrd_use_partition(VP9_COMP *cpi,
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
- *get_sb_index(x, subsize) = 0;
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
- subsize, output_enabled, totrate, totdist);
- *get_sb_index(x, subsize) = 1;
+ subsize, output_enabled, totrate, totdist,
+ pc_tree->split[0]);
nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp,
mi_row, mi_col + hbs, subsize, output_enabled,
- &rate, &dist);
+ &rate, &dist, pc_tree->split[1]);
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
*totdist += dist;
}
- *get_sb_index(x, subsize) = 2;
nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp,
mi_row + hbs, mi_col, subsize, output_enabled,
- &rate, &dist);
+ &rate, &dist, pc_tree->split[2]);
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
*totdist += dist;
}
- *get_sb_index(x, subsize) = 3;
nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp,
mi_row + hbs, mi_col + hbs, subsize, output_enabled,
- &rate, &dist);
+ &rate, &dist, pc_tree->split[3]);
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
@@ -2947,7 +2853,7 @@ static void nonrd_use_partition(VP9_COMP *cpi,
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
*totrate, *totdist);
- encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize);
+ encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize, pc_tree);
}
}
@@ -2964,6 +2870,7 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
// Code each SB in the row
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE) {
+ MACROBLOCK *x = &cpi->mb;
int dummy_rate = 0;
int64_t dummy_dist = 0;
const int idx_str = cm->mi_stride * mi_row + mi_col;
@@ -2979,12 +2886,12 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
case VAR_BASED_PARTITION:
choose_partitioning(cpi, tile, mi_row, mi_col);
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist);
+ 1, &dummy_rate, &dummy_dist, x->pc_root);
break;
case SOURCE_VAR_BASED_PARTITION:
set_source_var_based_partition(cpi, tile, mi_8x8, mi_row, mi_col);
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist);
+ 1, &dummy_rate, &dummy_dist, x->pc_root);
break;
case VAR_BASED_FIXED_PARTITION:
case FIXED_PARTITION:
@@ -2993,17 +2900,19 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist);
+ 1, &dummy_rate, &dummy_dist, x->pc_root);
break;
case REFERENCE_PARTITION:
if (cpi->sf.partition_check ||
!is_background(cpi, tile, mi_row, mi_col)) {
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1, INT64_MAX);
+ &dummy_rate, &dummy_dist, 1, INT64_MAX,
+ x->pc_root);
} else {
copy_partitioning(cm, mi_8x8, prev_mi_8x8);
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
- BLOCK_64X64, 1, &dummy_rate, &dummy_dist);
+ BLOCK_64X64, 1, &dummy_rate, &dummy_dist,
+ x->pc_root);
}
break;
default:
@@ -3066,7 +2975,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
int i;
struct macroblock_plane *const p = x->plane;
struct macroblockd_plane *const pd = xd->plane;
- PICK_MODE_CONTEXT *ctx = &cpi->mb.sb64_context;
+ PICK_MODE_CONTEXT *ctx = &x->pc_root->none;
for (i = 0; i < MAX_MB_PLANE; ++i) {
p[i].coeff = ctx->coeff_pbuf[i][0];
@@ -3332,14 +3241,14 @@ static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
}
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
- int mi_row, int mi_col, BLOCK_SIZE bsize) {
+ int mi_row, int mi_col, BLOCK_SIZE bsize,
+ PICK_MODE_CONTEXT *ctx) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO **mi_8x8 = xd->mi;
MODE_INFO *mi = mi_8x8[0];
MB_MODE_INFO *mbmi = &mi->mbmi;
- PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
unsigned int segment_id = mbmi->segment_id;
const int mis = cm->mi_stride;
const int mi_width = num_8x8_blocks_wide_lookup[bsize];