1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_onyxc_int.h"
12*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_entropymv.h"
13*fb1b10abSAndroid Build Coastguard Worker
14*fb1b10abSAndroid Build Coastguard Worker const vpx_tree_index vp9_mv_joint_tree[TREE_SIZE(MV_JOINTS)] = {
15*fb1b10abSAndroid Build Coastguard Worker -MV_JOINT_ZERO, 2, -MV_JOINT_HNZVZ, 4, -MV_JOINT_HZVNZ, -MV_JOINT_HNZVNZ
16*fb1b10abSAndroid Build Coastguard Worker };
17*fb1b10abSAndroid Build Coastguard Worker
18*fb1b10abSAndroid Build Coastguard Worker const vpx_tree_index vp9_mv_class_tree[TREE_SIZE(MV_CLASSES)] = {
19*fb1b10abSAndroid Build Coastguard Worker -MV_CLASS_0, 2, -MV_CLASS_1, 4, 6,
20*fb1b10abSAndroid Build Coastguard Worker 8, -MV_CLASS_2, -MV_CLASS_3, 10, 12,
21*fb1b10abSAndroid Build Coastguard Worker -MV_CLASS_4, -MV_CLASS_5, -MV_CLASS_6, 14, 16,
22*fb1b10abSAndroid Build Coastguard Worker 18, -MV_CLASS_7, -MV_CLASS_8, -MV_CLASS_9, -MV_CLASS_10,
23*fb1b10abSAndroid Build Coastguard Worker };
24*fb1b10abSAndroid Build Coastguard Worker
25*fb1b10abSAndroid Build Coastguard Worker const vpx_tree_index vp9_mv_class0_tree[TREE_SIZE(CLASS0_SIZE)] = { -0, -1 };
26*fb1b10abSAndroid Build Coastguard Worker
27*fb1b10abSAndroid Build Coastguard Worker const vpx_tree_index vp9_mv_fp_tree[TREE_SIZE(MV_FP_SIZE)] = { -0, 2, -1,
28*fb1b10abSAndroid Build Coastguard Worker 4, -2, -3 };
29*fb1b10abSAndroid Build Coastguard Worker
30*fb1b10abSAndroid Build Coastguard Worker static const nmv_context default_nmv_context = {
31*fb1b10abSAndroid Build Coastguard Worker { 32, 64, 96 },
32*fb1b10abSAndroid Build Coastguard Worker { {
33*fb1b10abSAndroid Build Coastguard Worker // Vertical component
34*fb1b10abSAndroid Build Coastguard Worker 128, // sign
35*fb1b10abSAndroid Build Coastguard Worker { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, // class
36*fb1b10abSAndroid Build Coastguard Worker { 216 }, // class0
37*fb1b10abSAndroid Build Coastguard Worker { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, // bits
38*fb1b10abSAndroid Build Coastguard Worker { { 128, 128, 64 }, { 96, 112, 64 } }, // class0_fp
39*fb1b10abSAndroid Build Coastguard Worker { 64, 96, 64 }, // fp
40*fb1b10abSAndroid Build Coastguard Worker 160, // class0_hp bit
41*fb1b10abSAndroid Build Coastguard Worker 128, // hp
42*fb1b10abSAndroid Build Coastguard Worker },
43*fb1b10abSAndroid Build Coastguard Worker {
44*fb1b10abSAndroid Build Coastguard Worker // Horizontal component
45*fb1b10abSAndroid Build Coastguard Worker 128, // sign
46*fb1b10abSAndroid Build Coastguard Worker { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, // class
47*fb1b10abSAndroid Build Coastguard Worker { 208 }, // class0
48*fb1b10abSAndroid Build Coastguard Worker { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, // bits
49*fb1b10abSAndroid Build Coastguard Worker { { 128, 128, 64 }, { 96, 112, 64 } }, // class0_fp
50*fb1b10abSAndroid Build Coastguard Worker { 64, 96, 64 }, // fp
51*fb1b10abSAndroid Build Coastguard Worker 160, // class0_hp bit
52*fb1b10abSAndroid Build Coastguard Worker 128, // hp
53*fb1b10abSAndroid Build Coastguard Worker } },
54*fb1b10abSAndroid Build Coastguard Worker };
55*fb1b10abSAndroid Build Coastguard Worker
56*fb1b10abSAndroid Build Coastguard Worker static const uint8_t log_in_base_2[] = {
57*fb1b10abSAndroid Build Coastguard Worker 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
58*fb1b10abSAndroid Build Coastguard Worker 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
59*fb1b10abSAndroid Build Coastguard Worker 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
60*fb1b10abSAndroid Build Coastguard Worker 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
61*fb1b10abSAndroid Build Coastguard Worker 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
62*fb1b10abSAndroid Build Coastguard Worker 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
63*fb1b10abSAndroid Build Coastguard Worker 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
64*fb1b10abSAndroid Build Coastguard Worker 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
65*fb1b10abSAndroid Build Coastguard Worker 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
66*fb1b10abSAndroid Build Coastguard Worker 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
67*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
68*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
69*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
70*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
71*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
72*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
73*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
74*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
75*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
76*fb1b10abSAndroid Build Coastguard Worker 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
77*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
78*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
79*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
80*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
81*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
82*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
83*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
84*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
85*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
86*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
87*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
88*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
89*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
90*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
91*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
92*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
93*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
94*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
95*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
96*fb1b10abSAndroid Build Coastguard Worker 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10
97*fb1b10abSAndroid Build Coastguard Worker };
98*fb1b10abSAndroid Build Coastguard Worker
mv_class_base(MV_CLASS_TYPE c)99*fb1b10abSAndroid Build Coastguard Worker static INLINE int mv_class_base(MV_CLASS_TYPE c) {
100*fb1b10abSAndroid Build Coastguard Worker return c ? CLASS0_SIZE << (c + 2) : 0;
101*fb1b10abSAndroid Build Coastguard Worker }
102*fb1b10abSAndroid Build Coastguard Worker
vp9_get_mv_class(int z,int * offset)103*fb1b10abSAndroid Build Coastguard Worker MV_CLASS_TYPE vp9_get_mv_class(int z, int *offset) {
104*fb1b10abSAndroid Build Coastguard Worker const MV_CLASS_TYPE c = (z >= CLASS0_SIZE * 4096)
105*fb1b10abSAndroid Build Coastguard Worker ? MV_CLASS_10
106*fb1b10abSAndroid Build Coastguard Worker : (MV_CLASS_TYPE)log_in_base_2[z >> 3];
107*fb1b10abSAndroid Build Coastguard Worker if (offset) *offset = z - mv_class_base(c);
108*fb1b10abSAndroid Build Coastguard Worker return c;
109*fb1b10abSAndroid Build Coastguard Worker }
110*fb1b10abSAndroid Build Coastguard Worker
inc_mv_component(int v,nmv_component_counts * comp_counts,int incr,int usehp)111*fb1b10abSAndroid Build Coastguard Worker static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
112*fb1b10abSAndroid Build Coastguard Worker int usehp) {
113*fb1b10abSAndroid Build Coastguard Worker int s, z, c, o, d, e, f;
114*fb1b10abSAndroid Build Coastguard Worker assert(v != 0); /* should not be zero */
115*fb1b10abSAndroid Build Coastguard Worker s = v < 0;
116*fb1b10abSAndroid Build Coastguard Worker comp_counts->sign[s] += incr;
117*fb1b10abSAndroid Build Coastguard Worker z = (s ? -v : v) - 1; /* magnitude - 1 */
118*fb1b10abSAndroid Build Coastguard Worker
119*fb1b10abSAndroid Build Coastguard Worker c = vp9_get_mv_class(z, &o);
120*fb1b10abSAndroid Build Coastguard Worker comp_counts->classes[c] += incr;
121*fb1b10abSAndroid Build Coastguard Worker
122*fb1b10abSAndroid Build Coastguard Worker d = (o >> 3); /* int mv data */
123*fb1b10abSAndroid Build Coastguard Worker f = (o >> 1) & 3; /* fractional pel mv data */
124*fb1b10abSAndroid Build Coastguard Worker e = (o & 1); /* high precision mv data */
125*fb1b10abSAndroid Build Coastguard Worker
126*fb1b10abSAndroid Build Coastguard Worker if (c == MV_CLASS_0) {
127*fb1b10abSAndroid Build Coastguard Worker comp_counts->class0[d] += incr;
128*fb1b10abSAndroid Build Coastguard Worker comp_counts->class0_fp[d][f] += incr;
129*fb1b10abSAndroid Build Coastguard Worker comp_counts->class0_hp[e] += usehp * incr;
130*fb1b10abSAndroid Build Coastguard Worker } else {
131*fb1b10abSAndroid Build Coastguard Worker int i;
132*fb1b10abSAndroid Build Coastguard Worker int b = c + CLASS0_BITS - 1; // number of bits
133*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < b; ++i) comp_counts->bits[i][((d >> i) & 1)] += incr;
134*fb1b10abSAndroid Build Coastguard Worker comp_counts->fp[f] += incr;
135*fb1b10abSAndroid Build Coastguard Worker comp_counts->hp[e] += usehp * incr;
136*fb1b10abSAndroid Build Coastguard Worker }
137*fb1b10abSAndroid Build Coastguard Worker }
138*fb1b10abSAndroid Build Coastguard Worker
vp9_inc_mv(const MV * mv,nmv_context_counts * counts)139*fb1b10abSAndroid Build Coastguard Worker void vp9_inc_mv(const MV *mv, nmv_context_counts *counts) {
140*fb1b10abSAndroid Build Coastguard Worker if (counts != NULL) {
141*fb1b10abSAndroid Build Coastguard Worker const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
142*fb1b10abSAndroid Build Coastguard Worker ++counts->joints[j];
143*fb1b10abSAndroid Build Coastguard Worker
144*fb1b10abSAndroid Build Coastguard Worker if (mv_joint_vertical(j)) {
145*fb1b10abSAndroid Build Coastguard Worker inc_mv_component(mv->row, &counts->comps[0], 1, 1);
146*fb1b10abSAndroid Build Coastguard Worker }
147*fb1b10abSAndroid Build Coastguard Worker
148*fb1b10abSAndroid Build Coastguard Worker if (mv_joint_horizontal(j)) {
149*fb1b10abSAndroid Build Coastguard Worker inc_mv_component(mv->col, &counts->comps[1], 1, 1);
150*fb1b10abSAndroid Build Coastguard Worker }
151*fb1b10abSAndroid Build Coastguard Worker }
152*fb1b10abSAndroid Build Coastguard Worker }
153*fb1b10abSAndroid Build Coastguard Worker
vp9_adapt_mv_probs(VP9_COMMON * cm,int allow_hp)154*fb1b10abSAndroid Build Coastguard Worker void vp9_adapt_mv_probs(VP9_COMMON *cm, int allow_hp) {
155*fb1b10abSAndroid Build Coastguard Worker int i, j;
156*fb1b10abSAndroid Build Coastguard Worker
157*fb1b10abSAndroid Build Coastguard Worker nmv_context *fc = &cm->fc->nmvc;
158*fb1b10abSAndroid Build Coastguard Worker const nmv_context *pre_fc = &cm->frame_contexts[cm->frame_context_idx].nmvc;
159*fb1b10abSAndroid Build Coastguard Worker const nmv_context_counts *counts = &cm->counts.mv;
160*fb1b10abSAndroid Build Coastguard Worker
161*fb1b10abSAndroid Build Coastguard Worker vpx_tree_merge_probs(vp9_mv_joint_tree, pre_fc->joints, counts->joints,
162*fb1b10abSAndroid Build Coastguard Worker fc->joints);
163*fb1b10abSAndroid Build Coastguard Worker
164*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < 2; ++i) {
165*fb1b10abSAndroid Build Coastguard Worker nmv_component *comp = &fc->comps[i];
166*fb1b10abSAndroid Build Coastguard Worker const nmv_component *pre_comp = &pre_fc->comps[i];
167*fb1b10abSAndroid Build Coastguard Worker const nmv_component_counts *c = &counts->comps[i];
168*fb1b10abSAndroid Build Coastguard Worker
169*fb1b10abSAndroid Build Coastguard Worker comp->sign = mode_mv_merge_probs(pre_comp->sign, c->sign);
170*fb1b10abSAndroid Build Coastguard Worker vpx_tree_merge_probs(vp9_mv_class_tree, pre_comp->classes, c->classes,
171*fb1b10abSAndroid Build Coastguard Worker comp->classes);
172*fb1b10abSAndroid Build Coastguard Worker vpx_tree_merge_probs(vp9_mv_class0_tree, pre_comp->class0, c->class0,
173*fb1b10abSAndroid Build Coastguard Worker comp->class0);
174*fb1b10abSAndroid Build Coastguard Worker
175*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < MV_OFFSET_BITS; ++j)
176*fb1b10abSAndroid Build Coastguard Worker comp->bits[j] = mode_mv_merge_probs(pre_comp->bits[j], c->bits[j]);
177*fb1b10abSAndroid Build Coastguard Worker
178*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < CLASS0_SIZE; ++j)
179*fb1b10abSAndroid Build Coastguard Worker vpx_tree_merge_probs(vp9_mv_fp_tree, pre_comp->class0_fp[j],
180*fb1b10abSAndroid Build Coastguard Worker c->class0_fp[j], comp->class0_fp[j]);
181*fb1b10abSAndroid Build Coastguard Worker
182*fb1b10abSAndroid Build Coastguard Worker vpx_tree_merge_probs(vp9_mv_fp_tree, pre_comp->fp, c->fp, comp->fp);
183*fb1b10abSAndroid Build Coastguard Worker
184*fb1b10abSAndroid Build Coastguard Worker if (allow_hp) {
185*fb1b10abSAndroid Build Coastguard Worker comp->class0_hp = mode_mv_merge_probs(pre_comp->class0_hp, c->class0_hp);
186*fb1b10abSAndroid Build Coastguard Worker comp->hp = mode_mv_merge_probs(pre_comp->hp, c->hp);
187*fb1b10abSAndroid Build Coastguard Worker }
188*fb1b10abSAndroid Build Coastguard Worker }
189*fb1b10abSAndroid Build Coastguard Worker }
190*fb1b10abSAndroid Build Coastguard Worker
vp9_init_mv_probs(VP9_COMMON * cm)191*fb1b10abSAndroid Build Coastguard Worker void vp9_init_mv_probs(VP9_COMMON *cm) { cm->fc->nmvc = default_nmv_context; }
192