diff --git a/configure b/configure index 2180ae37f3a3e74b894d82826bec1a296ab91cb6..168da07f4bec92651473e564a4bccdafa129363d 100755 --- a/configure +++ b/configure @@ -228,6 +228,7 @@ EXPERIMENT_LIST=" newbestrefmv new_mvref hybridtransform16x16 + newmventropy " CONFIG_LIST=" external_build diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c index 1664b289936887059e7c306d0b30d6e0aded0856..9d7d566515aaa69958df78f3d0dbc9c86e231591 100644 --- a/vp8/common/entropymv.c +++ b/vp8/common/entropymv.c @@ -12,6 +12,443 @@ #include "onyxc_int.h" #include "entropymv.h" +//#define MV_COUNT_TESTING + +#if CONFIG_NEWMVENTROPY + +#define MV_COUNT_SAT 16 +#define MV_MAX_UPDATE_FACTOR 160 + +/* Smooth or bias the mv-counts before prob computation */ +/* #define SMOOTH_MV_COUNTS */ + +const vp8_tree_index vp8_mv_joint_tree[2 * MV_JOINTS - 2] = { + -MV_JOINT_ZERO, 2, + -MV_JOINT_HNZVZ, 4, + -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ +}; +struct vp8_token_struct vp8_mv_joint_encodings[MV_JOINTS]; + +const vp8_tree_index vp8_mv_class_tree[2 * MV_CLASSES - 2] = { + -MV_CLASS_0, 2, + -MV_CLASS_1, 4, + 6, 8, + -MV_CLASS_2, -MV_CLASS_3, + 10, 12, + -MV_CLASS_4, -MV_CLASS_5, + -MV_CLASS_6, -MV_CLASS_7, +}; +struct vp8_token_struct vp8_mv_class_encodings[MV_CLASSES]; + +const vp8_tree_index vp8_mv_class0_tree [2 * CLASS0_SIZE - 2] = { + -0, -1, +}; +struct vp8_token_struct vp8_mv_class0_encodings[CLASS0_SIZE]; + +const vp8_tree_index vp8_mv_fp_tree [2 * 4 - 2] = { + -0, 2, + -1, 4, + -2, -3 +}; +struct vp8_token_struct vp8_mv_fp_encodings[4]; + +const nmv_context vp8_default_nmv_context = { + {32, 64, 96}, + { + { /* vert component */ + 128, /* sign */ + {224, 144, 192, 168, 192, 176, 192}, /* class */ + {216}, /* class0 */ + {136, 140, 148, 160, 176, 192, 224}, /* bits */ + {{128, 128, 64}, {96, 112, 64}}, /* class0_fp */ + {64, 96, 64}, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + }, + { /* hor component */ + 128, /* sign */ + {216, 128, 176, 160, 176, 176, 192}, /* class */ + {208}, /* class0 */ + {136, 140, 148, 160, 176, 192, 224}, /* bits */ + {{128, 128, 64}, {96, 112, 64}}, /* class0_fp */ + {64, 96, 64}, /* fp */ + 160, /* class0_hp bit */ + 128, /* hp */ + } + }, +}; + +MV_JOINT_TYPE vp8_get_mv_joint(MV mv) { + if (mv.row == 0 && mv.col == 0) return MV_JOINT_ZERO; + else if (mv.row == 0 && mv.col != 0) return MV_JOINT_HNZVZ; + else if (mv.row != 0 && mv.col == 0) return MV_JOINT_HZVNZ; + else return MV_JOINT_HNZVNZ; +} + +#define mv_class_base(c) ((c) ? (CLASS0_SIZE << (c + 2)) : 0) + +MV_CLASS_TYPE vp8_get_mv_class(int z, int *offset) { + MV_CLASS_TYPE c; + if (z < CLASS0_SIZE * 8) c = MV_CLASS_0; + else if (z < CLASS0_SIZE * 16) c = MV_CLASS_1; + else if (z < CLASS0_SIZE * 32) c = MV_CLASS_2; + else if (z < CLASS0_SIZE * 64) c = MV_CLASS_3; + else if (z < CLASS0_SIZE * 128) c = MV_CLASS_4; + else if (z < CLASS0_SIZE * 256) c = MV_CLASS_5; + else if (z < CLASS0_SIZE * 512) c = MV_CLASS_6; + else if (z < CLASS0_SIZE * 1024) c = MV_CLASS_7; + else assert(0); + if (offset) + *offset = z - mv_class_base(c); + return c; +} + +int vp8_get_mv_mag(MV_CLASS_TYPE c, int offset) { + return mv_class_base(c) + offset; +} + +static void increment_nmv_component_count(int v, + nmv_component_counts *mvcomp, + int incr, + int usehp) { + assert (v != 0); /* should not be zero */ + mvcomp->mvcount[MV_MAX + v] += incr; +} + +static void increment_nmv_component(int v, + nmv_component_counts *mvcomp, + int incr, + int usehp) { + int s, z, c, o, d, e, f; + assert (v != 0); /* should not be zero */ + s = v < 0; + mvcomp->sign[s] += incr; + z = (s ? -v : v) - 1; /* magnitude - 1 */ + + c = vp8_get_mv_class(z, &o); + mvcomp->classes[c] += incr; + + d = (o >> 3); /* int mv data */ + f = (o >> 1) & 3; /* fractional pel mv data */ + e = (o & 1); /* high precision mv data */ + if (c == MV_CLASS_0) { + mvcomp->class0[d] += incr; + } else { + int i, b; + b = c + CLASS0_BITS - 1; /* number of bits */ + for (i = 0; i < b; ++i) + mvcomp->bits[i][((d >> i) & 1)] += incr; + } + + /* Code the fractional pel bits */ + if (c == MV_CLASS_0) { + mvcomp->class0_fp[d][f] += incr; + } else { + mvcomp->fp[f] += incr; + } + + /* Code the high precision bit */ + if (usehp) { + if (c == MV_CLASS_0) { + mvcomp->class0_hp[e] += incr; + } else { + mvcomp->hp[e] += incr; + } + } else { /* assume the extra bit is 1 */ + if (c == MV_CLASS_0) { + mvcomp->class0_hp[1] += incr; + } else { + mvcomp->hp[1] += incr; + } + } +} + +#ifdef SMOOTH_MV_COUNTS +static void smooth_counts(nmv_component_counts *mvcomp) { + static const int flen = 3; // (filter_length + 1) / 2 + static const int fval[] = {8, 3, 1}; + static const int fvalbits = 4; + int i; + unsigned int smvcount[MV_VALS]; + vpx_memcpy(smvcount, mvcomp->mvcount, sizeof(smvcount)); + smvcount[MV_MAX] = (smvcount[MV_MAX - 1] + smvcount[MV_MAX + 1]) >> 1; + for (i = flen - 1; i <= MV_VALS - flen; ++i) { + int j, s = smvcount[i] * fval[0]; + for (j = 1; j < flen; ++j) + s += (smvcount[i - j] + smvcount[i + j]) * fval[j]; + mvcomp->mvcount[i] = (s + (1 << (fvalbits - 1))) >> fvalbits; + } +} +#endif + +static void counts_to_context(nmv_component_counts *mvcomp, int usehp) { + int v; + vpx_memset(mvcomp->sign, 0, sizeof(nmv_component_counts) - sizeof(mvcomp->mvcount)); + for (v = 1; v <= MV_MAX; v++) { + increment_nmv_component(-v, mvcomp, mvcomp->mvcount[MV_MAX - v], usehp); + increment_nmv_component( v, mvcomp, mvcomp->mvcount[MV_MAX + v], usehp); + } +} + +void vp8_increment_nmv(const MV *mv, const MV *ref, nmv_context_counts *mvctx, + int usehp) { + MV_JOINT_TYPE j = vp8_get_mv_joint(*mv); + mvctx->joints[j]++; + if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) { + increment_nmv_component_count(mv->row, &mvctx->comps[0], 1, usehp); + } + if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) { + increment_nmv_component_count(mv->col, &mvctx->comps[1], 1, usehp); + } +} + +static void adapt_prob(vp8_prob *dest, vp8_prob prep, vp8_prob newp, + unsigned int ct[2]) { + int factor; + int prob; + int count = ct[0] + ct[1]; + if (count) { + count = count > MV_COUNT_SAT ? MV_COUNT_SAT : count; + factor = (MV_MAX_UPDATE_FACTOR * count / MV_COUNT_SAT); + prob = ((int)prep * (256 - factor) + (int)(newp) * factor + 128) >> 8; + prob += !prob; + prob = (prob > 255 ? 255 : prob); + *dest = prob; + } +} + +void vp8_counts_to_nmv_context( + nmv_context_counts *NMVcount, + nmv_context *prob, + int usehp, + unsigned int (*branch_ct_joint)[2], + unsigned int (*branch_ct_sign)[2], + unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2], + unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2], + unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2], + unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2], + unsigned int (*branch_ct_fp)[4 - 1][2], + unsigned int (*branch_ct_class0_hp)[2], + unsigned int (*branch_ct_hp)[2]) { + int i, j, k; + counts_to_context(&NMVcount->comps[0], usehp); + counts_to_context(&NMVcount->comps[1], usehp); + vp8_tree_probs_from_distribution(MV_JOINTS, + vp8_mv_joint_encodings, + vp8_mv_joint_tree, + prob->joints, + branch_ct_joint, + NMVcount->joints, + 256, 1); + for (i = 0; i < 2; ++i) { + prob->comps[i].sign = + vp8_bin_prob_from_distribution(NMVcount->comps[i].sign); + branch_ct_sign[i][0] = NMVcount->comps[i].sign[0]; + branch_ct_sign[i][1] = NMVcount->comps[i].sign[1]; + vp8_tree_probs_from_distribution(MV_CLASSES, + vp8_mv_class_encodings, + vp8_mv_class_tree, + prob->comps[i].classes, + branch_ct_classes[i], + NMVcount->comps[i].classes, + 256, 1); + vp8_tree_probs_from_distribution(CLASS0_SIZE, + vp8_mv_class0_encodings, + vp8_mv_class0_tree, + prob->comps[i].class0, + branch_ct_class0[i], + NMVcount->comps[i].class0, + 256, 1); + for (j = 0; j < MV_OFFSET_BITS; ++j) { + prob->comps[i].bits[j] = vp8_bin_prob_from_distribution( + NMVcount->comps[i].bits[j]); + branch_ct_bits[i][j][0] = NMVcount->comps[i].bits[j][0]; + branch_ct_bits[i][j][1] = NMVcount->comps[i].bits[j][1]; + } + } + for (i = 0; i < 2; ++i) { + for (k = 0; k < CLASS0_SIZE; ++k) { + vp8_tree_probs_from_distribution(4, + vp8_mv_fp_encodings, + vp8_mv_fp_tree, + prob->comps[i].class0_fp[k], + branch_ct_class0_fp[i][k], + NMVcount->comps[i].class0_fp[k], + 256, 1); + } + vp8_tree_probs_from_distribution(4, + vp8_mv_fp_encodings, + vp8_mv_fp_tree, + prob->comps[i].fp, + branch_ct_fp[i], + NMVcount->comps[i].fp, + 256, 1); + } + if (usehp) { + for (i = 0; i < 2; ++i) { + prob->comps[i].class0_hp = vp8_bin_prob_from_distribution( + NMVcount->comps[i].class0_hp); + branch_ct_class0_hp[i][0] = NMVcount->comps[i].class0_hp[0]; + branch_ct_class0_hp[i][1] = NMVcount->comps[i].class0_hp[1]; + + prob->comps[i].hp = + vp8_bin_prob_from_distribution(NMVcount->comps[i].hp); + branch_ct_hp[i][0] = NMVcount->comps[i].hp[0]; + branch_ct_hp[i][1] = NMVcount->comps[i].hp[1]; + } + } +} + +void vp8_adapt_nmv_probs(VP8_COMMON *cm, int usehp) { + int i, j, k; + nmv_context prob; + unsigned int branch_ct_joint[MV_JOINTS - 1][2]; + unsigned int branch_ct_sign[2][2]; + unsigned int branch_ct_classes[2][MV_CLASSES - 1][2]; + unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2]; + unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2]; + unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2]; + unsigned int branch_ct_fp[2][4 - 1][2]; + unsigned int branch_ct_class0_hp[2][2]; + unsigned int branch_ct_hp[2][2]; +#ifdef MV_COUNT_TESTING + printf("joints count: "); + for (j = 0; j < MV_JOINTS; ++j) printf("%d ", cm->fc.NMVcount.joints[j]); + printf("\n"); fflush(stdout); + printf("signs count:\n"); + for (i = 0; i < 2; ++i) + printf("%d/%d ", cm->fc.NMVcount.comps[i].sign[0], cm->fc.NMVcount.comps[i].sign[1]); + printf("\n"); fflush(stdout); + printf("classes count:\n"); + for (i = 0; i < 2; ++i) { + for (j = 0; j < MV_CLASSES; ++j) + printf("%d ", cm->fc.NMVcount.comps[i].classes[j]); + printf("\n"); fflush(stdout); + } + printf("class0 count:\n"); + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) + printf("%d ", cm->fc.NMVcount.comps[i].class0[j]); + printf("\n"); fflush(stdout); + } + printf("bits count:\n"); + for (i = 0; i < 2; ++i) { + for (j = 0; j < MV_OFFSET_BITS; ++j) + printf("%d/%d ", cm->fc.NMVcount.comps[i].bits[j][0], + cm->fc.NMVcount.comps[i].bits[j][1]); + printf("\n"); fflush(stdout); + } + printf("class0_fp count:\n"); + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + printf("{"); + for (k = 0; k < 4; ++k) + printf("%d ", cm->fc.NMVcount.comps[i].class0_fp[j][k]); + printf("}, "); + } + printf("\n"); fflush(stdout); + } + printf("fp count:\n"); + for (i = 0; i < 2; ++i) { + for (j = 0; j < 4; ++j) + printf("%d ", cm->fc.NMVcount.comps[i].fp[j]); + printf("\n"); fflush(stdout); + } + if (usehp) { + printf("class0_hp count:\n"); + for (i = 0; i < 2; ++i) + printf("%d/%d ", cm->fc.NMVcount.comps[i].class0_hp[0], + cm->fc.NMVcount.comps[i].class0_hp[1]); + printf("\n"); fflush(stdout); + printf("hp count:\n"); + for (i = 0; i < 2; ++i) + printf("%d/%d ", cm->fc.NMVcount.comps[i].hp[0], + cm->fc.NMVcount.comps[i].hp[1]); + printf("\n"); fflush(stdout); + } +#endif +#ifdef SMOOTH_MV_COUNTS + smooth_counts(&cm->fc.NMVcount.comps[0]); + smooth_counts(&cm->fc.NMVcount.comps[1]); +#endif + vp8_counts_to_nmv_context(&cm->fc.NMVcount, + &prob, + usehp, + branch_ct_joint, + branch_ct_sign, + branch_ct_classes, + branch_ct_class0, + branch_ct_bits, + branch_ct_class0_fp, + branch_ct_fp, + branch_ct_class0_hp, + branch_ct_hp); + + for (j = 0; j < MV_JOINTS - 1; ++j) { + adapt_prob(&cm->fc.nmvc.joints[j], + cm->fc.pre_nmvc.joints[j], + prob.joints[j], + branch_ct_joint[j]); + } + for (i = 0; i < 2; ++i) { + adapt_prob(&cm->fc.nmvc.comps[i].sign, + cm->fc.pre_nmvc.comps[i].sign, + prob.comps[i].sign, + branch_ct_sign[i]); + for (j = 0; j < MV_CLASSES - 1; ++j) { + adapt_prob(&cm->fc.nmvc.comps[i].classes[j], + cm->fc.pre_nmvc.comps[i].classes[j], + prob.comps[i].classes[j], + branch_ct_classes[i][j]); + } + for (j = 0; j < CLASS0_SIZE - 1; ++j) { + adapt_prob(&cm->fc.nmvc.comps[i].class0[j], + cm->fc.pre_nmvc.comps[i].class0[j], + prob.comps[i].class0[j], + branch_ct_class0[i][j]); + } + for (j = 0; j < MV_OFFSET_BITS; ++j) { + adapt_prob(&cm->fc.nmvc.comps[i].bits[j], + cm->fc.pre_nmvc.comps[i].bits[j], + prob.comps[i].bits[j], + branch_ct_bits[i][j]); + } + } + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + for (k = 0; k < 3; ++k) { + adapt_prob(&cm->fc.nmvc.comps[i].class0_fp[j][k], + cm->fc.pre_nmvc.comps[i].class0_fp[j][k], + prob.comps[i].class0_fp[j][k], + branch_ct_class0_fp[i][j][k]); + } + } + for (j = 0; j < 3; ++j) { + adapt_prob(&cm->fc.nmvc.comps[i].fp[j], + cm->fc.pre_nmvc.comps[i].fp[j], + prob.comps[i].fp[j], + branch_ct_fp[i][j]); + } + } + if (usehp) { + for (i = 0; i < 2; ++i) { + adapt_prob(&cm->fc.nmvc.comps[i].class0_hp, + cm->fc.pre_nmvc.comps[i].class0_hp, + prob.comps[i].class0_hp, + branch_ct_class0_hp[i]); + adapt_prob(&cm->fc.nmvc.comps[i].hp, + cm->fc.pre_nmvc.comps[i].hp, + prob.comps[i].hp, + branch_ct_hp[i]); + } + } +} + +#else /* CONFIG_NEWMVENTROPY */ + +#define MV_COUNT_SAT 16 +#define MV_MAX_UPDATE_FACTOR 128 + const MV_CONTEXT_HP vp8_mv_update_probs_hp[2] = { {{ 237, @@ -266,14 +703,6 @@ static void compute_component_probs_hp( } } -void vp8_entropy_mv_init() { - vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree); - vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp); -} - -// #define MV_COUNT_TESTING -#define MV_COUNT_SAT 16 -#define MV_MAX_UPDATE_FACTOR 128 void vp8_adapt_mv_probs(VP8_COMMON *cm) { int i, t, count, factor; #ifdef MV_COUNT_TESTING @@ -400,3 +829,28 @@ void vp8_adapt_mv_probs(VP8_COMMON *cm) { } } } + +#endif /* CONFIG_NEWMVENTROPY */ + +void vp8_entropy_mv_init() { +#if CONFIG_NEWMVENTROPY + vp8_tokens_from_tree(vp8_mv_joint_encodings, vp8_mv_joint_tree); + vp8_tokens_from_tree(vp8_mv_class_encodings, vp8_mv_class_tree); + vp8_tokens_from_tree(vp8_mv_class0_encodings, vp8_mv_class0_tree); + vp8_tokens_from_tree(vp8_mv_fp_encodings, vp8_mv_fp_tree); +#else + vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree); + vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp); +#endif +} + +void vp8_init_mv_probs(VP8_COMMON *cm) { +#if CONFIG_NEWMVENTROPY + vpx_memcpy(&cm->fc.nmvc, &vp8_default_nmv_context, sizeof(nmv_context)); +#else + vpx_memcpy(cm->fc.mvc, + vp8_default_mv_context, sizeof(vp8_default_mv_context)); + vpx_memcpy(cm->fc.mvc_hp, + vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp)); +#endif +} diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h index 535d9b8acc50b8bbc508a282d440cab881f4151a..20af7e461d6090323a4aa01662b114dcf1a697d9 100644 --- a/vp8/common/entropymv.h +++ b/vp8/common/entropymv.h @@ -16,6 +16,121 @@ #include "vpx_config.h" #include "blockd.h" +struct VP8Common; + +void vp8_entropy_mv_init(); +void vp8_init_mv_probs(struct VP8Common *cm); +void vp8_adapt_mv_probs(struct VP8Common *cm); +#if CONFIG_NEWMVENTROPY +void vp8_adapt_nmv_probs(struct VP8Common *cm, int usehp); +#endif + +#if CONFIG_NEWMVENTROPY + +#define VP8_NMV_UPDATE_PROB 255 +//#define MV_GROUP_UPDATE + +#define LOW_PRECISION_MV_UPDATE /* Use 7 bit forward update */ + +/* Symbols for coding which components are zero jointly */ +#define MV_JOINTS 4 +typedef enum { + MV_JOINT_ZERO = 0, /* Zero vector */ + MV_JOINT_HNZVZ = 1, /* Vert zero, hor nonzero */ + MV_JOINT_HZVNZ = 2, /* Hor zero, vert nonzero */ + MV_JOINT_HNZVNZ = 3, /* Both components nonzero */ +} MV_JOINT_TYPE; + +extern const vp8_tree_index vp8_mv_joint_tree[2 * MV_JOINTS - 2]; +extern struct vp8_token_struct vp8_mv_joint_encodings [MV_JOINTS]; + +/* Symbols for coding magnitude class of nonzero components */ +#define MV_CLASSES 8 +typedef enum { + MV_CLASS_0 = 0, /* (0, 2] integer pel */ + MV_CLASS_1 = 1, /* (2, 4] integer pel */ + MV_CLASS_2 = 2, /* (4, 8] integer pel */ + MV_CLASS_3 = 3, /* (8, 16] integer pel */ + MV_CLASS_4 = 4, /* (16, 32] integer pel */ + MV_CLASS_5 = 5, /* (32, 64] integer pel */ + MV_CLASS_6 = 6, /* (64, 128] integer pel */ + MV_CLASS_7 = 7, /* (128, 256] integer pel */ +} MV_CLASS_TYPE; + +extern const vp8_tree_index vp8_mv_class_tree[2 * MV_CLASSES - 2]; +extern struct vp8_token_struct vp8_mv_class_encodings [MV_CLASSES]; + +#define CLASS0_BITS 1 /* bits at integer precision for class 0 */ +#define CLASS0_SIZE (1 << CLASS0_BITS) +#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2) + +#define MV_MAX_BITS (MV_CLASSES + CLASS0_BITS + 2) +#define MV_MAX ((1 << MV_MAX_BITS) - 1) +#define MV_VALS ((MV_MAX << 1) + 1) + +extern const vp8_tree_index vp8_mv_class0_tree[2 * CLASS0_SIZE - 2]; +extern struct vp8_token_struct vp8_mv_class0_encodings[CLASS0_SIZE]; + +extern const vp8_tree_index vp8_mv_fp_tree[2 * 4 - 2]; +extern struct vp8_token_struct vp8_mv_fp_encodings[4]; + +typedef struct { + vp8_prob sign; + vp8_prob classes[MV_CLASSES - 1]; + vp8_prob class0[CLASS0_SIZE - 1]; + vp8_prob bits[MV_OFFSET_BITS]; + vp8_prob class0_fp[CLASS0_SIZE][4 - 1]; + vp8_prob fp[4 - 1]; + vp8_prob class0_hp; + vp8_prob hp; +} nmv_component; + +typedef struct { + vp8_prob joints[MV_JOINTS - 1]; + nmv_component comps[2]; +} nmv_context; + +MV_JOINT_TYPE vp8_get_mv_joint(MV mv); +MV_CLASS_TYPE vp8_get_mv_class(int z, int *offset); +int vp8_get_mv_mag(MV_CLASS_TYPE c, int offset); + + +typedef struct { + unsigned int mvcount[MV_VALS]; + unsigned int sign[2]; + unsigned int classes[MV_CLASSES]; + unsigned int class0[CLASS0_SIZE]; + unsigned int bits[MV_OFFSET_BITS][2]; + unsigned int class0_fp[CLASS0_SIZE][4]; + unsigned int fp[4]; + unsigned int class0_hp[2]; + unsigned int hp[2]; +} nmv_component_counts; + +typedef struct { + unsigned int joints[MV_JOINTS]; + nmv_component_counts comps[2]; +} nmv_context_counts; + +void vp8_increment_nmv(const MV *mv, const MV *ref, nmv_context_counts *mvctx, + int usehp); +extern const nmv_context vp8_default_nmv_context; +void vp8_counts_to_nmv_context( + nmv_context_counts *NMVcount, + nmv_context *prob, + int usehp, + unsigned int (*branch_ct_joint)[2], + unsigned int (*branch_ct_sign)[2], + unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2], + unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2], + unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2], + unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2], + unsigned int (*branch_ct_fp)[4 - 1][2], + unsigned int (*branch_ct_class0_hp)[2], + unsigned int (*branch_ct_hp)[2]); + +#else /* CONFIG_NEWMVENTROPY */ + enum { mv_max = 1023, /* max absolute value of a MV component */ MVvals = (2 * mv_max) + 1, /* # possible values "" */ @@ -73,8 +188,6 @@ extern struct vp8_token_struct vp8_small_mvencodings [8]; extern const vp8_tree_index vp8_small_mvtree_hp[]; extern struct vp8_token_struct vp8_small_mvencodings_hp [16]; -void vp8_entropy_mv_init(); -struct VP8Common; -void vp8_adapt_mv_probs(struct VP8Common *cm); +#endif /* CONFIG_NEWMVENTROPY */ #endif diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index b76c4cc220cd582f00ab1b38a0baa65296e338a2..4cdcbeb0da01a3f1cd06b1f672b8aba22e1ea36f 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -55,10 +55,15 @@ typedef struct frame_contexts { #if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16 vp8_prob coef_probs_16x16 [BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; #endif +#if CONFIG_NEWMVENTROPY + nmv_context nmvc; + nmv_context pre_nmvc; +#else MV_CONTEXT mvc[2]; MV_CONTEXT_HP mvc_hp[2]; MV_CONTEXT pre_mvc[2]; MV_CONTEXT_HP pre_mvc_hp[2]; +#endif vp8_prob pre_bmode_prob [VP8_BINTRAMODES - 1]; vp8_prob pre_ymode_prob [VP8_YMODES - 1]; /* interframe intra mode probs */ vp8_prob pre_uv_mode_prob [VP8_YMODES][VP8_UV_MODES - 1]; @@ -88,8 +93,12 @@ typedef struct frame_contexts { unsigned int coef_counts_16x16 [BLOCK_TYPES_16X16] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; #endif +#if CONFIG_NEWMVENTROPY + nmv_context_counts NMVcount; +#else unsigned int MVcount [2] [MVvals]; unsigned int MVcount_hp [2] [MVvals_hp]; +#endif #if CONFIG_SWITCHABLE_INTERP vp8_prob switchable_interp_prob[VP8_SWITCHABLE_FILTERS+1] [VP8_SWITCHABLE_FILTERS-1]; diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c index 70d3832b2bb8b2297b7d2573169214516260ecb4..647b3ada7122523ecc43e63c4875d88314014a4f 100644 --- a/vp8/common/reconinter.c +++ b/vp8/common/reconinter.c @@ -723,9 +723,9 @@ void vp8_build_1st_inter16x16_predictors_mbuv(MACROBLOCKD *xd, // Sub-pel filter xd->subpixel_predict8x8(pTemp, len, - _o16x16mv.as_mv.col & 15, - _o16x16mv.as_mv.row & 15, - pDst, dst_uvstride); + _o16x16mv.as_mv.col & 15, + _o16x16mv.as_mv.row & 15, + pDst, dst_uvstride); } else { filter_mb(pSrc, pre_stride, pDst, dst_uvstride, 8, 8); } diff --git a/vp8/common/treecoder.c b/vp8/common/treecoder.c index def4caa0470804dbd2db571b78238cc4680c49c9..adf291beff85da0b87fe9739232fdffd56fd4ae2 100644 --- a/vp8/common/treecoder.c +++ b/vp8/common/treecoder.c @@ -124,3 +124,15 @@ void vp8_tree_probs_from_distribution( probs[t] = vp8_prob_half; } while (++t < tree_len); } + +vp8_prob vp8_bin_prob_from_distribution(const unsigned int counts[2]) { + int tot_count = counts[0] + counts[1]; + vp8_prob prob; + if (tot_count) { + prob = (counts[0] * 255 + (tot_count >> 1)) / tot_count; + prob += !prob; + } else { + prob = 128; + } + return prob; +} diff --git a/vp8/common/treecoder.h b/vp8/common/treecoder.h index c4d0aa6ee7ab90056654a6815ef616b5de31843a..b7fa17df9376c231b4cf99b57d1efc870b73906f 100644 --- a/vp8/common/treecoder.h +++ b/vp8/common/treecoder.h @@ -85,5 +85,6 @@ void vp8bc_tree_probs_from_distribution( c_bool_coder_spec *s ); +vp8_prob vp8_bin_prob_from_distribution(const unsigned int counts[2]); #endif diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 069d073d418464764787ac6c9fae6f5dcb2e3b22..e8b4a1f67238725a81a90445ea1b7d674156463e 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -172,6 +172,150 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, } +#if CONFIG_NEWMVENTROPY +static int read_nmv_component(vp8_reader *r, + int rv, + const nmv_component *mvcomp) { + int v, s, z, c, o, d; + s = vp8_read(r, mvcomp->sign); + c = vp8_treed_read(r, vp8_mv_class_tree, mvcomp->classes); + if (c == MV_CLASS_0) { + d = vp8_treed_read(r, vp8_mv_class0_tree, mvcomp->class0); + } else { + int i, b; + d = 0; + b = c + CLASS0_BITS - 1; /* number of bits */ + for (i = 0; i < b; ++i) + d |= (vp8_read(r, mvcomp->bits[i]) << i); + } + o = d << 3; + + z = vp8_get_mv_mag(c, o); + v = (s ? -(z + 1) : (z + 1)); + return v; +} + +static int read_nmv_component_fp(vp8_reader *r, + int v, + int rv, + const nmv_component *mvcomp, + int usehp) { + int s, z, c, o, d, e, f; + s = v < 0; + z = (s ? -v : v) - 1; /* magnitude - 1 */ + + c = vp8_get_mv_class(z, &o); + d = o >> 3; + + if (c == MV_CLASS_0) { + f = vp8_treed_read(r, vp8_mv_fp_tree, mvcomp->class0_fp[d]); + } else { + f = vp8_treed_read(r, vp8_mv_fp_tree, mvcomp->fp); + } + o += (f << 1); + + if (usehp) { + if (c == MV_CLASS_0) { + e = vp8_read(r, mvcomp->class0_hp); + } else { + e = vp8_read(r, mvcomp->hp); + } + o += e; + } else { + ++o; /* Note if hp is not used, the default value of the hp bit is 1 */ + } + z = vp8_get_mv_mag(c, o); + v = (s ? -(z + 1) : (z + 1)); + return v; +} + +static void read_nmv(vp8_reader *r, MV *mv, const MV *ref, + const nmv_context *mvctx) { + MV_JOINT_TYPE j = vp8_treed_read(r, vp8_mv_joint_tree, mvctx->joints); + mv->row = mv-> col = 0; + if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) { + mv->row = read_nmv_component(r, ref->row, &mvctx->comps[0]); + } + if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) { + mv->col = read_nmv_component(r, ref->col, &mvctx->comps[1]); + } +} + +static void read_nmv_fp(vp8_reader *r, MV *mv, const MV *ref, + const nmv_context *mvctx, int usehp) { + MV_JOINT_TYPE j = vp8_get_mv_joint(*mv); + if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) { + mv->row = read_nmv_component_fp(r, mv->row, ref->row, &mvctx->comps[0], + usehp); + } + if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) { + mv->col = read_nmv_component_fp(r, mv->col, ref->col, &mvctx->comps[1], + usehp); + } +} + +static void update_nmv(vp8_reader *bc, vp8_prob *const p, + const vp8_prob upd_p) { + if (vp8_read(bc, upd_p)) { +#ifdef LOW_PRECISION_MV_UPDATE + *p = (vp8_read_literal(bc, 7) << 1) | 1; +#else + *p = (vp8_read_literal(bc, 8)); +#endif + } +} + +static void read_nmvprobs(vp8_reader *bc, nmv_context *mvctx, + int usehp) { + int i, j, k; +#ifdef MV_GROUP_UPDATE + if (!vp8_read_bit(bc)) return; +#endif + for (j = 0; j < MV_JOINTS - 1; ++j) { + update_nmv(bc, &mvctx->joints[j], + VP8_NMV_UPDATE_PROB); + } + for (i = 0; i < 2; ++i) { + update_nmv(bc, &mvctx->comps[i].sign, + VP8_NMV_UPDATE_PROB); + for (j = 0; j < MV_CLASSES - 1; ++j) { + update_nmv(bc, &mvctx->comps[i].classes[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < CLASS0_SIZE - 1; ++j) { + update_nmv(bc, &mvctx->comps[i].class0[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < MV_OFFSET_BITS; ++j) { + update_nmv(bc, &mvctx->comps[i].bits[j], + VP8_NMV_UPDATE_PROB); + } + } + + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + for (k = 0; k < 3; ++k) + update_nmv(bc, &mvctx->comps[i].class0_fp[j][k], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < 3; ++j) { + update_nmv(bc, &mvctx->comps[i].fp[j], + VP8_NMV_UPDATE_PROB); + } + } + + if (usehp) { + for (i = 0; i < 2; ++i) { + update_nmv(bc, &mvctx->comps[i].class0_hp, + VP8_NMV_UPDATE_PROB); + update_nmv(bc, &mvctx->comps[i].hp, + VP8_NMV_UPDATE_PROB); + } + } +} + +#else + static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc) { const vp8_prob *const p = (const vp8_prob *) mvc; int x = 0; @@ -211,7 +355,6 @@ static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc) { #endif } - static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc) { int i = 0; @@ -287,6 +430,8 @@ static void read_mvcontexts_hp(vp8_reader *bc, MV_CONTEXT_HP *mvc) { } while (++i < 2); } +#endif /* CONFIG_NEWMVENTROPY */ + // Read the referncence frame static MV_REFERENCE_FRAME read_ref_frame(VP8D_COMP *pbi, vp8_reader *const bc, @@ -452,8 +597,12 @@ static void read_switchable_interp_probs(VP8D_COMP *pbi) { static void mb_mode_mv_init(VP8D_COMP *pbi) { VP8_COMMON *const cm = & pbi->common; vp8_reader *const bc = & pbi->bc; +#if CONFIG_NEWMVENTROPY + nmv_context *const nmvc = &pbi->common.fc.nmvc; +#else MV_CONTEXT *const mvc = pbi->common.fc.mvc; MV_CONTEXT_HP *const mvc_hp = pbi->common.fc.mvc_hp; +#endif MACROBLOCKD *const xd = & pbi->mb; vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs)); @@ -499,10 +648,14 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) { cm->fc.ymode_prob[i] = (vp8_prob) vp8_read_literal(bc, 8); } while (++i < VP8_YMODES - 1); } +#if CONFIG_NEWMVENTROPY + read_nmvprobs(bc, nmvc, xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) read_mvcontexts_hp(bc, mvc_hp); else read_mvcontexts(bc, mvc); +#endif } } @@ -585,12 +738,16 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, int mb_row, int mb_col) { VP8_COMMON *const cm = & pbi->common; vp8_reader *const bc = & pbi->bc; +#if CONFIG_NEWMVENTROPY + nmv_context *const nmvc = &pbi->common.fc.nmvc; +#else MV_CONTEXT *const mvc = pbi->common.fc.mvc; MV_CONTEXT_HP *const mvc_hp = pbi->common.fc.mvc_hp; +#endif const int mis = pbi->common.mode_info_stride; MACROBLOCKD *const xd = & pbi->mb; - int_mv *const mv = & mbmi->mv[0]; + int_mv *const mv = & mbmi->mv; int mb_to_left_edge; int mb_to_right_edge; int mb_to_top_edge; @@ -684,7 +841,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, // Update stats on relative distance of chosen vector to the // possible best reference vectors. { - int i; MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame; find_mv_refs(xd, mi, prev_mi, @@ -833,8 +989,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, int mv_contz; int blockmode; - second_leftmv.as_int = 0; - second_abovemv.as_int = 0; k = vp8_mbsplit_offset[s][j]; leftmv.as_int = left_block_mv(mi, k); @@ -849,6 +1003,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, switch (blockmode) { case NEW4X4: +#if CONFIG_NEWMVENTROPY + read_nmv(bc, &blockmv.as_mv, &best_mv.as_mv, nmvc); + read_nmv_fp(bc, &blockmv.as_mv, &best_mv.as_mv, nmvc, + xd->allow_high_precision_mv); + vp8_increment_nmv(&blockmv.as_mv, &best_mv.as_mv, + &cm->fc.NMVcount, xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { read_mv_hp(bc, &blockmv.as_mv, (const MV_CONTEXT_HP *) mvc_hp); cm->fc.MVcount_hp[0][mv_max_hp + (blockmv.as_mv.row)]++; @@ -858,10 +1019,18 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, cm->fc.MVcount[0][mv_max + (blockmv.as_mv.row >> 1)]++; cm->fc.MVcount[1][mv_max + (blockmv.as_mv.col >> 1)]++; } +#endif /* CONFIG_NEWMVENTROPY */ blockmv.as_mv.row += best_mv.as_mv.row; blockmv.as_mv.col += best_mv.as_mv.col; if (mbmi->second_ref_frame) { +#if CONFIG_NEWMVENTROPY + read_nmv(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc); + read_nmv_fp(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc, + xd->allow_high_precision_mv); + vp8_increment_nmv(&secondmv.as_mv, &best_mv_second.as_mv, + &cm->fc.NMVcount, xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { read_mv_hp(bc, &secondmv.as_mv, (const MV_CONTEXT_HP *) mvc_hp); cm->fc.MVcount_hp[0][mv_max_hp + (secondmv.as_mv.row)]++; @@ -871,6 +1040,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, cm->fc.MVcount[0][mv_max + (secondmv.as_mv.row >> 1)]++; cm->fc.MVcount[1][mv_max + (secondmv.as_mv.col >> 1)]++; } +#endif /* CONFIG_NEWMVENTROPY */ secondmv.as_mv.row += best_mv_second.as_mv.row; secondmv.as_mv.col += best_mv_second.as_mv.col; } @@ -975,6 +1145,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, break; case NEWMV: +#if CONFIG_NEWMVENTROPY + read_nmv(bc, &mv->as_mv, &best_mv.as_mv, nmvc); + read_nmv_fp(bc, &mv->as_mv, &best_mv.as_mv, nmvc, + xd->allow_high_precision_mv); + vp8_increment_nmv(&mv->as_mv, &best_mv.as_mv, &cm->fc.NMVcount, + xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { read_mv_hp(bc, &mv->as_mv, (const MV_CONTEXT_HP *) mvc_hp); cm->fc.MVcount_hp[0][mv_max_hp + (mv->as_mv.row)]++; @@ -984,6 +1161,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, cm->fc.MVcount[0][mv_max + (mv->as_mv.row >> 1)]++; cm->fc.MVcount[1][mv_max + (mv->as_mv.col >> 1)]++; } +#endif /* CONFIG_NEWMVENTROPY */ mv->as_mv.row += best_mv.as_mv.row; mv->as_mv.col += best_mv.as_mv.col; @@ -998,6 +1176,13 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mb_to_top_edge, mb_to_bottom_edge); if (mbmi->second_ref_frame) { +#if CONFIG_NEWMVENTROPY + read_nmv(bc, &mbmi->mv[1].as_mv, &best_mv_second.as_mv, nmvc); + read_nmv_fp(bc, &mbmi->mv[1].as_mv, &best_mv_second.as_mv, nmvc, + xd->allow_high_precision_mv); + vp8_increment_nmv(&mbmi->mv[1].as_mv, &best_mv_second.as_mv, + &cm->fc.NMVcount, xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { read_mv_hp(bc, &mbmi->mv[1].as_mv, (const MV_CONTEXT_HP *) mvc_hp); cm->fc.MVcount_hp[0][mv_max_hp + (mbmi->mv[1].as_mv.row)]++; @@ -1007,6 +1192,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, cm->fc.MVcount[0][mv_max + (mbmi->mv[1].as_mv.row >> 1)]++; cm->fc.MVcount[1][mv_max + (mbmi->mv[1].as_mv.col >> 1)]++; } +#endif /* CONFIG_NEWMVENTROPY */ mbmi->mv[1].as_mv.row += best_mv_second.as_mv.row; mbmi->mv[1].as_mv.col += best_mv_second.as_mv.col; mbmi->need_to_clamp_secondmv |= diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index d9326839625e381d75e702e064c862cbc0293b8c..5fb510b64506ebe0a50db8dfe77bc74c08d433c3 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -923,9 +923,7 @@ static void init_frame(VP8D_COMP *pbi) { if (pc->frame_type == KEY_FRAME) { /* Various keyframe initializations */ - vpx_memcpy(pc->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); - vpx_memcpy(pc->fc.mvc_hp, vp8_default_mv_context_hp, - sizeof(vp8_default_mv_context_hp)); + vp8_init_mv_probs(pc); vp8_init_mbmode_probs(pc); @@ -1464,8 +1462,12 @@ int vp8_decode_frame(VP8D_COMP *pbi) { vp8_copy(pbi->common.fc.pre_i8x8_mode_prob, pbi->common.fc.i8x8_mode_prob); vp8_copy(pbi->common.fc.pre_sub_mv_ref_prob, pbi->common.fc.sub_mv_ref_prob); vp8_copy(pbi->common.fc.pre_mbsplit_prob, pbi->common.fc.mbsplit_prob); +#if CONFIG_NEWMVENTROPY + pbi->common.fc.pre_nmvc = pbi->common.fc.nmvc; +#else vp8_copy(pbi->common.fc.pre_mvc, pbi->common.fc.mvc); vp8_copy(pbi->common.fc.pre_mvc_hp, pbi->common.fc.mvc_hp); +#endif vp8_zero(pbi->common.fc.coef_counts); vp8_zero(pbi->common.fc.coef_counts_8x8); #if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16 @@ -1477,8 +1479,12 @@ int vp8_decode_frame(VP8D_COMP *pbi) { vp8_zero(pbi->common.fc.i8x8_mode_counts); vp8_zero(pbi->common.fc.sub_mv_ref_counts); vp8_zero(pbi->common.fc.mbsplit_counts); +#if CONFIG_NEWMVENTROPY + vp8_zero(pbi->common.fc.NMVcount); +#else vp8_zero(pbi->common.fc.MVcount); vp8_zero(pbi->common.fc.MVcount_hp); +#endif vp8_zero(pbi->common.fc.mv_ref_ct); vp8_zero(pbi->common.fc.mv_ref_ct_a); #if COEFUPDATETYPE == 2 @@ -1544,7 +1550,11 @@ int vp8_decode_frame(VP8D_COMP *pbi) { vp8_adapt_coef_probs(pc); if (pc->frame_type != KEY_FRAME) { vp8_adapt_mode_probs(pc); +#if CONFIG_NEWMVENTROPY + vp8_adapt_nmv_probs(pc, xd->allow_high_precision_mv); +#else vp8_adapt_mv_probs(pc); +#endif vp8_update_mode_context(&pbi->common); } diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 7d94bec26983d1bd557a83a46daecaa760a66968..712019602f4fc9508a50ebdab4fa0eb808aab4ab 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -27,6 +27,7 @@ #include "vp8/common/seg_common.h" #include "vp8/common/pred_common.h" #include "vp8/common/entropy.h" +#include "vp8/encoder/encodemv.h" #if CONFIG_NEW_MVREF #include "vp8/common/mvref_common.h" @@ -36,6 +37,8 @@ unsigned __int64 Sectionbits[500]; #endif +//int final_packing = 0; + #ifdef ENTROPY_STATS int intra_mode_stats [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES]; unsigned int tree_update_hist [BLOCK_TYPES] @@ -564,6 +567,19 @@ static void write_sub_mv_ref vp8_sub_mv_ref_encoding_array - LEFT4X4 + m); } +#if CONFIG_NEWMVENTROPY +static void write_nmv (vp8_writer *w, const MV *mv, const int_mv *ref, + const nmv_context *nmvc, int usehp) { + MV e; + e.row = mv->row - ref->as_mv.row; + e.col = mv->col - ref->as_mv.col; + + vp8_encode_nmv(w, &e, &ref->as_mv, nmvc); + vp8_encode_nmv_fp(w, &e, &ref->as_mv, nmvc, usehp); +} + +#else + static void write_mv ( vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT *mvc @@ -585,6 +601,7 @@ static void write_mv_hp vp8_encode_motion_vector_hp(w, &e, mvc); } +#endif /* CONFIG_NEWMVENTROPY */ // This function writes the current macro block's segnment id to the bitstream // It should only be called if a segment map update is indicated. @@ -737,8 +754,12 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { int i; VP8_COMMON *const pc = & cpi->common; vp8_writer *const w = & cpi->bc; +#if CONFIG_NEWMVENTROPY + const nmv_context *nmvc = &pc->fc.nmvc; +#else const MV_CONTEXT *mvc = pc->fc.mvc; const MV_CONTEXT_HP *mvc_hp = pc->fc.mvc_hp; +#endif MACROBLOCKD *xd = &cpi->mb.e_mbd; MODE_INFO *m; MODE_INFO *prev_m; @@ -754,6 +775,8 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { int row_delta[4] = { 0, +1, 0, -1}; int col_delta[4] = { +1, -1, +1, +1}; + //final_packing = !cpi->dummy_packing; + cpi->mb.partition_info = cpi->mb.pi; // Update the probabilities used to encode reference frame data @@ -814,10 +837,14 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { update_mbintra_mode_probs(cpi); +#if CONFIG_NEWMVENTROPY + vp8_write_nmvprobs(cpi, xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) vp8_write_mvprobs_hp(cpi); else vp8_write_mvprobs(cpi); +#endif mb_row = 0; for (row = 0; row < pc->mb_rows; row += 2) { @@ -1055,10 +1082,17 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { pick_best_mv_ref( mi->mv[0], mi->ref_mvs[rf], &best_mv); #endif - if (xd->allow_high_precision_mv) +#if CONFIG_NEWMVENTROPY + write_nmv(w, &mi->mv[0].as_mv, &best_mv, + (const nmv_context*) nmvc, + xd->allow_high_precision_mv); +#else + if (xd->allow_high_precision_mv) { write_mv_hp(w, &mi->mv[0].as_mv, &best_mv, mvc_hp); - else + } else { write_mv(w, &mi->mv[0].as_mv, &best_mv, mvc); + } +#endif if (mi->second_ref_frame) { #if 0 //CONFIG_NEW_MVREF @@ -1071,10 +1105,17 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { mi->ref_mvs[mi->second_ref_frame], &best_second_mv); #endif - if (xd->allow_high_precision_mv) +#if CONFIG_NEWMVENTROPY + write_nmv(w, &mi->mv[1].as_mv, &best_second_mv, + (const nmv_context*) nmvc, + xd->allow_high_precision_mv); +#else + if (xd->allow_high_precision_mv) { write_mv_hp(w, &mi->mv[1].as_mv, &best_second_mv, mvc_hp); - else + } else { write_mv(w, &mi->mv[1].as_mv, &best_second_mv, mvc); + } +#endif } break; case SPLITMV: { @@ -1116,6 +1157,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { #ifdef ENTROPY_STATS active_section = 11; #endif +#if CONFIG_NEWMVENTROPY + write_nmv(w, &blockmv.as_mv, &best_mv, + (const nmv_context*) nmvc, + xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { write_mv_hp(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT_HP *) mvc_hp); @@ -1123,8 +1169,16 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc); } +#endif if (mi->second_ref_frame) { +#if CONFIG_NEWMVENTROPY + write_nmv(w, + &cpi->mb.partition_info->bmi[j].second_mv.as_mv, + &best_second_mv, + (const nmv_context*) nmvc, + xd->allow_high_precision_mv); +#else if (xd->allow_high_precision_mv) { write_mv_hp(w, &cpi->mb.partition_info->bmi[j].second_mv.as_mv, &best_second_mv, (const MV_CONTEXT_HP *) mvc_hp); @@ -1132,6 +1186,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { write_mv(w, &cpi->mb.partition_info->bmi[j].second_mv.as_mv, &best_second_mv, (const MV_CONTEXT *) mvc); } +#endif } } } while (++j < cpi->mb.partition_info->count); @@ -2313,8 +2368,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) vp8_copy(cpi->common.fc.pre_sub_mv_ref_prob, cpi->common.fc.sub_mv_ref_prob); vp8_copy(cpi->common.fc.pre_mbsplit_prob, cpi->common.fc.mbsplit_prob); vp8_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob); +#if CONFIG_NEWMVENTROPY + cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc; +#else vp8_copy(cpi->common.fc.pre_mvc, cpi->common.fc.mvc); vp8_copy(cpi->common.fc.pre_mvc_hp, cpi->common.fc.mvc_hp); +#endif vp8_zero(cpi->sub_mv_ref_count); vp8_zero(cpi->mbsplit_count); vp8_zero(cpi->common.fc.mv_ref_ct) diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h index 77980567d0686d9e7259dd7d5a9613736c3a0769..c0cd2e7833ad9f42167ff2b090e6054ae2270058 100644 --- a/vp8/encoder/block.h +++ b/vp8/encoder/block.h @@ -117,6 +117,19 @@ typedef struct { int *mb_norm_activity_ptr; signed int act_zbin_adj; +#if CONFIG_NEWMVENTROPY + int nmvjointcost[MV_JOINTS]; + int nmvcosts[2][MV_VALS]; + int *nmvcost[2]; + int nmvcosts_hp[2][MV_VALS]; + int *nmvcost_hp[2]; + + int nmvjointsadcost[MV_JOINTS]; + int nmvsadcosts[2][MV_VALS]; + int *nmvsadcost[2]; + int nmvsadcosts_hp[2][MV_VALS]; + int *nmvsadcost_hp[2]; +#else int mvcosts[2][MVvals + 1]; int *mvcost[2]; int mvsadcosts[2][MVfpvals + 1]; @@ -125,6 +138,7 @@ typedef struct { int *mvcost_hp[2]; int mvsadcosts_hp[2][MVfpvals_hp + 1]; int *mvsadcost_hp[2]; +#endif /* CONFIG_NEWMVENTROPY */ int mbmode_cost[2][MB_MODE_COUNT]; int intra_uv_mode_cost[2][MB_MODE_COUNT]; @@ -150,8 +164,6 @@ typedef struct { signed char *gf_active_ptr; unsigned char *active_ptr; - MV_CONTEXT *mvc; - MV_CONTEXT_HP *mvc_hp; unsigned int token_costs[TX_SIZE_MAX][BLOCK_TYPES][COEF_BANDS] [PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS]; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 41b87f2b0b719e7993b3f682999a2ee372cfa1f4..4670c314d27c11b854b38a6f284df01c0311afee 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1280,9 +1280,6 @@ void init_encode_frame_mb_context(VP8_COMP *cpi) { #endif // vp8_zero(cpi->uv_mode_count) - x->mvc = cm->fc.mvc; - x->mvc_hp = cm->fc.mvc_hp; - vpx_memset(cm->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols); @@ -1357,8 +1354,12 @@ static void encode_frame_internal(VP8_COMP *cpi) { xd->mode_info_context = cm->mi; xd->prev_mode_info_context = cm->prev_mi; +#if CONFIG_NEWMVENTROPY + vp8_zero(cpi->NMVcount); +#else vp8_zero(cpi->MVcount); vp8_zero(cpi->MVcount_hp); +#endif vp8_zero(cpi->coef_counts); vp8_zero(cpi->coef_counts_8x8); #if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16 diff --git a/vp8/encoder/encodemv.c b/vp8/encoder/encodemv.c index e5426f66295ba43a9e13b533d9697c806fa959c9..217cc00c5d0533d766b422614fc96b713c546a8d 100644 --- a/vp8/encoder/encodemv.c +++ b/vp8/encoder/encodemv.c @@ -20,6 +20,536 @@ extern unsigned int active_section; #endif +//extern int final_packing; + +#if CONFIG_NEWMVENTROPY + +#ifdef NMV_STATS +nmv_context_counts tnmvcounts; +#endif + +static void encode_nmv_component(vp8_writer *w, + int v, + int r, + const nmv_component *mvcomp) { + int s, z, c, o, d; + assert (v != 0); /* should not be zero */ + s = v < 0; + vp8_write(w, s, mvcomp->sign); + z = (s ? -v : v) - 1; /* magnitude - 1 */ + + c = vp8_get_mv_class(z, &o); + + vp8_write_token(w, vp8_mv_class_tree, mvcomp->classes, + vp8_mv_class_encodings + c); + + d = (o >> 3); /* int mv data */ + + if (c == MV_CLASS_0) { + vp8_write_token(w, vp8_mv_class0_tree, mvcomp->class0, + vp8_mv_class0_encodings + d); + } else { + int i, b; + b = c + CLASS0_BITS - 1; /* number of bits */ + for (i = 0; i < b; ++i) + vp8_write(w, ((d >> i) & 1), mvcomp->bits[i]); + } +} + +static void encode_nmv_component_fp(vp8_writer *w, + int v, + int r, + const nmv_component *mvcomp, + int usehp) { + int s, z, c, o, d, f, e; + assert (v != 0); /* should not be zero */ + s = v < 0; + z = (s ? -v : v) - 1; /* magnitude - 1 */ + + c = vp8_get_mv_class(z, &o); + + d = (o >> 3); /* int mv data */ + f = (o >> 1) & 3; /* fractional pel mv data */ + e = (o & 1); /* high precision mv data */ + + /* Code the fractional pel bits */ + if (c == MV_CLASS_0) { + vp8_write_token(w, vp8_mv_fp_tree, mvcomp->class0_fp[d], + vp8_mv_fp_encodings + f); + } else { + vp8_write_token(w, vp8_mv_fp_tree, mvcomp->fp, + vp8_mv_fp_encodings + f); + } + /* Code the high precision bit */ + if (usehp) { + if (c == MV_CLASS_0) { + vp8_write(w, e, mvcomp->class0_hp); + } else { + vp8_write(w, e, mvcomp->hp); + } + } +} + +static void build_nmv_component_cost_table(int *mvcost, + const nmv_component *mvcomp, + int usehp) { + int i, v; + int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE]; + int bits_cost[MV_OFFSET_BITS][2]; + int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4]; + int class0_hp_cost[2], hp_cost[2]; + + sign_cost[0] = vp8_cost_zero(mvcomp->sign); + sign_cost[1] = vp8_cost_one(mvcomp->sign); + vp8_cost_tokens(class_cost, mvcomp->classes, vp8_mv_class_tree); + vp8_cost_tokens(class0_cost, mvcomp->class0, vp8_mv_class0_tree); + for (i = 0; i < MV_OFFSET_BITS; ++i) { + bits_cost[i][0] = vp8_cost_zero(mvcomp->bits[i]); + bits_cost[i][1] = vp8_cost_one(mvcomp->bits[i]); + } + + for (i = 0; i < CLASS0_SIZE; ++i) + vp8_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], vp8_mv_fp_tree); + vp8_cost_tokens(fp_cost, mvcomp->fp, vp8_mv_fp_tree); + + if (usehp) { + class0_hp_cost[0] = vp8_cost_zero(mvcomp->class0_hp); + class0_hp_cost[1] = vp8_cost_one(mvcomp->class0_hp); + hp_cost[0] = vp8_cost_zero(mvcomp->hp); + hp_cost[1] = vp8_cost_one(mvcomp->hp); + } + mvcost[0] = 0; + for (v = 1; v <= MV_MAX; ++v) { + int z, c, o, d, e, f, cost = 0; + z = v - 1; + c = vp8_get_mv_class(z, &o); + cost += class_cost[c]; + d = (o >> 3); /* int mv data */ + f = (o >> 1) & 3; /* fractional pel mv data */ + e = (o & 1); /* high precision mv data */ + if (c == MV_CLASS_0) { + cost += class0_cost[d]; + } else { + int i, b; + b = c + CLASS0_BITS - 1; /* number of bits */ + for (i = 0; i < b; ++i) + cost += bits_cost[i][((d >> i) & 1)]; + } + if (c == MV_CLASS_0) { + cost += class0_fp_cost[d][f]; + } else { + cost += fp_cost[f]; + } + if (usehp) { + if (c == MV_CLASS_0) { + cost += class0_hp_cost[e]; + } else { + cost += hp_cost[e]; + } + } + mvcost[v] = cost + sign_cost[0]; + mvcost[-v] = cost + sign_cost[1]; + } +} + +static int update_nmv_savings(const unsigned int ct[2], + const vp8_prob cur_p, + const vp8_prob new_p, + const vp8_prob upd_p) { + +#ifdef LOW_PRECISION_MV_UPDATE + vp8_prob mod_p = new_p | 1; +#else + vp8_prob mod_p = new_p; +#endif + const int cur_b = vp8_cost_branch256(ct, cur_p); + const int mod_b = vp8_cost_branch256(ct, mod_p); + const int cost = 7 * 256 + +#ifndef LOW_PRECISION_MV_UPDATE + 256 + +#endif + (vp8_cost_one(upd_p) - vp8_cost_zero(upd_p)); + if (cur_b - mod_b - cost > 0) { + return cur_b - mod_b - cost; + } else { + return -vp8_cost_zero(upd_p); + } +} + +static int update_nmv( + vp8_writer *const w, + const unsigned int ct[2], + vp8_prob *const cur_p, + const vp8_prob new_p, + const vp8_prob upd_p) { + +#ifdef LOW_PRECISION_MV_UPDATE + vp8_prob mod_p = new_p | 1; +#else + vp8_prob mod_p = new_p; +#endif + + const int cur_b = vp8_cost_branch256(ct, *cur_p); + const int mod_b = vp8_cost_branch256(ct, mod_p); + const int cost = 7 * 256 + +#ifndef LOW_PRECISION_MV_UPDATE + 256 + +#endif + (vp8_cost_one(upd_p) - vp8_cost_zero(upd_p)); + + if (cur_b - mod_b > cost) { + *cur_p = mod_p; + vp8_write(w, 1, upd_p); +#ifdef LOW_PRECISION_MV_UPDATE + vp8_write_literal(w, mod_p >> 1, 7); +#else + vp8_write_literal(w, mod_p, 8); +#endif + return 1; + } else { + vp8_write(w, 0, upd_p); + return 0; + } +} + +#ifdef NMV_STATS +void init_nmvstats() { + vp8_zero(tnmvcounts); +} + +void print_nmvstats() { + nmv_context prob; + unsigned int branch_ct_joint[MV_JOINTS - 1][2]; + unsigned int branch_ct_sign[2][2]; + unsigned int branch_ct_classes[2][MV_CLASSES - 1][2]; + unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2]; + unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2]; + unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2]; + unsigned int branch_ct_fp[2][4 - 1][2]; + unsigned int branch_ct_class0_hp[2][2]; + unsigned int branch_ct_hp[2][2]; + int i, j, k; + vp8_counts_to_nmv_context(&tnmvcounts, &prob, 1, + branch_ct_joint, branch_ct_sign, branch_ct_classes, + branch_ct_class0, branch_ct_bits, + branch_ct_class0_fp, branch_ct_fp, + branch_ct_class0_hp, branch_ct_hp); + + printf("\nCounts =\n { "); + for (j = 0; j < MV_JOINTS; ++j) + printf("%d, ", tnmvcounts.joints[j]); + printf("},\n"); + for (i=0; i< 2; ++i) { + printf(" {\n"); + printf(" %d/%d,\n", tnmvcounts.comps[i].sign[0], + tnmvcounts.comps[i].sign[1]); + printf(" { "); + for (j = 0; j < MV_CLASSES; ++j) + printf("%d, ", tnmvcounts.comps[i].classes[j]); + printf("},\n"); + printf(" { "); + for (j = 0; j < CLASS0_SIZE; ++j) + printf("%d, ", tnmvcounts.comps[i].class0[j]); + printf("},\n"); + printf(" { "); + for (j = 0; j < MV_OFFSET_BITS; ++j) + printf("%d/%d, ", tnmvcounts.comps[i].bits[j][0], + tnmvcounts.comps[i].bits[j][1]); + printf("},\n"); + + printf(" {"); + for (j = 0; j < CLASS0_SIZE; ++j) { + printf("{"); + for (k = 0; k < 4; ++k) + printf("%d, ", tnmvcounts.comps[i].class0_fp[j][k]); + printf("}, "); + } + printf("},\n"); + + printf(" { "); + for (j = 0; j < 4; ++j) + printf("%d, ", tnmvcounts.comps[i].fp[j]); + printf("},\n"); + + printf(" %d/%d,\n", + tnmvcounts.comps[i].class0_hp[0], + tnmvcounts.comps[i].class0_hp[1]); + printf(" %d/%d,\n", + tnmvcounts.comps[i].hp[0], + tnmvcounts.comps[i].hp[1]); + printf(" },\n"); + } + + printf("\nProbs =\n { "); + for (j = 0; j < MV_JOINTS - 1; ++j) + printf("%d, ", prob.joints[j]); + printf("},\n"); + for (i=0; i< 2; ++i) { + printf(" {\n"); + printf(" %d,\n", prob.comps[i].sign); + printf(" { "); + for (j = 0; j < MV_CLASSES - 1; ++j) + printf("%d, ", prob.comps[i].classes[j]); + printf("},\n"); + printf(" { "); + for (j = 0; j < CLASS0_SIZE - 1; ++j) + printf("%d, ", prob.comps[i].class0[j]); + printf("},\n"); + printf(" { "); + for (j = 0; j < MV_OFFSET_BITS; ++j) + printf("%d, ", prob.comps[i].bits[j]); + printf("},\n"); + printf(" { "); + for (j = 0; j < CLASS0_SIZE; ++j) { + printf("{"); + for (k = 0; k < 3; ++k) + printf("%d, ", prob.comps[i].class0_fp[j][k]); + printf("}, "); + } + printf("},\n"); + printf(" { "); + for (j = 0; j < 3; ++j) + printf("%d, ", prob.comps[i].fp[j]); + printf("},\n"); + + printf(" %d,\n", prob.comps[i].class0_hp); + printf(" %d,\n", prob.comps[i].hp); + printf(" },\n"); + } +} + +static void add_nmvcount(nmv_context_counts *dst, nmv_context_counts *src) { + int i, j, k; + for (j = 0; j < MV_JOINTS; ++j) { + dst->joints[j] += src->joints[j]; + } + for (i = 0; i < 2; ++i) { + for (j = 0; j < MV_VALS; ++j) { + dst->comps[i].mvcount[j] += src->comps[i].mvcount[j]; + } + dst->comps[i].sign[0] += src->comps[i].sign[0]; + dst->comps[i].sign[1] += src->comps[i].sign[1]; + for (j = 0; j < MV_CLASSES; ++j) { + dst->comps[i].classes[j] += src->comps[i].classes[j]; + } + for (j = 0; j < CLASS0_SIZE; ++j) { + dst->comps[i].class0[j] += src->comps[i].class0[j]; + } + for (j = 0; j < MV_OFFSET_BITS; ++j) { + dst->comps[i].bits[j][0] += src->comps[i].bits[j][0]; + dst->comps[i].bits[j][1] += src->comps[i].bits[j][1]; + } + } + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + for (k = 0; k < 4; ++k) { + dst->comps[i].class0_fp[j][k] += src->comps[i].class0_fp[j][k]; + } + } + for (j = 0; j < 4; ++j) { + dst->comps[i].fp[j] += src->comps[i].fp[j]; + } + dst->comps[i].class0_hp[0] += src->comps[i].class0_hp[0]; + dst->comps[i].class0_hp[1] += src->comps[i].class0_hp[1]; + dst->comps[i].hp[0] += src->comps[i].hp[0]; + dst->comps[i].hp[1] += src->comps[i].hp[1]; + } +} +#endif + +void vp8_write_nmvprobs(VP8_COMP * cpi, int usehp) { + vp8_writer *const w = & cpi->bc; + int i, j; + nmv_context prob; + unsigned int branch_ct_joint[MV_JOINTS - 1][2]; + unsigned int branch_ct_sign[2][2]; + unsigned int branch_ct_classes[2][MV_CLASSES - 1][2]; + unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2]; + unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2]; + unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2]; + unsigned int branch_ct_fp[2][4 - 1][2]; + unsigned int branch_ct_class0_hp[2][2]; + unsigned int branch_ct_hp[2][2]; + int savings = 0; + +#ifdef NMV_STATS + if (!cpi->dummy_packing) + add_nmvcount(&tnmvcounts, &cpi->NMVcount); +#endif + vp8_counts_to_nmv_context(&cpi->NMVcount, &prob, usehp, + branch_ct_joint, branch_ct_sign, branch_ct_classes, + branch_ct_class0, branch_ct_bits, + branch_ct_class0_fp, branch_ct_fp, + branch_ct_class0_hp, branch_ct_hp); + /* write updates if they help */ +#ifdef MV_GROUP_UPDATE + for (j = 0; j < MV_JOINTS - 1; ++j) { + savings += update_nmv_savings(branch_ct_joint[j], + cpi->common.fc.nmvc.joints[j], + prob.joints[j], + VP8_NMV_UPDATE_PROB); + } + for (i = 0; i < 2; ++i) { + savings += update_nmv_savings(branch_ct_sign[i], + cpi->common.fc.nmvc.comps[i].sign, + prob.comps[i].sign, + VP8_NMV_UPDATE_PROB); + for (j = 0; j < MV_CLASSES - 1; ++j) { + savings += update_nmv_savings(branch_ct_classes[i][j], + cpi->common.fc.nmvc.comps[i].classes[j], + prob.comps[i].classes[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < CLASS0_SIZE - 1; ++j) { + savings += update_nmv_savings(branch_ct_class0[i][j], + cpi->common.fc.nmvc.comps[i].class0[j], + prob.comps[i].class0[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < MV_OFFSET_BITS; ++j) { + savings += update_nmv_savings(branch_ct_bits[i][j], + cpi->common.fc.nmvc.comps[i].bits[j], + prob.comps[i].bits[j], + VP8_NMV_UPDATE_PROB); + } + } + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + int k; + for (k = 0; k < 3; ++k) { + savings += update_nmv_savings(branch_ct_class0_fp[i][j][k], + cpi->common.fc.nmvc.comps[i].class0_fp[j][k], + prob.comps[i].class0_fp[j][k], + VP8_NMV_UPDATE_PROB); + } + } + for (j = 0; j < 3; ++j) { + savings += update_nmv_savings(branch_ct_fp[i][j], + cpi->common.fc.nmvc.comps[i].fp[j], + prob.comps[i].fp[j], + VP8_NMV_UPDATE_PROB); + } + } + if (usehp) { + for (i = 0; i < 2; ++i) { + savings += update_nmv_savings(branch_ct_class0_hp[i], + cpi->common.fc.nmvc.comps[i].class0_hp, + prob.comps[i].class0_hp, + VP8_NMV_UPDATE_PROB); + savings += update_nmv_savings(branch_ct_hp[i], + cpi->common.fc.nmvc.comps[i].hp, + prob.comps[i].hp, + VP8_NMV_UPDATE_PROB); + } + } + if (savings <= 0) { + vp8_write_bit(w, 0); + return; + } + vp8_write_bit(w, 1); +#endif + + for (j = 0; j < MV_JOINTS - 1; ++j) { + update_nmv(w, branch_ct_joint[j], + &cpi->common.fc.nmvc.joints[j], + prob.joints[j], + VP8_NMV_UPDATE_PROB); + } + for (i = 0; i < 2; ++i) { + update_nmv(w, branch_ct_sign[i], + &cpi->common.fc.nmvc.comps[i].sign, + prob.comps[i].sign, + VP8_NMV_UPDATE_PROB); + for (j = 0; j < MV_CLASSES - 1; ++j) { + update_nmv(w, branch_ct_classes[i][j], + &cpi->common.fc.nmvc.comps[i].classes[j], + prob.comps[i].classes[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < CLASS0_SIZE - 1; ++j) { + update_nmv(w, branch_ct_class0[i][j], + &cpi->common.fc.nmvc.comps[i].class0[j], + prob.comps[i].class0[j], + VP8_NMV_UPDATE_PROB); + } + for (j = 0; j < MV_OFFSET_BITS; ++j) { + update_nmv(w, branch_ct_bits[i][j], + &cpi->common.fc.nmvc.comps[i].bits[j], + prob.comps[i].bits[j], + VP8_NMV_UPDATE_PROB); + } + } + for (i = 0; i < 2; ++i) { + for (j = 0; j < CLASS0_SIZE; ++j) { + int k; + for (k = 0; k < 3; ++k) { + update_nmv(w, branch_ct_class0_fp[i][j][k], + &cpi->common.fc.nmvc.comps[i].class0_fp[j][k], + prob.comps[i].class0_fp[j][k], + VP8_NMV_UPDATE_PROB); + } + } + for (j = 0; j < 3; ++j) { + update_nmv(w, branch_ct_fp[i][j], + &cpi->common.fc.nmvc.comps[i].fp[j], + prob.comps[i].fp[j], + VP8_NMV_UPDATE_PROB); + } + } + if (usehp) { + for (i = 0; i < 2; ++i) { + update_nmv(w, branch_ct_class0_hp[i], + &cpi->common.fc.nmvc.comps[i].class0_hp, + prob.comps[i].class0_hp, + VP8_NMV_UPDATE_PROB); + update_nmv(w, branch_ct_hp[i], + &cpi->common.fc.nmvc.comps[i].hp, + prob.comps[i].hp, + VP8_NMV_UPDATE_PROB); + } + } +} + +void vp8_encode_nmv(vp8_writer *w, const MV *mv, const MV *ref, + const nmv_context *mvctx) { + MV_JOINT_TYPE j = vp8_get_mv_joint(*mv); + vp8_write_token(w, vp8_mv_joint_tree, mvctx->joints, + vp8_mv_joint_encodings + j); + if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) { + encode_nmv_component(w, mv->row, ref->col, &mvctx->comps[0]); + } + if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) { + encode_nmv_component(w, mv->col, ref->col, &mvctx->comps[1]); + } +} + +void vp8_encode_nmv_fp(vp8_writer *w, const MV *mv, const MV *ref, + const nmv_context *mvctx, int usehp) { + MV_JOINT_TYPE j = vp8_get_mv_joint(*mv); + if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) { + encode_nmv_component_fp(w, mv->row, ref->row, &mvctx->comps[0], usehp); + } + if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) { + encode_nmv_component_fp(w, mv->col, ref->col, &mvctx->comps[1], usehp); + } +} + +void vp8_build_nmv_cost_table(int *mvjoint, + int *mvcost[2], + const nmv_context *mvctx, + int usehp, + int mvc_flag_v, + int mvc_flag_h) { + vp8_clear_system_state(); + vp8_cost_tokens(mvjoint, mvctx->joints, vp8_mv_joint_tree); + if (mvc_flag_v) + build_nmv_component_cost_table(mvcost[0], &mvctx->comps[0], usehp); + if (mvc_flag_h) + build_nmv_component_cost_table(mvcost[1], &mvctx->comps[1], usehp); +} + +#else /* CONFIG_NEWMVENTROPY */ + static void encode_mvcomponent( vp8_writer *const w, const int v, @@ -596,8 +1126,9 @@ void vp8_write_mvprobs_hp(VP8_COMP *cpi) { vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flags); - #ifdef ENTROPY_STATS active_section = 5; #endif } + +#endif /* CONFIG_NEWMVENTROPY */ diff --git a/vp8/encoder/encodemv.h b/vp8/encoder/encodemv.h index 7e33007d7d503fcfc0baeb66eab9c4716e90c407..e675fe05867bde78738e6d8fd28dcfbf72a222d5 100644 --- a/vp8/encoder/encodemv.h +++ b/vp8/encoder/encodemv.h @@ -14,11 +14,31 @@ #include "onyx_int.h" +#if CONFIG_NEWMVENTROPY +void vp8_write_nmvprobs(VP8_COMP *, int usehp); +void vp8_encode_nmv(vp8_writer *w, const MV *mv, const MV *ref, + const nmv_context *mvctx); +void vp8_encode_nmv_fp(vp8_writer *w, const MV *mv, const MV *ref, + const nmv_context *mvctx, int usehp); +void vp8_build_nmv_cost_table(int *mvjoint, + int *mvcost[2], + const nmv_context *mvctx, + int usehp, + int mvc_flag_v, + int mvc_flag_h); +#else /* CONFIG_NEWMVENTROPY */ void vp8_write_mvprobs(VP8_COMP *); -void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *); -void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2]); +void vp8_encode_motion_vector(vp8_writer *, const MV *, + const MV_CONTEXT *); +void vp8_build_component_cost_table(int *mvcost[2], + const MV_CONTEXT *mvc, + int mvc_flag[2]); void vp8_write_mvprobs_hp(VP8_COMP *); -void vp8_encode_motion_vector_hp(vp8_writer *, const MV *, const MV_CONTEXT_HP *); -void vp8_build_component_cost_table_hp(int *mvcost[2], const MV_CONTEXT_HP *mvc, int mvc_flag[2]); +void vp8_encode_motion_vector_hp(vp8_writer *, const MV *, + const MV_CONTEXT_HP *); +void vp8_build_component_cost_table_hp(int *mvcost[2], + const MV_CONTEXT_HP *mvc, + int mvc_flag[2]); +#endif /* CONFIG_NEWMVENTROPY */ #endif diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index c1504f2ecec70f4e0430a0c2f619e1ec6ad15362..1e54371f74f2910bd4f2681271b54152601265ac 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -28,6 +28,7 @@ #include "rdopt.h" #include "ratectrl.h" #include "vp8/common/quant_common.h" +#include "vp8/common/entropymv.h" #include "encodemv.h" #define OUTPUT_FPF 0 @@ -38,8 +39,6 @@ #define IF_RTCD(x) NULL #endif -#define XMVCOST (x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost) - extern void vp8_build_block_offsets(MACROBLOCK *x); extern void vp8_setup_block_ptrs(MACROBLOCK *x); extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi); @@ -492,11 +491,13 @@ void vp8_first_pass(VP8_COMP *cpi) { // if ( 0 ) { int flag[2] = {1, 1}; + vp8_init_mv_probs(cm); +#if CONFIG_NEWMVENTROPY vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q); - vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); +#else vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag); - vpx_memcpy(cm->fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp)); vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cm->fc.mvc_hp, flag); +#endif } // for each macroblock row in image diff --git a/vp8/encoder/mbgraph.c b/vp8/encoder/mbgraph.c index dde000af112af2c4dfa2cc0f0367e1bb3dbf3a63..d512ae4bced7816a925d9b87fc3b816cee950527 100644 --- a/vp8/encoder/mbgraph.c +++ b/vp8/encoder/mbgraph.c @@ -31,12 +31,6 @@ static unsigned int do_16x16_motion_iteration vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; unsigned int best_err; int step_param, further_steps; - static int dummy_cost[2 * mv_max + 1]; - int *mvcost[2] = { &dummy_cost[mv_max + 1], &dummy_cost[mv_max + 1] }; - int *mvsadcost[2] = { &dummy_cost[mv_max + 1], &dummy_cost[mv_max + 1] }; - static int dummy_cost_hp[2 * mv_max_hp + 1]; - int *mvcost_hp[2] = { &dummy_cost_hp[mv_max_hp + 1], &dummy_cost_hp[mv_max_hp + 1] }; - int *mvsadcost_hp[2] = { &dummy_cost_hp[mv_max_hp + 1], &dummy_cost_hp[mv_max_hp + 1] }; int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max; @@ -65,8 +59,8 @@ static unsigned int do_16x16_motion_iteration step_param, x->errorperbit, &v_fn_ptr, - xd->allow_high_precision_mv ? mvsadcost_hp : mvsadcost, - xd->allow_high_precision_mv ? mvcost_hp : mvcost, + NULLMVCOST, + NULLMVCOST, ref_mv); // Try sub-pixel MC @@ -78,7 +72,7 @@ static unsigned int do_16x16_motion_iteration x, b, d, dst_mv, ref_mv, x->errorperbit, &v_fn_ptr, - xd->allow_high_precision_mv ? mvcost_hp : mvcost, + NULLMVCOST, & distortion, &sse); } diff --git a/vp8/encoder/mcomp.c b/vp8/encoder/mcomp.c index 79e10a5bccee1d29d654466af30d6e401ab9918e..76accd42355e5b48a011331a3fc4cb1d78645e23 100644 --- a/vp8/encoder/mcomp.c +++ b/vp8/encoder/mcomp.c @@ -42,42 +42,59 @@ void vp8_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) { x->mv_row_max = row_max; } -int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], +int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS, int Weight, int ishp) { - // MV costing is based on the distribution of vectors in the previous frame - // and as such will tend to over state the cost of vectors. In addition - // coding a new vector can have a knock on effect on the cost of subsequent - // vectors and the quality of prediction from NEAR and NEAREST for subsequent - // blocks. The "Weight" parameter allows, to a limited extent, for some - // account to be taken of these factors. - return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> (ishp == 0)] + - mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> (ishp == 0)]) + MV v; + v.row = (mv->as_mv.row - ref->as_mv.row); + v.col = (mv->as_mv.col - ref->as_mv.col); +#if CONFIG_NEWMVENTROPY + return ((mvjcost[vp8_get_mv_joint(v)] + + mvcost[0][v.row] + mvcost[1][v.col]) * + Weight) >> 7; +#else + return ((mvcost[0][v.row >> (ishp == 0)] + + mvcost[1][v.col >> (ishp == 0)]) * Weight) >> 7; +#endif } -static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], +static int mv_err_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS, int error_per_bit, int ishp) { - // Ignore costing if mvcost is NULL - if (mvcost) - return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> (ishp == 0)] + - mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> (ishp == 0)]) - * error_per_bit + 128) >> 8; + if (mvcost) { + MV v; + v.row = (mv->as_mv.row - ref->as_mv.row); + v.col = (mv->as_mv.col - ref->as_mv.col); +#if CONFIG_NEWMVENTROPY + return ((mvjcost[vp8_get_mv_joint(v)] + + mvcost[0][v.row] + mvcost[1][v.col]) * + error_per_bit + 128) >> 8; +#else + return ((mvcost[0][v.row >> (ishp == 0)] + + mvcost[1][v.col >> (ishp == 0)]) * error_per_bit + 128) >> 8; +#endif + } return 0; } - -static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], +static int mvsad_err_cost(int_mv *mv, int_mv *ref, DEC_MVSADCOSTS, int error_per_bit) { - // Calculate sad error cost on full pixel basis. - // Ignore costing if mvcost is NULL - if (mvsadcost) - return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] + - mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)]) + + if (mvsadcost) { + MV v; + v.row = (mv->as_mv.row - ref->as_mv.row); + v.col = (mv->as_mv.col - ref->as_mv.col); +#if CONFIG_NEWMVENTROPY + return ((mvjsadcost[vp8_get_mv_joint(v)] + + mvsadcost[0][v.row] + mvsadcost[1][v.col]) * + error_per_bit + 128) >> 8; +#else + return ((mvsadcost[0][v.row] + mvsadcost[1][v.col]) * error_per_bit + 128) >> 8; +#endif + } return 0; } - void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) { int Len; int search_site_count = 0; @@ -185,7 +202,6 @@ void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) { x->ss[search_site_count].offset = Len * stride + Len; search_site_count++; - // Contract. Len /= 2; } @@ -204,18 +220,35 @@ void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) { * could reduce the area. */ -#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector -#define SP(x) (((x)&3)<<2) // convert motion vector component to offset for svf calc -#define MVC(r,c) (mvcost ? ((mvcost[0][(r)-rr] + mvcost[1][(c)-rc]) * error_per_bit + 128 )>>8 : 0) // estimated cost of a motion vector (r,c) -#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function. -#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost -#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e; +#if CONFIG_NEWMVENTROPY +/* estimated cost of a motion vector (r,c) */ +#define MVC(r,c) \ + (mvcost ? \ + ((mvjcost[((r)!=rr)*2 + ((c)!=rc)] + \ + mvcost[0][((r)-rr)] + mvcost[1][((c)-rc)]) * error_per_bit + 128 )>>8 : 0) +#else +#define MVC(r,c) \ + (mvcost ? \ + ((mvcost[0][((r)-rr)>>(xd->allow_high_precision_mv==0)] + \ + mvcost[1][((c)-rc)>>(xd->allow_high_precision_mv==0)]) * \ + error_per_bit + 128 )>>8 : 0) +#endif /* CONFIG_NEWMVENTROPY */ + +#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc + +#define IFMVCV(r,c,s,e) \ + if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e; + +/* pointer to predictor base of a motionvector */ +#define PRE(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) -#define PREHP(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) // pointer to predictor base of a motionvector -#define SPHP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc -#define DISTHP(r,c) vfp->svf( PREHP(r,c), y_stride, SPHP(c),SPHP(r), z,b->src_stride,&sse) // returns subpixel variance error function. -#define ERRHP(r,c) (MVC(r,c)+DISTHP(r,c)) // returns distortion + motion vector cost -#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = ((xd->allow_high_precision_mv)?DISTHP(r,c):DIST(r,c)); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best +/* returns subpixel variance error function */ +#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) + +/* checks if (r,c) has better score than previous best */ +#define CHECK_BETTER(v,r,c) \ + IFMVCV(r,c,{thismse = (DIST(r,c)); if((v = MVC(r,c)+thismse) < besterr) \ + { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;) #define MIN(x,y) (((x)<(y))?(x):(y)) #define MAX(x,y) (((x)>(y))?(x):(y)) @@ -224,7 +257,8 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *bestmv, int_mv *ref_mv, int error_per_bit, const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, + DEC_MVCOSTS, + int *distortion, unsigned int *sse1) { unsigned char *z = (*(b->base_src) + b->src); MACROBLOCKD *xd = &x->e_mbd; @@ -268,27 +302,22 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, #endif - if (xd->allow_high_precision_mv) { - rr = ref_mv->as_mv.row; - rc = ref_mv->as_mv.col; - br = bestmv->as_mv.row << 3; - bc = bestmv->as_mv.col << 3; - hstep = 4; - minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << mvlong_width_hp) - 1)); - maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width_hp) - 1)); - minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width_hp) - 1)); - maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width_hp) - 1)); - } else { - rr = ref_mv->as_mv.row >> 1; - rc = ref_mv->as_mv.col >> 1; - br = bestmv->as_mv.row << 2; - bc = bestmv->as_mv.col << 2; - hstep = 2; - minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1)); - maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1)); - minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1)); - maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1)); - } + rr = ref_mv->as_mv.row; + rc = ref_mv->as_mv.col; + br = bestmv->as_mv.row << 3; + bc = bestmv->as_mv.col << 3; + hstep = 4; +#if CONFIG_NEWMVENTROPY + minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << MV_MAX_BITS) - 1)); + maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << MV_MAX_BITS) - 1)); + minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << MV_MAX_BITS) - 1)); + maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << MV_MAX_BITS) - 1)); +#else + minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << mvlong_width_hp) - 1)); + maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width_hp) - 1)); + minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width_hp) - 1)); + maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width_hp) - 1)); +#endif tr = br; tc = bc; @@ -303,8 +332,8 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // calculate central point error besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1); *distortion = besterr; - besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, - xd->allow_high_precision_mv); + besterr += mv_err_cost(bestmv, ref_mv, MVCOSTS, + error_per_bit, xd->allow_high_precision_mv); // TODO: Each subsequent iteration checks at least one point in // common with the last iteration could be 2 ( if diag selected) @@ -407,13 +436,8 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, tc = bc; } } - if (x->e_mbd.allow_high_precision_mv) { - bestmv->as_mv.row = br; - bestmv->as_mv.col = bc; - } else { - bestmv->as_mv.row = br << 1; - bestmv->as_mv.col = bc << 1; - } + bestmv->as_mv.row = br; + bestmv->as_mv.col = bc; if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL << 3)) || (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL << 3))) @@ -423,25 +447,17 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, } #undef MVC #undef PRE -#undef SP #undef DIST #undef IFMVCV -#undef ERR #undef CHECK_BETTER #undef MIN #undef MAX -#undef PREHP -#undef DPHP -#undef DISTHP -#undef ERRHP - -#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *bestmv, int_mv *ref_mv, int error_per_bit, const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, + DEC_MVCOSTS, int *distortion, unsigned int *sse1) { int bestmse = INT_MAX; int_mv startmv; @@ -478,14 +494,14 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // calculate central point error bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1); *distortion = bestmse; - bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, + bestmse += mv_err_cost(bestmv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); // go left then right and check error this_mv.as_mv.row = startmv.as_mv.row; this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4); thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse); - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (left < bestmse) { @@ -497,7 +513,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.col += 8; thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (right < bestmse) { @@ -511,7 +527,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.col = startmv.as_mv.col; this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4); thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse); - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (up < bestmse) { @@ -523,7 +539,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row += 8; thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (down < bestmse) { @@ -564,7 +580,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, break; } - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (diag < bestmse) { @@ -606,7 +622,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, b->src_stride, &sse); } - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (left < bestmse) { @@ -620,7 +636,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (right < bestmse) { @@ -644,7 +660,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, z, b->src_stride, &sse); } - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (up < bestmse) { @@ -657,7 +673,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row += 4; thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (down < bestmse) { @@ -736,7 +752,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, break; } - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (diag < bestmse) { @@ -776,7 +792,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, z, b->src_stride, &sse); } - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (left < bestmse) { @@ -787,8 +803,10 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, } this_mv.as_mv.col += 2; - thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv); + thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), + z, b->src_stride, &sse); + right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, + xd->allow_high_precision_mv); if (right < bestmse) { *bestmv = this_mv; @@ -808,7 +826,8 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse); } - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv); + up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, + xd->allow_high_precision_mv); if (up < bestmse) { *bestmv = this_mv; @@ -819,7 +838,8 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row += 2; thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv); + down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, + xd->allow_high_precision_mv); if (down < bestmse) { *bestmv = this_mv; @@ -892,7 +912,8 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, break; } - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv); + diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, + xd->allow_high_precision_mv); if (diag < bestmse) { *bestmv = this_mv; @@ -910,7 +931,8 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *bestmv, int_mv *ref_mv, int error_per_bit, const vp8_variance_fn_ptr_t *vfp, - int *mvcost[2], int *distortion, + DEC_MVCOSTS, + int *distortion, unsigned int *sse1) { int bestmse = INT_MAX; int_mv startmv; @@ -946,14 +968,14 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // calculate central point error bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1); *distortion = bestmse; - bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, + bestmse += mv_err_cost(bestmv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); // go left then right and check error this_mv.as_mv.row = startmv.as_mv.row; this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4); thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse); - left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (left < bestmse) { @@ -965,7 +987,7 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.col += 8; thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse); - right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (right < bestmse) { @@ -979,7 +1001,7 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.col = startmv.as_mv.col; this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4); thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse); - up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (up < bestmse) { @@ -991,7 +1013,7 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row += 8; thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse); - down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (down < bestmse) { @@ -1029,7 +1051,7 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, break; } - diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, + diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit, xd->allow_high_precision_mv); if (diag < bestmse) { @@ -1063,7 +1085,7 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, {\ if (thissad < bestsad)\ {\ - thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);\ + thissad += mvsad_err_cost(&this_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit);\ if (thissad < bestsad)\ {\ bestsad = thissad;\ @@ -1091,8 +1113,8 @@ int vp8_hex_search int search_param, int sad_per_bit, const vp8_variance_fn_ptr_t *vfp, - int *mvsadcost[2], - int *mvcost[2], + DEC_MVSADCOSTS, + DEC_MVCOSTS, int_mv *center_mv ) { MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} }; @@ -1128,7 +1150,7 @@ int vp8_hex_search this_mv.as_mv.col = bc; bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride, 0x7fffffff) - + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(&this_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // hex search // j=0 @@ -1240,7 +1262,7 @@ cal_neighbors: int vp8_diamond_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int_mv *best_mv, int search_param, int sad_per_bit, int *num00, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], + vp8_variance_fn_ptr_t *fn_ptr, DEC_MVCOSTS, int_mv *center_mv) { int i, j, step; @@ -1264,14 +1286,19 @@ int vp8_diamond_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, unsigned char *check_here; int thissad; MACROBLOCKD *xd = &x->e_mbd; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif + fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; @@ -1289,7 +1316,7 @@ int vp8_diamond_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // Check the starting position bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) - + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(best_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // search_param determines the length of the initial step and hence the number of iterations // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc. @@ -1315,7 +1342,7 @@ int vp8_diamond_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row = this_row_offset; this_mv.as_mv.col = this_col_offset; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1345,7 +1372,7 @@ int vp8_diamond_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); } @@ -1353,7 +1380,7 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int_mv *best_mv, int search_param, int sad_per_bit, int *num00, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { + DEC_MVCOSTS, int_mv *center_mv) { int i, j, step; unsigned char *what = (*(b->base_src) + b->src); @@ -1378,14 +1405,19 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, unsigned char *check_here; unsigned int thissad; MACROBLOCKD *xd = &x->e_mbd; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif + fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; @@ -1403,7 +1435,7 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, // Check the starting position bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) - + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(best_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // search_param determines the length of the initial step and hence the number of iterations // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc. @@ -1438,7 +1470,7 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row = best_mv->as_mv.row + ss[i].mv.row; this_mv.as_mv.col = best_mv->as_mv.col + ss[i].mv.col; sad_array[t] += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (sad_array[t] < bestsad) { bestsad = sad_array[t]; @@ -1462,7 +1494,7 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, this_mv.as_mv.row = this_row_offset; this_mv.as_mv.col = this_col_offset; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1492,11 +1524,10 @@ int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); } -#define XMVCOST (x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost) /* do_refine: If last step (1-away) of n-step search doesn't pick the center point as the best match, we will do a final 1-away diamond refining search */ @@ -1558,7 +1589,7 @@ int vp8_full_pixel_diamond(VP8_COMP *cpi, MACROBLOCK *x, BLOCK *b, int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int sad_per_bit, int distance, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], + vp8_variance_fn_ptr_t *fn_ptr, DEC_MVCOSTS, int_mv *center_mv) { unsigned char *what = (*(b->base_src) + b->src); int what_stride = b->src_stride; @@ -1582,14 +1613,19 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int row_max = ref_row + distance; int col_min = ref_col - distance; int col_max = ref_col + distance; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif + fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; @@ -1603,7 +1639,7 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, // Baseline value at the centre bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) - + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(best_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border if (col_min < x->mv_col_min) @@ -1627,7 +1663,7 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1647,7 +1683,7 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); else return INT_MAX; @@ -1655,7 +1691,7 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int sad_per_bit, int distance, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], + vp8_variance_fn_ptr_t *fn_ptr, DEC_MVCOSTS, int_mv *center_mv) { unsigned char *what = (*(b->base_src) + b->src); int what_stride = b->src_stride; @@ -1681,14 +1717,19 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int col_max = ref_col + distance; unsigned int sad_array[3]; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif + fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; @@ -1702,7 +1743,7 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, // Baseline value at the centre bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) - + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(best_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border if (col_min < x->mv_col_min) @@ -1733,7 +1774,7 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1754,7 +1795,7 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1777,7 +1818,7 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); else return INT_MAX; @@ -1785,7 +1826,8 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int sad_per_bit, int distance, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], + vp8_variance_fn_ptr_t *fn_ptr, + DEC_MVCOSTS, int_mv *center_mv) { unsigned char *what = (*(b->base_src) + b->src); int what_stride = b->src_stride; @@ -1812,14 +1854,19 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, DECLARE_ALIGNED_ARRAY(16, unsigned short, sad_array8, 8); unsigned int sad_array[3]; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif + fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; @@ -1833,7 +1880,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, // Baseline value at the centre bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) - + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit); + + mvsad_err_cost(best_mv, &fcenter_mv, MVSADCOSTS, sad_per_bit); // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border if (col_min < x->mv_col_min) @@ -1864,7 +1911,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1890,7 +1937,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1911,7 +1958,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.col = c; thissad += mvsad_err_cost(&this_mv, &fcenter_mv, - mvsadcost, sad_per_bit); + MVSADCOSTS, sad_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -1933,7 +1980,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); else return INT_MAX; @@ -1941,7 +1988,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int error_per_bit, int search_range, - vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], + vp8_variance_fn_ptr_t *fn_ptr, DEC_MVCOSTS, int_mv *center_mv) { MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; int i, j; @@ -1957,19 +2004,24 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int_mv this_mv; unsigned int bestsad = INT_MAX; MACROBLOCKD *xd = &x->e_mbd; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride, 0x7fffffff) + mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit); + bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride, 0x7fffffff) + + mvsad_err_cost(ref_mv, &fcenter_mv, MVSADCOSTS, error_per_bit); for (i = 0; i < search_range; i++) { int best_site = -1; @@ -1986,7 +2038,7 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, if (thissad < bestsad) { this_mv.as_mv.row = this_row_offset; this_mv.as_mv.col = this_col_offset; - thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); + thissad += mvsad_err_cost(&this_mv, &fcenter_mv, MVSADCOSTS, error_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -2012,7 +2064,7 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); else return INT_MAX; @@ -2021,7 +2073,7 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv, int error_per_bit, int search_range, vp8_variance_fn_ptr_t *fn_ptr, - int *mvcost[2], int_mv *center_mv) { + DEC_MVCOSTS, int_mv *center_mv) { MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}}; int i, j; short this_row_offset, this_col_offset; @@ -2036,19 +2088,24 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv this_mv; unsigned int bestsad = INT_MAX; MACROBLOCKD *xd = &x->e_mbd; - - int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; int_mv fcenter_mv; +#if CONFIG_NEWMVENTROPY + int *mvjsadcost = x->nmvjointsadcost; + int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; +#else + int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]}; if (xd->allow_high_precision_mv) { mvsadcost[0] = x->mvsadcost_hp[0]; mvsadcost[1] = x->mvsadcost_hp[1]; } +#endif fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3; fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3; - bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride, 0x7fffffff) + mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit); + bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride, 0x7fffffff) + + mvsad_err_cost(ref_mv, &fcenter_mv, MVSADCOSTS, error_per_bit); for (i = 0; i < search_range; i++) { int best_site = -1; @@ -2073,7 +2130,7 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, if (sad_array[j] < bestsad) { this_mv.as_mv.row = ref_mv->as_mv.row + neighbors[j].row; this_mv.as_mv.col = ref_mv->as_mv.col + neighbors[j].col; - sad_array[j] += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); + sad_array[j] += mvsad_err_cost(&this_mv, &fcenter_mv, MVSADCOSTS, error_per_bit); if (sad_array[j] < bestsad) { bestsad = sad_array[j]; @@ -2094,7 +2151,7 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, if (thissad < bestsad) { this_mv.as_mv.row = this_row_offset; this_mv.as_mv.col = this_col_offset; - thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit); + thissad += mvsad_err_cost(&this_mv, &fcenter_mv, MVSADCOSTS, error_per_bit); if (thissad < bestsad) { bestsad = thissad; @@ -2121,7 +2178,7 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad)) + - mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, + mv_err_cost(&this_mv, center_mv, MVCOSTS, x->errorperbit, xd->allow_high_precision_mv); else return INT_MAX; diff --git a/vp8/encoder/mcomp.h b/vp8/encoder/mcomp.h index c27f3bf75dd25bbe0204e3c3e779675240418e2c..afca5808415206ccdc1bef9926ddc7be2912f05d 100644 --- a/vp8/encoder/mcomp.h +++ b/vp8/encoder/mcomp.h @@ -15,6 +15,22 @@ #include "block.h" #include "variance.h" +#if CONFIG_NEWMVENTROPY +#define MVCOSTS mvjcost, mvcost +#define MVSADCOSTS mvjsadcost, mvsadcost +#define DEC_MVCOSTS int *mvjcost, int *mvcost[2] +#define DEC_MVSADCOSTS int *mvjsadcost, int *mvsadcost[2] +#define NULLMVCOST NULL, NULL +#define XMVCOST x->nmvjointcost, (x->e_mbd.allow_high_precision_mv?x->nmvcost_hp:x->nmvcost) +#else +#define MVCOSTS mvcost +#define MVSADCOSTS mvsadcost +#define DEC_MVCOSTS int *mvcost[2] +#define DEC_MVSADCOSTS int *mvsadcost[2] +#define NULLMVCOST NULL +#define XMVCOST (x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost) +#endif /* CONFIG_NEWMVENTROPY */ + #ifdef ENTROPY_STATS extern void init_mv_ref_counts(); extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]); @@ -26,7 +42,7 @@ extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]); #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1)) // Maximum size of the first step in full pel units extern void vp8_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv); -extern int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], +extern int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS, int Weight, int ishp); extern void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride); extern void vp8_init3smotion_compensation(MACROBLOCK *x, int stride); @@ -48,14 +64,14 @@ extern int vp8_hex_search int search_param, int error_per_bit, const vp8_variance_fn_ptr_t *vf, - int *mvsadcost[2], - int *mvcost[2], + DEC_MVSADCOSTS, + DEC_MVCOSTS, int_mv *center_mv ); typedef int (fractional_mv_step_fp) (MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *bestmv, int_mv *ref_mv, - int error_per_bit, const vp8_variance_fn_ptr_t *vfp, int *mvcost[2], + int error_per_bit, const vp8_variance_fn_ptr_t *vfp, DEC_MVCOSTS, int *distortion, unsigned int *sse); extern fractional_mv_step_fp vp8_find_best_sub_pixel_step_iteratively; extern fractional_mv_step_fp vp8_find_best_sub_pixel_step; @@ -72,7 +88,7 @@ extern fractional_mv_step_fp vp8_skip_fractional_mv_step; int sad_per_bit, \ int distance, \ vp8_variance_fn_ptr_t *fn_ptr, \ - int *mvcost[2], \ + DEC_MVSADCOSTS, \ int_mv *center_mv \ ) @@ -86,7 +102,7 @@ extern fractional_mv_step_fp vp8_skip_fractional_mv_step; int sad_per_bit, \ int distance, \ vp8_variance_fn_ptr_t *fn_ptr, \ - int *mvcost[2], \ + DEC_MVSADCOSTS, \ int_mv *center_mv \ ) @@ -102,7 +118,7 @@ extern fractional_mv_step_fp vp8_skip_fractional_mv_step; int sad_per_bit, \ int *num00, \ vp8_variance_fn_ptr_t *fn_ptr, \ - int *mvcost[2], \ + DEC_MVSADCOSTS, \ int_mv *center_mv \ ) diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 68c28c3f22f34c40ac3c012cef4bfc866347ccb3..fdb3fa196e60ab8433ed65db1641260f09bb5007 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -149,6 +149,13 @@ extern int skip_false_count; extern int intra_mode_stats[VP8_BINTRAMODES][VP8_BINTRAMODES][VP8_BINTRAMODES]; #endif +#if CONFIG_NEWMVENTROPY +#ifdef NMV_STATS +extern void init_nmvstats(); +extern void print_nmvstats(); +#endif +#endif + #ifdef SPEEDSTATS unsigned int frames_at_speed[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int tot_pm = 0; @@ -1697,6 +1704,48 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) { #define M_LOG2_E 0.693147180559945309417 #define log2f(x) (log (x) / (float) M_LOG2_E) + +#if CONFIG_NEWMVENTROPY + +static void cal_nmvjointsadcost(int *mvjointsadcost) { + mvjointsadcost[0] = 600; + mvjointsadcost[1] = 300; + mvjointsadcost[2] = 300; + mvjointsadcost[0] = 300; +} + +static void cal_nmvsadcosts(int *mvsadcost[2]) { + int i = 1; + + mvsadcost [0] [0] = 0; + mvsadcost [1] [0] = 0; + + do { + double z = 256 * (2 * (log2f(8 * i) + .6)); + mvsadcost [0][i] = (int) z; + mvsadcost [1][i] = (int) z; + mvsadcost [0][-i] = (int) z; + mvsadcost [1][-i] = (int) z; + } while (++i <= MV_MAX); +} + +static void cal_nmvsadcosts_hp(int *mvsadcost[2]) { + int i = 1; + + mvsadcost [0] [0] = 0; + mvsadcost [1] [0] = 0; + + do { + double z = 256 * (2 * (log2f(8 * i) + .6)); + mvsadcost [0][i] = (int) z; + mvsadcost [1][i] = (int) z; + mvsadcost [0][-i] = (int) z; + mvsadcost [1][-i] = (int) z; + } while (++i <= MV_MAX); +} + +#else + static void cal_mvsadcosts(int *mvsadcost[2]) { int i = 1; @@ -1727,6 +1776,8 @@ static void cal_mvsadcosts_hp(int *mvsadcost[2]) { } while (++i <= mvfp_max_hp); } +#endif /* CONFIG_NEWMVENTROPY */ + VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) { int i; volatile union { @@ -1837,6 +1888,11 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) { vp8_zero(inter_y_modes); vp8_zero(inter_uv_modes); vp8_zero(inter_b_modes); +#endif +#if CONFIG_NEWMVENTROPY +#ifdef NMV_STATS + init_nmvstats(); +#endif #endif /*Initialize the feed-forward activity masking.*/ @@ -1903,19 +1959,32 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) { cpi->gf_rate_correction_factor = 1.0; cpi->twopass.est_max_qcorrection_factor = 1.0; +#if CONFIG_NEWMVENTROPY + cal_nmvjointsadcost(cpi->mb.nmvjointsadcost); + cpi->mb.nmvcost[0] = &cpi->mb.nmvcosts[0][MV_MAX]; + cpi->mb.nmvcost[1] = &cpi->mb.nmvcosts[1][MV_MAX]; + cpi->mb.nmvsadcost[0] = &cpi->mb.nmvsadcosts[0][MV_MAX]; + cpi->mb.nmvsadcost[1] = &cpi->mb.nmvsadcosts[1][MV_MAX]; + cal_nmvsadcosts(cpi->mb.nmvsadcost); + + cpi->mb.nmvcost_hp[0] = &cpi->mb.nmvcosts_hp[0][MV_MAX]; + cpi->mb.nmvcost_hp[1] = &cpi->mb.nmvcosts_hp[1][MV_MAX]; + cpi->mb.nmvsadcost_hp[0] = &cpi->mb.nmvsadcosts_hp[0][MV_MAX]; + cpi->mb.nmvsadcost_hp[1] = &cpi->mb.nmvsadcosts_hp[1][MV_MAX]; + cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp); +#else cpi->mb.mvcost[0] = &cpi->mb.mvcosts[0][mv_max + 1]; cpi->mb.mvcost[1] = &cpi->mb.mvcosts[1][mv_max + 1]; cpi->mb.mvsadcost[0] = &cpi->mb.mvsadcosts[0][mvfp_max + 1]; cpi->mb.mvsadcost[1] = &cpi->mb.mvsadcosts[1][mvfp_max + 1]; - cal_mvsadcosts(cpi->mb.mvsadcost); cpi->mb.mvcost_hp[0] = &cpi->mb.mvcosts_hp[0][mv_max_hp + 1]; cpi->mb.mvcost_hp[1] = &cpi->mb.mvcosts_hp[1][mv_max_hp + 1]; cpi->mb.mvsadcost_hp[0] = &cpi->mb.mvsadcosts_hp[0][mvfp_max_hp + 1]; cpi->mb.mvsadcost_hp[1] = &cpi->mb.mvsadcosts_hp[1][mvfp_max_hp + 1]; - cal_mvsadcosts_hp(cpi->mb.mvsadcost_hp); +#endif /* CONFIG_NEWMVENTROPY */ for (i = 0; i < KEY_FRAME_CONTEXT; i++) { cpi->prior_key_frame_distance[i] = (int)cpi->output_frame_rate; @@ -2068,6 +2137,12 @@ void vp8_remove_compressor(VP8_PTR *ptr) { print_mode_context(); } #endif +#if CONFIG_NEWMVENTROPY +#ifdef NMV_STATS + if (cpi->pass != 1) + print_nmvstats(); +#endif +#endif #if CONFIG_INTERNAL_STATS @@ -3697,9 +3772,14 @@ static void encode_frame_to_data_rate vp8_copy(cpi->common.fc.mbsplit_counts, cpi->mbsplit_count); vp8_adapt_mode_probs(&cpi->common); +#if CONFIG_NEWMVENTROPY + cpi->common.fc.NMVcount = cpi->NMVcount; + vp8_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv); +#else vp8_copy(cpi->common.fc.MVcount, cpi->MVcount); vp8_copy(cpi->common.fc.MVcount_hp, cpi->MVcount_hp); vp8_adapt_mv_probs(&cpi->common); +#endif /* CONFIG_NEWMVENTROPY */ vp8_update_mode_context(&cpi->common); } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 04c7ad4edba01bee7ae0285e0d7f9b2e7ea52564..0bdc07fc295b02ef29af5e36f7fdc4acd3ef8ba0 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -67,10 +67,17 @@ #endif typedef struct { +#if CONFIG_NEWMVENTROPY + nmv_context nmvc; + int nmvjointcost[MV_JOINTS]; + int nmvcosts[2][MV_VALS]; + int nmvcosts_hp[2][MV_VALS]; +#else MV_CONTEXT mvc[2]; int mvcosts[2][MVvals + 1]; MV_CONTEXT_HP mvc_hp[2]; int mvcosts_hp[2][MVvals_hp + 1]; +#endif #ifdef MODE_STATS // Stats @@ -549,8 +556,12 @@ typedef struct VP8_COMP { // int uv_mode_count[VP8_UV_MODES]; /* intra MB type cts this frame */ int y_uv_mode_count[VP8_YMODES][VP8_UV_MODES]; +#if CONFIG_NEWMVENTROPY + nmv_context_counts NMVcount; +#else unsigned int MVcount [2] [MVvals]; /* (row,col) MV cts this frame */ unsigned int MVcount_hp [2] [MVvals_hp]; /* (row,col) MV cts this frame */ +#endif unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]; /* for this frame */ // DECLARE_ALIGNED(16, int, coef_counts_backup [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]); //not used any more diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 809279e7de3d2b3adb1f9ba764811c512ae235b5..e985748dafa8c348f82ae949b0f30caeef28b22a 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -132,10 +132,17 @@ void vp8_save_coding_context(VP8_COMP *cpi) { // intended for use in a re-code loop in vp8_compress_frame where the // quantizer value is adjusted between loop iterations. +#if CONFIG_NEWMVENTROPY + cc->nmvc = cm->fc.nmvc; + vp8_copy(cc->nmvjointcost, cpi->mb.nmvjointcost); + vp8_copy(cc->nmvcosts, cpi->mb.nmvcosts); + vp8_copy(cc->nmvcosts_hp, cpi->mb.nmvcosts_hp); +#else vp8_copy(cc->mvc, cm->fc.mvc); vp8_copy(cc->mvcosts, cpi->mb.mvcosts); vp8_copy(cc->mvc_hp, cm->fc.mvc_hp); vp8_copy(cc->mvcosts_hp, cpi->mb.mvcosts_hp); +#endif vp8_copy(cc->mv_ref_ct, cm->fc.mv_ref_ct); vp8_copy(cc->mode_context, cm->fc.mode_context); @@ -188,10 +195,17 @@ void vp8_restore_coding_context(VP8_COMP *cpi) { // Restore key state variables to the snapshot state stored in the // previous call to vp8_save_coding_context. +#if CONFIG_NEWMVENTROPY + cm->fc.nmvc = cc->nmvc; + vp8_copy(cpi->mb.nmvjointcost, cc->nmvjointcost); + vp8_copy(cpi->mb.nmvcosts, cc->nmvcosts); + vp8_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp); +#else vp8_copy(cm->fc.mvc, cc->mvc); vp8_copy(cpi->mb.mvcosts, cc->mvcosts); vp8_copy(cm->fc.mvc_hp, cc->mvc_hp); vp8_copy(cpi->mb.mvcosts_hp, cc->mvcosts_hp); +#endif vp8_copy(cm->fc.mv_ref_ct, cc->mv_ref_ct); vp8_copy(cm->fc.mode_context, cc->mode_context); @@ -244,17 +258,17 @@ void vp8_setup_key_frame(VP8_COMP *cpi) { vp8_kf_default_bmode_probs(cpi->common.kf_bmode_prob); vp8_init_mbmode_probs(& cpi->common); - vpx_memcpy(cpi->common.fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); - { - int flag[2] = {1, 1}; - vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag); - } - vpx_memcpy(cpi->common.fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp)); + vp8_init_mv_probs(& cpi->common); +#if CONFIG_NEWMVENTROPY == 0 + /* this is not really required */ { int flag[2] = {1, 1}; - vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag); + vp8_build_component_cost_table( + cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag); + vp8_build_component_cost_table_hp( + cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag); } - +#endif cpi->common.txfm_mode = ALLOW_8X8; @@ -285,6 +299,7 @@ void vp8_setup_key_frame(VP8_COMP *cpi) { sizeof(default_vp8_mode_contexts)); } + void vp8_setup_inter_frame(VP8_COMP *cpi) { cpi->common.txfm_mode = ALLOW_8X8; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 391254bf26bb0dec3190daef1ca31570bfb41cc0..a2b234ebe7a9375a0ff6366bc2cc425c07f7d13b 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -37,6 +37,7 @@ #include "vpx_mem/vpx_mem.h" #include "dct.h" #include "vp8/common/systemdependent.h" +#include "vp8/encoder/encodemv.h" #include "vp8/common/seg_common.h" #include "vp8/common/pred_common.h" @@ -58,8 +59,6 @@ extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x); extern void vp8_ht_quantize_b(BLOCK *b, BLOCKD *d); #endif -#define XMVCOST (x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost) - #define MAXF(a,b) (((a) > (b)) ? (a) : (b)) #define INVALID_MV 0x80008000 @@ -376,6 +375,17 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex) { cpi->common.kf_ymode_probs_index = cpi->common.base_qindex >> 4; vp8_init_mode_costs(cpi); + if (cpi->common.frame_type != KEY_FRAME) + { +#if CONFIG_NEWMVENTROPY + vp8_build_nmv_cost_table( + cpi->mb.nmvjointcost, + cpi->mb.e_mbd.allow_high_precision_mv ? + cpi->mb.nmvcost_hp : cpi->mb.nmvcost, + &cpi->common.fc.nmvc, + cpi->mb.e_mbd.allow_high_precision_mv, 1, 1); +#endif + } } void vp8_auto_select_speed(VP8_COMP *cpi) { @@ -404,7 +414,9 @@ void vp8_auto_select_speed(VP8_COMP *cpi) { cpi->oxcf.cpu_used = -16; */ - if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress) { + if (cpi->avg_pick_mode_time < milliseconds_for_compress && + (cpi->avg_encode_time - cpi->avg_pick_mode_time) < + milliseconds_for_compress) { if (cpi->avg_pick_mode_time == 0) { cpi->Speed = 4; } else { @@ -418,7 +430,8 @@ void vp8_auto_select_speed(VP8_COMP *cpi) { } } - if (milliseconds_for_compress * 100 > cpi->avg_encode_time * auto_speed_thresh[cpi->Speed]) { + if (milliseconds_for_compress * 100 > + cpi->avg_encode_time * auto_speed_thresh[cpi->Speed]) { cpi->Speed -= 1; cpi->avg_pick_mode_time = 0; cpi->avg_encode_time = 0; @@ -1883,11 +1896,15 @@ void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) { x->e_mbd.mode_info_context->mbmi.mv[0].as_int = mv->as_int; } -static int labels2mode(MACROBLOCK *x, int const *labelings, int which_label, - B_PREDICTION_MODE this_mode, - int_mv *this_mv, int_mv *this_second_mv, - int_mv seg_mvs[MAX_REF_FRAMES - 1], int_mv *best_ref_mv, - int_mv *second_best_ref_mv, int *mvcost[2]) { +static int labels2mode( + MACROBLOCK *x, + int const *labelings, int which_label, + B_PREDICTION_MODE this_mode, + int_mv *this_mv, int_mv *this_second_mv, + int_mv seg_mvs[MAX_REF_FRAMES - 1], + int_mv *best_ref_mv, + int_mv *second_best_ref_mv, + DEC_MVCOSTS) { MACROBLOCKD *const xd = & x->e_mbd; MODE_INFO *const mic = xd->mode_info_context; MB_MODE_INFO * mbmi = &mic->mbmi; @@ -1922,11 +1939,11 @@ static int labels2mode(MACROBLOCK *x, int const *labelings, int which_label, seg_mvs[mbmi->second_ref_frame - 1].as_int; } - thismvcost = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, + thismvcost = vp8_mv_bit_cost(this_mv, best_ref_mv, MVCOSTS, 102, xd->allow_high_precision_mv); if (mbmi->second_ref_frame) { thismvcost += vp8_mv_bit_cost(this_second_mv, second_best_ref_mv, - mvcost, 102, + MVCOSTS, 102, xd->allow_high_precision_mv); } break; @@ -2656,8 +2673,10 @@ void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffse void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv, int_mv *second_best_ref_mv) { - MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; +#if CONFIG_NEWMVENTROPY + MV mv; +#endif if (mbmi->mode == SPLITMV) { int i; @@ -2665,6 +2684,21 @@ void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, for (i = 0; i < x->partition_info->count; i++) { if (x->partition_info->bmi[i].mode == NEW4X4) { if (x->e_mbd.allow_high_precision_mv) { +#if CONFIG_NEWMVENTROPY + mv.row = (x->partition_info->bmi[i].mv.as_mv.row + - best_ref_mv->as_mv.row); + mv.col = (x->partition_info->bmi[i].mv.as_mv.col + - best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 1); + if (x->e_mbd.mode_info_context->mbmi.second_ref_frame) { + mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row + - second_best_ref_mv->as_mv.row); + mv.col = (x->partition_info->bmi[i].second_mv.as_mv.col + - second_best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &second_best_ref_mv->as_mv, + &cpi->NMVcount, 1); + } +#else cpi->MVcount_hp[0][mv_max_hp + (x->partition_info->bmi[i].mv.as_mv.row - best_ref_mv->as_mv.row)]++; cpi->MVcount_hp[1][mv_max_hp + (x->partition_info->bmi[i].mv.as_mv.col @@ -2675,8 +2709,23 @@ void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, cpi->MVcount_hp[1][mv_max_hp + (x->partition_info->bmi[i].second_mv.as_mv.col - second_best_ref_mv->as_mv.col)]++; } - } else - { +#endif + } else { +#if CONFIG_NEWMVENTROPY + mv.row = (x->partition_info->bmi[i].mv.as_mv.row + - best_ref_mv->as_mv.row); + mv.col = (x->partition_info->bmi[i].mv.as_mv.col + - best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 0); + if (x->e_mbd.mode_info_context->mbmi.second_ref_frame) { + mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row + - second_best_ref_mv->as_mv.row); + mv.col = (x->partition_info->bmi[i].second_mv.as_mv.col + - second_best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &second_best_ref_mv->as_mv, + &cpi->NMVcount, 0); + } +#else cpi->MVcount[0][mv_max + ((x->partition_info->bmi[i].mv.as_mv.row - best_ref_mv->as_mv.row) >> 1)]++; cpi->MVcount[1][mv_max + ((x->partition_info->bmi[i].mv.as_mv.col @@ -2687,11 +2736,22 @@ void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, cpi->MVcount[1][mv_max + ((x->partition_info->bmi[i].second_mv.as_mv.col - second_best_ref_mv->as_mv.col) >> 1)]++; } +#endif } } } } else if (mbmi->mode == NEWMV) { if (x->e_mbd.allow_high_precision_mv) { +#if CONFIG_NEWMVENTROPY + mv.row = (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row); + mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 1); + if (mbmi->second_ref_frame) { + mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row); + mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount, 1); + } +#else cpi->MVcount_hp[0][mv_max_hp + (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row)]++; cpi->MVcount_hp[1][mv_max_hp + (mbmi->mv[0].as_mv.col @@ -2702,8 +2762,18 @@ void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, cpi->MVcount_hp[1][mv_max_hp + (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col)]++; } - } else - { +#endif + } else { +#if CONFIG_NEWMVENTROPY + mv.row = (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row); + mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 0); + if (mbmi->second_ref_frame) { + mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row); + mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col); + vp8_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount, 0); + } +#else cpi->MVcount[0][mv_max + ((mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row) >> 1)]++; cpi->MVcount[1][mv_max + ((mbmi->mv[0].as_mv.col @@ -2714,6 +2784,7 @@ void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, cpi->MVcount[1][mv_max + ((mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col) >> 1)]++; } +#endif } } } diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c index 035eebb986f68bc104dbd809d002c702351d9558..d57613bd5568ebe9daf7fcc008393f6da023bc22 100644 --- a/vp8/encoder/temporal_filter.c +++ b/vp8/encoder/temporal_filter.c @@ -187,7 +187,8 @@ static int vp8_temporal_filter_find_matching_mb_c // Ignore mv costing by sending NULL pointer instead of cost arrays bestsme = vp8_hex_search(x, b, d, &best_ref_mv1_full, &d->bmi.as_mv.first, step_param, sadpb, &cpi->fn_ptr[BLOCK_16X16], - NULL, NULL, &best_ref_mv1); + NULLMVCOST, NULLMVCOST, + &best_ref_mv1); #if ALT_REF_SUBPEL_ENABLED // Try sub-pixel MC? @@ -200,7 +201,8 @@ static int vp8_temporal_filter_find_matching_mb_c &best_ref_mv1, x->errorperbit, &cpi->fn_ptr[BLOCK_16X16], - NULL, &distortion, &sse); + NULLMVCOST, + &distortion, &sse); } #endif