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_config.h" |
michael@0 | 12 | #include "vpx_scale/yv12config.h" |
michael@0 | 13 | #include "vpx_mem/vpx_mem.h" |
michael@0 | 14 | |
michael@0 | 15 | /**************************************************************************** |
michael@0 | 16 | * Exports |
michael@0 | 17 | ****************************************************************************/ |
michael@0 | 18 | |
michael@0 | 19 | /**************************************************************************** |
michael@0 | 20 | * |
michael@0 | 21 | ****************************************************************************/ |
michael@0 | 22 | int |
michael@0 | 23 | vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { |
michael@0 | 24 | if (ybf) { |
michael@0 | 25 | vpx_free(ybf->buffer_alloc); |
michael@0 | 26 | |
michael@0 | 27 | /* buffer_alloc isn't accessed by most functions. Rather y_buffer, |
michael@0 | 28 | u_buffer and v_buffer point to buffer_alloc and are used. Clear out |
michael@0 | 29 | all of this so that a freed pointer isn't inadvertently used */ |
michael@0 | 30 | vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); |
michael@0 | 31 | } else { |
michael@0 | 32 | return -1; |
michael@0 | 33 | } |
michael@0 | 34 | |
michael@0 | 35 | return 0; |
michael@0 | 36 | } |
michael@0 | 37 | |
michael@0 | 38 | int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, |
michael@0 | 39 | int width, int height, int border) { |
michael@0 | 40 | if (ybf) { |
michael@0 | 41 | int aligned_width = (width + 15) & ~15; |
michael@0 | 42 | int aligned_height = (height + 15) & ~15; |
michael@0 | 43 | int y_stride = ((aligned_width + 2 * border) + 31) & ~31; |
michael@0 | 44 | int yplane_size = (aligned_height + 2 * border) * y_stride; |
michael@0 | 45 | int uv_width = aligned_width >> 1; |
michael@0 | 46 | int uv_height = aligned_height >> 1; |
michael@0 | 47 | /** There is currently a bunch of code which assumes |
michael@0 | 48 | * uv_stride == y_stride/2, so enforce this here. */ |
michael@0 | 49 | int uv_stride = y_stride >> 1; |
michael@0 | 50 | int uvplane_size = (uv_height + border) * uv_stride; |
michael@0 | 51 | const int frame_size = yplane_size + 2 * uvplane_size; |
michael@0 | 52 | |
michael@0 | 53 | if (!ybf->buffer_alloc) { |
michael@0 | 54 | ybf->buffer_alloc = vpx_memalign(32, frame_size); |
michael@0 | 55 | ybf->buffer_alloc_sz = frame_size; |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size) |
michael@0 | 59 | return -1; |
michael@0 | 60 | |
michael@0 | 61 | /* Only support allocating buffers that have a border that's a multiple |
michael@0 | 62 | * of 32. The border restriction is required to get 16-byte alignment of |
michael@0 | 63 | * the start of the chroma rows without introducing an arbitrary gap |
michael@0 | 64 | * between planes, which would break the semantics of things like |
michael@0 | 65 | * vpx_img_set_rect(). */ |
michael@0 | 66 | if (border & 0x1f) |
michael@0 | 67 | return -3; |
michael@0 | 68 | |
michael@0 | 69 | ybf->y_crop_width = width; |
michael@0 | 70 | ybf->y_crop_height = height; |
michael@0 | 71 | ybf->y_width = aligned_width; |
michael@0 | 72 | ybf->y_height = aligned_height; |
michael@0 | 73 | ybf->y_stride = y_stride; |
michael@0 | 74 | |
michael@0 | 75 | ybf->uv_width = uv_width; |
michael@0 | 76 | ybf->uv_height = uv_height; |
michael@0 | 77 | ybf->uv_stride = uv_stride; |
michael@0 | 78 | |
michael@0 | 79 | ybf->alpha_width = 0; |
michael@0 | 80 | ybf->alpha_height = 0; |
michael@0 | 81 | ybf->alpha_stride = 0; |
michael@0 | 82 | |
michael@0 | 83 | ybf->border = border; |
michael@0 | 84 | ybf->frame_size = frame_size; |
michael@0 | 85 | |
michael@0 | 86 | ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; |
michael@0 | 87 | ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2 * uv_stride) + border / 2; |
michael@0 | 88 | ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2 * uv_stride) + border / 2; |
michael@0 | 89 | ybf->alpha_buffer = NULL; |
michael@0 | 90 | |
michael@0 | 91 | ybf->corrupted = 0; /* assume not currupted by errors */ |
michael@0 | 92 | return 0; |
michael@0 | 93 | } |
michael@0 | 94 | return -2; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, |
michael@0 | 98 | int width, int height, int border) { |
michael@0 | 99 | if (ybf) { |
michael@0 | 100 | vp8_yv12_de_alloc_frame_buffer(ybf); |
michael@0 | 101 | return vp8_yv12_realloc_frame_buffer(ybf, width, height, border); |
michael@0 | 102 | } |
michael@0 | 103 | return -2; |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | #if CONFIG_VP9 |
michael@0 | 107 | // TODO(jkoleszar): Maybe replace this with struct vpx_image |
michael@0 | 108 | |
michael@0 | 109 | int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) { |
michael@0 | 110 | if (ybf) { |
michael@0 | 111 | vpx_free(ybf->buffer_alloc); |
michael@0 | 112 | |
michael@0 | 113 | /* buffer_alloc isn't accessed by most functions. Rather y_buffer, |
michael@0 | 114 | u_buffer and v_buffer point to buffer_alloc and are used. Clear out |
michael@0 | 115 | all of this so that a freed pointer isn't inadvertently used */ |
michael@0 | 116 | vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); |
michael@0 | 117 | } else { |
michael@0 | 118 | return -1; |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | return 0; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, |
michael@0 | 125 | int width, int height, |
michael@0 | 126 | int ss_x, int ss_y, int border) { |
michael@0 | 127 | if (ybf) { |
michael@0 | 128 | const int aligned_width = (width + 7) & ~7; |
michael@0 | 129 | const int aligned_height = (height + 7) & ~7; |
michael@0 | 130 | const int y_stride = ((aligned_width + 2 * border) + 31) & ~31; |
michael@0 | 131 | const int yplane_size = (aligned_height + 2 * border) * y_stride; |
michael@0 | 132 | const int uv_width = aligned_width >> ss_x; |
michael@0 | 133 | const int uv_height = aligned_height >> ss_y; |
michael@0 | 134 | const int uv_stride = y_stride >> ss_x; |
michael@0 | 135 | const int uv_border_w = border >> ss_x; |
michael@0 | 136 | const int uv_border_h = border >> ss_y; |
michael@0 | 137 | const int uvplane_size = (uv_height + 2 * uv_border_h) * uv_stride; |
michael@0 | 138 | #if CONFIG_ALPHA |
michael@0 | 139 | const int alpha_width = aligned_width; |
michael@0 | 140 | const int alpha_height = aligned_height; |
michael@0 | 141 | const int alpha_stride = y_stride; |
michael@0 | 142 | const int alpha_border_w = border; |
michael@0 | 143 | const int alpha_border_h = border; |
michael@0 | 144 | const int alpha_plane_size = (alpha_height + 2 * alpha_border_h) * |
michael@0 | 145 | alpha_stride; |
michael@0 | 146 | const int frame_size = yplane_size + 2 * uvplane_size + |
michael@0 | 147 | alpha_plane_size; |
michael@0 | 148 | #else |
michael@0 | 149 | const int frame_size = yplane_size + 2 * uvplane_size; |
michael@0 | 150 | #endif |
michael@0 | 151 | if (frame_size > ybf->buffer_alloc_sz) { |
michael@0 | 152 | // Allocation to hold larger frame, or first allocation. |
michael@0 | 153 | if (ybf->buffer_alloc) |
michael@0 | 154 | vpx_free(ybf->buffer_alloc); |
michael@0 | 155 | ybf->buffer_alloc = vpx_memalign(32, frame_size); |
michael@0 | 156 | ybf->buffer_alloc_sz = frame_size; |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size) |
michael@0 | 160 | return -1; |
michael@0 | 161 | |
michael@0 | 162 | /* Only support allocating buffers that have a border that's a multiple |
michael@0 | 163 | * of 32. The border restriction is required to get 16-byte alignment of |
michael@0 | 164 | * the start of the chroma rows without introducing an arbitrary gap |
michael@0 | 165 | * between planes, which would break the semantics of things like |
michael@0 | 166 | * vpx_img_set_rect(). */ |
michael@0 | 167 | if (border & 0x1f) |
michael@0 | 168 | return -3; |
michael@0 | 169 | |
michael@0 | 170 | ybf->y_crop_width = width; |
michael@0 | 171 | ybf->y_crop_height = height; |
michael@0 | 172 | ybf->y_width = aligned_width; |
michael@0 | 173 | ybf->y_height = aligned_height; |
michael@0 | 174 | ybf->y_stride = y_stride; |
michael@0 | 175 | |
michael@0 | 176 | ybf->uv_crop_width = (width + ss_x) >> ss_x; |
michael@0 | 177 | ybf->uv_crop_height = (height + ss_y) >> ss_y; |
michael@0 | 178 | ybf->uv_width = uv_width; |
michael@0 | 179 | ybf->uv_height = uv_height; |
michael@0 | 180 | ybf->uv_stride = uv_stride; |
michael@0 | 181 | |
michael@0 | 182 | ybf->border = border; |
michael@0 | 183 | ybf->frame_size = frame_size; |
michael@0 | 184 | |
michael@0 | 185 | ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; |
michael@0 | 186 | ybf->u_buffer = ybf->buffer_alloc + yplane_size + |
michael@0 | 187 | (uv_border_h * uv_stride) + uv_border_w; |
michael@0 | 188 | ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + |
michael@0 | 189 | (uv_border_h * uv_stride) + uv_border_w; |
michael@0 | 190 | |
michael@0 | 191 | #if CONFIG_ALPHA |
michael@0 | 192 | ybf->alpha_width = alpha_width; |
michael@0 | 193 | ybf->alpha_height = alpha_height; |
michael@0 | 194 | ybf->alpha_stride = alpha_stride; |
michael@0 | 195 | ybf->alpha_buffer = ybf->buffer_alloc + yplane_size + 2 * uvplane_size + |
michael@0 | 196 | (alpha_border_h * alpha_stride) + alpha_border_w; |
michael@0 | 197 | #endif |
michael@0 | 198 | ybf->corrupted = 0; /* assume not corrupted by errors */ |
michael@0 | 199 | return 0; |
michael@0 | 200 | } |
michael@0 | 201 | return -2; |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, |
michael@0 | 205 | int width, int height, |
michael@0 | 206 | int ss_x, int ss_y, int border) { |
michael@0 | 207 | if (ybf) { |
michael@0 | 208 | vp9_free_frame_buffer(ybf); |
michael@0 | 209 | return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border); |
michael@0 | 210 | } |
michael@0 | 211 | return -2; |
michael@0 | 212 | } |
michael@0 | 213 | #endif |