Index: source/libvpx/vp9/encoder/vp9_encodeframe.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 278778) |
+++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy) |
@@ -70,18 +70,12 @@ |
128, 128, 128, 128, 128, 128, 128, 128 |
}; |
-static void get_sse_sum_8x8(const uint8_t *src, int src_stride, |
- const uint8_t *ref, int ref_stride, |
- unsigned int *sse, int *sum) { |
- variance(src, src_stride, ref, ref_stride, 8, 8, sse, sum); |
-} |
+typedef struct { |
+ unsigned int sse; |
+ int sum; |
+ unsigned int var; |
+} diff; |
-static void get_sse_sum_16x16(const uint8_t *src, int src_stride, |
- const uint8_t *ref, int ref_stride, |
- unsigned int *sse, int *sum) { |
- variance(src, src_stride, ref, ref_stride, 16, 16, sse, sum); |
-} |
- |
static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, |
const struct buf_2d *ref, |
BLOCK_SIZE bs) { |
@@ -484,8 +478,8 @@ |
unsigned int sse = 0; |
int sum = 0; |
if (x_idx < pixels_wide && y_idx < pixels_high) |
- get_sse_sum_8x8(s + y_idx * sp + x_idx, sp, |
- d + y_idx * dp + x_idx, dp, &sse, &sum); |
+ vp9_get8x8var(s + y_idx * sp + x_idx, sp, |
+ d + y_idx * dp + x_idx, dp, &sse, &sum); |
fill_variance(sse, sum, 64, &vst->split[k].part_variances.none); |
} |
} |
@@ -553,22 +547,6 @@ |
} |
} |
-// Original activity measure from Tim T's code. |
-static unsigned int tt_activity_measure(MACROBLOCK *x) { |
- unsigned int sse; |
- // TODO: This could also be done over smaller areas (8x8), but that would |
- // require extensive changes elsewhere, as lambda is assumed to be fixed |
- // over an entire MB in most of the code. |
- // Another option is to compute four 8x8 variances, and pick a single |
- // lambda using a non-linear combination (e.g., the smallest, or second |
- // smallest, etc.). |
- const unsigned int act = vp9_variance16x16(x->plane[0].src.buf, |
- x->plane[0].src.stride, |
- VP9_VAR_OFFS, 0, &sse) << 4; |
- // If the region is flat, lower the activity some more. |
- return act < (8 << 12) ? MIN(act, 5 << 12) : act; |
-} |
- |
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, |
int mi_row, int mi_col, BLOCK_SIZE bsize, |
int output_enabled) { |
@@ -719,6 +697,38 @@ |
x->e_mbd.plane[i].subsampling_y); |
} |
+static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, int *rate, |
+ int64_t *dist, BLOCK_SIZE bsize) { |
+ MACROBLOCKD *const xd = &x->e_mbd; |
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
+ INTERP_FILTER filter_ref; |
+ |
+ if (xd->up_available) |
+ filter_ref = xd->mi[-xd->mi_stride]->mbmi.interp_filter; |
+ else if (xd->left_available) |
+ filter_ref = xd->mi[-1]->mbmi.interp_filter; |
+ else |
+ filter_ref = EIGHTTAP; |
+ |
+ mbmi->sb_type = bsize; |
+ mbmi->mode = ZEROMV; |
+ mbmi->tx_size = MIN(max_txsize_lookup[bsize], |
+ tx_mode_to_biggest_tx_size[tx_mode]); |
+ mbmi->skip = 1; |
+ mbmi->uv_mode = DC_PRED; |
+ mbmi->ref_frame[0] = LAST_FRAME; |
+ mbmi->ref_frame[1] = NONE; |
+ mbmi->mv[0].as_int = 0; |
+ mbmi->interp_filter = filter_ref; |
+ |
+ xd->mi[0]->bmi[0].as_mv[0].as_int = 0; |
+ x->skip = 1; |
+ x->skip_encode = 1; |
+ |
+ *rate = 0; |
+ *dist = 0; |
+} |
+ |
static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, |
int mi_row, int mi_col, |
int *totalrate, int64_t *totaldist, |
@@ -1220,9 +1230,9 @@ |
int b_offset = b_mi_row * MI_SIZE * src_stride + |
b_mi_col * MI_SIZE; |
- get_sse_sum_16x16(src + b_offset, src_stride, |
- pre_src + b_offset, pre_stride, |
- &d16[j].sse, &d16[j].sum); |
+ vp9_get16x16var(src + b_offset, src_stride, |
+ pre_src + b_offset, pre_stride, |
+ &d16[j].sse, &d16[j].sum); |
d16[j].var = d16[j].sse - |
(((uint32_t)d16[j].sum * d16[j].sum) >> 8); |
@@ -1297,14 +1307,14 @@ |
if (row8x8_remaining >= MI_BLOCK_SIZE && |
col8x8_remaining >= MI_BLOCK_SIZE) { |
this_sad = cpi->fn_ptr[BLOCK_64X64].sdf(src, src_stride, |
- pre, pre_stride, 0x7fffffff); |
+ pre, pre_stride); |
threshold = (1 << 12); |
} else { |
int r, c; |
for (r = 0; r < row8x8_remaining; r += 2) |
for (c = 0; c < col8x8_remaining; c += 2) |
- this_sad += cpi->fn_ptr[BLOCK_16X16].sdf(src, src_stride, pre, |
- pre_stride, 0x7fffffff); |
+ this_sad += cpi->fn_ptr[BLOCK_16X16].sdf(src, src_stride, |
+ pre, pre_stride); |
threshold = (row8x8_remaining * col8x8_remaining) << 6; |
} |
@@ -1312,7 +1322,8 @@ |
return x->in_static_area; |
} |
-static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { |
+static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8, |
+ const int motion_thresh) { |
const int mis = cm->mi_stride; |
int block_row, block_col; |
@@ -1321,8 +1332,8 @@ |
for (block_col = 0; block_col < 8; ++block_col) { |
const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col]; |
if (prev_mi) { |
- if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || |
- abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) |
+ if (abs(prev_mi->mbmi.mv[0].as_mv.row) > motion_thresh || |
+ abs(prev_mi->mbmi.mv[0].as_mv.col) > motion_thresh) |
return 1; |
} |
} |
@@ -1359,6 +1370,7 @@ |
} |
x->skip = ctx->skip; |
+ x->skip_txfm = mbmi->segment_id ? 0 : ctx->skip_txfm; |
} |
static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile, |
@@ -1538,7 +1550,7 @@ |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
if (none_rate < INT_MAX) { |
- none_rate += x->partition_cost[pl][PARTITION_NONE]; |
+ none_rate += cpi->partition_cost[pl][PARTITION_NONE]; |
none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist); |
} |
@@ -1636,7 +1648,7 @@ |
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_rate += cpi->partition_cost[pl][partition]; |
last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist); |
} |
@@ -1689,11 +1701,11 @@ |
pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx, |
split_subsize); |
- chosen_rate += x->partition_cost[pl][PARTITION_NONE]; |
+ chosen_rate += cpi->partition_cost[pl][PARTITION_NONE]; |
} |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
if (chosen_rate < INT_MAX) { |
- chosen_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
+ chosen_rate += cpi->partition_cost[pl][PARTITION_SPLIT]; |
chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist); |
} |
} |
@@ -1877,8 +1889,8 @@ |
BLOCK_SIZE min_size = BLOCK_32X32; |
BLOCK_SIZE max_size = BLOCK_8X8; |
int bsl = mi_width_log2_lookup[BLOCK_64X64]; |
- int search_range_ctrl = (((mi_row + mi_col) >> bsl) + |
- cpi->sf.chessboard_index) & 0x01; |
+ const int search_range_ctrl = (((mi_row + mi_col) >> bsl) + |
+ get_chessboard_index(cm)) % 2; |
// Trap case where we do not have a prediction. |
if (search_range_ctrl && |
(left_in_image || above_in_image || cm->frame_type != KEY_FRAME)) { |
@@ -2015,7 +2027,7 @@ |
if (this_rate != INT_MAX) { |
if (bsize >= BLOCK_8X8) { |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
- this_rate += x->partition_cost[pl][PARTITION_NONE]; |
+ this_rate += cpi->partition_cost[pl][PARTITION_NONE]; |
} |
sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); |
if (sum_rd < best_rd) { |
@@ -2103,7 +2115,7 @@ |
if (sum_rd < best_rd && i == 4) { |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
- sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
+ sum_rate += cpi->partition_cost[pl][PARTITION_SPLIT]; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd) { |
best_rate = sum_rate; |
@@ -2157,7 +2169,7 @@ |
} |
if (sum_rd < best_rd) { |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
- sum_rate += x->partition_cost[pl][PARTITION_HORZ]; |
+ sum_rate += cpi->partition_cost[pl][PARTITION_HORZ]; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd) { |
best_rd = sum_rd; |
@@ -2206,7 +2218,7 @@ |
} |
if (sum_rd < best_rd) { |
pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
- sum_rate += x->partition_cost[pl][PARTITION_VERT]; |
+ sum_rate += cpi->partition_cost[pl][PARTITION_VERT]; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd) { |
best_rate = sum_rate; |
@@ -2268,17 +2280,16 @@ |
int64_t dummy_dist; |
int i; |
- MACROBLOCK *x = &cpi->mb; |
if (sf->adaptive_pred_interp_filter) { |
for (i = 0; i < 64; ++i) |
- x->leaf_tree[i].pred_interp_filter = SWITCHABLE; |
+ cpi->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; |
+ cpi->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE; |
+ cpi->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE; |
+ cpi->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE; |
+ cpi->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE; |
} |
} |
@@ -2298,18 +2309,18 @@ |
set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, |
sf->always_this_block_size); |
rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, cpi->pc_root); |
} 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, mi_row, mi_col, bsize); |
rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, cpi->pc_root); |
} else if (sf->partition_search_type == VAR_BASED_PARTITION) { |
choose_partitioning(cpi, tile, mi_row, mi_col); |
rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, cpi->pc_root); |
} else { |
if ((cm->current_video_frame |
% sf->last_partitioning_redo_frequency) == 0 |
@@ -2319,7 +2330,7 @@ |
|| cpi->rc.is_src_frame_alt_ref |
|| ((sf->use_lastframe_partitioning == |
LAST_FRAME_PARTITION_LOW_MOTION) && |
- sb_has_motion(cm, prev_mi))) { |
+ sb_has_motion(cm, prev_mi, sf->lf_motion_threshold))) { |
// If required set upper and lower partition size limits |
if (sf->auto_min_max_partition_size) { |
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
@@ -2328,16 +2339,17 @@ |
&sf->max_partition_size); |
} |
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, |
+ cpi->pc_root); |
} else { |
if (sf->constrain_copy_partition && |
- sb_has_motion(cm, prev_mi)) |
+ sb_has_motion(cm, prev_mi, sf->lf_motion_threshold)) |
constrain_copy_partitioning(cpi, tile, mi, prev_mi, |
mi_row, mi_col, BLOCK_16X16); |
else |
copy_partitioning(cm, mi, prev_mi); |
rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, cpi->pc_root); |
} |
} |
} else { |
@@ -2349,7 +2361,7 @@ |
&sf->max_partition_size); |
} |
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root); |
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, cpi->pc_root); |
} |
} |
} |
@@ -2374,22 +2386,6 @@ |
sizeof(*xd->above_seg_context) * aligned_mi_cols); |
} |
-static void switch_lossless_mode(VP9_COMP *cpi, int lossless) { |
- if (lossless) { |
- // printf("Switching to lossless\n"); |
- cpi->mb.fwd_txm4x4 = vp9_fwht4x4; |
- cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add; |
- cpi->mb.optimize = 0; |
- cpi->common.lf.filter_level = 0; |
- cpi->zbin_mode_boost_enabled = 0; |
- cpi->common.tx_mode = ONLY_4X4; |
- } else { |
- // printf("Not lossless\n"); |
- cpi->mb.fwd_txm4x4 = vp9_fdct4x4; |
- cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; |
- } |
-} |
- |
static int check_dual_ref_flags(VP9_COMP *cpi) { |
const int ref_flags = cpi->ref_frame_flags; |
@@ -2401,15 +2397,15 @@ |
} |
} |
-static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) { |
+static void reset_skip_tx_size(VP9_COMMON *cm, TX_SIZE max_tx_size) { |
int mi_row, mi_col; |
const int mis = cm->mi_stride; |
MODE_INFO **mi_ptr = cm->mi_grid_visible; |
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; |
+ if (mi_ptr[mi_col]->mbmi.tx_size > max_tx_size) |
+ mi_ptr[mi_col]->mbmi.tx_size = max_tx_size; |
} |
} |
} |
@@ -2426,7 +2422,7 @@ |
} |
static TX_MODE select_tx_mode(const VP9_COMP *cpi) { |
- if (cpi->oxcf.lossless) { |
+ if (cpi->mb.e_mbd.lossless) { |
return ONLY_4X4; |
} else if (cpi->common.current_video_frame == 0) { |
return TX_MODE_SELECT; |
@@ -2439,6 +2435,8 @@ |
return rd_opt->tx_select_threshes[frame_type][ALLOW_32X32] > |
rd_opt->tx_select_threshes[frame_type][TX_MODE_SELECT] ? |
ALLOW_32X32 : TX_MODE_SELECT; |
+ } else if (cpi->sf.tx_size_search_method == USE_TX_8X8) { |
+ return ALLOW_8X8; |
} else { |
unsigned int total = 0; |
int i; |
@@ -2455,18 +2453,6 @@ |
} |
} |
-// Start RTC Exploration |
-typedef enum { |
- BOTH_ZERO = 0, |
- ZERO_PLUS_PREDICTED = 1, |
- BOTH_PREDICTED = 2, |
- NEW_PLUS_NON_INTRA = 3, |
- BOTH_NEW = 4, |
- INTRA_PLUS_NON_INTRA = 5, |
- BOTH_INTRA = 6, |
- INVALID_CASE = 9 |
-} motion_vector_context; |
- |
static void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize, |
PREDICTION_MODE mode) { |
mbmi->mode = mode; |
@@ -2488,17 +2474,21 @@ |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
+ MB_MODE_INFO *mbmi; |
set_offsets(cpi, tile, mi_row, mi_col, bsize); |
- xd->mi[0]->mbmi.sb_type = bsize; |
+ mbmi = &xd->mi[0]->mbmi; |
+ mbmi->sb_type = bsize; |
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) { |
- if (xd->mi[0]->mbmi.segment_id && x->in_static_area) |
+ if (mbmi->segment_id && x->in_static_area) |
x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh); |
} |
if (!frame_is_intra_only(cm)) { |
- vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, |
- rate, dist, bsize); |
+ if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) |
+ set_mode_info_seg_skip(x, cm->tx_mode, rate, dist, bsize); |
+ else |
+ vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rate, dist, bsize); |
} else { |
set_mode_info(&xd->mi[0]->mbmi, bsize, DC_PRED); |
} |
@@ -2624,10 +2614,11 @@ |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, |
&this_rate, &this_dist, bsize); |
ctx->mic.mbmi = xd->mi[0]->mbmi; |
+ ctx->skip_txfm = x->skip_txfm; |
if (this_rate != INT_MAX) { |
int pl = partition_plane_context(xd, mi_row, mi_col, bsize); |
- this_rate += x->partition_cost[pl][PARTITION_NONE]; |
+ this_rate += cpi->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; |
@@ -2665,7 +2656,7 @@ |
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]; |
+ sum_rate += cpi->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; |
@@ -2710,6 +2701,7 @@ |
&this_rate, &this_dist, subsize); |
pc_tree->horizontal[0].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->horizontal[0].skip_txfm = x->skip_txfm; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
@@ -2719,12 +2711,13 @@ |
&this_rate, &this_dist, subsize); |
pc_tree->horizontal[1].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->horizontal[1].skip_txfm = x->skip_txfm; |
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]; |
+ this_rate += cpi->partition_cost[pl][PARTITION_HORZ]; |
sum_rate += this_rate; |
sum_dist += this_dist; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
@@ -2748,17 +2741,19 @@ |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, |
&this_rate, &this_dist, subsize); |
pc_tree->vertical[0].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->vertical[0].skip_txfm = x->skip_txfm; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) { |
load_pred_mv(x, ctx); |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms, |
&this_rate, &this_dist, subsize); |
pc_tree->vertical[1].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->vertical[1].skip_txfm = x->skip_txfm; |
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]; |
+ this_rate += cpi->partition_cost[pl][PARTITION_VERT]; |
sum_rate += this_rate; |
sum_dist += this_dist; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
@@ -2842,14 +2837,17 @@ |
case PARTITION_NONE: |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); |
pc_tree->none.mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->none.skip_txfm = x->skip_txfm; |
break; |
case PARTITION_VERT: |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); |
pc_tree->vertical[0].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->vertical[0].skip_txfm = x->skip_txfm; |
if (mi_col + hbs < cm->mi_cols) { |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs, |
&rate, &dist, subsize); |
pc_tree->vertical[1].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->vertical[1].skip_txfm = x->skip_txfm; |
if (rate != INT_MAX && dist != INT64_MAX && |
*totrate != INT_MAX && *totdist != INT64_MAX) { |
*totrate += rate; |
@@ -2860,10 +2858,12 @@ |
case PARTITION_HORZ: |
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); |
pc_tree->horizontal[0].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->horizontal[0].skip_txfm = x->skip_txfm; |
if (mi_row + hbs < cm->mi_rows) { |
nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col, |
&rate, &dist, subsize); |
- pc_tree->horizontal[1].mic.mbmi = mi[0]->mbmi; |
+ pc_tree->horizontal[1].mic.mbmi = xd->mi[0]->mbmi; |
+ pc_tree->horizontal[1].skip_txfm = x->skip_txfm; |
if (rate != INT_MAX && dist != INT64_MAX && |
*totrate != INT_MAX && *totdist != INT64_MAX) { |
*totrate += rate; |
@@ -2944,12 +2944,12 @@ |
case VAR_BASED_PARTITION: |
choose_partitioning(cpi, tile, mi_row, mi_col); |
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- 1, &dummy_rate, &dummy_dist, x->pc_root); |
+ 1, &dummy_rate, &dummy_dist, cpi->pc_root); |
break; |
case SOURCE_VAR_BASED_PARTITION: |
set_source_var_based_partition(cpi, tile, mi, mi_row, mi_col); |
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- 1, &dummy_rate, &dummy_dist, x->pc_root); |
+ 1, &dummy_rate, &dummy_dist, cpi->pc_root); |
break; |
case VAR_BASED_FIXED_PARTITION: |
case FIXED_PARTITION: |
@@ -2958,7 +2958,7 @@ |
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col); |
set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, bsize); |
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
- 1, &dummy_rate, &dummy_dist, x->pc_root); |
+ 1, &dummy_rate, &dummy_dist, cpi->pc_root); |
break; |
case REFERENCE_PARTITION: |
if (cpi->sf.partition_check || |
@@ -2969,12 +2969,12 @@ |
&cpi->sf.max_partition_size); |
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX, |
- x->pc_root); |
+ cpi->pc_root); |
} else { |
copy_partitioning(cm, mi, prev_mi); |
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, |
BLOCK_64X64, 1, &dummy_rate, &dummy_dist, |
- x->pc_root); |
+ cpi->pc_root); |
} |
break; |
default: |
@@ -2998,6 +2998,33 @@ |
cm->show_frame; |
} |
+static void encode_tiles(VP9_COMP *cpi) { |
+ const VP9_COMMON *const cm = &cpi->common; |
+ const int tile_cols = 1 << cm->log2_tile_cols; |
+ const int tile_rows = 1 << cm->log2_tile_rows; |
+ int tile_col, tile_row; |
+ TOKENEXTRA *tok = cpi->tok; |
+ |
+ for (tile_row = 0; tile_row < tile_rows; ++tile_row) { |
+ for (tile_col = 0; tile_col < tile_cols; ++tile_col) { |
+ TileInfo tile; |
+ TOKENEXTRA *old_tok = tok; |
+ int mi_row; |
+ |
+ vp9_tile_init(&tile, cm, tile_row, tile_col); |
+ for (mi_row = tile.mi_row_start; mi_row < tile.mi_row_end; |
+ mi_row += MI_BLOCK_SIZE) { |
+ if (cpi->sf.use_nonrd_pick_mode && cm->frame_type != KEY_FRAME) |
+ encode_nonrd_sb_row(cpi, &tile, mi_row, &tok); |
+ else |
+ encode_rd_sb_row(cpi, &tile, mi_row, &tok); |
+ } |
+ cpi->tok_count[tile_row][tile_col] = (unsigned int)(tok - old_tok); |
+ assert(tok - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); |
+ } |
+ } |
+} |
+ |
static void encode_frame_internal(VP9_COMP *cpi) { |
SPEED_FEATURES *const sf = &cpi->sf; |
RD_OPT *const rd_opt = &cpi->rd; |
@@ -3016,14 +3043,22 @@ |
vp9_zero(rd_opt->tx_select_diff); |
vp9_zero(rd_opt->tx_select_threshes); |
- cm->tx_mode = select_tx_mode(cpi); |
- |
cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && |
cm->y_dc_delta_q == 0 && |
cm->uv_dc_delta_q == 0 && |
cm->uv_ac_delta_q == 0; |
- switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless); |
+ cm->tx_mode = select_tx_mode(cpi); |
+ |
+ cpi->mb.fwd_txm4x4 = cpi->mb.e_mbd.lossless ? vp9_fwht4x4 : vp9_fdct4x4; |
+ cpi->mb.itxm_add = cpi->mb.e_mbd.lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; |
+ |
+ if (cpi->mb.e_mbd.lossless) { |
+ cpi->mb.optimize = 0; |
+ cpi->common.lf.filter_level = 0; |
+ cpi->zbin_mode_boost_enabled = 0; |
+ } |
+ |
vp9_frame_init_quantizer(cpi); |
vp9_initialize_rd_consts(cpi); |
@@ -3031,13 +3066,14 @@ |
init_encode_frame_mb_context(cpi); |
set_prev_mi(cm); |
+ x->skip_txfm = 0; |
if (sf->use_nonrd_pick_mode) { |
// Initialize internal buffer pointers for rtc coding, where non-RD |
// mode decision is used and hence no buffer pointer swap needed. |
int i; |
struct macroblock_plane *const p = x->plane; |
struct macroblockd_plane *const pd = xd->plane; |
- PICK_MODE_CONTEXT *ctx = &x->pc_root->none; |
+ PICK_MODE_CONTEXT *ctx = &cpi->pc_root->none; |
for (i = 0; i < MAX_MB_PLANE; ++i) { |
p[i].coeff = ctx->coeff_pbuf[i][0]; |
@@ -3075,34 +3111,8 @@ |
struct vpx_usec_timer emr_timer; |
vpx_usec_timer_start(&emr_timer); |
- { |
- // Take tiles into account and give start/end MB |
- int tile_col, tile_row; |
- TOKENEXTRA *tp = cpi->tok; |
- const int tile_cols = 1 << cm->log2_tile_cols; |
- const int tile_rows = 1 << cm->log2_tile_rows; |
+ encode_tiles(cpi); |
- for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
- for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
- TileInfo tile; |
- TOKENEXTRA *tp_old = tp; |
- int mi_row; |
- |
- // For each row of SBs in the frame |
- vp9_tile_init(&tile, cm, tile_row, tile_col); |
- for (mi_row = tile.mi_row_start; |
- mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) { |
- if (sf->use_nonrd_pick_mode && cm->frame_type != KEY_FRAME) |
- encode_nonrd_sb_row(cpi, &tile, mi_row, &tp); |
- else |
- encode_rd_sb_row(cpi, &tile, mi_row, &tp); |
- } |
- cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); |
- assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); |
- } |
- } |
- } |
- |
vpx_usec_timer_mark(&emr_timer); |
cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer); |
} |
@@ -3245,16 +3255,16 @@ |
if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 && |
count32x32 == 0) { |
cm->tx_mode = ALLOW_8X8; |
- reset_skip_txfm_size(cm, TX_8X8); |
+ reset_skip_tx_size(cm, TX_8X8); |
} else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 && |
count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) { |
cm->tx_mode = ONLY_4X4; |
- reset_skip_txfm_size(cm, TX_4X4); |
+ reset_skip_tx_size(cm, TX_4X4); |
} else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) { |
cm->tx_mode = ALLOW_32X32; |
} else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) { |
cm->tx_mode = ALLOW_16X16; |
- reset_skip_txfm_size(cm, TX_16X16); |
+ reset_skip_tx_size(cm, TX_16X16); |
} |
} |
} else { |
@@ -3315,7 +3325,7 @@ |
const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
- x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 && |
+ x->skip_recode = !x->select_tx_size && mbmi->sb_type >= BLOCK_8X8 && |
cpi->oxcf.aq_mode != COMPLEXITY_AQ && |
cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ && |
cpi->sf.allow_skip_recode; |
@@ -3362,7 +3372,8 @@ |
vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); |
} else { |
mbmi->skip = 1; |
- if (output_enabled) |
+ if (output_enabled && |
+ !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) |
cm->counts.skip[vp9_get_skip_context(xd)][1]++; |
reset_skip_context(xd, MAX(bsize, BLOCK_8X8)); |
} |