11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann 11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h" 121b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_scale/yv12config.h" 131b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h" 141b362b15af34006e6a11974088a46d42b903418eJohann 151b362b15af34006e6a11974088a46d42b903418eJohann/**************************************************************************** 161b362b15af34006e6a11974088a46d42b903418eJohann* Exports 171b362b15af34006e6a11974088a46d42b903418eJohann****************************************************************************/ 181b362b15af34006e6a11974088a46d42b903418eJohann 191b362b15af34006e6a11974088a46d42b903418eJohann/**************************************************************************** 201b362b15af34006e6a11974088a46d42b903418eJohann * 211b362b15af34006e6a11974088a46d42b903418eJohann ****************************************************************************/ 221b362b15af34006e6a11974088a46d42b903418eJohannint 231b362b15af34006e6a11974088a46d42b903418eJohannvp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { 241b362b15af34006e6a11974088a46d42b903418eJohann if (ybf) { 251b362b15af34006e6a11974088a46d42b903418eJohann vpx_free(ybf->buffer_alloc); 261b362b15af34006e6a11974088a46d42b903418eJohann 271b362b15af34006e6a11974088a46d42b903418eJohann /* buffer_alloc isn't accessed by most functions. Rather y_buffer, 281b362b15af34006e6a11974088a46d42b903418eJohann u_buffer and v_buffer point to buffer_alloc and are used. Clear out 291b362b15af34006e6a11974088a46d42b903418eJohann all of this so that a freed pointer isn't inadvertently used */ 301b362b15af34006e6a11974088a46d42b903418eJohann vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); 311b362b15af34006e6a11974088a46d42b903418eJohann } else { 321b362b15af34006e6a11974088a46d42b903418eJohann return -1; 331b362b15af34006e6a11974088a46d42b903418eJohann } 341b362b15af34006e6a11974088a46d42b903418eJohann 351b362b15af34006e6a11974088a46d42b903418eJohann return 0; 361b362b15af34006e6a11974088a46d42b903418eJohann} 371b362b15af34006e6a11974088a46d42b903418eJohann 38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, 39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int width, int height, int border) { 401b362b15af34006e6a11974088a46d42b903418eJohann if (ybf) { 41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int aligned_width = (width + 15) & ~15; 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int aligned_height = (height + 15) & ~15; 43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int y_stride = ((aligned_width + 2 * border) + 31) & ~31; 44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int yplane_size = (aligned_height + 2 * border) * y_stride; 45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int uv_width = aligned_width >> 1; 46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int uv_height = aligned_height >> 1; 471b362b15af34006e6a11974088a46d42b903418eJohann /** There is currently a bunch of code which assumes 481b362b15af34006e6a11974088a46d42b903418eJohann * uv_stride == y_stride/2, so enforce this here. */ 491b362b15af34006e6a11974088a46d42b903418eJohann int uv_stride = y_stride >> 1; 501b362b15af34006e6a11974088a46d42b903418eJohann int uvplane_size = (uv_height + border) * uv_stride; 51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int frame_size = yplane_size + 2 * uvplane_size; 521b362b15af34006e6a11974088a46d42b903418eJohann 53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ybf->buffer_alloc) { 54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->buffer_alloc = vpx_memalign(32, frame_size); 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->buffer_alloc_sz = frame_size; 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 571b362b15af34006e6a11974088a46d42b903418eJohann 58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size) 59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -1; 60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Only support allocating buffers that have a border that's a multiple 62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * of 32. The border restriction is required to get 16-byte alignment of 63f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * the start of the chroma rows without introducing an arbitrary gap 64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * between planes, which would break the semantics of things like 65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * vpx_img_set_rect(). */ 66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (border & 0x1f) 671b362b15af34006e6a11974088a46d42b903418eJohann return -3; 681b362b15af34006e6a11974088a46d42b903418eJohann 69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_crop_width = width; 70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_crop_height = height; 71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_width = aligned_width; 72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_height = aligned_height; 731b362b15af34006e6a11974088a46d42b903418eJohann ybf->y_stride = y_stride; 741b362b15af34006e6a11974088a46d42b903418eJohann 751b362b15af34006e6a11974088a46d42b903418eJohann ybf->uv_width = uv_width; 761b362b15af34006e6a11974088a46d42b903418eJohann ybf->uv_height = uv_height; 771b362b15af34006e6a11974088a46d42b903418eJohann ybf->uv_stride = uv_stride; 781b362b15af34006e6a11974088a46d42b903418eJohann 79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_width = 0; 80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_height = 0; 81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_stride = 0; 821b362b15af34006e6a11974088a46d42b903418eJohann 83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->border = border; 84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->frame_size = frame_size; 851b362b15af34006e6a11974088a46d42b903418eJohann 861b362b15af34006e6a11974088a46d42b903418eJohann ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; 871b362b15af34006e6a11974088a46d42b903418eJohann ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2 * uv_stride) + border / 2; 881b362b15af34006e6a11974088a46d42b903418eJohann ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2 * uv_stride) + border / 2; 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_buffer = NULL; 901b362b15af34006e6a11974088a46d42b903418eJohann 911b362b15af34006e6a11974088a46d42b903418eJohann ybf->corrupted = 0; /* assume not currupted by errors */ 92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -2; 95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, 98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int width, int height, int border) { 99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ybf) { 100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vp8_yv12_de_alloc_frame_buffer(ybf); 101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return vp8_yv12_realloc_frame_buffer(ybf, width, height, border); 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -2; 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_VP9 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// TODO(jkoleszar): Maybe replace this with struct vpx_image 108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) { 110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ybf) { 111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_free(ybf->buffer_alloc); 112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* buffer_alloc isn't accessed by most functions. Rather y_buffer, 114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang u_buffer and v_buffer point to buffer_alloc and are used. Clear out 115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang all of this so that a freed pointer isn't inadvertently used */ 116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG)); 1171b362b15af34006e6a11974088a46d42b903418eJohann } else { 118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -1; 1191b362b15af34006e6a11974088a46d42b903418eJohann } 1201b362b15af34006e6a11974088a46d42b903418eJohann 1211b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1221b362b15af34006e6a11974088a46d42b903418eJohann} 123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int width, int height, 126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ss_x, int ss_y, int border) { 127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ybf) { 128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int aligned_width = (width + 7) & ~7; 129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int aligned_height = (height + 7) & ~7; 130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int y_stride = ((aligned_width + 2 * border) + 31) & ~31; 131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int yplane_size = (aligned_height + 2 * border) * y_stride; 132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uv_width = aligned_width >> ss_x; 133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uv_height = aligned_height >> ss_y; 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uv_stride = y_stride >> ss_x; 135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uv_border_w = border >> ss_x; 136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uv_border_h = border >> ss_y; 137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int uvplane_size = (uv_height + 2 * uv_border_h) * uv_stride; 138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA 139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_width = aligned_width; 140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_height = aligned_height; 141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_stride = y_stride; 142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_border_w = border; 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_border_h = border; 144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int alpha_plane_size = (alpha_height + 2 * alpha_border_h) * 145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang alpha_stride; 146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int frame_size = yplane_size + 2 * uvplane_size + 147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang alpha_plane_size; 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#else 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int frame_size = yplane_size + 2 * uvplane_size; 150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ybf->buffer_alloc) { 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->buffer_alloc = vpx_memalign(32, frame_size); 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->buffer_alloc_sz = frame_size; 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size) 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -1; 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang /* Only support allocating buffers that have a border that's a multiple 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * of 32. The border restriction is required to get 16-byte alignment of 161f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * the start of the chroma rows without introducing an arbitrary gap 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * between planes, which would break the semantics of things like 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang * vpx_img_set_rect(). */ 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (border & 0x1f) 165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -3; 166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_crop_width = width; 168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_crop_height = height; 169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_width = aligned_width; 170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_height = aligned_height; 171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_stride = y_stride; 172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 17391037db265ecdd914a26e056cf69207b4f50924ehkuang ybf->uv_crop_width = (width + ss_x) >> ss_x; 17491037db265ecdd914a26e056cf69207b4f50924ehkuang ybf->uv_crop_height = (height + ss_y) >> ss_y; 175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->uv_width = uv_width; 176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->uv_height = uv_height; 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->uv_stride = uv_stride; 178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->border = border; 180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->frame_size = frame_size; 181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; 183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->u_buffer = ybf->buffer_alloc + yplane_size + 184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (uv_border_h * uv_stride) + uv_border_w; 185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + 186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (uv_border_h * uv_stride) + uv_border_w; 187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA 189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_width = alpha_width; 190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_height = alpha_height; 191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_stride = alpha_stride; 192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ybf->alpha_buffer = ybf->buffer_alloc + yplane_size + 2 * uvplane_size + 193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang (alpha_border_h * alpha_stride) + alpha_border_w; 194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 1951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang ybf->corrupted = 0; /* assume not corrupted by errors */ 196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return 0; 197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -2; 199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, 202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int width, int height, 203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int ss_x, int ss_y, int border) { 204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (ybf) { 205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang vp9_free_frame_buffer(ybf); 206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border); 207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return -2; 209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif 211