media/libvpx/vp9/decoder/vp9_detokenize.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.

michael@0 1 /*
michael@0 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11 #include "vpx_mem/vpx_mem.h"
michael@0 12 #include "vpx_ports/mem.h"
michael@0 13
michael@0 14 #include "vp9/common/vp9_blockd.h"
michael@0 15 #include "vp9/common/vp9_common.h"
michael@0 16 #include "vp9/common/vp9_seg_common.h"
michael@0 17
michael@0 18 #include "vp9/decoder/vp9_dboolhuff.h"
michael@0 19 #include "vp9/decoder/vp9_detokenize.h"
michael@0 20 #include "vp9/decoder/vp9_onyxd_int.h"
michael@0 21 #include "vp9/decoder/vp9_treereader.h"
michael@0 22
michael@0 23 #define EOB_CONTEXT_NODE 0
michael@0 24 #define ZERO_CONTEXT_NODE 1
michael@0 25 #define ONE_CONTEXT_NODE 2
michael@0 26 #define LOW_VAL_CONTEXT_NODE 3
michael@0 27 #define TWO_CONTEXT_NODE 4
michael@0 28 #define THREE_CONTEXT_NODE 5
michael@0 29 #define HIGH_LOW_CONTEXT_NODE 6
michael@0 30 #define CAT_ONE_CONTEXT_NODE 7
michael@0 31 #define CAT_THREEFOUR_CONTEXT_NODE 8
michael@0 32 #define CAT_THREE_CONTEXT_NODE 9
michael@0 33 #define CAT_FIVE_CONTEXT_NODE 10
michael@0 34
michael@0 35 #define CAT1_MIN_VAL 5
michael@0 36 #define CAT2_MIN_VAL 7
michael@0 37 #define CAT3_MIN_VAL 11
michael@0 38 #define CAT4_MIN_VAL 19
michael@0 39 #define CAT5_MIN_VAL 35
michael@0 40 #define CAT6_MIN_VAL 67
michael@0 41 #define CAT1_PROB0 159
michael@0 42 #define CAT2_PROB0 145
michael@0 43 #define CAT2_PROB1 165
michael@0 44
michael@0 45 #define CAT3_PROB0 140
michael@0 46 #define CAT3_PROB1 148
michael@0 47 #define CAT3_PROB2 173
michael@0 48
michael@0 49 #define CAT4_PROB0 135
michael@0 50 #define CAT4_PROB1 140
michael@0 51 #define CAT4_PROB2 155
michael@0 52 #define CAT4_PROB3 176
michael@0 53
michael@0 54 #define CAT5_PROB0 130
michael@0 55 #define CAT5_PROB1 134
michael@0 56 #define CAT5_PROB2 141
michael@0 57 #define CAT5_PROB3 157
michael@0 58 #define CAT5_PROB4 180
michael@0 59
michael@0 60 static const vp9_prob cat6_prob[15] = {
michael@0 61 254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0
michael@0 62 };
michael@0 63
michael@0 64 static const int token_to_counttoken[MAX_ENTROPY_TOKENS] = {
michael@0 65 ZERO_TOKEN, ONE_TOKEN, TWO_TOKEN, TWO_TOKEN,
michael@0 66 TWO_TOKEN, TWO_TOKEN, TWO_TOKEN, TWO_TOKEN,
michael@0 67 TWO_TOKEN, TWO_TOKEN, TWO_TOKEN, DCT_EOB_MODEL_TOKEN
michael@0 68 };
michael@0 69
michael@0 70 #define INCREMENT_COUNT(token) \
michael@0 71 do { \
michael@0 72 if (!cm->frame_parallel_decoding_mode) \
michael@0 73 ++coef_counts[band][pt][token_to_counttoken[token]]; \
michael@0 74 } while (0)
michael@0 75
michael@0 76
michael@0 77 #define WRITE_COEF_CONTINUE(val, token) \
michael@0 78 { \
michael@0 79 dqcoeff_ptr[scan[c]] = (vp9_read_bit(r) ? -val : val) * \
michael@0 80 dq[c > 0] / (1 + (tx_size == TX_32X32)); \
michael@0 81 INCREMENT_COUNT(token); \
michael@0 82 token_cache[scan[c]] = vp9_pt_energy_class[token]; \
michael@0 83 ++c; \
michael@0 84 continue; \
michael@0 85 }
michael@0 86
michael@0 87 #define ADJUST_COEF(prob, bits_count) \
michael@0 88 do { \
michael@0 89 val += (vp9_read(r, prob) << bits_count); \
michael@0 90 } while (0)
michael@0 91
michael@0 92 static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd,
michael@0 93 vp9_reader *r, int block_idx,
michael@0 94 PLANE_TYPE type, int seg_eob, int16_t *dqcoeff_ptr,
michael@0 95 TX_SIZE tx_size, const int16_t *dq, int pt,
michael@0 96 uint8_t *token_cache) {
michael@0 97 const FRAME_CONTEXT *const fc = &cm->fc;
michael@0 98 FRAME_COUNTS *const counts = &cm->counts;
michael@0 99 const int ref = is_inter_block(&xd->mi_8x8[0]->mbmi);
michael@0 100 int band, c = 0;
michael@0 101 const vp9_prob (*coef_probs)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES] =
michael@0 102 fc->coef_probs[tx_size][type][ref];
michael@0 103 vp9_prob coef_probs_full[COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
michael@0 104 uint8_t load_map[COEF_BANDS][PREV_COEF_CONTEXTS] = { { 0 } };
michael@0 105 const vp9_prob *prob;
michael@0 106 unsigned int (*coef_counts)[PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES + 1] =
michael@0 107 counts->coef[tx_size][type][ref];
michael@0 108 unsigned int (*eob_branch_count)[PREV_COEF_CONTEXTS] =
michael@0 109 counts->eob_branch[tx_size][type][ref];
michael@0 110 const int16_t *scan, *nb;
michael@0 111 const uint8_t *cat6;
michael@0 112 const uint8_t *band_translate = get_band_translate(tx_size);
michael@0 113 get_scan(xd, tx_size, type, block_idx, &scan, &nb);
michael@0 114
michael@0 115 while (c < seg_eob) {
michael@0 116 int val;
michael@0 117 if (c)
michael@0 118 pt = get_coef_context(nb, token_cache, c);
michael@0 119 band = *band_translate++;
michael@0 120 prob = coef_probs[band][pt];
michael@0 121 if (!cm->frame_parallel_decoding_mode)
michael@0 122 ++eob_branch_count[band][pt];
michael@0 123 if (!vp9_read(r, prob[EOB_CONTEXT_NODE]))
michael@0 124 break;
michael@0 125 goto DECODE_ZERO;
michael@0 126
michael@0 127 SKIP_START:
michael@0 128 if (c >= seg_eob)
michael@0 129 break;
michael@0 130 if (c)
michael@0 131 pt = get_coef_context(nb, token_cache, c);
michael@0 132 band = *band_translate++;
michael@0 133 prob = coef_probs[band][pt];
michael@0 134
michael@0 135 DECODE_ZERO:
michael@0 136 if (!vp9_read(r, prob[ZERO_CONTEXT_NODE])) {
michael@0 137 INCREMENT_COUNT(ZERO_TOKEN);
michael@0 138 token_cache[scan[c]] = vp9_pt_energy_class[ZERO_TOKEN];
michael@0 139 ++c;
michael@0 140 goto SKIP_START;
michael@0 141 }
michael@0 142
michael@0 143 // ONE_CONTEXT_NODE_0_
michael@0 144 if (!vp9_read(r, prob[ONE_CONTEXT_NODE])) {
michael@0 145 WRITE_COEF_CONTINUE(1, ONE_TOKEN);
michael@0 146 }
michael@0 147 // Load full probabilities if not already loaded
michael@0 148 if (!load_map[band][pt]) {
michael@0 149 vp9_model_to_full_probs(coef_probs[band][pt],
michael@0 150 coef_probs_full[band][pt]);
michael@0 151 load_map[band][pt] = 1;
michael@0 152 }
michael@0 153 prob = coef_probs_full[band][pt];
michael@0 154 // LOW_VAL_CONTEXT_NODE_0_
michael@0 155 if (!vp9_read(r, prob[LOW_VAL_CONTEXT_NODE])) {
michael@0 156 if (!vp9_read(r, prob[TWO_CONTEXT_NODE])) {
michael@0 157 WRITE_COEF_CONTINUE(2, TWO_TOKEN);
michael@0 158 }
michael@0 159 if (!vp9_read(r, prob[THREE_CONTEXT_NODE])) {
michael@0 160 WRITE_COEF_CONTINUE(3, THREE_TOKEN);
michael@0 161 }
michael@0 162 WRITE_COEF_CONTINUE(4, FOUR_TOKEN);
michael@0 163 }
michael@0 164 // HIGH_LOW_CONTEXT_NODE_0_
michael@0 165 if (!vp9_read(r, prob[HIGH_LOW_CONTEXT_NODE])) {
michael@0 166 if (!vp9_read(r, prob[CAT_ONE_CONTEXT_NODE])) {
michael@0 167 val = CAT1_MIN_VAL;
michael@0 168 ADJUST_COEF(CAT1_PROB0, 0);
michael@0 169 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY1);
michael@0 170 }
michael@0 171 val = CAT2_MIN_VAL;
michael@0 172 ADJUST_COEF(CAT2_PROB1, 1);
michael@0 173 ADJUST_COEF(CAT2_PROB0, 0);
michael@0 174 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY2);
michael@0 175 }
michael@0 176 // CAT_THREEFOUR_CONTEXT_NODE_0_
michael@0 177 if (!vp9_read(r, prob[CAT_THREEFOUR_CONTEXT_NODE])) {
michael@0 178 if (!vp9_read(r, prob[CAT_THREE_CONTEXT_NODE])) {
michael@0 179 val = CAT3_MIN_VAL;
michael@0 180 ADJUST_COEF(CAT3_PROB2, 2);
michael@0 181 ADJUST_COEF(CAT3_PROB1, 1);
michael@0 182 ADJUST_COEF(CAT3_PROB0, 0);
michael@0 183 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY3);
michael@0 184 }
michael@0 185 val = CAT4_MIN_VAL;
michael@0 186 ADJUST_COEF(CAT4_PROB3, 3);
michael@0 187 ADJUST_COEF(CAT4_PROB2, 2);
michael@0 188 ADJUST_COEF(CAT4_PROB1, 1);
michael@0 189 ADJUST_COEF(CAT4_PROB0, 0);
michael@0 190 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY4);
michael@0 191 }
michael@0 192 // CAT_FIVE_CONTEXT_NODE_0_:
michael@0 193 if (!vp9_read(r, prob[CAT_FIVE_CONTEXT_NODE])) {
michael@0 194 val = CAT5_MIN_VAL;
michael@0 195 ADJUST_COEF(CAT5_PROB4, 4);
michael@0 196 ADJUST_COEF(CAT5_PROB3, 3);
michael@0 197 ADJUST_COEF(CAT5_PROB2, 2);
michael@0 198 ADJUST_COEF(CAT5_PROB1, 1);
michael@0 199 ADJUST_COEF(CAT5_PROB0, 0);
michael@0 200 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY5);
michael@0 201 }
michael@0 202 val = 0;
michael@0 203 cat6 = cat6_prob;
michael@0 204 while (*cat6)
michael@0 205 val = (val << 1) | vp9_read(r, *cat6++);
michael@0 206 val += CAT6_MIN_VAL;
michael@0 207
michael@0 208 WRITE_COEF_CONTINUE(val, DCT_VAL_CATEGORY6);
michael@0 209 }
michael@0 210
michael@0 211 if (c < seg_eob) {
michael@0 212 if (!cm->frame_parallel_decoding_mode)
michael@0 213 ++coef_counts[band][pt][DCT_EOB_MODEL_TOKEN];
michael@0 214 }
michael@0 215
michael@0 216 return c;
michael@0 217 }
michael@0 218
michael@0 219 int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
michael@0 220 int plane, int block, BLOCK_SIZE plane_bsize,
michael@0 221 int x, int y, TX_SIZE tx_size, vp9_reader *r,
michael@0 222 uint8_t *token_cache) {
michael@0 223 struct macroblockd_plane *const pd = &xd->plane[plane];
michael@0 224 const int seg_eob = get_tx_eob(&cm->seg, xd->mi_8x8[0]->mbmi.segment_id,
michael@0 225 tx_size);
michael@0 226 const int pt = get_entropy_context(tx_size, pd->above_context + x,
michael@0 227 pd->left_context + y);
michael@0 228 const int eob = decode_coefs(cm, xd, r, block, pd->plane_type, seg_eob,
michael@0 229 BLOCK_OFFSET(pd->dqcoeff, block), tx_size,
michael@0 230 pd->dequant, pt, token_cache);
michael@0 231 set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, x, y);
michael@0 232 pd->eobs[block] = eob;
michael@0 233 return eob;
michael@0 234 }
michael@0 235
michael@0 236

mercurial