summaryrefslogtreecommitdiff
path: root/vpx_scale
diff options
context:
space:
mode:
authorFrank Galligan <fgalligan@google.com>2013-12-11 09:06:35 -0800
committerFrank Galligan <fgalligan@google.com>2013-12-15 18:45:46 -0800
commit10f891696bc4c972c13cc9fde2c53470501a03e2 (patch)
tree21d8f81ea2df7408f5e1e16e547c2113d0c99012 /vpx_scale
parent52b2d50db4d194b7484e8ca0bec4c8c71bf94eaa (diff)
downloadlibvpx-10f891696bc4c972c13cc9fde2c53470501a03e2.tar.gz
libvpx-10f891696bc4c972c13cc9fde2c53470501a03e2.tar.bz2
libvpx-10f891696bc4c972c13cc9fde2c53470501a03e2.zip
Add support to pass in external frame buffers.
VP9 decoder can now use frame buffers passed in by the application. Change-Id: I599527ec85c577f3f5552831d79a693884fafb73
Diffstat (limited to 'vpx_scale')
-rw-r--r--vpx_scale/generic/yv12config.c57
-rw-r--r--vpx_scale/yv12config.h14
2 files changed, 59 insertions, 12 deletions
diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c
index 7c3f7ece9..a020e19b7 100644
--- a/vpx_scale/generic/yv12config.c
+++ b/vpx_scale/generic/yv12config.c
@@ -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 vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
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_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
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,15 +161,36 @@ int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
#else
const int frame_size = yplane_size + 2 * uvplane_size;
#endif
- 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 (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
@@ -206,7 +240,8 @@ int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
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;
}
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index 0e950fb14..f23e1163c 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -15,6 +15,7 @@
extern "C" {
#endif
+#include "vpx/vpx_external_frame_buffer.h"
#include "vpx/vpx_integer.h"
#define VP8BORDERINPIXELS 32
@@ -64,9 +65,20 @@ extern "C" {
int vp9_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height, int ss_x, int ss_y,
int border);
+
+ // Updates the yv12 buffer config with the frame buffer. If ext_fb is not
+ // NULL then libvpx is using external frame buffers. The function will
+ // check if the frame buffer is big enough to fit the decoded frame and
+ // try to reallocate the frame buffer. If ext_fb is not NULL and the frame
+ // buffer is not big enough libvpx will call cb with minimum size in bytes.
+ //
+ // Returns 0 on success. Returns < 0 on failure.
int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height, int ss_x, int ss_y,
- int border);
+ int border,
+ vpx_codec_frame_buffer_t *ext_fb,
+ vpx_realloc_frame_buffer_cb_fn_t cb,
+ void *user_priv);
int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf);
#ifdef __cplusplus