B_D63_PRED,
B_TM_PRED,
- LEFT4X4,
- ABOVE4X4,
- ZERO4X4,
- NEW4X4,
-
B_MODE_COUNT
} B_PREDICTION_MODE;
-#define VP9_BINTRAMODES (LEFT4X4)
-#define VP9_SUBMVREFS (1 + NEW4X4 - LEFT4X4)
+#define VP9_BINTRAMODES (B_MODE_COUNT)
#define VP9_KF_BINTRAMODES (VP9_BINTRAMODES) /* 10 */
#define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES) /* 10 */
43891, 10036, 3920, 3363, 2546, 5119, 2471, 1723, 3221, 17694
};
-typedef enum {
- SUBMVREF_NORMAL,
- SUBMVREF_LEFT_ZED,
- SUBMVREF_ABOVE_ZED,
- SUBMVREF_LEFT_ABOVE_SAME,
- SUBMVREF_LEFT_ABOVE_ZED
-} sumvfref_t;
-
-int vp9_mv_cont(const int_mv *l, const int_mv *a) {
- const int lez = (l->as_int == 0);
- const int aez = (a->as_int == 0);
- const int lea = (l->as_int == a->as_int);
-
- if (lea && lez)
- return SUBMVREF_LEFT_ABOVE_ZED;
-
- if (lea)
- return SUBMVREF_LEFT_ABOVE_SAME;
-
- if (aez)
- return SUBMVREF_ABOVE_ZED;
-
- if (lez)
- return SUBMVREF_LEFT_ZED;
-
- return SUBMVREF_NORMAL;
-}
-
-const vp9_prob vp9_sub_mv_ref_prob2 [SUBMVREF_COUNT][VP9_SUBMVREFS - 1] = {
- { 147, 136, 18 },
- { 106, 145, 1 },
- { 179, 121, 1 },
- { 223, 1, 34 },
- { 208, 1, 1 }
-};
-
const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS]
[PARTITION_TYPES - 1] = {
// FIXME(jingning,rbultje) put real probabilities here
-NEARMV, -NEWMV
};
-const vp9_tree_index vp9_sub_mv_ref_tree[6] = {
- -LEFT4X4, 2,
- -ABOVE4X4, 4,
- -ZERO4X4, -NEW4X4
-};
-
const vp9_tree_index vp9_partition_tree[6] = {
-PARTITION_NONE, 2,
-PARTITION_HORZ, 4,
struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
-struct vp9_token vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS];
struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
bct, uv_mode_cts[i], 0);
}
- vpx_memcpy(x->fc.sub_mv_ref_prob, vp9_sub_mv_ref_prob2,
- sizeof(vp9_sub_mv_ref_prob2));
vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
sizeof(vp9_switchable_interp_prob));
vp9_mv_ref_tree, NEARESTMV);
vp9_tokens_from_tree_offset(vp9_sb_mv_ref_encoding_array,
vp9_sb_mv_ref_tree, NEARESTMV);
- vp9_tokens_from_tree_offset(vp9_sub_mv_ref_encoding_array,
- vp9_sub_mv_ref_tree, LEFT4X4);
}
void vp9_init_mode_contexts(VP9_COMMON *pc) {
for (t = 0; t < VP9_I8X8_MODES; ++t)
printf("%d, ", fc->i8x8_mode_counts[t]);
printf("};\n");
- printf("static const unsigned int\nsub_mv_ref_counts"
- "[SUBMVREF_COUNT] [VP9_SUBMVREFS] = {\n");
- for (i = 0; i < SUBMVREF_COUNT; ++i) {
- printf(" {");
- for (t = 0; t < VP9_SUBMVREFS; ++t)
- printf("%d, ", fc->sub_mv_ref_counts[i][t]);
- printf("},\n");
- }
- printf("};\n");
printf("static const unsigned int\nmbsplit_counts"
"[VP9_NUMMBSPLITS] = {\n");
for (t = 0; t < VP9_NUMMBSPLITS; ++t)
fc->bmode_counts, fc->pre_bmode_prob,
fc->bmode_prob, 0);
- for (i = 0; i < SUBMVREF_COUNT; ++i)
- update_mode_probs(VP9_SUBMVREFS,
- vp9_sub_mv_ref_tree, fc->sub_mv_ref_counts[i],
- fc->pre_sub_mv_ref_prob[i], fc->sub_mv_ref_prob[i],
- LEFT4X4);
-
for (i = 0; i < NUM_PARTITION_CONTEXTS; i++)
update_mode_probs(PARTITION_TYPES, vp9_partition_tree,
fc->partition_counts[i], fc->pre_partition_prob[i],
extern int vp9_mv_cont(const int_mv *l, const int_mv *a);
-extern const vp9_prob vp9_sub_mv_ref_prob2[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
-
extern const vp9_prob vp9_kf_default_bmode_probs[VP9_KF_BINTRAMODES]
[VP9_KF_BINTRAMODES]
[VP9_KF_BINTRAMODES -1 ];
extern struct vp9_token vp9_mv_ref_encoding_array[VP9_MVREFS];
extern struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_MVREFS];
-extern struct vp9_token vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS];
// probability models for partition information
extern const vp9_tree_index vp9_partition_tree[];
#include <limits.h>
#include "vp9/common/vp9_findnearmv.h"
+#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_sadmxn.h"
#include "vp9/common/vp9_subpelvar.h"
*nearest = mvlist[0];
*near = mvlist[1];
}
+
+void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
+ int_mv *dst_nearest,
+ int_mv *dst_near,
+ int block_idx, int ref_idx) {
+ int_mv dst_list[MAX_MV_REF_CANDIDATES];
+ int_mv mv_list[MAX_MV_REF_CANDIDATES];
+ MODE_INFO *mi = xd->mode_info_context;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
+ int use_prev_in_find_mv_refs;
+
+ assert(ref_idx == 0 || ref_idx == 1);
+ assert(MAX_MV_REF_CANDIDATES == 2); // makes code here slightly easier
+
+ use_prev_in_find_mv_refs = cm->width == cm->last_width &&
+ cm->height == cm->last_height &&
+ !cm->error_resilient_mode &&
+ cm->last_show_frame;
+ vp9_find_mv_refs_idx(cm, xd, xd->mode_info_context,
+ use_prev_in_find_mv_refs ?
+ xd->prev_mode_info_context : NULL,
+ ref_idx ? mbmi->second_ref_frame : mbmi->ref_frame,
+ mv_list, cm->ref_frame_sign_bias, block_idx);
+
+ dst_list[1].as_int = 0;
+ if (block_idx == 0) {
+ memcpy(dst_list, mv_list, MAX_MV_REF_CANDIDATES * sizeof(int_mv));
+ } else if (block_idx == 1 || block_idx == 2) {
+ int dst = 0, n;
+ union b_mode_info *bmi = mi->bmi;
+
+ dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
+ for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
+ n < MAX_MV_REF_CANDIDATES; n++)
+ if (mv_list[n].as_int != dst_list[0].as_int)
+ dst_list[dst++].as_int = mv_list[n].as_int;
+ } else {
+ int dst = 0, n;
+ union b_mode_info *bmi = mi->bmi;
+
+ assert(block_idx == 3);
+ dst_list[dst++].as_int = bmi[2].as_mv[ref_idx].as_int;
+ if (dst_list[0].as_int != bmi[1].as_mv[ref_idx].as_int)
+ dst_list[dst++].as_int = bmi[1].as_mv[ref_idx].as_int;
+ if (dst < MAX_MV_REF_CANDIDATES &&
+ dst_list[0].as_int != bmi[0].as_mv[ref_idx].as_int)
+ dst_list[dst++].as_int = bmi[0].as_mv[ref_idx].as_int;
+ for (n = 0; dst < MAX_MV_REF_CANDIDATES &&
+ n < MAX_MV_REF_CANDIDATES; n++)
+ if (mv_list[n].as_int != dst_list[0].as_int)
+ dst_list[dst++].as_int = mv_list[n].as_int;
+ }
+
+ dst_nearest->as_int = dst_list[0].as_int;
+ dst_near->as_int = dst_list[1].as_int;
+}
vp9_prob p[VP9_MVREFS - 1],
const int context);
-static int left_block_mv(const MACROBLOCKD *xd,
- const MODE_INFO *cur_mb, int b) {
- if (!(b & 1)) {
- if (!xd->left_available)
- return 0;
-
- // On L edge, get from MB to left of us
- --cur_mb;
-
- if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.mv[0].as_int;
-
- b += 2;
- }
-
- return (cur_mb->bmi + b - 1)->as_mv[0].as_int;
-}
-
-static int left_block_second_mv(const MACROBLOCKD *xd,
- const MODE_INFO *cur_mb, int b) {
- if (!(b & 1)) {
- if (!xd->left_available)
- return 0;
-
- /* On L edge, get from MB to left of us */
- --cur_mb;
-
- if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.second_ref_frame > 0 ?
- cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
- b += 2;
- }
-
- return cur_mb->mbmi.second_ref_frame > 0 ?
- (cur_mb->bmi + b - 1)->as_mv[1].as_int :
- (cur_mb->bmi + b - 1)->as_mv[0].as_int;
-}
-
-static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
- if (!(b >> 1)) {
- /* On top edge, get from MB above us */
- cur_mb -= mi_stride;
-
- if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.mv[0].as_int;
- b += 4;
- }
-
- return (cur_mb->bmi + b - 2)->as_mv[0].as_int;
-}
-
-static int above_block_second_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
- if (!(b >> 1)) {
- /* On top edge, get from MB above us */
- cur_mb -= mi_stride;
-
- if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.second_ref_frame > 0 ?
- cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
- b += 4;
- }
-
- return cur_mb->mbmi.second_ref_frame > 0 ?
- (cur_mb->bmi + b - 2)->as_mv[1].as_int :
- (cur_mb->bmi + b - 2)->as_mv[0].as_int;
-}
+void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *pc,
+ MACROBLOCKD *xd,
+ int_mv *dst_nearest,
+ int_mv *dst_near,
+ int block_idx, int ref_idx);
static MB_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) {
// FIXME(rbultje, jingning): temporary hack because jenkins doesn't
// structure if one exists that matches the given reference frame.
static int get_matching_candidate(const MODE_INFO *candidate_mi,
MV_REFERENCE_FRAME ref_frame,
- int_mv *c_mv) {
+ int_mv *c_mv, int block_idx) {
if (ref_frame == candidate_mi->mbmi.ref_frame) {
- c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
+ if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
+ c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int;
+ else
+ c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
} else if (ref_frame == candidate_mi->mbmi.second_ref_frame) {
- c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
+ if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
+ c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int;
+ else
+ c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
} else {
return 0;
}
// This function searches the neighbourhood of a given MB/SB
// to try and find candidate reference vectors.
//
-void vp9_find_mv_refs(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here,
- MODE_INFO *lf_here, MV_REFERENCE_FRAME ref_frame,
- int_mv *mv_ref_list, int *ref_sign_bias) {
+void vp9_find_mv_refs_idx(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here,
+ MODE_INFO *lf_here, MV_REFERENCE_FRAME ref_frame,
+ int_mv *mv_ref_list, int *ref_sign_bias,
+ int block_idx) {
int i;
MODE_INFO *candidate_mi;
MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
int intra_count = 0;
int zero_count = 0;
int newmv_count = 0;
+ int x_idx = 0, y_idx = 0;
// Blank the reference vector lists and other local structures.
vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
mv_ref_search = mb_mv_ref_search;
} else {
mv_ref_search = b_mv_ref_search;
+ if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
+ x_idx = block_idx & 1;
+ y_idx = block_idx >> 1;
+ }
}
// We first scan for candidate vectors that match the current reference frame
if ((mi_search_col >= cm->cur_tile_mi_col_start) &&
(mi_search_col < cm->cur_tile_mi_col_end) &&
((mv_ref_search[i][1] << 6) >= xd->mb_to_top_edge)) {
+ int b;
candidate_mi = here + mv_ref_search[i][0] +
(mv_ref_search[i][1] * xd->mode_info_stride);
- if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ if (block_idx >= 0) {
+ if (mv_ref_search[i][0])
+ b = 1 + y_idx * 2;
+ else
+ b = 2 + x_idx;
+ } else {
+ b = -1;
+ }
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, b)) {
add_candidate_mv(mv_ref_list, candidate_scores,
&refmv_count, c_refmv, 16);
}
candidate_mi = here + mv_ref_search[i][0] +
(mv_ref_search[i][1] * xd->mode_info_stride);
- if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, -1)) {
add_candidate_mv(mv_ref_list, candidate_scores,
&refmv_count, c_refmv, 16);
}
// Look in the last frame if it exists
if (lf_here && (refmv_count < MAX_MV_REF_CANDIDATES)) {
candidate_mi = lf_here;
- if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, block_idx)) {
add_candidate_mv(mv_ref_list, candidate_scores,
&refmv_count, c_refmv, 16);
}
#ifndef VP9_COMMON_VP9_MVREF_COMMON_H_
#define VP9_COMMON_VP9_MVREF_COMMON_H_
-void vp9_find_mv_refs(VP9_COMMON *cm,
- MACROBLOCKD *xd,
- MODE_INFO *here,
- MODE_INFO *lf_here,
- MV_REFERENCE_FRAME ref_frame,
- int_mv *mv_ref_list,
- int *ref_sign_bias);
+void vp9_find_mv_refs_idx(VP9_COMMON *cm,
+ MACROBLOCKD *xd,
+ MODE_INFO *here,
+ MODE_INFO *lf_here,
+ MV_REFERENCE_FRAME ref_frame,
+ int_mv *mv_ref_list,
+ int *ref_sign_bias,
+ int block_idx);
+
+static INLINE void vp9_find_mv_refs(VP9_COMMON *cm,
+ MACROBLOCKD *xd,
+ MODE_INFO *here,
+ MODE_INFO *lf_here,
+ MV_REFERENCE_FRAME ref_frame,
+ int_mv *mv_ref_list,
+ int *ref_sign_bias) {
+ vp9_find_mv_refs_idx(cm, xd, here, lf_here, ref_frame,
+ mv_ref_list, ref_sign_bias, -1);
+}
#endif // VP9_COMMON_VP9_MVREF_COMMON_H_
vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob sb_ymode_prob[VP9_I32X32_MODES - 1];
vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
- vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
nmv_context nmvc;
vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob pre_sb_ymode_prob[VP9_I32X32_MODES - 1];
vp9_prob pre_uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
- vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
unsigned int bmode_counts[VP9_NKF_BINTRAMODES];
unsigned int ymode_counts[VP9_YMODES]; /* interframe intra mode probs */
unsigned int sb_ymode_counts[VP9_I32X32_MODES];
unsigned int uv_mode_counts[VP9_YMODES][VP9_UV_MODES];
- unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS];
unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
vp9_coeff_probs_model coef_probs_4x4[BLOCK_TYPES];
return (MB_PREDICTION_MODE) treed_read(r, vp9_mv_ref_tree, p);
}
-static B_PREDICTION_MODE read_sub_mv_ref(vp9_reader *r, const vp9_prob *p) {
- return (B_PREDICTION_MODE) treed_read(r, vp9_sub_mv_ref_tree, p);
-}
-
#ifdef VPX_MODE_COUNT
unsigned int vp9_mv_cont_count[5][4] = {
{ 0, 0, 0, 0 },
vp9_reader *r) {
VP9_COMMON *const cm = &pbi->common;
nmv_context *const nmvc = &cm->fc.nmvc;
- const int mis = cm->mode_info_stride;
MACROBLOCKD *const xd = &pbi->mb;
int_mv *const mv0 = &mbmi->mv[0];
mbmi->need_to_clamp_mvs = 0;
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
- int_mv leftmv, abovemv, second_leftmv, second_abovemv;
int_mv blockmv, secondmv;
- int mv_contz;
int blockmode;
- int i, k;
+ int i;
j = idy * 2 + idx;
- k = j;
-
- leftmv.as_int = left_block_mv(xd, mi, k);
- abovemv.as_int = above_block_mv(mi, k, mis);
- second_leftmv.as_int = 0;
- second_abovemv.as_int = 0;
- if (mbmi->second_ref_frame > 0) {
- second_leftmv.as_int = left_block_second_mv(xd, mi, k);
- second_abovemv.as_int = above_block_second_mv(mi, k, mis);
+
+ blockmode = read_sb_mv_ref(r, mv_ref_p);
+ vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref_frame]);
+ if (blockmode == NEARESTMV || blockmode == NEARMV) {
+ MV_REFERENCE_FRAME rf2 = mbmi->second_ref_frame;
+ vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
+ if (rf2 > 0) {
+ vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest_second,
+ &nearby_second, j, 1);
+ }
}
- mv_contz = vp9_mv_cont(&leftmv, &abovemv);
- blockmode = read_sub_mv_ref(r, cm->fc.sub_mv_ref_prob[mv_contz]);
- cm->fc.sub_mv_ref_counts[mv_contz][blockmode - LEFT4X4]++;
switch (blockmode) {
- case NEW4X4:
+ case NEWMV:
decode_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
&cm->fc.NMVcount, xd->allow_high_precision_mv);
vp9_mv_cont_count[mv_contz][3]++;
#endif
break;
- case LEFT4X4:
- blockmv.as_int = leftmv.as_int;
+ case NEARESTMV:
+ blockmv.as_int = nearest.as_int;
if (mbmi->second_ref_frame > 0)
- secondmv.as_int = second_leftmv.as_int;
+ secondmv.as_int = nearest_second.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][0]++;
#endif
break;
- case ABOVE4X4:
- blockmv.as_int = abovemv.as_int;
+ case NEARMV:
+ blockmv.as_int = nearby.as_int;
if (mbmi->second_ref_frame > 0)
- secondmv.as_int = second_abovemv.as_int;
+ secondmv.as_int = nearby_second.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][1]++;
#endif
break;
- case ZERO4X4:
+ case ZEROMV:
blockmv.as_int = 0;
if (mbmi->second_ref_frame > 0)
secondmv.as_int = 0;
vp9_copy(fc->pre_sb_ymode_prob, fc->sb_ymode_prob);
vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob);
vp9_copy(fc->pre_bmode_prob, fc->bmode_prob);
- vp9_copy(fc->pre_sub_mv_ref_prob, fc->sub_mv_ref_prob);
vp9_copy(fc->pre_partition_prob, fc->partition_prob);
fc->pre_nmvc = fc->nmvc;
vp9_zero(fc->sb_ymode_counts);
vp9_zero(fc->uv_mode_counts);
vp9_zero(fc->bmode_counts);
- vp9_zero(fc->sub_mv_ref_counts);
vp9_zero(fc->NMVcount);
vp9_zero(fc->mv_ref_ct);
vp9_zero(fc->partition_counts);
vp9_sb_mv_ref_encoding_array - NEARESTMV + m);
}
-static void write_sub_mv_ref(vp9_writer *bc, B_PREDICTION_MODE m,
- const vp9_prob *p) {
-#if CONFIG_DEBUG
- assert(LEFT4X4 <= m && m <= NEW4X4);
-#endif
- write_token(bc, vp9_sub_mv_ref_tree, p,
- vp9_sub_mv_ref_encoding_array - LEFT4X4 + m);
-}
-
-
// This function writes the current macro block's segnment id to the bitstream
// It should only be called if a segment map update is indicated.
static void write_mb_segid(vp9_writer *bc,
const nmv_context *nmvc = &pc->fc.nmvc;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
- const int mis = pc->mode_info_stride;
MB_MODE_INFO *const mi = &m->mbmi;
const MV_REFERENCE_FRAME rf = mi->ref_frame;
const MB_PREDICTION_MODE mode = mi->mode;
break;
case SPLITMV: {
int j;
- B_PREDICTION_MODE blockmode;
+ MB_PREDICTION_MODE blockmode;
int_mv blockmv;
- int k = -1; /* first block in subset j */
- int mv_contz;
- int_mv leftmv, abovemv;
int bwl = b_width_log2(mi->sb_type), bw = 1 << bwl;
int bhl = b_height_log2(mi->sb_type), bh = 1 << bhl;
int idx, idy;
j = idy * 2 + idx;
blockmode = cpi->mb.partition_info->bmi[j].mode;
blockmv = cpi->mb.partition_info->bmi[j].mv;
- k = j;
- leftmv.as_int = left_block_mv(xd, m, k);
- abovemv.as_int = above_block_mv(m, k, mis);
- mv_contz = vp9_mv_cont(&leftmv, &abovemv);
-
- write_sub_mv_ref(bc, blockmode,
- cpi->common.fc.sub_mv_ref_prob[mv_contz]);
- cpi->sub_mv_ref_count[mv_contz][blockmode - LEFT4X4]++;
- if (blockmode == NEW4X4) {
+ write_sb_mv_ref(bc, blockmode, mv_ref_p);
+ vp9_accum_mv_refs(&cpi->common, blockmode, mi->mb_mode_context[rf]);
+ if (blockmode == NEWMV) {
#ifdef ENTROPY_STATS
active_section = 11;
#endif
vp9_copy(cpi->common.fc.pre_ymode_prob, cpi->common.fc.ymode_prob);
vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob);
vp9_copy(cpi->common.fc.pre_bmode_prob, cpi->common.fc.bmode_prob);
- vp9_copy(cpi->common.fc.pre_sub_mv_ref_prob, cpi->common.fc.sub_mv_ref_prob);
vp9_copy(cpi->common.fc.pre_partition_prob, cpi->common.fc.partition_prob);
cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
- vp9_zero(cpi->sub_mv_ref_count);
vp9_zero(cpi->common.fc.mv_ref_ct);
update_coef_probs(cpi, &header_bc);
typedef struct {
int count;
struct {
- B_PREDICTION_MODE mode;
+ MB_PREDICTION_MODE mode;
int_mv mv;
int_mv second_mv;
} bmi[4];
vp9_zero(cpi->bmode_count)
vp9_zero(cpi->ymode_count)
vp9_zero(cpi->y_uv_mode_count)
- vp9_zero(cpi->sub_mv_ref_count)
vp9_zero(cpi->common.fc.mv_ref_ct)
vp9_zero(cpi->sb_ymode_count)
vp9_zero(cpi->partition_count);
for (idy = 0; idy < 2; idy += bh) {
for (idx = 0; idx < 2; idx += bw) {
i = idy * 2 + idx;
- if (pi->bmi[i].mode == NEW4X4) {
+ if (pi->bmi[i].mode == NEWMV) {
mv.row = (pi->bmi[i].mv.as_mv.row - best_ref_mv->as_mv.row);
mv.col = (pi->bmi[i].mv.as_mv.col - best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount,
}
vp9_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T);
- vp9_cost_tokens((int *)c->mb.inter_bmode_costs,
- x->fc.sub_mv_ref_prob[0], vp9_sub_mv_ref_tree);
// TODO(rbultje) separate tables for superblock costing?
vp9_cost_tokens(c->mb.mbmode_cost[1], x->fc.sb_ymode_prob,
vp9_copy(cpi->common.fc.ymode_counts, cpi->ymode_count);
vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count);
vp9_copy(cpi->common.fc.bmode_counts, cpi->bmode_count);
- vp9_copy(cpi->common.fc.sub_mv_ref_counts, cpi->sub_mv_ref_count);
vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count);
cpi->common.fc.NMVcount = cpi->NMVcount;
if (!cpi->common.error_resilient_mode &&
// Don't increment frame counters if this was an altref buffer
// update not a real frame
+ cm->last_show_frame = cm->show_frame;
if (cm->show_frame) {
++cm->current_video_frame;
++cpi->frames_since_key;
vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1];
vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
- vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1];
vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1];
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
int sb_ymode_count [VP9_I32X32_MODES];
int ymode_count[VP9_YMODES]; /* intra MB type cts this frame */
int bmode_count[VP9_NKF_BINTRAMODES];
- int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
unsigned int partition_count[NUM_PARTITION_CONTEXTS][PARTITION_TYPES];
vp9_copy(cc->sb_ymode_prob, cm->fc.sb_ymode_prob);
vp9_copy(cc->bmode_prob, cm->fc.bmode_prob);
vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob);
- vp9_copy(cc->sub_mv_ref_prob, cm->fc.sub_mv_ref_prob);
vp9_copy(cc->partition_prob, cm->fc.partition_prob);
vp9_copy(cc->segment_pred_probs, cm->segment_pred_probs);
vp9_copy(cm->fc.sb_ymode_prob, cc->sb_ymode_prob);
vp9_copy(cm->fc.bmode_prob, cc->bmode_prob);
vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob);
- vp9_copy(cm->fc.sub_mv_ref_prob, cc->sub_mv_ref_prob);
vp9_copy(cm->fc.partition_prob, cc->partition_prob);
vp9_copy(cm->segment_pred_probs, cc->segment_pred_probs);
int const *labelings, int which_label,
B_PREDICTION_MODE this_mode,
int_mv *this_mv, int_mv *this_second_mv,
+ int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
int_mv seg_mvs[MAX_REF_FRAMES - 1],
int_mv *best_ref_mv,
int_mv *second_best_ref_mv,
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mode_info_context;
MB_MODE_INFO * mbmi = &mic->mbmi;
- const int mis = xd->mode_info_stride;
int i, cost = 0, thismvcost = 0;
int idx, idy;
int bw = 1 << b_width_log2(mbmi->sb_type);
Ones from this macroblock have to be pulled from the BLOCKD array
as they have not yet made it to the bmi array in our MB_MODE_INFO. */
for (i = 0; i < 4; ++i) {
- const int row = i >> 1, col = i & 1;
- B_PREDICTION_MODE m;
+ MB_PREDICTION_MODE m;
if (labelings[i] != which_label)
continue;
- if (col && labelings[i] == labelings[i - 1])
- m = LEFT4X4;
- else if (row && labelings[i] == labelings[i - 2])
- m = ABOVE4X4;
- else {
+ {
// the only time we should do costing for new motion vector or mode
// is when we are on a new label (jbb May 08, 2007)
switch (m = this_mode) {
- case NEW4X4 :
+ case NEWMV:
if (mbmi->second_ref_frame > 0) {
this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
this_second_mv->as_int =
xd->allow_high_precision_mv);
}
break;
- case LEFT4X4:
- this_mv->as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
- left_block_mv(xd, mic, i);
+ case NEARESTMV:
+ this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame].as_int;
if (mbmi->second_ref_frame > 0)
- this_second_mv->as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
- left_block_second_mv(xd, mic, i);
+ this_second_mv->as_int =
+ frame_mv[NEARESTMV][mbmi->second_ref_frame].as_int;
break;
- case ABOVE4X4:
- this_mv->as_int = row ? mic->bmi[i - 2].as_mv[0].as_int :
- above_block_mv(mic, i, mis);
+ case NEARMV:
+ this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame].as_int;
if (mbmi->second_ref_frame > 0)
- this_second_mv->as_int = row ? mic->bmi[i - 2].as_mv[1].as_int :
- above_block_second_mv(mic, i, mis);
+ this_second_mv->as_int =
+ frame_mv[NEARMV][mbmi->second_ref_frame].as_int;
break;
- case ZERO4X4:
+ case ZEROMV:
this_mv->as_int = 0;
if (mbmi->second_ref_frame > 0)
this_second_mv->as_int = 0;
break;
}
- if (m == ABOVE4X4) { // replace above with left if same
- int_mv left_mv, left_second_mv;
-
- left_second_mv.as_int = 0;
- left_mv.as_int = col ? mic->bmi[i - 1].as_mv[0].as_int :
- left_block_mv(xd, mic, i);
- if (mbmi->second_ref_frame > 0)
- left_second_mv.as_int = col ? mic->bmi[i - 1].as_mv[1].as_int :
- left_block_second_mv(xd, mic, i);
-
- if (left_mv.as_int == this_mv->as_int &&
- (mbmi->second_ref_frame <= 0 ||
- left_second_mv.as_int == this_second_mv->as_int))
- m = LEFT4X4;
- }
- cost = x->inter_bmode_costs[m];
+ cost = vp9_cost_mv_ref(cpi, this_mode,
+ mbmi->mb_mode_context[mbmi->ref_frame]);
}
mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
int i, j;
static const int labels[4] = { 0, 1, 2, 3 };
int br = 0, bd = 0;
- B_PREDICTION_MODE this_mode;
+ MB_PREDICTION_MODE this_mode;
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
const int label_count = 4;
int64_t this_segment_rd = 0, other_segment_rd;
for (idx = 0; idx < 2; idx += bw) {
// TODO(jingning,rbultje): rewrite the rate-distortion optimization
// loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
-#if CONFIG_AB4X4 || 1
- int_mv mode_mv[B_MODE_COUNT], second_mode_mv[B_MODE_COUNT];
+ int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT];
+ int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
int64_t best_label_rd = INT64_MAX, best_other_rd = INT64_MAX;
- B_PREDICTION_MODE mode_selected = ZERO4X4;
+ MB_PREDICTION_MODE mode_selected = ZEROMV;
int bestlabelyrate = 0;
i = idy * 2 + idx;
- // search for the best motion vector on this segment
- for (this_mode = LEFT4X4; this_mode <= NEW4X4; ++this_mode) {
- int64_t this_rd;
- int distortion;
- int labelyrate;
- ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
-
- vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
- vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
-
- // motion search for newmv (single predictor case only)
- if (mbmi->second_ref_frame <= 0 && this_mode == NEW4X4) {
- int sseshift, n;
- int step_param = 0;
- int further_steps;
- int thissme, bestsme = INT_MAX;
- const struct buf_2d orig_src = x->plane[0].src;
- const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
-
- /* Is the best so far sufficiently good that we cant justify doing
- * and new motion search. */
- if (best_label_rd < label_mv_thresh)
- break;
-
- if (cpi->compressor_speed) {
- // use previous block's result as next block's MV predictor.
- if (i > 0) {
- bsi->mvp.as_int =
- x->e_mbd.mode_info_context->bmi[i - 1].as_mv[0].as_int;
- if (i == 2)
- bsi->mvp.as_int =
- x->e_mbd.mode_info_context->bmi[i - 2].as_mv[0].as_int;
- step_param = 2;
- }
- }
-
- further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
-
- {
- int sadpb = x->sadperbit4;
- int_mv mvp_full;
-
- mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
- mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
-
- // find first label
- n = i;
-
- // adjust src pointer for this segment
- x->plane[0].src.buf =
- raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
- x->plane[0].src.buf,
- x->plane[0].src.stride);
- assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
- x->e_mbd.plane[0].pre[0].buf =
- raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, n,
- x->e_mbd.plane[0].pre[0].buf,
- x->e_mbd.plane[0].pre[0].stride);
-
- bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
- sadpb, further_steps, 0, v_fn_ptr,
- bsi->ref_mv, &mode_mv[NEW4X4]);
-
- sseshift = 0;
-
- // Should we do a full search (best quality only)
- if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) {
- /* Check if mvp_full is within the range. */
- clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
- x->mv_row_min, x->mv_row_max);
-
- thissme = cpi->full_search_sad(x, &mvp_full,
- sadpb, 16, v_fn_ptr,
- x->nmvjointcost, x->mvcost,
- bsi->ref_mv,
- n);
-
- if (thissme < bestsme) {
- bestsme = thissme;
- mode_mv[NEW4X4].as_int =
- x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int;
- } else {
- /* The full search result is actually worse so re-instate the
- * previous best vector */
- x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int =
- mode_mv[NEW4X4].as_int;
- }
- }
- }
-
- if (bestsme < INT_MAX) {
- int distortion;
- unsigned int sse;
- cpi->find_fractional_mv_step(x, &mode_mv[NEW4X4],
- bsi->ref_mv, x->errorperbit, v_fn_ptr,
- x->nmvjointcost, x->mvcost,
- &distortion, &sse);
-
- // safe motion search result for use in compound prediction
- seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int;
- }
-
- // restore src pointers
- x->plane[0].src = orig_src;
- x->e_mbd.plane[0].pre[0] = orig_pre;
- } else if (mbmi->second_ref_frame > 0 && this_mode == NEW4X4) {
- /* NEW4X4 */
- /* motion search not completed? Then skip newmv for this block with
- * comppred */
- if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
- seg_mvs[i][mbmi->ref_frame - 1].as_int == INVALID_MV) {
- continue;
- }
- }
-
- rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
- &second_mode_mv[this_mode], seg_mvs[i],
- bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
- x->mvcost, cpi);
-
- // Trap vectors that reach beyond the UMV borders
- if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) ||
- ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
- ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) ||
- ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
- continue;
- }
- if (mbmi->second_ref_frame > 0 &&
- mv_check_bounds(x, &second_mode_mv[this_mode]))
- continue;
-
- this_rd = encode_inter_mb_segment(&cpi->common,
- x, labels, i, &labelyrate,
- &distortion, t_above_s, t_left_s);
- this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0);
- rate += labelyrate;
-
- if (this_rd < best_label_rd) {
- sbr = rate;
- sbd = distortion;
- bestlabelyrate = labelyrate;
- mode_selected = this_mode;
- best_label_rd = this_rd;
- for (j = 0; j < 4; j++)
- if (labels[j] == i)
- best_eobs[j] = x->e_mbd.plane[0].eobs[j];
-
- vpx_memcpy(t_above_b, t_above_s, sizeof(t_above_s));
- vpx_memcpy(t_left_b, t_left_s, sizeof(t_left_s));
- }
- } /*for each 4x4 mode*/
-
- vpx_memcpy(t_above, t_above_b, sizeof(t_above));
- vpx_memcpy(t_left, t_left_b, sizeof(t_left));
-
- labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
- &second_mode_mv[mode_selected], seg_mvs[i],
- bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
- x->mvcost, cpi);
-#else
- int_mv mode_mv[B_MODE_COUNT], second_mode_mv[B_MODE_COUNT];
- int64_t best_label_rd = INT64_MAX, best_other_rd = INT64_MAX;
- B_PREDICTION_MODE mode_selected = ZERO4X4;
- int bestlabelyrate = 0;
- i = idy * 2 + idx;
+ frame_mv[ZEROMV][mbmi->ref_frame].as_int = 0;
+ frame_mv[ZEROMV][mbmi->second_ref_frame].as_int = 0;
+ vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd,
+ &frame_mv[NEARESTMV][mbmi->ref_frame],
+ &frame_mv[NEARMV][mbmi->ref_frame],
+ i, 0);
+ if (mbmi->second_ref_frame > 0)
+ vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd,
+ &frame_mv[NEARESTMV][mbmi->second_ref_frame],
+ &frame_mv[NEARMV][mbmi->second_ref_frame],
+ i, 1);
// search for the best motion vector on this segment
- for (this_mode = LEFT4X4; this_mode <= NEW4X4; this_mode ++) {
+ for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
int64_t this_rd;
int distortion;
int labelyrate;
- ENTROPY_CONTEXT t_above_s[2], t_left_s[2];
+ ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
// motion search for newmv (single predictor case only)
- if (mbmi->second_ref_frame <= 0 && this_mode == NEW4X4) {
+ if (mbmi->second_ref_frame <= 0 && this_mode == NEWMV) {
int sseshift, n;
int step_param = 0;
int further_steps;
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 0, v_fn_ptr,
- bsi->ref_mv, &mode_mv[NEW4X4]);
+ bsi->ref_mv, &mode_mv[NEWMV]);
sseshift = 0;
if (thissme < bestsme) {
bestsme = thissme;
- mode_mv[NEW4X4].as_int =
+ mode_mv[NEWMV].as_int =
x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int;
} else {
/* The full search result is actually worse so re-instate the
* previous best vector */
x->e_mbd.mode_info_context->bmi[n].as_mv[0].as_int =
- mode_mv[NEW4X4].as_int;
+ mode_mv[NEWMV].as_int;
}
}
}
if (bestsme < INT_MAX) {
int distortion;
unsigned int sse;
- cpi->find_fractional_mv_step(x, &mode_mv[NEW4X4],
+ cpi->find_fractional_mv_step(x, &mode_mv[NEWMV],
bsi->ref_mv, x->errorperbit, v_fn_ptr,
x->nmvjointcost, x->mvcost,
&distortion, &sse);
// safe motion search result for use in compound prediction
- seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int;
+ seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEWMV].as_int;
}
// restore src pointers
x->plane[0].src = orig_src;
x->e_mbd.plane[0].pre[0] = orig_pre;
- } else if (mbmi->second_ref_frame > 0 && this_mode == NEW4X4) {
+ } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
/* NEW4X4 */
/* motion search not completed? Then skip newmv for this block with
* comppred */
}
rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
- &second_mode_mv[this_mode], seg_mvs[i],
+ &second_mode_mv[this_mode], frame_mv, seg_mvs[i],
bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
x->mvcost, cpi);
vpx_memcpy(t_left, t_left_b, sizeof(t_left));
labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
- &second_mode_mv[mode_selected], seg_mvs[i],
+ &second_mode_mv[mode_selected], frame_mv, seg_mvs[i],
bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
x->mvcost, cpi);
-#endif
br += sbr;
bd += sbd;
bsi.mvthresh = mvthresh;
for (i = 0; i < 4; i++)
- bsi.modes[i] = ZERO4X4;
+ bsi.modes[i] = ZEROMV;
rd_check_segment(cpi, x, &bsi, seg_mvs);