Home | History | Annotate | Download | only in encoder
      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 <math.h>
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <assert.h>
     16 #include "vp9/encoder/vp9_onyx_int.h"
     17 #include "vp9/encoder/vp9_tokenize.h"
     18 #include "vpx_mem/vpx_mem.h"
     19 
     20 #include "vp9/common/vp9_pred_common.h"
     21 #include "vp9/common/vp9_seg_common.h"
     22 #include "vp9/common/vp9_entropy.h"
     23 
     24 static TOKENVALUE dct_value_tokens[DCT_MAX_VALUE * 2];
     25 const TOKENVALUE *vp9_dct_value_tokens_ptr;
     26 static int dct_value_cost[DCT_MAX_VALUE * 2];
     27 const int *vp9_dct_value_cost_ptr;
     28 
     29 static void fill_value_tokens() {
     30   TOKENVALUE *const t = dct_value_tokens + DCT_MAX_VALUE;
     31   const vp9_extra_bit *const e = vp9_extra_bits;
     32 
     33   int i = -DCT_MAX_VALUE;
     34   int sign = 1;
     35 
     36   do {
     37     if (!i)
     38       sign = 0;
     39 
     40     {
     41       const int a = sign ? -i : i;
     42       int eb = sign;
     43 
     44       if (a > 4) {
     45         int j = 4;
     46 
     47         while (++j < 11  &&  e[j].base_val <= a) {}
     48 
     49         t[i].token = --j;
     50         eb |= (a - e[j].base_val) << 1;
     51       } else {
     52         t[i].token = a;
     53       }
     54       t[i].extra = eb;
     55     }
     56 
     57     // initialize the cost for extra bits for all possible coefficient value.
     58     {
     59       int cost = 0;
     60       const vp9_extra_bit *p = &vp9_extra_bits[t[i].token];
     61 
     62       if (p->base_val) {
     63         const int extra = t[i].extra;
     64         const int length = p->len;
     65 
     66         if (length)
     67           cost += treed_cost(p->tree, p->prob, extra >> 1, length);
     68 
     69         cost += vp9_cost_bit(vp9_prob_half, extra & 1); /* sign */
     70         dct_value_cost[i + DCT_MAX_VALUE] = cost;
     71       }
     72     }
     73   } while (++i < DCT_MAX_VALUE);
     74 
     75   vp9_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
     76   vp9_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
     77 }
     78 
     79 struct tokenize_b_args {
     80   VP9_COMP *cpi;
     81   MACROBLOCKD *xd;
     82   TOKENEXTRA **tp;
     83   TX_SIZE tx_size;
     84   uint8_t *token_cache;
     85 };
     86 
     87 static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize,
     88                                   TX_SIZE tx_size, void *arg) {
     89   struct tokenize_b_args* const args = arg;
     90   MACROBLOCKD *const xd = args->xd;
     91   struct macroblockd_plane *pd = &xd->plane[plane];
     92   int aoff, loff;
     93   txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff);
     94   set_contexts(xd, pd, plane_bsize, tx_size, pd->eobs[block] > 0, aoff, loff);
     95 }
     96 
     97 static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize,
     98                        TX_SIZE tx_size, void *arg) {
     99   struct tokenize_b_args* const args = arg;
    100   VP9_COMP *cpi = args->cpi;
    101   MACROBLOCKD *xd = args->xd;
    102   TOKENEXTRA **tp = args->tp;
    103   uint8_t *token_cache = args->token_cache;
    104   struct macroblockd_plane *pd = &xd->plane[plane];
    105   MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
    106   int pt; /* near block/prev token context index */
    107   int c = 0, rc = 0;
    108   TOKENEXTRA *t = *tp;        /* store tokens starting here */
    109   const int eob = pd->eobs[block];
    110   const PLANE_TYPE type = pd->plane_type;
    111   const int16_t *qcoeff_ptr = BLOCK_OFFSET(pd->qcoeff, block);
    112 
    113   const int segment_id = mbmi->segment_id;
    114   const int16_t *scan, *nb;
    115   vp9_coeff_count *const counts = cpi->coef_counts[tx_size];
    116   vp9_coeff_probs_model *const coef_probs = cpi->common.fc.coef_probs[tx_size];
    117   const int ref = is_inter_block(mbmi);
    118   const uint8_t *const band_translate = get_band_translate(tx_size);
    119   const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
    120   int aoff, loff;
    121   txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff);
    122 
    123   assert((!type && !plane) || (type && plane));
    124 
    125   pt = get_entropy_context(tx_size, pd->above_context + aoff,
    126                                     pd->left_context + loff);
    127   get_scan(xd, tx_size, type, block, &scan, &nb);
    128   c = 0;
    129   do {
    130     const int band = band_translate[c];
    131     int token;
    132     int v = 0;
    133     rc = scan[c];
    134     if (c)
    135       pt = get_coef_context(nb, token_cache, c);
    136     if (c < eob) {
    137       v = qcoeff_ptr[rc];
    138       assert(-DCT_MAX_VALUE <= v  &&  v < DCT_MAX_VALUE);
    139 
    140       t->extra = vp9_dct_value_tokens_ptr[v].extra;
    141       token    = vp9_dct_value_tokens_ptr[v].token;
    142     } else {
    143       token = DCT_EOB_TOKEN;
    144     }
    145 
    146     t->token = token;
    147     t->context_tree = coef_probs[type][ref][band][pt];
    148     t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0);
    149 
    150     assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
    151 
    152     ++counts[type][ref][band][pt][token];
    153     if (!t->skip_eob_node)
    154       ++cpi->common.counts.eob_branch[tx_size][type][ref][band][pt];
    155 
    156     token_cache[rc] = vp9_pt_energy_class[token];
    157     ++t;
    158   } while (c < eob && ++c < seg_eob);
    159 
    160   *tp = t;
    161 
    162   set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff);
    163 }
    164 
    165 struct is_skippable_args {
    166   MACROBLOCKD *xd;
    167   int *skippable;
    168 };
    169 
    170 static void is_skippable(int plane, int block,
    171                          BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
    172                          void *argv) {
    173   struct is_skippable_args *args = argv;
    174   args->skippable[0] &= (!args->xd->plane[plane].eobs[block]);
    175 }
    176 
    177 int vp9_sb_is_skippable(MACROBLOCKD *xd, BLOCK_SIZE bsize) {
    178   int result = 1;
    179   struct is_skippable_args args = {xd, &result};
    180   foreach_transformed_block(xd, bsize, is_skippable, &args);
    181   return result;
    182 }
    183 
    184 int vp9_is_skippable_in_plane(MACROBLOCKD *xd, BLOCK_SIZE bsize,
    185                               int plane) {
    186   int result = 1;
    187   struct is_skippable_args args = {xd, &result};
    188   foreach_transformed_block_in_plane(xd, bsize, plane, is_skippable, &args);
    189   return result;
    190 }
    191 
    192 void vp9_tokenize_sb(VP9_COMP *cpi, TOKENEXTRA **t, int dry_run,
    193                      BLOCK_SIZE bsize) {
    194   VP9_COMMON *const cm = &cpi->common;
    195   MACROBLOCKD *const xd = &cpi->mb.e_mbd;
    196   MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
    197   TOKENEXTRA *t_backup = *t;
    198   const int mb_skip_context = vp9_get_pred_context_mbskip(xd);
    199   const int skip_inc = !vp9_segfeature_active(&cm->seg, mbmi->segment_id,
    200                                               SEG_LVL_SKIP);
    201   struct tokenize_b_args arg = {cpi, xd, t, mbmi->tx_size, cpi->mb.token_cache};
    202 
    203   mbmi->skip_coeff = vp9_sb_is_skippable(xd, bsize);
    204   if (mbmi->skip_coeff) {
    205     if (!dry_run)
    206       cm->counts.mbskip[mb_skip_context][1] += skip_inc;
    207     reset_skip_context(xd, bsize);
    208     if (dry_run)
    209       *t = t_backup;
    210     return;
    211   }
    212 
    213   if (!dry_run) {
    214     cm->counts.mbskip[mb_skip_context][0] += skip_inc;
    215     foreach_transformed_block(xd, bsize, tokenize_b, &arg);
    216   } else {
    217     foreach_transformed_block(xd, bsize, set_entropy_context_b, &arg);
    218     *t = t_backup;
    219   }
    220 }
    221 
    222 void vp9_tokenize_initialize() {
    223   fill_value_tokens();
    224 }
    225