LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp8/encoder - encodemv.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 134 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "vp8/common/common.h"
      12             : #include "encodemv.h"
      13             : #include "vp8/common/entropymode.h"
      14             : #include "vp8/common/systemdependent.h"
      15             : #include "vpx_ports/system_state.h"
      16             : 
      17             : #include <math.h>
      18             : 
      19             : #ifdef VP8_ENTROPY_STATS
      20             : extern unsigned int active_section;
      21             : #endif
      22             : 
      23           0 : static void encode_mvcomponent(vp8_writer *const w, const int v,
      24             :                                const struct mv_context *mvc) {
      25           0 :   const vp8_prob *p = mvc->prob;
      26           0 :   const int x = v < 0 ? -v : v;
      27             : 
      28           0 :   if (x < mvnum_short) /* Small */
      29             :   {
      30           0 :     vp8_write(w, 0, p[mvpis_short]);
      31           0 :     vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
      32             : 
      33           0 :     if (!x) return; /* no sign bit */
      34             :   } else            /* Large */
      35             :   {
      36           0 :     int i = 0;
      37             : 
      38           0 :     vp8_write(w, 1, p[mvpis_short]);
      39             : 
      40             :     do
      41           0 :       vp8_write(w, (x >> i) & 1, p[MVPbits + i]);
      42             : 
      43           0 :     while (++i < 3);
      44             : 
      45           0 :     i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */
      46             : 
      47             :     do
      48           0 :       vp8_write(w, (x >> i) & 1, p[MVPbits + i]);
      49             : 
      50           0 :     while (--i > 3);
      51             : 
      52           0 :     if (x & 0xFFF0) vp8_write(w, (x >> 3) & 1, p[MVPbits + 3]);
      53             :   }
      54             : 
      55           0 :   vp8_write(w, v < 0, p[MVPsign]);
      56             : }
      57             : #if 0
      58             : static int max_mv_r = 0;
      59             : static int max_mv_c = 0;
      60             : #endif
      61           0 : void vp8_encode_motion_vector(vp8_writer *w, const MV *mv,
      62             :                               const MV_CONTEXT *mvc) {
      63             : #if 0
      64             :     {
      65             :         if (abs(mv->row >> 1) > max_mv_r)
      66             :         {
      67             :             FILE *f = fopen("maxmv.stt", "a");
      68             :             max_mv_r = abs(mv->row >> 1);
      69             :             fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
      70             : 
      71             :             if ((abs(mv->row) / 2) != max_mv_r)
      72             :                 fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
      73             : 
      74             :             fclose(f);
      75             :         }
      76             : 
      77             :         if (abs(mv->col >> 1) > max_mv_c)
      78             :         {
      79             :             FILE *f = fopen("maxmv.stt", "a");
      80             :             fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
      81             :             max_mv_c = abs(mv->col >> 1);
      82             :             fclose(f);
      83             :         }
      84             :     }
      85             : #endif
      86             : 
      87           0 :   encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
      88           0 :   encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
      89           0 : }
      90             : 
      91           0 : static unsigned int cost_mvcomponent(const int v,
      92             :                                      const struct mv_context *mvc) {
      93           0 :   const vp8_prob *p = mvc->prob;
      94           0 :   const int x = v;
      95             :   unsigned int cost;
      96             : 
      97           0 :   if (x < mvnum_short) {
      98           0 :     cost = vp8_cost_zero(p[mvpis_short]) +
      99           0 :            vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
     100             : 
     101           0 :     if (!x) return cost;
     102             :   } else {
     103           0 :     int i = 0;
     104           0 :     cost = vp8_cost_one(p[mvpis_short]);
     105             : 
     106             :     do {
     107           0 :       cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1);
     108             : 
     109           0 :     } while (++i < 3);
     110             : 
     111           0 :     i = mvlong_width - 1; /* Skip bit 3, which is sometimes implicit */
     112             : 
     113             :     do {
     114           0 :       cost += vp8_cost_bit(p[MVPbits + i], (x >> i) & 1);
     115             : 
     116           0 :     } while (--i > 3);
     117             : 
     118           0 :     if (x & 0xFFF0) cost += vp8_cost_bit(p[MVPbits + 3], (x >> 3) & 1);
     119             :   }
     120             : 
     121           0 :   return cost; /* + vp8_cost_bit( p [MVPsign], v < 0); */
     122             : }
     123             : 
     124           0 : void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc,
     125             :                                     int mvc_flag[2]) {
     126           0 :   int i = 1;
     127           0 :   unsigned int cost0 = 0;
     128           0 :   unsigned int cost1 = 0;
     129             : 
     130           0 :   vpx_clear_system_state();
     131             : 
     132           0 :   i = 1;
     133             : 
     134           0 :   if (mvc_flag[0]) {
     135           0 :     mvcost[0][0] = cost_mvcomponent(0, &mvc[0]);
     136             : 
     137             :     do {
     138           0 :       cost0 = cost_mvcomponent(i, &mvc[0]);
     139             : 
     140           0 :       mvcost[0][i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
     141           0 :       mvcost[0][-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
     142           0 :     } while (++i <= mv_max);
     143             :   }
     144             : 
     145           0 :   i = 1;
     146             : 
     147           0 :   if (mvc_flag[1]) {
     148           0 :     mvcost[1][0] = cost_mvcomponent(0, &mvc[1]);
     149             : 
     150             :     do {
     151           0 :       cost1 = cost_mvcomponent(i, &mvc[1]);
     152             : 
     153           0 :       mvcost[1][i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
     154           0 :       mvcost[1][-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
     155           0 :     } while (++i <= mv_max);
     156             :   }
     157           0 : }
     158             : 
     159             : /* Motion vector probability table update depends on benefit.
     160             :  * Small correction allows for the fact that an update to an MV probability
     161             :  * may have benefit in subsequent frames as well as the current one.
     162             :  */
     163             : #define MV_PROB_UPDATE_CORRECTION -1
     164             : 
     165           0 : static void calc_prob(vp8_prob *p, const unsigned int ct[2]) {
     166           0 :   const unsigned int tot = ct[0] + ct[1];
     167             : 
     168           0 :   if (tot) {
     169           0 :     const vp8_prob x = ((ct[0] * 255) / tot) & -2;
     170           0 :     *p = x ? x : 1;
     171             :   }
     172           0 : }
     173             : 
     174           0 : static void update(vp8_writer *const w, const unsigned int ct[2],
     175             :                    vp8_prob *const cur_p, const vp8_prob new_p,
     176             :                    const vp8_prob update_p, int *updated) {
     177           0 :   const int cur_b = vp8_cost_branch(ct, *cur_p);
     178           0 :   const int new_b = vp8_cost_branch(ct, new_p);
     179           0 :   const int cost =
     180           0 :       7 + MV_PROB_UPDATE_CORRECTION +
     181           0 :       ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
     182             : 
     183           0 :   if (cur_b - new_b > cost) {
     184           0 :     *cur_p = new_p;
     185           0 :     vp8_write(w, 1, update_p);
     186           0 :     vp8_write_literal(w, new_p >> 1, 7);
     187           0 :     *updated = 1;
     188             : 
     189             :   } else
     190           0 :     vp8_write(w, 0, update_p);
     191           0 : }
     192             : 
     193           0 : static void write_component_probs(vp8_writer *const w,
     194             :                                   struct mv_context *cur_mvc,
     195             :                                   const struct mv_context *default_mvc_,
     196             :                                   const struct mv_context *update_mvc,
     197             :                                   const unsigned int events[MVvals],
     198             :                                   unsigned int rc, int *updated) {
     199           0 :   vp8_prob *Pcur = cur_mvc->prob;
     200           0 :   const vp8_prob *default_mvc = default_mvc_->prob;
     201           0 :   const vp8_prob *Pupdate = update_mvc->prob;
     202             :   unsigned int is_short_ct[2], sign_ct[2];
     203             : 
     204             :   unsigned int bit_ct[mvlong_width][2];
     205             : 
     206             :   unsigned int short_ct[mvnum_short];
     207             :   unsigned int short_bct[mvnum_short - 1][2];
     208             : 
     209             :   vp8_prob Pnew[MVPcount];
     210             : 
     211             :   (void)rc;
     212           0 :   vp8_copy_array(Pnew, default_mvc, MVPcount);
     213             : 
     214           0 :   vp8_zero(is_short_ct) vp8_zero(sign_ct) vp8_zero(bit_ct) vp8_zero(short_ct)
     215           0 :       vp8_zero(short_bct)
     216             : 
     217             :   /* j=0 */
     218             :   {
     219           0 :     const int c = events[mv_max];
     220             : 
     221           0 :     is_short_ct[0] += c; /* Short vector */
     222           0 :     short_ct[0] += c;    /* Magnitude distribution */
     223             :   }
     224             : 
     225             :   /* j: 1 ~ mv_max (1023) */
     226             :   {
     227           0 :     int j = 1;
     228             : 
     229             :     do {
     230           0 :       const int c1 = events[mv_max + j]; /* positive */
     231           0 :       const int c2 = events[mv_max - j]; /* negative */
     232           0 :       const int c = c1 + c2;
     233           0 :       int a = j;
     234             : 
     235           0 :       sign_ct[0] += c1;
     236           0 :       sign_ct[1] += c2;
     237             : 
     238           0 :       if (a < mvnum_short) {
     239           0 :         is_short_ct[0] += c; /* Short vector */
     240           0 :         short_ct[a] += c;    /* Magnitude distribution */
     241             :       } else {
     242           0 :         int k = mvlong_width - 1;
     243           0 :         is_short_ct[1] += c; /* Long vector */
     244             : 
     245             :         /*  bit 3 not always encoded. */
     246             :         do {
     247           0 :           bit_ct[k][(a >> k) & 1] += c;
     248             : 
     249           0 :         } while (--k >= 0);
     250             :       }
     251           0 :     } while (++j <= mv_max);
     252             :   }
     253             : 
     254           0 :   calc_prob(Pnew + mvpis_short, is_short_ct);
     255             : 
     256           0 :   calc_prob(Pnew + MVPsign, sign_ct);
     257             : 
     258             :   {
     259             :     vp8_prob p[mvnum_short - 1]; /* actually only need branch ct */
     260           0 :     int j = 0;
     261             : 
     262           0 :     vp8_tree_probs_from_distribution(8, vp8_small_mvencodings, vp8_small_mvtree,
     263             :                                      p, short_bct, short_ct, 256, 1);
     264             : 
     265             :     do {
     266           0 :       calc_prob(Pnew + MVPshort + j, short_bct[j]);
     267             : 
     268           0 :     } while (++j < mvnum_short - 1);
     269             :   }
     270             : 
     271             :   {
     272           0 :     int j = 0;
     273             : 
     274             :     do {
     275           0 :       calc_prob(Pnew + MVPbits + j, bit_ct[j]);
     276             : 
     277           0 :     } while (++j < mvlong_width);
     278             :   }
     279             : 
     280           0 :   update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++,
     281             :          updated);
     282             : 
     283           0 :   update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
     284             : 
     285             :   {
     286           0 :     const vp8_prob *const new_p = Pnew + MVPshort;
     287           0 :     vp8_prob *const cur_p = Pcur + MVPshort;
     288             : 
     289           0 :     int j = 0;
     290             : 
     291             :     do {
     292           0 :       update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
     293             : 
     294           0 :     } while (++j < mvnum_short - 1);
     295             :   }
     296             : 
     297             :   {
     298           0 :     const vp8_prob *const new_p = Pnew + MVPbits;
     299           0 :     vp8_prob *const cur_p = Pcur + MVPbits;
     300             : 
     301           0 :     int j = 0;
     302             : 
     303             :     do {
     304           0 :       update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
     305             : 
     306           0 :     } while (++j < mvlong_width);
     307             :   }
     308           0 : }
     309             : 
     310           0 : void vp8_write_mvprobs(VP8_COMP *cpi) {
     311           0 :   vp8_writer *const w = cpi->bc;
     312           0 :   MV_CONTEXT *mvc = cpi->common.fc.mvc;
     313           0 :   int flags[2] = { 0, 0 };
     314             : #ifdef VP8_ENTROPY_STATS
     315             :   active_section = 4;
     316             : #endif
     317           0 :   write_component_probs(w, &mvc[0], &vp8_default_mv_context[0],
     318           0 :                         &vp8_mv_update_probs[0], cpi->mb.MVcount[0], 0,
     319             :                         &flags[0]);
     320           0 :   write_component_probs(w, &mvc[1], &vp8_default_mv_context[1],
     321           0 :                         &vp8_mv_update_probs[1], cpi->mb.MVcount[1], 1,
     322             :                         &flags[1]);
     323             : 
     324           0 :   if (flags[0] || flags[1]) {
     325           0 :     vp8_build_component_cost_table(
     326           0 :         cpi->mb.mvcost, (const MV_CONTEXT *)cpi->common.fc.mvc, flags);
     327             :   }
     328             : 
     329             : #ifdef VP8_ENTROPY_STATS
     330             :   active_section = 5;
     331             : #endif
     332           0 : }

Generated by: LCOV version 1.13