Thu, 15 Jan 2015 15:59:08 +0100
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 |