};
static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
- 220, 220, 200, 200, 180, 128, 1, 250,
+ 220, 220, 200, 200, 180, 128, 30, 220, 30,
};
#endif
#if CONFIG_REF_MV
#define NEWMV_MODE_CONTEXTS 7
#define ZEROMV_MODE_CONTEXTS 2
-#define REFMV_MODE_CONTEXTS 8
+#define REFMV_MODE_CONTEXTS 9
#define ZEROMV_OFFSET 3
#define REFMV_OFFSET 4
#define ALL_ZERO_FLAG_OFFSET 8
#define SKIP_NEARESTMV_OFFSET 9
#define SKIP_NEARMV_OFFSET 10
+#define SKIP_NEARESTMV_SUB8X8_OFFSET 11
#endif
#define INTER_MODE_CONTEXTS 7
}
static void handle_sec_rect_block(const MB_MODE_INFO * const candidate,
- uint8_t *refmv_count,
+ uint8_t refmv_count,
CANDIDATE_MV *ref_mv_stack,
MV_REFERENCE_FRAME ref_frame,
int16_t *mode_context) {
for (rf = 0; rf < 2; ++rf) {
if (candidate->ref_frame[rf] == ref_frame) {
- const int list_range = VPXMIN(*refmv_count, MAX_MV_REF_CANDIDATES);
+ const int list_range = VPXMIN(refmv_count, MAX_MV_REF_CANDIDATES);
const int_mv pred_mv = candidate->mv[rf];
for (idx = 0; idx < list_range; ++idx)
break;
if (idx < list_range) {
- mode_context[ref_frame] &= ~(0x0f << REFMV_OFFSET);
-
- if (idx == 0) {
+ if (idx == 0)
mode_context[ref_frame] |= (1 << SKIP_NEARESTMV_OFFSET);
- mode_context[ref_frame] |= (6 << REFMV_OFFSET);
- } else if (idx == 1) {
+ else if (idx == 1)
mode_context[ref_frame] |= (1 << SKIP_NEARMV_OFFSET);
- mode_context[ref_frame] |= (7 << REFMV_OFFSET);
- }
}
}
}
if (xd->n8_w < xd->n8_h) {
const MODE_INFO *const candidate_mi = xd->mi[-1];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
- handle_sec_rect_block(candidate, refmv_count, ref_mv_stack,
+ handle_sec_rect_block(candidate, nearest_refmv_count, ref_mv_stack,
ref_frame, mode_context);
}
if (xd->n8_w > xd->n8_h) {
const MODE_INFO *const candidate_mi = xd->mi[-xd->mi_stride];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
- handle_sec_rect_block(candidate, refmv_count, ref_mv_stack,
+ handle_sec_rect_block(candidate, nearest_refmv_count, ref_mv_stack,
ref_frame, mode_context);
}
}
mi_col + mi_pos->col >= tile->mi_col_end);
}
+#if CONFIG_REF_MV
+static int16_t vp10_mode_context_analyzer(const int16_t *const mode_context,
+ const MV_REFERENCE_FRAME *const rf,
+ BLOCK_SIZE bsize, int block) {
+ int16_t mode_ctx = 0;
+ if (block >= 0) {
+ mode_ctx = mode_context[rf[0]] & 0x00ff;
+
+ if (block > 0 && bsize < BLOCK_8X8 && bsize > BLOCK_4X4)
+ mode_ctx |= (1 << SKIP_NEARESTMV_SUB8X8_OFFSET);
+
+ return mode_ctx;
+ }
+
+ if (rf[1] > INTRA_FRAME)
+ return mode_context[rf[0]] & (mode_context[rf[1]] | 0x00ff);
+ else if (rf[0] != ALTREF_FRAME)
+ return mode_context[rf[0]] & ~(mode_context[ALTREF_FRAME] & 0xfe00);
+ else
+ return mode_context[rf[0]];
+}
+#endif
+
typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
++counts->zeromv_mode[mode_ctx][1];
mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+ if (ctx & (1 << SKIP_NEARESTMV_OFFSET))
+ mode_ctx = 6;
+ if (ctx & (1 << SKIP_NEARMV_OFFSET))
+ mode_ctx = 7;
+ if (ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+ mode_ctx = 8;
+
mode_prob = cm->fc->refmv_prob[mode_ctx];
if (vpx_read(r, mode_prob) == 0) {
int ref, is_compound;
int16_t inter_mode_ctx[MAX_REF_FRAMES];
int16_t mode_ctx = 0;
+ MV_REFERENCE_FRAME ref_frame;
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
is_compound = has_second_ref(mbmi);
for (ref = 0; ref < 1 + is_compound; ++ref) {
- const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
+ MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
xd->block_refs[ref] = ref_buf;
"Reference frame has invalid dimensions");
vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
&ref_buf->sf);
- vp10_find_mv_refs(cm, xd, mi, frame,
+ }
+
+ for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) {
+ vp10_find_mv_refs(cm, xd, mi, ref_frame,
#if CONFIG_REF_MV
- &xd->ref_mv_count[frame],
- xd->ref_mv_stack[frame],
+ &xd->ref_mv_count[ref_frame],
+ xd->ref_mv_stack[ref_frame],
#endif
- ref_mvs[frame],
+ ref_mvs[ref_frame],
mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
}
mode_ctx = inter_mode_ctx[mbmi->ref_frame[0]];
#if CONFIG_REF_MV
- if (mbmi->ref_frame[1] > NONE)
- mode_ctx &= (inter_mode_ctx[mbmi->ref_frame[1]] | 0x00ff);
- if (bsize < BLOCK_8X8)
- mode_ctx &= 0x00ff;
+ mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,
+ mbmi->ref_frame, bsize, -1);
#endif
if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
for (idx = 0; idx < 2; idx += num_4x4_w) {
int_mv block[2];
const int j = idy * 2 + idx;
+#if CONFIG_REF_MV
+ mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx, mbmi->ref_frame,
+ bsize, j);
+#endif
b_mode = read_inter_mode(cm, xd, r, mode_ctx);
if (b_mode == NEARESTMV || b_mode == NEARMV) {
vpx_write(w, mode != ZEROMV, zeromv_prob);
if (mode != ZEROMV) {
- const int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
- const vpx_prob refmv_prob = cm->fc->refmv_prob[refmv_ctx];
+ int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+ vpx_prob refmv_prob;
+
+ if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET))
+ refmv_ctx = 6;
+ if (mode_ctx & (1 << SKIP_NEARMV_OFFSET))
+ refmv_ctx = 7;
+ if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+ refmv_ctx = 8;
+
+ refmv_prob = cm->fc->refmv_prob[refmv_ctx];
vpx_write(w, mode != NEARESTMV, refmv_prob);
}
}
write_ref_frames(cm, xd, w);
#if CONFIG_REF_MV
- if (mbmi->ref_frame[1] > NONE)
- mode_ctx &= (mbmi_ext->mode_context[mbmi->ref_frame[1]] | 0x00ff);
- if (bsize < BLOCK_8X8)
- mode_ctx &= 0x00ff;
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, bsize, -1);
#endif
// If segment skip is not enabled code the mode.
for (idx = 0; idx < 2; idx += num_4x4_w) {
const int j = idy * 2 + idx;
const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
+#if CONFIG_REF_MV
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, bsize, j);
+#endif
write_inter_mode(cm, w, b_mode, mode_ctx);
if (b_mode == NEWMV) {
for (ref = 0; ref < 1 + is_compound; ++ref)
} else {
++counts->zeromv_mode[mode_ctx][1];
mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+ if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
+ mode_ctx = 6;
+ if (mode_context & (1 << SKIP_NEARMV_OFFSET))
+ mode_ctx = 7;
+ if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+ mode_ctx = 8;
+
++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
}
}
if (bsize >= BLOCK_8X8) {
const PREDICTION_MODE mode = mbmi->mode;
#if CONFIG_REF_MV
- if (mbmi->ref_frame[1] > NONE)
- mode_ctx &= (mbmi_ext->mode_context[mbmi->ref_frame[1]] | 0x00ff);
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, bsize, -1);
update_inter_mode_stats(counts, mode, mode_ctx);
#else
++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
const int j = idy * 2 + idx;
const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
#if CONFIG_REF_MV
- mode_ctx &= 0x00ff;
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, bsize, j);
update_inter_mode_stats(counts, b_mode, mode_ctx);
#else
++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
// update_base_skip_probs(cpi);
vpx_clear_system_state();
-
// Dummy pack of the bitstream using up to date stats to get an
// accurate estimate of output frame size to determine if we need
// to recode.
} else {
mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+ if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
+ mode_ctx = 6;
+ if (mode_context & (1 << SKIP_NEARMV_OFFSET))
+ mode_ctx = 7;
+ if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+ mode_ctx = 8;
+
mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
return mode_cost;
}
memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
#if CONFIG_REF_MV
- mode_ctx &= 0x00ff;
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, mbmi->sb_type, i);
#endif
return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
}
static int check_best_zero_mv(
const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
- const MV_REFERENCE_FRAME ref_frames[2]) {
+ const MV_REFERENCE_FRAME ref_frames[2],
+ const BLOCK_SIZE bsize, int block) {
if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
(ref_frames[1] == NONE ||
frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
#if CONFIG_REF_MV
- int16_t rfc = (ref_frames[1] == NONE) ? mode_context[ref_frames[0]] :
- mode_context[ref_frames[0]] & (mode_context[ref_frames[1]] | 0x00ff);
+ int16_t rfc = vp10_mode_context_analyzer(mode_context,
+ ref_frames, bsize, block);
#else
int16_t rfc = mode_context[ref_frames[0]];
#endif
int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
+#if !CONFIG_REF_MV
+ (void)bsize;
+ (void)block;
+#endif
+
if (this_mode == NEARMV) {
if (c1 > c3) return 0;
} else if (this_mode == NEARESTMV) {
continue;
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
- this_mode, mbmi->ref_frame))
+ this_mode, mbmi->ref_frame, bsize, i))
continue;
memcpy(orig_pre, pd->pre, sizeof(orig_pre));
}
}
-
-
static INLINE void restore_dst_buf(MACROBLOCKD *xd,
uint8_t *orig_dst[MAX_MB_PLANE],
int orig_dst_stride[MAX_MB_PLANE]) {
int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
#if CONFIG_REF_MV
- if (refs[1] > NONE)
- mode_ctx &= (mbmi_ext->mode_context[refs[1]] | 0x00ff);
+ mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+ mbmi->ref_frame, bsize, -1);
#endif
#if CONFIG_VP9_HIGHBITDEPTH
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
+ x->mbmi_ext->mode_context[ref_frame] = 0;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
} else {
const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
- this_mode, ref_frames))
+ this_mode, ref_frames, bsize, -1))
continue;
}
#endif
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+ x->mbmi_ext->mode_context[ref_frame] = 0;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV],