1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/common.h"
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "encodemv.h"
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/entropymode.h"
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/systemdependent.h"
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h>
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef VP8_ENTROPY_STATS
20233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern unsigned int active_section;
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan
23233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_mvcomponent(
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_writer *const w,
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int v,
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const struct mv_context *mvc
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan)
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob *p = mvc->prob;
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int x = v < 0 ? -v : v;
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x < mvnum_short)     /* Small */
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_write(w, 0, p [mvpis_short]);
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!x)
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return;         /* no sign bit */
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else                    /* Large */
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int i = 0;
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_write(w, 1, p [mvpis_short]);
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++i < 3);
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (--i > 3);
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (x & 0xFFF0)
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_write(w, (x >> 3) & 1, p [MVPbits + 3]);
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_write(w, v < 0, p [MVPsign]);
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 0
65233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int max_mv_r = 0;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int max_mv_c = 0;
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
68233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc)
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 0
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (abs(mv->row >> 1) > max_mv_r)
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan            FILE *f = fopen("maxmv.stt", "a");
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan            max_mv_r = abs(mv->row >> 1);
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan            fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if ((abs(mv->row) / 2) != max_mv_r)
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan                fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan            fclose(f);
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (abs(mv->col >> 1) > max_mv_c)
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan            FILE *f = fopen("maxmv.stt", "a");
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan            fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan            max_mv_c = abs(mv->col >> 1);
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan            fclose(f);
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan
100233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc)
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob *p = mvc->prob;
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int x = v;
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int cost;
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x < mvnum_short)
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost = vp8_cost_zero(p [mvpis_short])
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!x)
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return cost;
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int i = 0;
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost = vp8_cost_one(p [mvpis_short]);
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++i < 3);
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan
124233d2500723e5594f3e7c70896ffeeef32b9c950ywan        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (--i > 3);
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (x & 0xFFF0)
132233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cost += vp8_cost_bit(p [MVPbits + 3], (x >> 3) & 1);
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return cost;   /* + vp8_cost_bit( p [MVPsign], v < 0); */
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
137233d2500723e5594f3e7c70896ffeeef32b9c950ywan
138233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2])
139233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
140233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i = 1;
141233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int cost0 = 0;
142233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int cost1 = 0;
143233d2500723e5594f3e7c70896ffeeef32b9c950ywan
144233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_clear_system_state();
145233d2500723e5594f3e7c70896ffeeef32b9c950ywan
146233d2500723e5594f3e7c70896ffeeef32b9c950ywan    i = 1;
147233d2500723e5594f3e7c70896ffeeef32b9c950ywan
148233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mvc_flag[0])
149233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
150233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mvcost [0] [0] = cost_mvcomponent(0, &mvc[0]);
151233d2500723e5594f3e7c70896ffeeef32b9c950ywan
152233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
153233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
154233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cost0 = cost_mvcomponent(i, &mvc[0]);
155233d2500723e5594f3e7c70896ffeeef32b9c950ywan
156233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvcost [0] [i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
157233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvcost [0] [-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
158233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
159233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++i <= mv_max);
160233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
161233d2500723e5594f3e7c70896ffeeef32b9c950ywan
162233d2500723e5594f3e7c70896ffeeef32b9c950ywan    i = 1;
163233d2500723e5594f3e7c70896ffeeef32b9c950ywan
164233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mvc_flag[1])
165233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
166233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mvcost [1] [0] = cost_mvcomponent(0, &mvc[1]);
167233d2500723e5594f3e7c70896ffeeef32b9c950ywan
168233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
169233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
170233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cost1 = cost_mvcomponent(i, &mvc[1]);
171233d2500723e5594f3e7c70896ffeeef32b9c950ywan
172233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvcost [1] [i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
173233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvcost [1] [-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
174233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
175233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++i <= mv_max);
176233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
177233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
178233d2500723e5594f3e7c70896ffeeef32b9c950ywan
179233d2500723e5594f3e7c70896ffeeef32b9c950ywan
180233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Motion vector probability table update depends on benefit.
181233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Small correction allows for the fact that an update to an MV probability
182233d2500723e5594f3e7c70896ffeeef32b9c950ywan * may have benefit in subsequent frames as well as the current one.
183233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
184233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MV_PROB_UPDATE_CORRECTION   -1
185233d2500723e5594f3e7c70896ffeeef32b9c950ywan
186233d2500723e5594f3e7c70896ffeeef32b9c950ywan
187233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void calc_prob(vp8_prob *p, const unsigned int ct[2])
188233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
189233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const unsigned int tot = ct[0] + ct[1];
190233d2500723e5594f3e7c70896ffeeef32b9c950ywan
191233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (tot)
192233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
193233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const vp8_prob x = ((ct[0] * 255) / tot) & -2;
194233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *p = x ? x : 1;
195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
196233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
197233d2500723e5594f3e7c70896ffeeef32b9c950ywan
198233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void update(
199233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_writer *const w,
200233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const unsigned int ct[2],
201233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_prob *const cur_p,
202233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob new_p,
203233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob update_p,
204233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int *updated
205233d2500723e5594f3e7c70896ffeeef32b9c950ywan)
206233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
207233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int cur_b = vp8_cost_branch(ct, *cur_p);
208233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int new_b = vp8_cost_branch(ct, new_p);
209233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int cost = 7 + MV_PROB_UPDATE_CORRECTION + ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
210233d2500723e5594f3e7c70896ffeeef32b9c950ywan
211233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cur_b - new_b > cost)
212233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
213233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *cur_p = new_p;
214233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_write(w, 1, update_p);
215233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_write_literal(w, new_p >> 1, 7);
216233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *updated = 1;
217233d2500723e5594f3e7c70896ffeeef32b9c950ywan
218233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
219233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
220233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_write(w, 0, update_p);
221233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
222233d2500723e5594f3e7c70896ffeeef32b9c950ywan
223233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void write_component_probs(
224233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_writer *const w,
225233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct mv_context *cur_mvc,
226233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const struct mv_context *default_mvc_,
227233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const struct mv_context *update_mvc,
228233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const unsigned int events [MVvals],
229233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int rc,
230233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int *updated
231233d2500723e5594f3e7c70896ffeeef32b9c950ywan)
232233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
233233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_prob *Pcur = cur_mvc->prob;
234233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob *default_mvc = default_mvc_->prob;
235233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const vp8_prob *Pupdate = update_mvc->prob;
236233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int is_short_ct[2], sign_ct[2];
237233d2500723e5594f3e7c70896ffeeef32b9c950ywan
238233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int bit_ct [mvlong_width] [2];
239233d2500723e5594f3e7c70896ffeeef32b9c950ywan
240233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int short_ct  [mvnum_short];
241233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int short_bct [mvnum_short-1] [2];
242233d2500723e5594f3e7c70896ffeeef32b9c950ywan
243233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_prob Pnew [MVPcount];
244233d2500723e5594f3e7c70896ffeeef32b9c950ywan
245233d2500723e5594f3e7c70896ffeeef32b9c950ywan    (void) rc;
246233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_copy_array(Pnew, default_mvc, MVPcount);
247233d2500723e5594f3e7c70896ffeeef32b9c950ywan
248233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_zero(is_short_ct)
249233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_zero(sign_ct)
250233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_zero(bit_ct)
251233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_zero(short_ct)
252233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_zero(short_bct)
253233d2500723e5594f3e7c70896ffeeef32b9c950ywan
254233d2500723e5594f3e7c70896ffeeef32b9c950ywan
255233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* j=0 */
256233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
257233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const int c = events [mv_max];
258233d2500723e5594f3e7c70896ffeeef32b9c950ywan
259233d2500723e5594f3e7c70896ffeeef32b9c950ywan        is_short_ct [0] += c;     /* Short vector */
260233d2500723e5594f3e7c70896ffeeef32b9c950ywan        short_ct [0] += c;       /* Magnitude distribution */
261233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
262233d2500723e5594f3e7c70896ffeeef32b9c950ywan
263233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* j: 1 ~ mv_max (1023) */
264233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
265233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j = 1;
266233d2500723e5594f3e7c70896ffeeef32b9c950ywan
267233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
268233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
269233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int c1 = events [mv_max + j];  /* positive */
270233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int c2 = events [mv_max - j];  /* negative */
271233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int c  = c1 + c2;
272233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int a = j;
273233d2500723e5594f3e7c70896ffeeef32b9c950ywan
274233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sign_ct [0] += c1;
275233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sign_ct [1] += c2;
276233d2500723e5594f3e7c70896ffeeef32b9c950ywan
277233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (a < mvnum_short)
278233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
279233d2500723e5594f3e7c70896ffeeef32b9c950ywan                is_short_ct [0] += c;     /* Short vector */
280233d2500723e5594f3e7c70896ffeeef32b9c950ywan                short_ct [a] += c;       /* Magnitude distribution */
281233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
282233d2500723e5594f3e7c70896ffeeef32b9c950ywan            else
283233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
284233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int k = mvlong_width - 1;
285233d2500723e5594f3e7c70896ffeeef32b9c950ywan                is_short_ct [1] += c;     /* Long vector */
286233d2500723e5594f3e7c70896ffeeef32b9c950ywan
287233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /*  bit 3 not always encoded. */
288233d2500723e5594f3e7c70896ffeeef32b9c950ywan                do
289233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    bit_ct [k] [(a >> k) & 1] += c;
290233d2500723e5594f3e7c70896ffeeef32b9c950ywan
291233d2500723e5594f3e7c70896ffeeef32b9c950ywan                while (--k >= 0);
292233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
293233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
294233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++j <= mv_max);
295233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
296233d2500723e5594f3e7c70896ffeeef32b9c950ywan
297233d2500723e5594f3e7c70896ffeeef32b9c950ywan    calc_prob(Pnew + mvpis_short, is_short_ct);
298233d2500723e5594f3e7c70896ffeeef32b9c950ywan
299233d2500723e5594f3e7c70896ffeeef32b9c950ywan    calc_prob(Pnew + MVPsign, sign_ct);
300233d2500723e5594f3e7c70896ffeeef32b9c950ywan
301233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
302233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_prob p [mvnum_short - 1];    /* actually only need branch ct */
303233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j = 0;
304233d2500723e5594f3e7c70896ffeeef32b9c950ywan
305233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_tree_probs_from_distribution(
306233d2500723e5594f3e7c70896ffeeef32b9c950ywan            8, vp8_small_mvencodings, vp8_small_mvtree,
307233d2500723e5594f3e7c70896ffeeef32b9c950ywan            p, short_bct, short_ct,
308233d2500723e5594f3e7c70896ffeeef32b9c950ywan            256, 1
309233d2500723e5594f3e7c70896ffeeef32b9c950ywan        );
310233d2500723e5594f3e7c70896ffeeef32b9c950ywan
311233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
312233d2500723e5594f3e7c70896ffeeef32b9c950ywan            calc_prob(Pnew + MVPshort + j, short_bct[j]);
313233d2500723e5594f3e7c70896ffeeef32b9c950ywan
314233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++j < mvnum_short - 1);
315233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
316233d2500723e5594f3e7c70896ffeeef32b9c950ywan
317233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
318233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j = 0;
319233d2500723e5594f3e7c70896ffeeef32b9c950ywan
320233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
321233d2500723e5594f3e7c70896ffeeef32b9c950ywan            calc_prob(Pnew + MVPbits + j, bit_ct[j]);
322233d2500723e5594f3e7c70896ffeeef32b9c950ywan
323233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++j < mvlong_width);
324233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
325233d2500723e5594f3e7c70896ffeeef32b9c950ywan
326233d2500723e5594f3e7c70896ffeeef32b9c950ywan    update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, updated);
327233d2500723e5594f3e7c70896ffeeef32b9c950ywan
328233d2500723e5594f3e7c70896ffeeef32b9c950ywan    update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
329233d2500723e5594f3e7c70896ffeeef32b9c950ywan
330233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
331233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const vp8_prob *const new_p = Pnew + MVPshort;
332233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_prob *const cur_p = Pcur + MVPshort;
333233d2500723e5594f3e7c70896ffeeef32b9c950ywan
334233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j = 0;
335233d2500723e5594f3e7c70896ffeeef32b9c950ywan
336233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
337233d2500723e5594f3e7c70896ffeeef32b9c950ywan
338233d2500723e5594f3e7c70896ffeeef32b9c950ywan            update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
339233d2500723e5594f3e7c70896ffeeef32b9c950ywan
340233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++j < mvnum_short - 1);
341233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
342233d2500723e5594f3e7c70896ffeeef32b9c950ywan
343233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
344233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const vp8_prob *const new_p = Pnew + MVPbits;
345233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_prob *const cur_p = Pcur + MVPbits;
346233d2500723e5594f3e7c70896ffeeef32b9c950ywan
347233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j = 0;
348233d2500723e5594f3e7c70896ffeeef32b9c950ywan
349233d2500723e5594f3e7c70896ffeeef32b9c950ywan        do
350233d2500723e5594f3e7c70896ffeeef32b9c950ywan
351233d2500723e5594f3e7c70896ffeeef32b9c950ywan            update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
352233d2500723e5594f3e7c70896ffeeef32b9c950ywan
353233d2500723e5594f3e7c70896ffeeef32b9c950ywan        while (++j < mvlong_width);
354233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
355233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
356233d2500723e5594f3e7c70896ffeeef32b9c950ywan
357233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8_write_mvprobs(VP8_COMP *cpi)
358233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
359233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp8_writer *const w  = cpi->bc;
360233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MV_CONTEXT *mvc = cpi->common.fc.mvc;
361233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int flags[2] = {0, 0};
362233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef VP8_ENTROPY_STATS
363233d2500723e5594f3e7c70896ffeeef32b9c950ywan    active_section = 4;
364233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
365233d2500723e5594f3e7c70896ffeeef32b9c950ywan    write_component_probs(
366233d2500723e5594f3e7c70896ffeeef32b9c950ywan        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0],
367233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->mb.MVcount[0], 0, &flags[0]
368233d2500723e5594f3e7c70896ffeeef32b9c950ywan    );
369233d2500723e5594f3e7c70896ffeeef32b9c950ywan    write_component_probs(
370233d2500723e5594f3e7c70896ffeeef32b9c950ywan        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1],
371233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->mb.MVcount[1], 1, &flags[1]
372233d2500723e5594f3e7c70896ffeeef32b9c950ywan    );
373233d2500723e5594f3e7c70896ffeeef32b9c950ywan
374233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (flags[0] || flags[1])
375233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
376233d2500723e5594f3e7c70896ffeeef32b9c950ywan
377233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef VP8_ENTROPY_STATS
378233d2500723e5594f3e7c70896ffeeef32b9c950ywan    active_section = 5;
379233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
380233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
381