summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2012-08-24 15:44:01 +0100
committerPaul Wilkins <paulwilkins@google.com>2012-08-24 18:08:21 +0100
commit2d60bee1fbfb7e5b6862e4e636151effabae98e3 (patch)
tree3f0760847eaba681c8c708f6e4f029129cd81137 /vp8/encoder
parent3777125ba66d15fef1436ea8871b3901a86c6991 (diff)
downloadlibvpx-2d60bee1fbfb7e5b6862e4e636151effabae98e3.tar
libvpx-2d60bee1fbfb7e5b6862e4e636151effabae98e3.tar.gz
libvpx-2d60bee1fbfb7e5b6862e4e636151effabae98e3.tar.bz2
libvpx-2d60bee1fbfb7e5b6862e4e636151effabae98e3.zip
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
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/bitstream.c22
-rw-r--r--vp8/encoder/encodeframe.c10
-rw-r--r--vp8/encoder/onyx_if.c34
-rw-r--r--vp8/encoder/onyx_int.h13
-rw-r--r--vp8/encoder/rdopt.c67
5 files changed, 143 insertions, 3 deletions
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,