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
11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <assert.h>
12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h"
141b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_scale/yv12config.h"
151b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h"
161b362b15af34006e6a11974088a46d42b903418eJohann
171b362b15af34006e6a11974088a46d42b903418eJohann/****************************************************************************
181b362b15af34006e6a11974088a46d42b903418eJohann*  Exports
191b362b15af34006e6a11974088a46d42b903418eJohann****************************************************************************/
201b362b15af34006e6a11974088a46d42b903418eJohann
211b362b15af34006e6a11974088a46d42b903418eJohann/****************************************************************************
221b362b15af34006e6a11974088a46d42b903418eJohann *
231b362b15af34006e6a11974088a46d42b903418eJohann ****************************************************************************/
24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define yv12_align_addr(addr, align) \
25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
271b362b15af34006e6a11974088a46d42b903418eJohannint
281b362b15af34006e6a11974088a46d42b903418eJohannvp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
291b362b15af34006e6a11974088a46d42b903418eJohann  if (ybf) {
30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // If libvpx is using frame buffer callbacks then buffer_alloc_sz must
31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // not be set.
32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ybf->buffer_alloc_sz > 0) {
33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_free(ybf->buffer_alloc);
34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
351b362b15af34006e6a11974088a46d42b903418eJohann
361b362b15af34006e6a11974088a46d42b903418eJohann    /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
371b362b15af34006e6a11974088a46d42b903418eJohann      u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
381b362b15af34006e6a11974088a46d42b903418eJohann      all of this so that a freed pointer isn't inadvertently used */
391b362b15af34006e6a11974088a46d42b903418eJohann    vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG));
401b362b15af34006e6a11974088a46d42b903418eJohann  } else {
411b362b15af34006e6a11974088a46d42b903418eJohann    return -1;
421b362b15af34006e6a11974088a46d42b903418eJohann  }
431b362b15af34006e6a11974088a46d42b903418eJohann
441b362b15af34006e6a11974088a46d42b903418eJohann  return 0;
451b362b15af34006e6a11974088a46d42b903418eJohann}
461b362b15af34006e6a11974088a46d42b903418eJohann
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  int width, int height, int border) {
491b362b15af34006e6a11974088a46d42b903418eJohann  if (ybf) {
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int aligned_width = (width + 15) & ~15;
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int aligned_height = (height + 15) & ~15;
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int y_stride = ((aligned_width + 2 * border) + 31) & ~31;
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int yplane_size = (aligned_height + 2 * border) * y_stride;
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int uv_width = aligned_width >> 1;
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int uv_height = aligned_height >> 1;
561b362b15af34006e6a11974088a46d42b903418eJohann    /** There is currently a bunch of code which assumes
571b362b15af34006e6a11974088a46d42b903418eJohann      *  uv_stride == y_stride/2, so enforce this here. */
581b362b15af34006e6a11974088a46d42b903418eJohann    int uv_stride = y_stride >> 1;
591b362b15af34006e6a11974088a46d42b903418eJohann    int uvplane_size = (uv_height + border) * uv_stride;
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int frame_size = yplane_size + 2 * uvplane_size;
611b362b15af34006e6a11974088a46d42b903418eJohann
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!ybf->buffer_alloc) {
63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      ybf->buffer_alloc = (uint8_t *)vpx_memalign(32, frame_size);
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ybf->buffer_alloc_sz = frame_size;
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
661b362b15af34006e6a11974088a46d42b903418eJohann
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return -1;
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Only support allocating buffers that have a border that's a multiple
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * of 32. The border restriction is required to get 16-byte alignment of
72f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang     * the start of the chroma rows without introducing an arbitrary gap
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * between planes, which would break the semantics of things like
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * vpx_img_set_rect(). */
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (border & 0x1f)
761b362b15af34006e6a11974088a46d42b903418eJohann      return -3;
771b362b15af34006e6a11974088a46d42b903418eJohann
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_crop_width = width;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_crop_height = height;
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_width  = aligned_width;
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_height = aligned_height;
821b362b15af34006e6a11974088a46d42b903418eJohann    ybf->y_stride = y_stride;
831b362b15af34006e6a11974088a46d42b903418eJohann
841b362b15af34006e6a11974088a46d42b903418eJohann    ybf->uv_width = uv_width;
851b362b15af34006e6a11974088a46d42b903418eJohann    ybf->uv_height = uv_height;
861b362b15af34006e6a11974088a46d42b903418eJohann    ybf->uv_stride = uv_stride;
871b362b15af34006e6a11974088a46d42b903418eJohann
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_width = 0;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_height = 0;
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_stride = 0;
911b362b15af34006e6a11974088a46d42b903418eJohann
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->border = border;
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->frame_size = frame_size;
941b362b15af34006e6a11974088a46d42b903418eJohann
951b362b15af34006e6a11974088a46d42b903418eJohann    ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
961b362b15af34006e6a11974088a46d42b903418eJohann    ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2  * uv_stride) + border / 2;
971b362b15af34006e6a11974088a46d42b903418eJohann    ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2  * uv_stride) + border / 2;
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_buffer = NULL;
991b362b15af34006e6a11974088a46d42b903418eJohann
1001b362b15af34006e6a11974088a46d42b903418eJohann    ybf->corrupted = 0; /* assume not currupted by errors */
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return -2;
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int width, int height, int border) {
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ybf) {
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp8_yv12_de_alloc_frame_buffer(ybf);
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return vp8_yv12_realloc_frame_buffer(ybf, width, height, border);
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return -2;
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_VP9
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// TODO(jkoleszar): Maybe replace this with struct vpx_image
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ybf) {
120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ybf->buffer_alloc_sz > 0) {
121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_free(ybf->buffer_alloc);
122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      all of this so that a freed pointer isn't inadvertently used */
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memset(ybf, 0, sizeof(YV12_BUFFER_CONFIG));
1281b362b15af34006e6a11974088a46d42b903418eJohann  } else {
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return -1;
1301b362b15af34006e6a11974088a46d42b903418eJohann  }
1311b362b15af34006e6a11974088a46d42b903418eJohann
1321b362b15af34006e6a11974088a46d42b903418eJohann  return 0;
1331b362b15af34006e6a11974088a46d42b903418eJohann}
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             int width, int height,
137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             int ss_x, int ss_y, int border,
138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             vpx_codec_frame_buffer_t *fb,
139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             vpx_get_frame_buffer_cb_fn_t cb,
140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             void *cb_priv) {
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ybf) {
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int aligned_width = (width + 7) & ~7;
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int aligned_height = (height + 7) & ~7;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int y_stride = ((aligned_width + 2 * border) + 31) & ~31;
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int yplane_size = (aligned_height + 2 * border) * y_stride;
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uv_width = aligned_width >> ss_x;
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uv_height = aligned_height >> ss_y;
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uv_stride = y_stride >> ss_x;
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uv_border_w = border >> ss_x;
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uv_border_h = border >> ss_y;
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int uvplane_size = (uv_height + 2 * uv_border_h) * uv_stride;
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_width = aligned_width;
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_height = aligned_height;
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_stride = y_stride;
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_border_w = border;
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_border_h = border;
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int alpha_plane_size = (alpha_height + 2 * alpha_border_h) *
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 alpha_stride;
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int frame_size = yplane_size + 2 * uvplane_size +
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           alpha_plane_size;
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#else
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    const int frame_size = yplane_size + 2 * uvplane_size;
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cb != NULL) {
166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int align_addr_extra_size = 31;
167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const size_t external_frame_size = frame_size + align_addr_extra_size;
168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      assert(fb != NULL);
170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // Allocation to hold larger frame, or first allocation.
172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cb(cb_priv, external_frame_size, fb) < 0)
173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return -1;
174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (fb->data == NULL || fb->size < external_frame_size)
176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return -1;
177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // This memset is needed for fixing valgrind error from C loop filter
179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // due to access uninitialized memory in frame border. It could be
180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // removed if border is totally removed.
181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_memset(fb->data, 0, fb->size);
182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      ybf->buffer_alloc = (uint8_t *)yv12_align_addr(fb->data, 32);
184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else if (frame_size > ybf->buffer_alloc_sz) {
1859b35249446b07f40ac5fcc3205f2c048616efacchkuang      // Allocation to hold larger frame, or first allocation.
1869b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (ybf->buffer_alloc)
1879b35249446b07f40ac5fcc3205f2c048616efacchkuang        vpx_free(ybf->buffer_alloc);
188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      ybf->buffer_alloc = (uint8_t *)vpx_memalign(32, frame_size);
189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!ybf->buffer_alloc)
190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return -1;
191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ybf->buffer_alloc_sz = frame_size;
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // This memset is needed for fixing valgrind error from C loop filter
195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // due to access uninitialized memory in frame border. It could be
196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // removed if border is totally removed.
197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_memset(ybf->buffer_alloc, 0, ybf->buffer_alloc_sz);
198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Only support allocating buffers that have a border that's a multiple
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * of 32. The border restriction is required to get 16-byte alignment of
202f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang     * the start of the chroma rows without introducing an arbitrary gap
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * between planes, which would break the semantics of things like
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang     * vpx_img_set_rect(). */
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (border & 0x1f)
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return -3;
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_crop_width = width;
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_crop_height = height;
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_width  = aligned_width;
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_height = aligned_height;
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_stride = y_stride;
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
21491037db265ecdd914a26e056cf69207b4f50924ehkuang    ybf->uv_crop_width = (width + ss_x) >> ss_x;
21591037db265ecdd914a26e056cf69207b4f50924ehkuang    ybf->uv_crop_height = (height + ss_y) >> ss_y;
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->uv_width = uv_width;
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->uv_height = uv_height;
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->uv_stride = uv_stride;
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->border = border;
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->frame_size = frame_size;
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->u_buffer = ybf->buffer_alloc + yplane_size +
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    (uv_border_h * uv_stride) + uv_border_w;
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size +
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    (uv_border_h * uv_stride) + uv_border_w;
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_width = alpha_width;
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_height = alpha_height;
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_stride = alpha_stride;
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ybf->alpha_buffer = ybf->buffer_alloc + yplane_size + 2 * uvplane_size +
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        (alpha_border_h * alpha_stride) + alpha_border_w;
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
2361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    ybf->corrupted = 0; /* assume not corrupted by errors */
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return -2;
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           int width, int height,
244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           int ss_x, int ss_y, int border) {
245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ybf) {
246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_free_frame_buffer(ybf);
247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border,
248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    NULL, NULL, NULL);
249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return -2;
251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
253