From: Paul Wilkins Date: Mon, 10 Dec 2012 12:38:48 +0000 (+0000) Subject: Added update-able mv-ref probabilities. X-Git-Tag: v1.3.0~1210^2~42 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=313d1100afad5544fb719897bbd24fe9fcc41d90;p=platform%2Fupstream%2Flibvpx.git Added update-able mv-ref probabilities. Part of NEW_MVREF experiment. Added update-able probabilities. Change-Id: I5a4fcf4aaed1d0d1dac980f69d535639a3d59401 --- diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index ad5f3b3..c430ea2 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -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 diff --git a/vp9/common/vp9_entropymv.h b/vp9/common/vp9_entropymv.h index dcdd0ec..f5cfee9 100644 --- a/vp9/common/vp9_entropymv.h +++ b/vp9/common/vp9_entropymv.h @@ -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 */ diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index f36a224..f846117 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -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; } } diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index c3a17ef..af34582 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -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", diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 54d44fa..956c16c 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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, diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 63fc1a9..b7a5b80 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -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); diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 9e43673..5043bc4 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -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"); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 0c2b8cc..6452be3 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -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; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 540a680..08ad54b 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -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) { diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 69bc892..0d4c2b6 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -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) {