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.c876
1 files changed, 556 insertions, 320 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index a38592240..80abb1fa5 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -30,6 +30,9 @@
#include "vp9/common/vp9_systemdependent.h"
#include "vp9/common/vp9_tile_common.h"
+#include "vp9/encoder/vp9_aq_complexity.h"
+#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
+#include "vp9/encoder/vp9_aq_variance.h"
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
@@ -38,8 +41,6 @@
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
#include "vp9/encoder/vp9_tokenize.h"
-#include "vp9/encoder/vp9_vaq.h"
-#include "vp9/encoder/vp9_craq.h"
#define GF_ZEROMV_ZBIN_BOOST 0
#define LF_ZEROMV_ZBIN_BOOST 0
@@ -164,13 +165,12 @@ static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm,
int mi_col) {
const int idx_str = xd->mode_info_stride * mi_row + mi_col;
xd->mi_8x8 = cm->mi_grid_visible + idx_str;
- xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
xd->mi_8x8[0] = cm->mi + idx_str;
}
-static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col,
+static int is_block_in_mb_map(const VP9_COMP *cpi, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
- VP9_COMMON *const cm = &cpi->common;
+ const VP9_COMMON *const cm = &cpi->common;
const int mb_rows = cm->mb_rows;
const int mb_cols = cm->mb_cols;
const int mb_row = mi_row >> 1;
@@ -194,6 +194,16 @@ static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col,
return 0;
}
+static int check_active_map(const VP9_COMP *cpi, const MACROBLOCK *x,
+ int mi_row, int mi_col,
+ BLOCK_SIZE bsize) {
+ if (cpi->active_map_enabled && !x->e_mbd.lossless) {
+ return is_block_in_mb_map(cpi, mi_row, mi_col, bsize);
+ } else {
+ return 1;
+ }
+}
+
static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, int mi_col, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &cpi->mb;
@@ -207,16 +217,11 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
const int idx_map = mb_row * cm->mb_cols + mb_col;
const struct segmentation *const seg = &cm->seg;
- set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col);
+ set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col);
// Activity map pointer
x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
-
- if (cpi->active_map_enabled && !x->e_mbd.lossless) {
- x->in_active_map = is_block_in_mb_map(cpi, mi_row, mi_col, bsize);
- } else {
- x->in_active_map = 1;
- }
+ x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
set_modeinfo_offsets(cm, xd, mi_row, mi_col);
@@ -276,7 +281,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
}
}
-static void duplicate_modeinfo_in_sb(VP9_COMMON * const cm,
+static void duplicate_mode_info_in_sb(VP9_COMMON * const cm,
MACROBLOCKD *const xd,
int mi_row,
int mi_col,
@@ -300,7 +305,7 @@ static void set_block_size(VP9_COMP * const cpi,
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col);
xd->mi_8x8[0]->mbmi.sb_type = bsize;
- duplicate_modeinfo_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
+ duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
}
}
@@ -829,52 +834,6 @@ static void activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
adjust_act_zbin(cpi, x);
}
-// Select a segment for the current SB64
-static void select_in_frame_q_segment(VP9_COMP *cpi,
- int mi_row, int mi_col,
- int output_enabled, int projected_rate) {
- VP9_COMMON *const cm = &cpi->common;
-
- const int mi_offset = mi_row * cm->mi_cols + mi_col;
- const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64];
- const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64];
- const int xmis = MIN(cm->mi_cols - mi_col, bw);
- const int ymis = MIN(cm->mi_rows - mi_row, bh);
- int complexity_metric = 64;
- int x, y;
-
- unsigned char segment;
-
- if (!output_enabled) {
- segment = 0;
- } else {
- // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
- // It is converted to bits * 256 units
- const int target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) /
- (bw * bh);
-
- if (projected_rate < (target_rate / 4)) {
- segment = 1;
- } else {
- segment = 0;
- }
-
- if (target_rate > 0) {
- complexity_metric =
- clamp((int)((projected_rate * 64) / target_rate), 16, 255);
- }
- }
-
- // Fill in the entires in the segment map corresponding to this SB64
- for (y = 0; y < ymis; y++) {
- for (x = 0; x < xmis; x++) {
- cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment;
- cpi->complexity_map[mi_offset + y * cm->mi_cols + x] =
- (unsigned char)complexity_metric;
- }
- }
-}
-
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
int mi_row, int mi_col, BLOCK_SIZE bsize,
int output_enabled) {
@@ -896,21 +855,17 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
assert(mi->mbmi.sb_type == bsize);
- // For in frame adaptive Q copy over the chosen segment id into the
- // mode innfo context for the chosen mode / partition.
- if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ ||
- cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) &&
+ *mi_addr = *mi;
+
+ // For in frame adaptive Q, check for reseting the segment_id and updating
+ // the cyclic refresh map.
+ if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled &&
output_enabled) {
- // Check for reseting segment_id and update cyclic map.
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && seg->enabled) {
- vp9_update_segment_aq(cpi, xd->mi_8x8[0], mi_row, mi_col, bsize, 1);
- vp9_init_plane_quantizers(cpi, x);
- }
- mi->mbmi.segment_id = xd->mi_8x8[0]->mbmi.segment_id;
+ vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi,
+ mi_row, mi_col, bsize, 1);
+ vp9_init_plane_quantizers(cpi, x);
}
- *mi_addr = *mi;
-
max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
for (i = 0; i < max_plane; ++i) {
p[i].coeff = ctx->coeff_pbuf[i][1];
@@ -985,12 +940,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
#endif
if (!frame_is_intra_only(cm)) {
if (is_inter_block(mbmi)) {
- if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- MV best_mv[2];
- for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
- vp9_update_mv_count(cm, xd, best_mv);
- }
+ vp9_update_mv_count(cm, xd);
if (cm->interp_filter == SWITCHABLE) {
const int ctx = vp9_get_pred_context_switchable_interp(xd);
@@ -1111,7 +1061,7 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
: cm->last_frame_seg_map;
// If segment 1, use rdmult for that segment.
if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col))
- x->rdmult = cpi->cyclic_refresh.rdmult;
+ x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
}
// Find best coding mode & reconstruct the MB so it is available
@@ -1211,21 +1161,21 @@ static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
int mi_height = num_8x8_blocks_high_lookup[bsize];
for (p = 0; p < MAX_MB_PLANE; p++) {
vpx_memcpy(
- cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
+ xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
a + num_4x4_blocks_wide * p,
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
xd->plane[p].subsampling_x);
vpx_memcpy(
- cpi->left_context[p]
+ xd->left_context[p]
+ ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
l + num_4x4_blocks_high * p,
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
xd->plane[p].subsampling_y);
}
- vpx_memcpy(cpi->above_seg_context + mi_col, sa,
- sizeof(*cpi->above_seg_context) * mi_width);
- vpx_memcpy(cpi->left_seg_context + (mi_row & MI_MASK), sl,
- sizeof(cpi->left_seg_context[0]) * mi_height);
+ vpx_memcpy(xd->above_seg_context + mi_col, sa,
+ sizeof(*xd->above_seg_context) * mi_width);
+ vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
+ sizeof(xd->left_seg_context[0]) * mi_height);
}
static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
@@ -1244,20 +1194,20 @@ static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
for (p = 0; p < MAX_MB_PLANE; ++p) {
vpx_memcpy(
a + num_4x4_blocks_wide * p,
- cpi->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
+ xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
xd->plane[p].subsampling_x);
vpx_memcpy(
l + num_4x4_blocks_high * p,
- cpi->left_context[p]
+ xd->left_context[p]
+ ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
xd->plane[p].subsampling_y);
}
- vpx_memcpy(sa, cpi->above_seg_context + mi_col,
- sizeof(*cpi->above_seg_context) * mi_width);
- vpx_memcpy(sl, cpi->left_seg_context + (mi_row & MI_MASK),
- sizeof(cpi->left_seg_context[0]) * mi_height);
+ vpx_memcpy(sa, xd->above_seg_context + mi_col,
+ sizeof(*xd->above_seg_context) * mi_width);
+ vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
+ sizeof(xd->left_seg_context[0]) * mi_height);
}
static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
@@ -1289,6 +1239,8 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
int output_enabled, BLOCK_SIZE bsize) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
+
const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
int ctx;
PARTITION_TYPE partition;
@@ -1298,8 +1250,7 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
return;
if (bsize >= BLOCK_8X8) {
- ctx = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
subsize = *get_sb_partitioning(x, bsize);
} else {
ctx = 0;
@@ -1354,8 +1305,7 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
}
if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
- update_partition_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, subsize, bsize);
+ update_partition_context(xd, mi_row, mi_col, subsize, bsize);
}
// Check to see if the given partition size is allowed for a specified number
@@ -1432,6 +1382,7 @@ static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8,
for (block_col = 0; block_col < 8; ++block_col) {
MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col];
const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
+
if (prev_mi) {
const ptrdiff_t offset = prev_mi - cm->prev_mi;
mi_8x8[block_row * mis + block_col] = cm->mi + offset;
@@ -1460,45 +1411,39 @@ static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
return 0;
}
-static void update_state_rt(VP9_COMP *cpi, const PICK_MODE_CONTEXT *ctx,
+static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
int mi_row, int mi_col, int bsize) {
- int i;
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
const struct segmentation *const seg = &cm->seg;
- // TODO(jingning) We might need PICK_MODE_CONTEXT to buffer coding modes
- // associated with variable block sizes. Otherwise, remove this ctx
- // from argument list.
- (void)ctx;
+ *(xd->mi_8x8[0]) = ctx->mic;
- // Check for reseting segment_id and update cyclic map.
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && seg->enabled) {
- vp9_update_segment_aq(cpi, xd->mi_8x8[0], mi_row, mi_col, bsize, 1);
+ // For in frame adaptive Q, check for reseting the segment_id and updating
+ // the cyclic refresh map.
+ if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled) {
+ vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi,
+ mi_row, mi_col, bsize, 1);
vp9_init_plane_quantizers(cpi, x);
}
-
if (is_inter_block(mbmi)) {
- if (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV) {
- MV best_mv[2];
- for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
- best_mv[i] = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_mv;
- vp9_update_mv_count(cm, xd, best_mv);
- }
+ vp9_update_mv_count(cm, xd);
if (cm->interp_filter == SWITCHABLE) {
const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter];
}
}
+
+ x->skip = ctx->skip;
}
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) {
+ TOKENEXTRA **tp, int mi_row, int mi_col,
+ int output_enabled, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &cpi->mb;
if (bsize < BLOCK_8X8) {
@@ -1507,6 +1452,7 @@ static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
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);
@@ -1522,6 +1468,8 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
int output_enabled, BLOCK_SIZE bsize) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
+
const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
int ctx;
PARTITION_TYPE partition;
@@ -1534,8 +1482,7 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
const int idx_str = xd->mode_info_stride * mi_row + mi_col;
MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str;
- ctx = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
subsize = mi_8x8[0]->mbmi.sb_type;
} else {
ctx = 0;
@@ -1594,8 +1541,7 @@ static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
}
if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
- update_partition_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, subsize, bsize);
+ update_partition_context(xd, mi_row, mi_col, subsize, bsize);
}
static void rd_use_partition(VP9_COMP *cpi,
@@ -1606,12 +1552,10 @@ static void rd_use_partition(VP9_COMP *cpi,
int do_recon) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
const int mis = cm->mode_info_stride;
const int bsl = b_width_log2(bsize);
- const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
- const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
- const int ms = num_4x4_blocks_wide / 2;
- const int mh = num_4x4_blocks_high / 2;
+ const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2;
const int bss = (1 << bsl) / 4;
int i, pl;
PARTITION_TYPE partition = PARTITION_NONE;
@@ -1630,10 +1574,14 @@ static void rd_use_partition(VP9_COMP *cpi,
BLOCK_SIZE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
+ int do_partition_search = 1;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
+ assert(num_4x4_blocks_wide_lookup[bsize] ==
+ num_4x4_blocks_high_lookup[bsize]);
+
partition = partition_lookup[bsl][bs_type];
subsize = get_subsize(bsize, partition);
@@ -1653,9 +1601,22 @@ static void rd_use_partition(VP9_COMP *cpi,
if (bsize == BLOCK_16X16) {
set_offsets(cpi, tile, mi_row, mi_col, bsize);
x->mb_energy = vp9_block_energy(cpi, x, bsize);
+ } else {
+ x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
}
- if (cpi->sf.partition_search_type == SEARCH_PARTITION &&
+ if (!x->in_active_map) {
+ 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;
+ bs_type = mi_8x8[0]->mbmi.sb_type = bsize;
+ subsize = bsize;
+ partition = PARTITION_NONE;
+ }
+ }
+ if (do_partition_search &&
+ cpi->sf.partition_search_type == SEARCH_PARTITION &&
cpi->sf.adjust_partitioning_from_last_frame) {
// Check if any of the sub blocks are further split.
if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
@@ -1673,15 +1634,13 @@ static void rd_use_partition(VP9_COMP *cpi,
// If partition is not none try none unless each of the 4 splits are split
// even further..
if (partition != PARTITION_NONE && !splits_below &&
- mi_row + (ms >> 1) < cm->mi_rows &&
- mi_col + (ms >> 1) < cm->mi_cols) {
+ mi_row + (mi_step >> 1) < cm->mi_rows &&
+ mi_col + (mi_step >> 1) < cm->mi_cols) {
*(get_sb_partitioning(x, bsize)) = bsize;
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
get_block_context(x, bsize), INT64_MAX);
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
if (none_rate < INT_MAX) {
none_rate += x->partition_cost[pl][PARTITION_NONE];
@@ -1706,14 +1665,14 @@ static void rd_use_partition(VP9_COMP *cpi,
&last_part_dist, subsize,
get_block_context(x, subsize), INT64_MAX);
if (last_part_rate != INT_MAX &&
- bsize >= BLOCK_8X8 && mi_row + (mh >> 1) < cm->mi_rows) {
+ 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;
- rd_pick_sb_modes(cpi, tile, mi_row + (ms >> 1), mi_col, &rt, &dt,
+ rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
subsize, get_block_context(x, subsize), INT64_MAX);
if (rt == INT_MAX || dt == INT64_MAX) {
last_part_rate = INT_MAX;
@@ -1731,14 +1690,14 @@ static void rd_use_partition(VP9_COMP *cpi,
&last_part_dist, subsize,
get_block_context(x, subsize), INT64_MAX);
if (last_part_rate != INT_MAX &&
- bsize >= BLOCK_8X8 && mi_col + (ms >> 1) < cm->mi_cols) {
+ 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;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (ms >> 1), &rt, &dt,
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
subsize, get_block_context(x, subsize), INT64_MAX);
if (rt == INT_MAX || dt == INT64_MAX) {
last_part_rate = INT_MAX;
@@ -1754,8 +1713,8 @@ static void rd_use_partition(VP9_COMP *cpi,
last_part_rate = 0;
last_part_dist = 0;
for (i = 0; i < 4; i++) {
- int x_idx = (i & 1) * (ms >> 1);
- int y_idx = (i >> 1) * (ms >> 1);
+ int x_idx = (i & 1) * (mi_step >> 1);
+ int y_idx = (i >> 1) * (mi_step >> 1);
int jj = i >> 1, ii = i & 0x01;
int rt;
int64_t dt;
@@ -1781,18 +1740,20 @@ static void rd_use_partition(VP9_COMP *cpi,
assert(0);
}
- pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
if (last_part_rate < INT_MAX) {
last_part_rate += x->partition_cost[pl][partition];
last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
}
- if (cpi->sf.adjust_partitioning_from_last_frame
+ if (do_partition_search
+ && cpi->sf.adjust_partitioning_from_last_frame
&& cpi->sf.partition_search_type == SEARCH_PARTITION
&& partition != PARTITION_SPLIT && bsize > BLOCK_8X8
- && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows)
- && (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) {
+ && (mi_row + mi_step < cm->mi_rows ||
+ mi_row + (mi_step >> 1) == cm->mi_rows)
+ && (mi_col + mi_step < cm->mi_cols ||
+ mi_col + (mi_step >> 1) == cm->mi_cols)) {
BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
chosen_rate = 0;
chosen_dist = 0;
@@ -1800,8 +1761,8 @@ static void rd_use_partition(VP9_COMP *cpi,
// Split partition.
for (i = 0; i < 4; i++) {
- int x_idx = (i & 1) * (num_4x4_blocks_wide >> 2);
- int y_idx = (i >> 1) * (num_4x4_blocks_wide >> 2);
+ int x_idx = (i & 1) * (mi_step >> 1);
+ int y_idx = (i >> 1) * (mi_step >> 1);
int rt = 0;
int64_t dt = 0;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
@@ -1835,14 +1796,11 @@ static void rd_use_partition(VP9_COMP *cpi,
encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
split_subsize);
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row + y_idx, mi_col + x_idx,
+ pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
split_subsize);
chosen_rate += x->partition_cost[pl][PARTITION_NONE];
}
- pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
if (chosen_rate < INT_MAX) {
chosen_rate += x->partition_cost[pl][PARTITION_SPLIT];
chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
@@ -1880,14 +1838,14 @@ static void rd_use_partition(VP9_COMP *cpi,
// and and if necessary apply a Q delta using segmentation to get
// closer to the target.
if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
- select_in_frame_q_segment(cpi, mi_row, mi_col,
- output_enabled, chosen_rate);
- }
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
- cpi->cyclic_refresh.projected_rate_sb = chosen_rate;
- cpi->cyclic_refresh.projected_dist_sb = chosen_dist;
+ vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
+ output_enabled, chosen_rate);
}
+ 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);
}
@@ -1951,77 +1909,71 @@ static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
// Look at neighboring blocks and set a min and max partition size based on
// what they chose.
static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
- int row, int col,
+ int mi_row, int mi_col,
BLOCK_SIZE *min_block_size,
BLOCK_SIZE *max_block_size) {
- VP9_COMMON * const cm = &cpi->common;
+ VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
- MODE_INFO ** mi_8x8 = xd->mi_8x8;
- MODE_INFO ** prev_mi_8x8 = xd->prev_mi_8x8;
-
+ MODE_INFO **mi_8x8 = xd->mi_8x8;
const int left_in_image = xd->left_available && mi_8x8[-1];
const int above_in_image = xd->up_available &&
mi_8x8[-xd->mode_info_stride];
- MODE_INFO ** above_sb64_mi_8x8;
- MODE_INFO ** left_sb64_mi_8x8;
+ MODE_INFO **above_sb64_mi_8x8;
+ MODE_INFO **left_sb64_mi_8x8;
- int row8x8_remaining = tile->mi_row_end - row;
- int col8x8_remaining = tile->mi_col_end - col;
+ int row8x8_remaining = tile->mi_row_end - mi_row;
+ int col8x8_remaining = tile->mi_col_end - mi_col;
int bh, bw;
-
+ BLOCK_SIZE min_size = BLOCK_4X4;
+ BLOCK_SIZE max_size = BLOCK_64X64;
// Trap case where we do not have a prediction.
- if (!left_in_image && !above_in_image &&
- ((cm->frame_type == KEY_FRAME) || !cm->prev_mi)) {
- *min_block_size = BLOCK_4X4;
- *max_block_size = BLOCK_64X64;
- } else {
+ if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
// Default "min to max" and "max to min"
- *min_block_size = BLOCK_64X64;
- *max_block_size = BLOCK_4X4;
+ min_size = BLOCK_64X64;
+ max_size = BLOCK_4X4;
// NOTE: each call to get_sb_partition_size_range() uses the previous
// passed in values for min and max as a starting point.
- //
// Find the min and max partition used in previous frame at this location
- if (cm->prev_mi && (cm->frame_type != KEY_FRAME)) {
- get_sb_partition_size_range(cpi, prev_mi_8x8,
- min_block_size, max_block_size);
+ if (cm->frame_type != KEY_FRAME) {
+ MODE_INFO **const prev_mi =
+ &cm->prev_mi_grid_visible[mi_row * xd->mode_info_stride + mi_col];
+ get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size);
}
-
// Find the min and max partition sizes used in the left SB64
if (left_in_image) {
left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE];
get_sb_partition_size_range(cpi, left_sb64_mi_8x8,
- min_block_size, max_block_size);
+ &min_size, &max_size);
}
-
// Find the min and max partition sizes used in the above SB64.
if (above_in_image) {
above_sb64_mi_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE];
get_sb_partition_size_range(cpi, above_sb64_mi_8x8,
- min_block_size, max_block_size);
+ &min_size, &max_size);
+ }
+ // adjust observed min and max
+ if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
+ min_size = min_partition_size[min_size];
+ max_size = max_partition_size[max_size];
}
}
- // adjust observed min and max
- if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
- *min_block_size = min_partition_size[*min_block_size];
- *max_block_size = max_partition_size[*max_block_size];
- }
-
- // Check border cases where max and min from neighbours may not be legal.
- *max_block_size = find_partition_size(*max_block_size,
- row8x8_remaining, col8x8_remaining,
- &bh, &bw);
- *min_block_size = MIN(*min_block_size, *max_block_size);
+ // Check border cases where max and min from neighbors may not be legal.
+ max_size = find_partition_size(max_size,
+ row8x8_remaining, col8x8_remaining,
+ &bh, &bw);
+ min_size = MIN(min_size, max_size);
// When use_square_partition_only is true, make sure at least one square
// partition is allowed by selecting the next smaller square size as
// *min_block_size.
if (cpi->sf.use_square_partition_only &&
- next_square_size[*max_block_size] < *min_block_size) {
- *min_block_size = next_square_size[*max_block_size];
+ next_square_size[max_size] < min_size) {
+ min_size = next_square_size[max_size];
}
+ *min_block_size = min_size;
+ *max_block_size = max_size;
}
static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
@@ -2041,7 +1993,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
int64_t *dist, int do_recon, int64_t best_rd) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
- const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
TOKENEXTRA *tp_orig = *tp;
@@ -2054,8 +2007,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
int do_split = bsize >= BLOCK_8X8;
int do_rect = 1;
// Override skipping rectangular partition operations for edge blocks
- const int force_horz_split = (mi_row + ms >= cm->mi_rows);
- const int force_vert_split = (mi_col + ms >= cm->mi_cols);
+ const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
+ const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
const int xss = x->e_mbd.plane[1].subsampling_x;
const int yss = x->e_mbd.plane[1].subsampling_y;
@@ -2081,6 +2034,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (bsize == BLOCK_16X16) {
set_offsets(cpi, tile, mi_row, mi_col, bsize);
x->mb_energy = vp9_block_energy(cpi, x, bsize);
+ } 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.
@@ -2122,9 +2077,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
ctx, best_rd);
if (this_rate != INT_MAX) {
if (bsize >= BLOCK_8X8) {
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
this_rate += x->partition_cost[pl][PARTITION_NONE];
}
sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
@@ -2169,8 +2122,8 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
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) * ms;
- const int y_idx = (i >> 1) * ms;
+ 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;
@@ -2194,9 +2147,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
}
if (sum_rd < best_rd && i == 4) {
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd) {
@@ -2228,7 +2179,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
get_block_context(x, subsize), best_rd);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
+ 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);
@@ -2240,7 +2191,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
partition_none_allowed)
get_block_context(x, subsize)->pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate,
+ 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);
if (this_rate == INT_MAX) {
@@ -2252,9 +2203,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
}
if (sum_rd < best_rd) {
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
sum_rate += x->partition_cost[pl][PARTITION_HORZ];
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd) {
@@ -2281,7 +2230,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
get_block_context(x, subsize), best_rd);
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
+ 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);
@@ -2293,7 +2242,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
partition_none_allowed)
get_block_context(x, subsize)->pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate,
+ 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);
if (this_rate == INT_MAX) {
@@ -2305,9 +2254,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
}
}
if (sum_rd < best_rd) {
- pl = partition_plane_context(cpi->above_seg_context,
- cpi->left_seg_context,
- mi_row, mi_col, bsize);
+ pl = partition_plane_context(xd, mi_row, mi_col, bsize);
sum_rate += x->partition_cost[pl][PARTITION_VERT];
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
if (sum_rd < best_rd) {
@@ -2335,13 +2282,14 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// and and if necessary apply a Q delta using segmentation to get
// closer to the target.
if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
- select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, best_rate);
- }
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
- cpi->cyclic_refresh.projected_rate_sb = best_rate;
- cpi->cyclic_refresh.projected_dist_sb = best_dist;
+ 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);
+
encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
}
if (bsize == BLOCK_64X64) {
@@ -2356,11 +2304,12 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, TOKENEXTRA **tp) {
VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
int mi_col;
// Initialize the left context for the new SB row
- vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context));
- vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context));
+ vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
+ vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
// Code each SB in the row
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
@@ -2486,11 +2435,11 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
// Note: this memset assumes above_context[0], [1] and [2]
// are allocated as part of the same buffer.
- vpx_memset(cpi->above_context[0], 0,
- sizeof(*cpi->above_context[0]) *
+ vpx_memset(xd->above_context[0], 0,
+ sizeof(*xd->above_context[0]) *
2 * aligned_mi_cols * MAX_MB_PLANE);
- vpx_memset(cpi->above_seg_context, 0,
- sizeof(*cpi->above_seg_context) * aligned_mi_cols);
+ vpx_memset(xd->above_seg_context, 0,
+ sizeof(*xd->above_seg_context) * aligned_mi_cols);
}
static void switch_lossless_mode(VP9_COMP *cpi, int lossless) {
@@ -2533,87 +2482,15 @@ static int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) {
return 1;
}
-static void set_txfm_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs,
- TX_SIZE tx_size) {
- int x, y;
-
- for (y = 0; y < ymbs; y++) {
- for (x = 0; x < xmbs; x++)
- mi_8x8[y * mis + x]->mbmi.tx_size = tx_size;
- }
-}
-
-static void reset_skip_txfm_size_b(const VP9_COMMON *cm, int mis,
- TX_SIZE max_tx_size, int bw, int bh,
- int mi_row, int mi_col,
- MODE_INFO **mi_8x8) {
- if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) {
- return;
- } else {
- const MB_MODE_INFO *const mbmi = &mi_8x8[0]->mbmi;
- if (mbmi->tx_size > max_tx_size) {
- const int ymbs = MIN(bh, cm->mi_rows - mi_row);
- const int xmbs = MIN(bw, cm->mi_cols - mi_col);
-
- assert(vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) ||
- get_skip_flag(mi_8x8, mis, ymbs, xmbs));
- set_txfm_flag(mi_8x8, mis, ymbs, xmbs, max_tx_size);
- }
- }
-}
-
-static void reset_skip_txfm_size_sb(VP9_COMMON *cm, MODE_INFO **mi_8x8,
- TX_SIZE max_tx_size, int mi_row, int mi_col,
- BLOCK_SIZE bsize) {
- const int mis = cm->mode_info_stride;
- int bw, bh;
- const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2;
-
- if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
- return;
-
- bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type];
- bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type];
-
- if (bw == bs && bh == bs) {
- reset_skip_txfm_size_b(cm, mis, max_tx_size, bs, bs, mi_row, mi_col,
- mi_8x8);
- } else if (bw == bs && bh < bs) {
- reset_skip_txfm_size_b(cm, mis, max_tx_size, bs, hbs, mi_row, mi_col,
- mi_8x8);
- reset_skip_txfm_size_b(cm, mis, max_tx_size, bs, hbs, mi_row + hbs,
- mi_col, mi_8x8 + hbs * mis);
- } else if (bw < bs && bh == bs) {
- reset_skip_txfm_size_b(cm, mis, max_tx_size, hbs, bs, mi_row, mi_col,
- mi_8x8);
- reset_skip_txfm_size_b(cm, mis, max_tx_size, hbs, bs, mi_row,
- mi_col + hbs, mi_8x8 + hbs);
- } else {
- const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
- int n;
-
- assert(bw < bs && bh < bs);
-
- for (n = 0; n < 4; n++) {
- const int mi_dc = hbs * (n & 1);
- const int mi_dr = hbs * (n >> 1);
-
- reset_skip_txfm_size_sb(cm, &mi_8x8[mi_dr * mis + mi_dc], max_tx_size,
- mi_row + mi_dr, mi_col + mi_dc, subsize);
- }
- }
-}
-
static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) {
int mi_row, mi_col;
const int mis = cm->mode_info_stride;
- MODE_INFO **mi_8x8, **mi_ptr = cm->mi_grid_visible;
+ MODE_INFO **mi_ptr = cm->mi_grid_visible;
- for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8, mi_ptr += 8 * mis) {
- mi_8x8 = mi_ptr;
- for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8, mi_8x8 += 8) {
- reset_skip_txfm_size_sb(cm, mi_8x8, txfm_max, mi_row, mi_col,
- BLOCK_64X64);
+ for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
+ for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
+ if (mi_ptr[mi_col]->mbmi.tx_size > txfm_max)
+ mi_ptr[mi_col]->mbmi.tx_size = txfm_max;
}
}
}
@@ -2693,6 +2570,7 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
MACROBLOCKD *const xd = &x->e_mbd;
set_offsets(cpi, tile, mi_row, mi_col, bsize);
xd->mi_8x8[0]->mbmi.sb_type = bsize;
+
if (!frame_is_intra_only(cm)) {
vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col,
rate, dist, bsize);
@@ -2700,7 +2578,338 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
MB_PREDICTION_MODE intramode = DC_PRED;
set_mode_info(&xd->mi_8x8[0]->mbmi, bsize, intramode);
}
- duplicate_modeinfo_in_sb(cm, xd, mi_row, mi_col, bsize);
+ duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
+}
+
+static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
+ int mi_row, int mi_col,
+ BLOCK_SIZE bsize, BLOCK_SIZE subsize) {
+ MACROBLOCKD *xd = &x->e_mbd;
+ int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
+ PARTITION_TYPE partition = partition_lookup[bsl][subsize];
+
+ assert(bsize >= BLOCK_8X8);
+
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
+ return;
+
+ switch (partition) {
+ case PARTITION_NONE:
+ set_modeinfo_offsets(cm, xd, mi_row, mi_col);
+ *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->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_8x8[0]) = (get_block_context(x, subsize))->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_8x8[0]) = (get_block_context(x, subsize))->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_8x8[0]) = (get_block_context(x, subsize))->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_8x8[0]) = (get_block_context(x, subsize))->mic;
+ duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
+ }
+ break;
+ case PARTITION_SPLIT:
+ *get_sb_index(x, subsize) = 0;
+ fill_mode_info_sb(cm, x, mi_row, mi_col, subsize,
+ *(get_sb_partitioning(x, subsize)));
+ *get_sb_index(x, subsize) = 1;
+ fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
+ *(get_sb_partitioning(x, subsize)));
+ *get_sb_index(x, subsize) = 2;
+ fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
+ *(get_sb_partitioning(x, subsize)));
+ *get_sb_index(x, subsize) = 3;
+ fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
+ *(get_sb_partitioning(x, subsize)));
+ break;
+ default:
+ break;
+ }
+}
+
+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) {
+ 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);
+ int i;
+ BLOCK_SIZE subsize;
+ 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;
+ int do_split = bsize >= BLOCK_8X8;
+ int do_rect = 1;
+ // Override skipping rectangular partition operations for edge blocks
+ const int force_horz_split = (mi_row + ms >= cm->mi_rows);
+ const int force_vert_split = (mi_col + ms >= cm->mi_cols);
+ const int xss = x->e_mbd.plane[1].subsampling_x;
+ const int yss = x->e_mbd.plane[1].subsampling_y;
+
+ int partition_none_allowed = !force_horz_split && !force_vert_split;
+ int partition_horz_allowed = !force_vert_split && yss <= xss &&
+ bsize >= BLOCK_8X8;
+ int partition_vert_allowed = !force_horz_split && xss <= yss &&
+ 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]);
+
+ 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) {
+ partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
+ bsize >= cpi->sf.min_partition_size);
+ partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
+ bsize > cpi->sf.min_partition_size) ||
+ force_horz_split);
+ partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
+ bsize > cpi->sf.min_partition_size) ||
+ force_vert_split);
+ do_split &= bsize > cpi->sf.min_partition_size;
+ }
+ if (cpi->sf.use_square_partition_only) {
+ partition_horz_allowed &= force_horz_split;
+ partition_vert_allowed &= force_vert_split;
+ }
+
+ if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
+ do_split = 0;
+
+ // PARTITION_NONE
+ if (partition_none_allowed) {
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
+ &this_rate, &this_dist, bsize);
+ ctx->mic.mbmi = xd->mi_8x8[0]->mbmi;
+
+ if (this_rate != INT_MAX) {
+ int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ this_rate += x->partition_cost[pl][PARTITION_NONE];
+ sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
+ if (sum_rd < best_rd) {
+ int64_t stop_thresh = 4096;
+ int64_t stop_thresh_rd;
+
+ best_rate = this_rate;
+ best_dist = this_dist;
+ best_rd = sum_rd;
+ if (bsize >= BLOCK_8X8)
+ *(get_sb_partitioning(x, bsize)) = bsize;
+
+ // Adjust threshold according to partition size.
+ stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
+ b_height_log2_lookup[bsize]);
+
+ stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
+ // If obtained distortion is very small, choose current partition
+ // and stop splitting.
+ if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
+ do_split = 0;
+ do_rect = 0;
+ }
+ }
+ }
+ if (!x->in_active_map) {
+ do_split = 0;
+ do_rect = 0;
+ }
+ }
+
+ // store estimated motion vector
+ store_pred_mv(x, ctx);
+
+ // PARTITION_SPLIT
+ sum_rd = 0;
+ if (do_split) {
+ int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
+ subsize = get_subsize(bsize, PARTITION_SPLIT);
+ for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
+ const int x_idx = (i & 1) * ms;
+ const int y_idx = (i >> 1) * ms;
+
+ 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);
+
+ 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) {
+ best_rate = sum_rate;
+ best_dist = sum_dist;
+ best_rd = sum_rd;
+ *(get_sb_partitioning(x, bsize)) = subsize;
+ } else {
+ // skip rectangular partition test when larger block size
+ // gives better rd cost
+ if (cpi->sf.less_rectangular_check)
+ do_rect &= !partition_none_allowed;
+ }
+ }
+
+ // 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_8x8[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_8x8[0]->mbmi;
+
+ if (this_rate == INT_MAX) {
+ sum_rd = INT64_MAX;
+ } else {
+ int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ this_rate += x->partition_cost[pl][PARTITION_HORZ];
+ sum_rate += this_rate;
+ sum_dist += this_dist;
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ }
+ }
+ if (sum_rd < best_rd) {
+ best_rd = sum_rd;
+ best_rate = sum_rate;
+ best_dist = sum_dist;
+ *(get_sb_partitioning(x, bsize)) = subsize;
+ }
+ }
+
+ // 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);
+
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
+ &this_rate, &this_dist, subsize);
+ (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[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_8x8[0]->mbmi;
+
+ if (this_rate == INT_MAX) {
+ sum_rd = INT64_MAX;
+ } else {
+ int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ this_rate += x->partition_cost[pl][PARTITION_VERT];
+ sum_rate += this_rate;
+ sum_dist += this_dist;
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ }
+ }
+ if (sum_rd < best_rd) {
+ best_rate = sum_rate;
+ best_dist = sum_dist;
+ best_rd = sum_rd;
+ *(get_sb_partitioning(x, bsize)) = subsize;
+ }
+ }
+
+ *rate = best_rate;
+ *dist = best_dist;
+
+ if (best_rate == INT_MAX)
+ return;
+
+ // update mode info array
+ fill_mode_info_sb(cm, x, mi_row, mi_col, bsize,
+ *(get_sb_partitioning(x, bsize)));
+
+ if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
+ int output_enabled = (bsize == BLOCK_64X64);
+
+ // Check the projected output rate for this SB against it's target
+ // and and if necessary apply a Q delta using segmentation to get
+ // closer to the target.
+ if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
+ 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);
+
+ encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
+ }
+
+ if (bsize == BLOCK_64X64) {
+ assert(tp_orig < *tp);
+ assert(best_rate < INT_MAX);
+ assert(best_dist < INT64_MAX);
+ } else {
+ assert(tp_orig == *tp);
+ }
}
static void nonrd_use_partition(VP9_COMP *cpi,
@@ -2712,12 +2921,13 @@ static void nonrd_use_partition(VP9_COMP *cpi,
int *totrate, int64_t *totdist) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
const int mis = cm->mode_info_stride;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
- int rate;
- int64_t dist;
+ int rate = INT_MAX;
+ int64_t dist = INT64_MAX;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -2733,14 +2943,17 @@ 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_8x8[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_8x8[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_8x8[0]->mbmi;
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
@@ -2751,10 +2964,12 @@ static void nonrd_use_partition(VP9_COMP *cpi,
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_8x8[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 = xd->mi_8x8[0]->mbmi;
if (rate != INT_MAX && dist != INT64_MAX &&
*totrate != INT_MAX && *totdist != INT64_MAX) {
*totrate += rate;
@@ -2764,7 +2979,6 @@ 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);
@@ -2801,10 +3015,9 @@ static void nonrd_use_partition(VP9_COMP *cpi,
}
if (bsize == BLOCK_64X64 && output_enabled) {
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
- cpi->cyclic_refresh.projected_rate_sb = *totrate;
- cpi->cyclic_refresh.projected_dist_sb = *totdist;
- }
+ 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);
}
}
@@ -2812,33 +3025,55 @@ static void nonrd_use_partition(VP9_COMP *cpi,
static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
int mi_row, TOKENEXTRA **tp) {
VP9_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
int mi_col;
// Initialize the left context for the new SB row
- vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context));
- vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context));
+ vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
+ vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
// Code each SB in the row
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE) {
- int dummy_rate;
- int64_t dummy_dist;
+ int dummy_rate = 0;
+ int64_t dummy_dist = 0;
const int idx_str = cm->mode_info_stride * mi_row + mi_col;
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
+ MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
+
BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
cpi->sf.always_this_block_size :
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
cpi->mb.source_variance = UINT_MAX;
+ vp9_zero(cpi->mb.pred_mv);
// Set the partition type of the 64X64 block
- if (cpi->sf.partition_search_type == VAR_BASED_PARTITION)
- choose_partitioning(cpi, tile, mi_row, mi_col);
- else
- 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);
+ switch (cpi->sf.partition_search_type) {
+ 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);
+ break;
+ case VAR_BASED_FIXED_PARTITION:
+ case FIXED_PARTITION:
+ 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);
+ break;
+ case REFERENCE_PARTITION:
+ if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) {
+ nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
+ &dummy_rate, &dummy_dist, 1, INT64_MAX);
+ } 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);
+ }
+ break;
+ default:
+ assert(0);
+ }
}
}
// end RTC play code
@@ -3192,9 +3427,10 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
const int mi_height = num_8x8_blocks_high_lookup[bsize];
x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
- (cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
- cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ) &&
- !cpi->sf.use_nonrd_pick_mode;
+ cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
+ cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ &&
+ cpi->sf.allow_skip_recode;
+
x->skip_optimize = ctx->is_coded;
ctx->is_coded = 1;
x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;