Part of NEW_MVREF experiment.
Added update-able probabilities.
Change-Id: I5a4fcf4aaed1d0d1dac980f69d535639a3d59401
vp9_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
#if CONFIG_NEW_MVREF
- vp9_prob mb_mv_ref_id_probs[MAX_REF_FRAMES][3];
+ vp9_prob mb_mv_ref_probs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES-1];
#endif
// Segment features
int vp9_use_nmv_hp(const MV *ref);
#define VP9_NMV_UPDATE_PROB 255
+
+#if CONFIG_NEW_MVREF
+#define VP9_MVREF_UPDATE_PROB 252
+#define VP9_DEFAULT_MV_REF_PROB 192
+#define VP9_MV_REF_UPDATE_COST (14 << 8)
+#endif
+
//#define MV_GROUP_UPDATE
#define LOW_PRECISION_MV_UPDATE /* Use 7 bit forward update */
}
#endif
-#if CONFIG_NEW_MVREF
- // Temp defaults probabilities for ecnoding the MV ref id signal
- vpx_memset(xd->mb_mv_ref_id_probs, 192, sizeof(xd->mb_mv_ref_id_probs));
-#endif
-
read_nmvprobs(bc, nmvc, xd->allow_high_precision_mv);
}
}
// Encode the index of the choice.
best_index =
- vp9_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);
+ vp9_read_mv_ref_id(bc, xd->mb_mv_ref_probs[ref_frame]);
best_mv.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
// Encode the index of the choice.
best_index =
- vp9_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);
+ vp9_read_mv_ref_id(bc, xd->mb_mv_ref_probs[ref_frame]);
best_mv_second.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
}
}
}
}
+#if CONFIG_NEW_MVREF
+ // If Key frame reset mv ref id probabilities to defaults
+ if (pc->frame_type == KEY_FRAME) {
+ // Defaults probabilities for encoding the MV ref id signal
+ vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
+ sizeof(xd->mb_mv_ref_probs));
+ } else {
+ // Read any mv_ref index probability updates
+ int i, j;
+
+ for (i = 0; i < MAX_REF_FRAMES; ++i) {
+ // Skip the dummy entry for intra ref frame.
+ if (i == INTRA_FRAME) {
+ continue;
+ }
+
+ // Read any updates to probabilities
+ for (j = 0; j < MAX_MV_REF_CANDIDATES - 1; ++j) {
+ if (vp9_read(&header_bc, VP9_MVREF_UPDATE_PROB)) {
+ xd->mb_mv_ref_probs[i][j] =
+ (vp9_prob)vp9_read_literal(&header_bc, 8);
+ }
+ }
+ }
+ }
+#endif
+
if (0) {
FILE *z = fopen("decodestats.stt", "a");
fprintf(z, "%6d F:%d,G:%d,A:%d,L:%d,Q:%d\n",
#include "vp9/common/vp9_header.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/common/vp9_entropymode.h"
+#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_findnearmv.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/common/vp9_systemdependent.h"
}
}
}
+
+#if CONFIG_NEW_MVREF
+static void update_mv_ref_probs(VP9_COMP *cpi,
+ int mvref_probs[MAX_REF_FRAMES]
+ [MAX_MV_REF_CANDIDATES-1]) {
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+ int rf; // Reference frame
+ int ref_c; // Motion reference candidate
+ int node; // Probability node index
+
+ for (rf = 0; rf < MAX_REF_FRAMES; ++rf) {
+ int count = 0;
+
+ // Skip the dummy entry for intra ref frame.
+ if (rf == INTRA_FRAME) {
+ continue;
+ }
+
+ // Sum the counts for all candidates
+ for (ref_c = 0; ref_c < MAX_MV_REF_CANDIDATES; ++ref_c) {
+ count += cpi->mb_mv_ref_count[rf][ref_c];
+ }
+
+ // Calculate the tree node probabilities
+ for (node = 0; node < MAX_MV_REF_CANDIDATES-1; ++node) {
+ int new_prob, old_cost, new_cost;
+ unsigned int branch_cnts[2];
+
+ // How many hits on each branch at this node
+ branch_cnts[0] = cpi->mb_mv_ref_count[rf][node];
+ branch_cnts[1] = count - cpi->mb_mv_ref_count[rf][node];
+
+ // Work out cost of coding branches with the old and optimal probability
+ old_cost = cost_branch256(branch_cnts, xd->mb_mv_ref_probs[rf][node]);
+ new_prob = get_prob(branch_cnts[0], count);
+ new_cost = cost_branch256(branch_cnts, new_prob);
+
+ // Take current 0 branch cases out of residual count
+ count -= cpi->mb_mv_ref_count[rf][node];
+
+ if ((new_cost + VP9_MV_REF_UPDATE_COST) <= old_cost) {
+ mvref_probs[rf][node] = new_prob;
+ } else {
+ mvref_probs[rf][node] = xd->mb_mv_ref_probs[rf][node];
+ }
+ }
+ }
+}
+#endif
+
static void write_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
write_token(bc, vp9_ymode_tree, p, vp9_ymode_encodings + m);
}
if (mode == NEWMV) {
// Encode the index of the choice.
vp9_write_mv_ref_id(bc,
- xd->mb_mv_ref_id_probs[rf], mi->best_index);
- cpi->best_ref_index_counts[rf][mi->best_index]++;
+ xd->mb_mv_ref_probs[rf], mi->best_index);
if (mi->second_ref_frame > 0) {
// Encode the index of the choice.
vp9_write_mv_ref_id(
- bc, xd->mb_mv_ref_id_probs[mi->second_ref_frame],
+ bc, xd->mb_mv_ref_probs[mi->second_ref_frame],
mi->best_second_index);
-
- cpi->best_ref_index_counts[mi->second_ref_frame]
- [mi->best_second_index]++;
}
}
#endif
// If appropriate update the inter mode probability context and code the
// changes in the bitstream.
- if ((pc->frame_type != KEY_FRAME)) {
+ if (pc->frame_type != KEY_FRAME) {
int i, j;
int new_context[INTER_MODE_CONTEXTS][4];
update_mode_probs(pc, new_context);
}
}
+#if CONFIG_NEW_MVREF
+ if ((pc->frame_type != KEY_FRAME)) {
+ int new_mvref_probs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES-1];
+ int i, j;
+
+ update_mv_ref_probs(cpi, new_mvref_probs);
+
+ for (i = 0; i < MAX_REF_FRAMES; ++i) {
+ // Skip the dummy entry for intra ref frame.
+ if (i == INTRA_FRAME) {
+ continue;
+ }
+
+ // Encode any mandated updates to probabilities
+ for (j = 0; j < MAX_MV_REF_CANDIDATES - 1; ++j) {
+ if (new_mvref_probs[i][j] != xd->mb_mv_ref_probs[i][j]) {
+ vp9_write(&header_bc, 1, VP9_MVREF_UPDATE_PROB);
+ vp9_write_literal(&header_bc, new_mvref_probs[i][j], 8);
+
+ // Only update the persistent copy if this is the "real pack"
+ if (!cpi->dummy_packing) {
+ xd->mb_mv_ref_probs[i][j] = new_mvref_probs[i][j];
+ }
+ } else {
+ vp9_write(&header_bc, 0, VP9_MVREF_UPDATE_PROB);
+ }
+ }
+ }
+ }
+#endif
+
vp9_clear_system_state(); // __asm emms;
vp9_copy(cpi->common.fc.pre_coef_probs_4x4,
MACROBLOCKD *xd = &x->e_mbd;
int max_mv = MV_MAX;
- cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], 0) +
+ cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], 0) +
vp9_mv_bit_cost(&target_mv, &mv_ref_list[0], x->nmvjointcost,
x->mvcost, 96, xd->allow_high_precision_mv);
continue;
}
- cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], i) +
+ cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], i) +
vp9_mv_bit_cost(&target_mv, &mv_ref_list[i], x->nmvjointcost,
x->mvcost, 96, xd->allow_high_precision_mv);
best_index = i;
}
}
-
- // best_index = x->mv_best_ref_index[ref_frame];
best_ref->as_int = mv_ref_list[best_index].as_int;
return best_index;
best_index = pick_best_mv_ref(x, rf, mbmi->mv[0],
mbmi->ref_mvs[rf], &best_mv);
mbmi->best_index = best_index;
+ ++cpi->mb_mv_ref_count[rf][best_index];
if (mbmi->second_ref_frame > 0) {
unsigned int best_index;
mbmi->ref_mvs[sec_ref_frame],
&best_second_mv);
mbmi->best_second_index = best_index;
+ ++cpi->mb_mv_ref_count[sec_ref_frame][best_index];
}
#endif
}
// this frame which may be updated with each iteration of the recode loop.
vp9_compute_mod_refprobs(cm);
-#if CONFIG_NEW_MVREF
- // temp stats reset
- vp9_zero( cpi->best_ref_index_counts );
-#endif
-
// debug output
#if DBG_PRNT_SEGMAP
{
#if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
vp9_zero(cpi->coef_counts_32x32);
#endif
+#if CONFIG_NEW_MVREF
+ vp9_zero(cpi->mb_mv_ref_count);
+#endif
vp9_frame_init_quantizer(cpi);
// Set default state for segment based loop filter update flags
xd->mode_ref_lf_delta_update = 0;
-#if CONFIG_NEW_MVREF
- // Temp defaults probabilities for ecnoding the MV ref id signal
- vpx_memset(xd->mb_mv_ref_id_probs, 192,
- sizeof(xd->mb_mv_ref_id_probs));
-#endif
// Set various flags etc to special state if it is a key frame
if (cm->frame_type == KEY_FRAME) {
// in this frame.
update_base_skip_probs(cpi);
-#if 0 //CONFIG_NEW_MVREF && CONFIG_INTERNAL_STATS
- {
- FILE *f = fopen("mv_ref_dist.stt", "a");
- unsigned int i;
- for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
- fprintf(f, "%10d", cpi->best_ref_index_counts[0][i]);
- }
- fprintf(f, "\n" );
-
- fclose(f);
- }
-#endif
-
#if 0// 1 && CONFIG_INTERNAL_STATS
{
FILE *f = fopen("tmp.stt", "a");
unsigned int switchable_interp_count[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS];
#if CONFIG_NEW_MVREF
- unsigned int best_ref_index_counts[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
+ unsigned int mb_mv_ref_count[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
#endif
} VP9_COMP;
vp9_update_mode_info_border(cm, cm->mip);
vp9_update_mode_info_in_image(cm, cm->mi);
+
+#if CONFIG_NEW_MVREF
+ if (1) {
+ MACROBLOCKD *xd = &cpi->mb.e_mbd;
+
+ // Defaults probabilities for encoding the MV ref id signal
+ vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
+ sizeof(xd->mb_mv_ref_probs));
+ }
+#endif
}
void vp9_setup_inter_frame(VP9_COMP *cpi) {
mv_pred(cpi, x, y_buffer[frame_type], yv12->y_stride,
frame_type, block_size);
-#if CONFIG_NEW_MVREF
- // TODO(paulwilkins): Final choice of which of the best 4 candidates from
- // above gives lowest error score when used in isolation. This stage encoder
- // and sets the reference MV
-#endif
}
static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
case NEWMV:
ref_mv[0] = mbmi->ref_mvs[refs[0]][0];
ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
- // ref_mv[0] = mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]];
- // ref_mv[1] = mbmi->ref_mvs[refs[1]][x->mv_best_ref_index[refs[1]]];
+
if (is_comp_pred) {
if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
vp9_clamp_mv_min_max(x, &ref_mv[0]);
+ // mvp_full.as_int = ref_mv[0].as_int;
mvp_full.as_int =
- mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;
+ mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;
+
mvp_full.as_mv.col >>= 3;
mvp_full.as_mv.row >>= 3;
if (mvp_full.as_int != mvp_full.as_int) {