media/libvpx/vpx_scale/generic/yv12config.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libvpx/vpx_scale/generic/yv12config.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,213 @@
     1.4 +/*
     1.5 + *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     1.6 + *
     1.7 + *  Use of this source code is governed by a BSD-style license
     1.8 + *  that can be found in the LICENSE file in the root of the source
     1.9 + *  tree. An additional intellectual property rights grant can be found
    1.10 + *  in the file PATENTS.  All contributing project authors may
    1.11 + *  be found in the AUTHORS file in the root of the source tree.
    1.12 + */
    1.13 +
    1.14 +#include "./vpx_config.h"
    1.15 +#include "vpx_scale/yv12config.h"
    1.16 +#include "vpx_mem/vpx_mem.h"
    1.17 +
    1.18 +/****************************************************************************
    1.19 +*  Exports
    1.20 +****************************************************************************/
    1.21 +
    1.22 +/****************************************************************************
    1.23 + *
    1.24 + ****************************************************************************/
    1.25 +int
    1.26 +vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
    1.27 +  if (ybf) {
    1.28 +    vpx_free(ybf->buffer_alloc);
    1.29 +
    1.30 +    /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
    1.31 +      u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
    1.32 +      all of this so that a freed pointer isn't inadvertently used */
    1.33 +    vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG));
    1.34 +  } else {
    1.35 +    return -1;
    1.36 +  }
    1.37 +
    1.38 +  return 0;
    1.39 +}
    1.40 +
    1.41 +int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
    1.42 +                                  int width, int height, int border) {
    1.43 +  if (ybf) {
    1.44 +    int aligned_width = (width + 15) & ~15;
    1.45 +    int aligned_height = (height + 15) & ~15;
    1.46 +    int y_stride = ((aligned_width + 2 * border) + 31) & ~31;
    1.47 +    int yplane_size = (aligned_height + 2 * border) * y_stride;
    1.48 +    int uv_width = aligned_width >> 1;
    1.49 +    int uv_height = aligned_height >> 1;
    1.50 +    /** There is currently a bunch of code which assumes
    1.51 +      *  uv_stride == y_stride/2, so enforce this here. */
    1.52 +    int uv_stride = y_stride >> 1;
    1.53 +    int uvplane_size = (uv_height + border) * uv_stride;
    1.54 +    const int frame_size = yplane_size + 2 * uvplane_size;
    1.55 +
    1.56 +    if (!ybf->buffer_alloc) {
    1.57 +      ybf->buffer_alloc = vpx_memalign(32, frame_size);
    1.58 +      ybf->buffer_alloc_sz = frame_size;
    1.59 +    }
    1.60 +
    1.61 +    if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
    1.62 +      return -1;
    1.63 +
    1.64 +    /* Only support allocating buffers that have a border that's a multiple
    1.65 +     * of 32. The border restriction is required to get 16-byte alignment of
    1.66 +     * the start of the chroma rows without introducing an arbitrary gap
    1.67 +     * between planes, which would break the semantics of things like
    1.68 +     * vpx_img_set_rect(). */
    1.69 +    if (border & 0x1f)
    1.70 +      return -3;
    1.71 +
    1.72 +    ybf->y_crop_width = width;
    1.73 +    ybf->y_crop_height = height;
    1.74 +    ybf->y_width  = aligned_width;
    1.75 +    ybf->y_height = aligned_height;
    1.76 +    ybf->y_stride = y_stride;
    1.77 +
    1.78 +    ybf->uv_width = uv_width;
    1.79 +    ybf->uv_height = uv_height;
    1.80 +    ybf->uv_stride = uv_stride;
    1.81 +
    1.82 +    ybf->alpha_width = 0;
    1.83 +    ybf->alpha_height = 0;
    1.84 +    ybf->alpha_stride = 0;
    1.85 +
    1.86 +    ybf->border = border;
    1.87 +    ybf->frame_size = frame_size;
    1.88 +
    1.89 +    ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
    1.90 +    ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2  * uv_stride) + border / 2;
    1.91 +    ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2  * uv_stride) + border / 2;
    1.92 +    ybf->alpha_buffer = NULL;
    1.93 +
    1.94 +    ybf->corrupted = 0; /* assume not currupted by errors */
    1.95 +    return 0;
    1.96 +  }
    1.97 +  return -2;
    1.98 +}
    1.99 +
   1.100 +int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
   1.101 +                                int width, int height, int border) {
   1.102 +  if (ybf) {
   1.103 +    vp8_yv12_de_alloc_frame_buffer(ybf);
   1.104 +    return vp8_yv12_realloc_frame_buffer(ybf, width, height, border);
   1.105 +  }
   1.106 +  return -2;
   1.107 +}
   1.108 +
   1.109 +#if CONFIG_VP9
   1.110 +// TODO(jkoleszar): Maybe replace this with struct vpx_image
   1.111 +
   1.112 +int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
   1.113 +  if (ybf) {
   1.114 +    vpx_free(ybf->buffer_alloc);
   1.115 +
   1.116 +    /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
   1.117 +      u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
   1.118 +      all of this so that a freed pointer isn't inadvertently used */
   1.119 +    vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG));
   1.120 +  } else {
   1.121 +    return -1;
   1.122 +  }
   1.123 +
   1.124 +  return 0;
   1.125 +}
   1.126 +
   1.127 +int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
   1.128 +                             int width, int height,
   1.129 +                             int ss_x, int ss_y, int border) {
   1.130 +  if (ybf) {
   1.131 +    const int aligned_width = (width + 7) & ~7;
   1.132 +    const int aligned_height = (height + 7) & ~7;
   1.133 +    const int y_stride = ((aligned_width + 2 * border) + 31) & ~31;
   1.134 +    const int yplane_size = (aligned_height + 2 * border) * y_stride;
   1.135 +    const int uv_width = aligned_width >> ss_x;
   1.136 +    const int uv_height = aligned_height >> ss_y;
   1.137 +    const int uv_stride = y_stride >> ss_x;
   1.138 +    const int uv_border_w = border >> ss_x;
   1.139 +    const int uv_border_h = border >> ss_y;
   1.140 +    const int uvplane_size = (uv_height + 2 * uv_border_h) * uv_stride;
   1.141 +#if CONFIG_ALPHA
   1.142 +    const int alpha_width = aligned_width;
   1.143 +    const int alpha_height = aligned_height;
   1.144 +    const int alpha_stride = y_stride;
   1.145 +    const int alpha_border_w = border;
   1.146 +    const int alpha_border_h = border;
   1.147 +    const int alpha_plane_size = (alpha_height + 2 * alpha_border_h) *
   1.148 +                                 alpha_stride;
   1.149 +    const int frame_size = yplane_size + 2 * uvplane_size +
   1.150 +                           alpha_plane_size;
   1.151 +#else
   1.152 +    const int frame_size = yplane_size + 2 * uvplane_size;
   1.153 +#endif
   1.154 +    if (frame_size > ybf->buffer_alloc_sz) {
   1.155 +      // Allocation to hold larger frame, or first allocation.
   1.156 +      if (ybf->buffer_alloc)
   1.157 +        vpx_free(ybf->buffer_alloc);
   1.158 +      ybf->buffer_alloc = vpx_memalign(32, frame_size);
   1.159 +      ybf->buffer_alloc_sz = frame_size;
   1.160 +    }
   1.161 +
   1.162 +    if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
   1.163 +      return -1;
   1.164 +
   1.165 +    /* Only support allocating buffers that have a border that's a multiple
   1.166 +     * of 32. The border restriction is required to get 16-byte alignment of
   1.167 +     * the start of the chroma rows without introducing an arbitrary gap
   1.168 +     * between planes, which would break the semantics of things like
   1.169 +     * vpx_img_set_rect(). */
   1.170 +    if (border & 0x1f)
   1.171 +      return -3;
   1.172 +
   1.173 +    ybf->y_crop_width = width;
   1.174 +    ybf->y_crop_height = height;
   1.175 +    ybf->y_width  = aligned_width;
   1.176 +    ybf->y_height = aligned_height;
   1.177 +    ybf->y_stride = y_stride;
   1.178 +
   1.179 +    ybf->uv_crop_width = (width + ss_x) >> ss_x;
   1.180 +    ybf->uv_crop_height = (height + ss_y) >> ss_y;
   1.181 +    ybf->uv_width = uv_width;
   1.182 +    ybf->uv_height = uv_height;
   1.183 +    ybf->uv_stride = uv_stride;
   1.184 +
   1.185 +    ybf->border = border;
   1.186 +    ybf->frame_size = frame_size;
   1.187 +
   1.188 +    ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
   1.189 +    ybf->u_buffer = ybf->buffer_alloc + yplane_size +
   1.190 +                    (uv_border_h * uv_stride) + uv_border_w;
   1.191 +    ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size +
   1.192 +                    (uv_border_h * uv_stride) + uv_border_w;
   1.193 +
   1.194 +#if CONFIG_ALPHA
   1.195 +    ybf->alpha_width = alpha_width;
   1.196 +    ybf->alpha_height = alpha_height;
   1.197 +    ybf->alpha_stride = alpha_stride;
   1.198 +    ybf->alpha_buffer = ybf->buffer_alloc + yplane_size + 2 * uvplane_size +
   1.199 +                        (alpha_border_h * alpha_stride) + alpha_border_w;
   1.200 +#endif
   1.201 +    ybf->corrupted = 0; /* assume not corrupted by errors */
   1.202 +    return 0;
   1.203 +  }
   1.204 +  return -2;
   1.205 +}
   1.206 +
   1.207 +int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
   1.208 +                           int width, int height,
   1.209 +                           int ss_x, int ss_y, int border) {
   1.210 +  if (ybf) {
   1.211 +    vp9_free_frame_buffer(ybf);
   1.212 +    return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border);
   1.213 +  }
   1.214 +  return -2;
   1.215 +}
   1.216 +#endif

mercurial