media/libvpx/vp9/encoder/vp9_tokenize.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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  */
    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"
    20 #include "vp9/common/vp9_pred_common.h"
    21 #include "vp9/common/vp9_seg_common.h"
    22 #include "vp9/common/vp9_entropy.h"
    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;
    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;
    33   int i = -DCT_MAX_VALUE;
    34   int sign = 1;
    36   do {
    37     if (!i)
    38       sign = 0;
    40     {
    41       const int a = sign ? -i : i;
    42       int eb = sign;
    44       if (a > 4) {
    45         int j = 4;
    47         while (++j < 11  &&  e[j].base_val <= a) {}
    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     }
    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];
    62       if (p->base_val) {
    63         const int extra = t[i].extra;
    64         const int length = p->len;
    66         if (length)
    67           cost += treed_cost(p->tree, p->prob, extra >> 1, length);
    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);
    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 }
    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 };
    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 }
    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);
   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);
   123   assert((!type && !plane) || (type && plane));
   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);
   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     }
   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);
   150     assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0);
   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];
   156     token_cache[rc] = vp9_pt_energy_class[token];
   157     ++t;
   158   } while (c < eob && ++c < seg_eob);
   160   *tp = t;
   162   set_contexts(xd, pd, plane_bsize, tx_size, c > 0, aoff, loff);
   163 }
   165 struct is_skippable_args {
   166   MACROBLOCKD *xd;
   167   int *skippable;
   168 };
   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 }
   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 }
   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 }
   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};
   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   }
   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 }
   222 void vp9_tokenize_initialize() {
   223   fill_value_tokens();
   224 }

mercurial