PageRenderTime 31ms CodeModel.GetById 10ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/media/libvpx/vp8/encoder/encodemv.c

http://github.com/zpao/v8monkey
C | 417 lines | 274 code | 90 blank | 53 comment | 30 complexity | c01c71c128a618707c33a5d2568ce2df MD5 | raw file
  1/*
  2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
  3 *
  4 *  Use of this source code is governed by a BSD-style license
  5 *  that can be found in the LICENSE file in the root of the source
  6 *  tree. An additional intellectual property rights grant can be found
  7 *  in the file PATENTS.  All contributing project authors may
  8 *  be found in the AUTHORS file in the root of the source tree.
  9 */
 10
 11
 12#include "vp8/common/common.h"
 13#include "encodemv.h"
 14#include "vp8/common/entropymode.h"
 15#include "vp8/common/systemdependent.h"
 16
 17#include <math.h>
 18
 19#ifdef ENTROPY_STATS
 20extern unsigned int active_section;
 21#endif
 22
 23static void encode_mvcomponent(
 24    vp8_writer *const w,
 25    const int v,
 26    const struct mv_context *mvc
 27)
 28{
 29    const vp8_prob *p = mvc->prob;
 30    const int x = v < 0 ? -v : v;
 31
 32    if (x < mvnum_short)     // Small
 33    {
 34        vp8_write(w, 0, p [mvpis_short]);
 35        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
 36
 37        if (!x)
 38            return;         // no sign bit
 39    }
 40    else                    // Large
 41    {
 42        int i = 0;
 43
 44        vp8_write(w, 1, p [mvpis_short]);
 45
 46        do
 47            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
 48
 49        while (++i < 3);
 50
 51        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
 52
 53        do
 54            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
 55
 56        while (--i > 3);
 57
 58        if (x & 0xFFF0)
 59            vp8_write(w, (x >> 3) & 1, p [MVPbits + 3]);
 60    }
 61
 62    vp8_write(w, v < 0, p [MVPsign]);
 63}
 64#if 0
 65static int max_mv_r = 0;
 66static int max_mv_c = 0;
 67#endif
 68void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc)
 69{
 70
 71#if 0
 72    {
 73        if (abs(mv->row >> 1) > max_mv_r)
 74        {
 75            FILE *f = fopen("maxmv.stt", "a");
 76            max_mv_r = abs(mv->row >> 1);
 77            fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
 78
 79            if ((abs(mv->row) / 2) != max_mv_r)
 80                fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
 81
 82            fclose(f);
 83        }
 84
 85        if (abs(mv->col >> 1) > max_mv_c)
 86        {
 87            FILE *f = fopen("maxmv.stt", "a");
 88            fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
 89            max_mv_c = abs(mv->col >> 1);
 90            fclose(f);
 91        }
 92    }
 93#endif
 94
 95    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
 96    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
 97}
 98
 99
