From 2d60bee1fbfb7e5b6862e4e636151effabae98e3 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Fri, 24 Aug 2012 15:44:01 +0100 Subject: New Motion Reference Search Alternative strategy for finding a list of candidate motion vectors to use as reference values in mv coding and as nearest and near. Sort by sad in vp8_find_best_ref_mvs() rather than just pick the best. Allow 0,0 as a best ref option but not a nearest or near unless there are no alternatives. Encode/Decode verified on at least some clips. Some commented out experimental and stats code still in place. Gain over existing code averages about 1% on derf (alll metrics) with improvement on all clips. Other test results pending. The entropy coding of the mode (nearest/near etc) still depends upon and requires the old "findnear" code so this needs looking at and may provide room for further gains. Change-Id: I871d7cba1d1c379c4bad9bcccce1fb19c46b8247 --- vp8/encoder/bitstream.c | 22 ++++++++++++++++ vp8/encoder/encodeframe.c | 10 +++++++ vp8/encoder/onyx_if.c | 34 ++++++++++++++++++++++++ vp8/encoder/onyx_int.h | 13 +++++++++ vp8/encoder/rdopt.c | 67 ++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 143 insertions(+), 3 deletions(-) (limited to 'vp8/encoder') diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 90bc8e987..7e667aa63 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -28,6 +28,10 @@ #include "vp8/common/pred_common.h" #include "vp8/common/entropy.h" +#if CONFIG_NEW_MVREF +#include "vp8/common/mvref_common.h" +#endif + #if defined(SECTIONBITS_OUTPUT) unsigned __int64 Sectionbits[500]; #endif @@ -1043,12 +1047,30 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { active_section = 5; #endif +#if 0 //CONFIG_NEW_MVREF + find_mv_refs(xd, m, prev_m, + m->mbmi.ref_frame, + mi->ref_mvs[rf], + cpi->common.ref_frame_sign_bias ); + + pick_best_mv_ref( mi->mv[0], mi->ref_mvs[rf], &best_mv); +#endif if (xd->allow_high_precision_mv) write_mv_hp(w, &mi->mv[0].as_mv, &best_mv, mvc_hp); else write_mv(w, &mi->mv[0].as_mv, &best_mv, mvc); if (mi->second_ref_frame) { +#if 0 //CONFIG_NEW_MVREF + find_mv_refs(xd, m, prev_m, + m->mbmi.second_ref_frame, + mi->ref_mvs[mi->second_ref_frame], + cpi->common.ref_frame_sign_bias ); + + pick_best_mv_ref( mi->mv[1], + mi->ref_mvs[mi->second_ref_frame], + &best_second_mv); +#endif if (xd->allow_high_precision_mv) write_mv_hp(w, &mi->mv[1].as_mv, &best_second_mv, mvc_hp); else diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index f834e0b83..6ade0aa78 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -34,6 +34,10 @@ #include "vp8/common/pred_common.h" #define DBG_PRNT_SEGMAP 0 +#if CONFIG_NEW_MVREF +#include "vp8/common/mvref_common.h" +#endif + #if CONFIG_RUNTIME_CPU_DETECT #define RTCD(x) &cpi->common.rtcd.x @@ -1301,6 +1305,12 @@ static void encode_frame_internal(VP8_COMP *cpi) { // this frame which may be updated with each iteration of the recode loop. compute_mod_refprobs(cm); +#if CONFIG_NEW_MVREF + // temp stats reset + vp8_zero( cpi->mv_ref_sum_distance ); + vp8_zero( cpi->best_ref_index_counts ); +#endif + // debug output #if DBG_PRNT_SEGMAP { diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index c3df54481..85a3c5402 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -40,6 +40,10 @@ #include "bitstream.h" #include "ratectrl.h" +#if CONFIG_NEW_MVREF +#include "vp8/common/mvref_common.h" +#endif + #if ARCH_ARM #include "vpx_ports/arm.h" #endif @@ -3790,6 +3794,36 @@ static void encode_frame_to_data_rate // in this frame. update_base_skip_probs(cpi); + +#if CONFIG_NEW_MVREF +#if 0 && CONFIG_INTERNAL_STATS + { + FILE *f = fopen("mv_ref_dist.stt", "a"); + unsigned int i; + //fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %10d %10d\n", + fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %10d %10d", + cpi->common.current_video_frame, + cpi->mv_ref_sum_distance[1][0], + cpi->mv_ref_sum_distance[1][1], + cpi->mv_ref_sum_distance[1][2], + cpi->mv_ref_sum_distance[2][0], + cpi->mv_ref_sum_distance[2][1], + cpi->mv_ref_sum_distance[2][2], + cpi->mv_ref_sum_distance[3][0], + cpi->mv_ref_sum_distance[3][1], + cpi->mv_ref_sum_distance[3][2] ); + + for (i = 0; i < MAX_MV_REFS; ++i) { + fprintf(f, "%10d", cpi->best_ref_index_counts[i] ); + } + fprintf(f, "\n" ); + + fclose(f); + } +#endif +#endif + + #if 0// 1 && CONFIG_INTERNAL_STATS { FILE *f = fopen("tmp.stt", "a"); diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 7fb7dd2ff..bff3cdf6c 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -59,6 +59,13 @@ #define VP8_TEMPORAL_ALT_REF 1 +#if CONFIG_NEW_MVREF +// temp. relate to mv_ref_sum_distance stats +#define CUR_BEST 0 +#define NEW_BEST 1 +#define BEST_SELECTED 2 +#endif + typedef struct { MV_CONTEXT mvc[2]; int mvcosts[2][MVvals + 1]; @@ -752,6 +759,12 @@ typedef struct VP8_COMP { [VP8_SWITCHABLE_FILTERS]; #endif +#if CONFIG_NEW_MVREF + // temp stats [REF_FRAME]{REF_METHOD] + unsigned int mv_ref_sum_distance[4][3]; + unsigned int best_ref_index_counts[17]; +#endif + } VP8_COMP; void control_data_rate(VP8_COMP *cpi); diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index d217f2ffc..d07c2383e 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -41,6 +41,10 @@ #include "vp8/common/seg_common.h" #include "vp8/common/pred_common.h" +#if CONFIG_NEW_MVREF +#include "vp8/common/mvref_common.h" +#endif + #if CONFIG_RUNTIME_CPU_DETECT #define IF_RTCD(x) (x) #else @@ -2892,9 +2896,10 @@ void setup_buffer_inter(VP8_COMP *cpi, MACROBLOCK *x, int idx, int frame_type, unsigned char *y_buffer[4], unsigned char *u_buffer[4], unsigned char *v_buffer[4]) { YV12_BUFFER_CONFIG *yv12 = &cpi->common.yv12_fb[idx]; + MACROBLOCKD *xd = &x->e_mbd; - vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, - x->e_mbd.prev_mode_info_context, + vp8_find_near_mvs(xd, xd->mode_info_context, + xd->prev_mode_info_context, &frame_nearest_mv[frame_type], &frame_near_mv[frame_type], &frame_best_ref_mv[frame_type], frame_mdcounts[frame_type], frame_type, cpi->common.ref_frame_sign_bias); @@ -2902,8 +2907,27 @@ void setup_buffer_inter(VP8_COMP *cpi, MACROBLOCK *x, int idx, int frame_type, y_buffer[frame_type] = yv12->y_buffer + recon_yoffset; u_buffer[frame_type] = yv12->u_buffer + recon_uvoffset; v_buffer[frame_type] = yv12->v_buffer + recon_uvoffset; + #if CONFIG_NEWBESTREFMV - vp8_find_best_ref_mvs(&x->e_mbd, y_buffer[frame_type], +#if CONFIG_NEW_MVREF + // Update stats on relative distance of chosen vector to the + // possible best reference vectors. + { + MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi; + + find_mv_refs(xd, xd->mode_info_context, + xd->prev_mode_info_context, + frame_type, + mbmi->ref_mvs[frame_type], + cpi->common.ref_frame_sign_bias ); + + // Copy over the mv candidates + vpx_memcpy(xd->ref_mv, mbmi->ref_mvs[frame_type], + (MAX_MV_REFS * sizeof(int_mv)) ); + } +#endif + + vp8_find_best_ref_mvs(xd, y_buffer[frame_type], yv12->y_stride, &frame_best_ref_mv[frame_type], &frame_nearest_mv[frame_type], @@ -3407,6 +3431,43 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int d->bmi.as_mv.first.as_int = tmp_mv.as_int; frame_mv[NEWMV][refs[0]].as_int = d->bmi.as_mv.first.as_int; +#if CONFIG_NEW_MVREF + // Update stats on relative distance of chosen vector to the + // possible best reference vectors. + { + unsigned int distance; + MV_REFERENCE_FRAME ref = mbmi->ref_frame; + int_mv selected_best_ref; + unsigned int best_index = 0; + + find_mv_refs(xd, xd->mode_info_context, + xd->prev_mode_info_context, + ref, + mbmi->ref_mvs[ref], + cpi->common.ref_frame_sign_bias ); + + distance = mv_distance(&tmp_mv, &best_ref_mv); + cpi->mv_ref_sum_distance[ref][CUR_BEST] += distance; + + distance = + mv_distance(&tmp_mv, + &mbmi->ref_mvs[ref][0]); + cpi->mv_ref_sum_distance[ref][NEW_BEST] += distance; + + best_index = pick_best_mv_ref(tmp_mv, mbmi->ref_mvs[ref], + &selected_best_ref); + + distance = mv_distance(&tmp_mv, &selected_best_ref); + mbmi->mv_ref_index[ref] = best_index; + cpi->mv_ref_sum_distance[ref][BEST_SELECTED] += distance; + cpi->best_ref_index_counts[best_index]++; + + // Temp + //mbmi->mv_ref_index[ref] = 0; + //mbmi->ref_mvs[ref][0].as_int = best_ref_mv.as_int; + } +#endif + // Add the new motion vector cost to our rolling cost variable rate2 += vp8_mv_bit_cost(&tmp_mv, &best_ref_mv, XMVCOST, 96, -- cgit v1.2.3