Added update-able mv-ref probabilities.

Part of NEW_MVREF experiment.
Added update-able probabilities.

Change-Id: I5a4fcf4aaed1d0d1dac980f69d535639a3d59401
This commit is contained in:
Paul Wilkins 2012-12-10 12:38:48 +00:00
parent 89ac94f8fb
commit 313d1100af
10 changed files with 144 additions and 51 deletions

View File

@ -362,7 +362,7 @@ typedef struct macroblockd {
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

View File

@ -25,6 +25,13 @@ void vp9_adapt_nmv_probs(struct VP9Common *cm, int usehp);
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 */

View File

@ -591,11 +591,6 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *bc) {
}
#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);
}
}
@ -936,7 +931,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
// 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;
@ -945,7 +940,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
// 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;
}
}

View File

@ -1608,6 +1608,33 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
}
}
#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",

View File

@ -12,6 +12,7 @@
#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"
@ -259,6 +260,56 @@ static void update_mode_probs(VP9_COMMON *cm,
}
}
}
#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);
}
@ -912,17 +963,13 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
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
@ -1964,7 +2011,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
// 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);
@ -1986,6 +2033,37 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
}
}
#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,

View File

@ -392,7 +392,7 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
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);
@ -413,7 +413,7 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
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);
@ -422,8 +422,6 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
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;
@ -555,6 +553,7 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
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;
@ -563,6 +562,7 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
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
}
@ -1443,11 +1443,6 @@ static void encode_frame_internal(VP9_COMP *cpi) {
// 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
{
@ -1496,6 +1491,9 @@ static void encode_frame_internal(VP9_COMP *cpi) {
#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);

View File

@ -2992,11 +2992,6 @@ static void encode_frame_to_data_rate(VP9_COMP *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) {
@ -3789,19 +3784,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// 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");

View File

@ -800,7 +800,7 @@ typedef struct VP9_COMP {
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;

View File

@ -277,6 +277,16 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
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) {

View File

@ -3256,11 +3256,6 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
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,
@ -3300,8 +3295,7 @@ 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)
@ -3328,8 +3322,10 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
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) {