100static unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc)
101{
102    const vp8_prob *p = mvc->prob;
103    const int x = v;   //v<0? -v:v;
104    unsigned int cost;
105
106    if (x < mvnum_short)
107    {
108        cost = vp8_cost_zero(p [mvpis_short])
109               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
110
111        if (!x)
112            return cost;
113    }
114    else
115    {
116        int i = 0;
117        cost = vp8_cost_one(p [mvpis_short]);
118
119        do
120            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
121
122        while (++i < 3);
123
124        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
125
126        do
127            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
128
129        while (--i > 3);
130
131        if (x & 0xFFF0)
132            cost += vp8_cost_bit(p [MVPbits + 3], (x >> 3) & 1);
133    }
134
135    return cost;   // + vp8_cost_bit( p [MVPsign], v < 0);
136}
137
138void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2])
139{
140    int i = 1;   //-mv_max;
141    unsigned int cost0 = 0;
142    unsigned int cost1 = 0;
143
144    vp8_clear_system_state();
145
146    i = 1;
147
148    if (mvc_flag[0])
149    {
150        mvcost [0] [0] = cost_mvcomponent(0, &mvc[0]);
151
152        do
153        {
154            //mvcost [0] [i] = cost_mvcomponent( i, &mvc[0]);
155            cost0 = cost_mvcomponent(i, &mvc[0]);
156
157            mvcost [0] [i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
158            mvcost [0] [-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
159        }
160        while (++i <= mv_max);
161    }
162
163    i = 1;
164
165    if (mvc_flag[1])
166    {
167        mvcost [1] [0] = cost_mvcomponent(0, &mvc[1]);
168
169        do
170        {
171            //mvcost [1] [i] = cost_mvcomponent( i, mvc[1]);
172            cost1 = cost_mvcomponent(i, &mvc[1]);
173
174            mvcost [1] [i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
175            mvcost [1] [-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
176        }
177        while (++i <= mv_max);
178    }
179}
180
181
182// Motion vector probability table update depends on benefit.
183// Small correction allows for the fact that an update to an MV probability
184// may have benefit in subsequent frames as well as the current one.
185
186#define MV_PROB_UPDATE_CORRECTION   -1
187
188
189__inline static void calc_prob(vp8_prob *p, const unsigned int ct[2])
190{
191    const unsigned int tot = ct[0] + ct[1];
192
193    if (tot)
194    {
195        const vp8_prob x = ((ct[0] * 255) / tot) & -2;
196        *p = x ? x : 1;
197    }
198}
199
200static void update(
201    vp8_writer *const w,
202    const unsigned int ct[2],
203    vp8_prob *const cur_p,
204    const vp8_prob new_p,
205    const vp8_prob update_p,
206    int *updated
207)
208{
209    const int cur_b = vp8_cost_branch(ct, *cur_p);
210    const int new_b = vp8_cost_branch(ct, new_p);
211    const int cost = 7 + MV_PROB_UPDATE_CORRECTION + ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
212
213    if (cur_b - new_b > cost)
214    {
215        *cur_p = new_p;
216        vp8_write(w, 1, update_p);
217        vp8_write_literal(w, new_p >> 1, 7);
218        *updated = 1;
219
220    }
221    else
222        vp8_write(w, 0, update_p);
223}
224
225static void write_component_probs(
226    vp8_writer *const w,
227    struct mv_context *cur_mvc,
228    const struct mv_context *default_mvc_,
229    const struct mv_context *update_mvc,
230    const unsigned int events [MVvals],
231    unsigned int rc,
232    int *updated
233)
234{
235    vp8_prob *Pcur = cur_mvc->prob;
236    const vp8_prob *default_mvc = default_mvc_->prob;
237    const vp8_prob *Pupdate = update_mvc->prob;
238    unsigned int is_short_ct[2], sign_ct[2];
239
240    unsigned int bit_ct [mvlong_width] [2];
241
242    unsigned int short_ct  [mvnum_short];
243    unsigned int short_bct [mvnum_short-1] [2];
244
245    vp8_prob Pnew [MVPcount];
246
247    (void) rc;
248    vp8_copy_array(Pnew, default_mvc, MVPcount);
249
250    vp8_zero(is_short_ct)
251    vp8_zero(sign_ct)
252    vp8_zero(bit_ct)
253    vp8_zero(short_ct)
254    vp8_zero(short_bct)
255
256
257    //j=0
258    {
259        const int c = events [mv_max];
260
261        is_short_ct [0] += c;     // Short vector
262        short_ct [0] += c;       // Magnitude distribution
263    }
264
265    //j: 1 ~ mv_max (1023)
266    {
267        int j = 1;
268
269        do
270        {
271            const int c1 = events [mv_max + j];  //positive
272            const int c2 = events [mv_max - j];  //negative
273            const int c  = c1 + c2;
274            int a = j;
275
276            sign_ct [0] += c1;
277            sign_ct [1] += c2;
278
279            if (a < mvnum_short)
280            {
281                is_short_ct [0] += c;     // Short vector
282                short_ct [a] += c;       // Magnitude distribution
283            }
284            else
285            {
286                int k = mvlong_width - 1;
287                is_short_ct [1] += c;     // Long vector
288
289                /*  bit 3 not always encoded. */
290                do
291                    bit_ct [k] [(a >> k) & 1] += c;
292
293                while (--k >= 0);
294            }
295        }
296        while (++j <= mv_max);
297    }
298
299    /*
300    {
301        int j = -mv_max;
302        do
303        {
304
305            const int c = events [mv_max + j];
306            int a = j;
307
308            if( j < 0)
309            {
310                sign_ct [1] += c;
311                a = -j;
312            }
313            else if( j)
314                sign_ct [0] += c;
315
316            if( a < mvnum_short)
317            {
318                is_short_ct [0] += c;     // Short vector
319                short_ct [a] += c;       // Magnitude distribution
320            }
321            else
322            {
323                int k = mvlong_width - 1;
324                is_short_ct [1] += c;     // Long vector
325
326                //  bit 3 not always encoded.
327
328                do
329                    bit_ct [k] [(a >> k) & 1] += c;
330                while( --k >= 0);
331            }
332        } while( ++j <= mv_max);
333    }
334    */
335
336    calc_prob(Pnew + mvpis_short, is_short_ct);
337
338    calc_prob(Pnew + MVPsign, sign_ct);
339
340    {
341        vp8_prob p [mvnum_short - 1];    /* actually only need branch ct */
342        int j = 0;
343
344        vp8_tree_probs_from_distribution(
345            8, vp8_small_mvencodings, vp8_small_mvtree,
346            p, short_bct, short_ct,
347            256, 1
348        );
349
350        do
351            calc_prob(Pnew + MVPshort + j, short_bct[j]);
352
353        while (++j < mvnum_short - 1);
354    }
355
356    {
357        int j = 0;
358
359        do
360            calc_prob(Pnew + MVPbits + j, bit_ct[j]);
361
362        while (++j < mvlong_width);
363    }
364
365    update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, updated);
366
367    update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
368
369    {
370        const vp8_prob *const new_p = Pnew + MVPshort;
371        vp8_prob *const cur_p = Pcur + MVPshort;
372
373        int j = 0;
374
375        do
376
377            update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
378
379        while (++j < mvnum_short - 1);
380    }
381
382    {
383        const vp8_prob *const new_p = Pnew + MVPbits;
384        vp8_prob *const cur_p = Pcur + MVPbits;
385
386        int j = 0;
387
388        do
389
390            update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
391
392        while (++j < mvlong_width);
393    }
394}
395
396void vp8_write_mvprobs(VP8_COMP *cpi)
397{
398    vp8_writer *const w  = & cpi->bc;
399    MV_CONTEXT *mvc = cpi->common.fc.mvc;
400    int flags[2] = {0, 0};
401#ifdef ENTROPY_STATS
402    active_section = 4;
403#endif
404    write_component_probs(
405        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0], cpi->MVcount[0], 0, &flags[0]
406    );
407    write_component_probs(
408        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1], cpi->MVcount[1], 1, &flags[1]
409    );
410
411    if (flags[0] || flags[1])
412        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
413
414#ifdef ENTROPY_STATS
415    active_section = 5;
416#endif
417}