| Index: source/libvpx/vpx_scale/generic/yv12config.c
 | 
| ===================================================================
 | 
| --- source/libvpx/vpx_scale/generic/yv12config.c	(revision 240950)
 | 
| +++ source/libvpx/vpx_scale/generic/yv12config.c	(working copy)
 | 
| @@ -19,10 +19,18 @@
 | 
|  /****************************************************************************
 | 
|   *
 | 
|   ****************************************************************************/
 | 
| +
 | 
| +#define yv12_align_addr(addr, align) \
 | 
| +  (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
 | 
| +
 | 
|  int
 | 
|  vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
 | 
|    if (ybf) {
 | 
| -    vpx_free(ybf->buffer_alloc);
 | 
| +    // If libvpx is using external frame buffers then buffer_alloc_sz must
 | 
| +    // not be set.
 | 
| +    if (ybf->buffer_alloc_sz > 0) {
 | 
| +      vpx_free(ybf->buffer_alloc);
 | 
| +    }
 | 
|  
 | 
|      /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
 | 
|        u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
 | 
| @@ -108,7 +116,9 @@
 | 
|  
 | 
|  int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
 | 
|    if (ybf) {
 | 
| -    vpx_free(ybf->buffer_alloc);
 | 
| +    if (ybf->buffer_alloc_sz > 0) {
 | 
| +      vpx_free(ybf->buffer_alloc);
 | 
| +    }
 | 
|  
 | 
|      /* buffer_alloc isn't accessed by most functions.  Rather y_buffer,
 | 
|        u_buffer and v_buffer point to buffer_alloc and are used.  Clear out
 | 
| @@ -123,7 +133,10 @@
 | 
|  
 | 
|  int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
 | 
|                               int width, int height,
 | 
| -                             int ss_x, int ss_y, int border) {
 | 
| +                             int ss_x, int ss_y, int border,
 | 
| +                             vpx_codec_frame_buffer_t *ext_fb,
 | 
| +                             vpx_realloc_frame_buffer_cb_fn_t cb,
 | 
| +                             void *user_priv) {
 | 
|    if (ybf) {
 | 
|      const int aligned_width = (width + 7) & ~7;
 | 
|      const int aligned_height = (height + 7) & ~7;
 | 
| @@ -148,12 +161,36 @@
 | 
|  #else
 | 
|      const int frame_size = yplane_size + 2 * uvplane_size;
 | 
|  #endif
 | 
| -    if (!ybf->buffer_alloc) {
 | 
| -      ybf->buffer_alloc = vpx_memalign(32, frame_size);
 | 
| -      ybf->buffer_alloc_sz = frame_size;
 | 
| +
 | 
| +    if (ext_fb != NULL) {
 | 
| +      const int align_addr_extra_size = 31;
 | 
| +      const int external_frame_size = frame_size + align_addr_extra_size;
 | 
| +      if (external_frame_size > ext_fb->size) {
 | 
| +        // Allocation to hold larger frame, or first allocation.
 | 
| +        if (cb(user_priv, external_frame_size, ext_fb) < 0) {
 | 
| +          return -1;
 | 
| +        }
 | 
| +
 | 
| +        if (ext_fb->data == NULL || ext_fb->size < external_frame_size) {
 | 
| +          return -1;
 | 
| +        }
 | 
| +
 | 
| +        ybf->buffer_alloc = yv12_align_addr(ext_fb->data, 32);
 | 
| +      }
 | 
| +    } else {
 | 
| +      if (frame_size > ybf->buffer_alloc_sz) {
 | 
| +        // Allocation to hold larger frame, or first allocation.
 | 
| +        if (ybf->buffer_alloc)
 | 
| +          vpx_free(ybf->buffer_alloc);
 | 
| +        ybf->buffer_alloc = vpx_memalign(32, frame_size);
 | 
| +        ybf->buffer_alloc_sz = frame_size;
 | 
| +      }
 | 
| +
 | 
| +      if (ybf->buffer_alloc_sz < frame_size)
 | 
| +        return -1;
 | 
|      }
 | 
|  
 | 
| -    if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
 | 
| +    if (!ybf->buffer_alloc)
 | 
|        return -1;
 | 
|  
 | 
|      /* Only support allocating buffers that have a border that's a multiple
 | 
| @@ -203,7 +240,8 @@
 | 
|                             int ss_x, int ss_y, int border) {
 | 
|    if (ybf) {
 | 
|      vp9_free_frame_buffer(ybf);
 | 
| -    return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border);
 | 
| +    return vp9_realloc_frame_buffer(ybf, width, height, ss_x, ss_y, border,
 | 
| +                                    NULL, NULL, NULL);
 | 
|    }
 | 
|    return -2;
 | 
|  }
 | 
| 
 |