summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorFrank Galligan <fgalligan@google.com>2014-02-13 15:29:52 -0800
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2014-02-13 15:29:52 -0800
commitfb8c246b70d7403c8ef9eb638d4492d7854423cb (patch)
treed94df29fc7635a66a08a16100dfbe8487ce97176 /vp9
parente590e087d5ba59131c2004690f8df11ee68a46b6 (diff)
parenta4f30a5023b0216bf3681f87c7f35a8ee09027a4 (diff)
downloadlibvpx-fb8c246b70d7403c8ef9eb638d4492d7854423cb.tar
libvpx-fb8c246b70d7403c8ef9eb638d4492d7854423cb.tar.gz
libvpx-fb8c246b70d7403c8ef9eb638d4492d7854423cb.tar.bz2
libvpx-fb8c246b70d7403c8ef9eb638d4492d7854423cb.zip
Merge "Add VP9 decoder support for external frame buffers"
Diffstat (limited to 'vp9')
-rw-r--r--vp9/common/vp9_frame_buffers.c8
-rw-r--r--vp9/vp9_dx_iface.c51
2 files changed, 45 insertions, 14 deletions
diff --git a/vp9/common/vp9_frame_buffers.c b/vp9/common/vp9_frame_buffers.c
index d903ed695..dffeb8a22 100644
--- a/vp9/common/vp9_frame_buffers.c
+++ b/vp9/common/vp9_frame_buffers.c
@@ -42,7 +42,7 @@ int vp9_get_frame_buffer(void *cb_priv, size_t min_size,
int i;
InternalFrameBufferList *const int_fb_list =
(InternalFrameBufferList *)cb_priv;
- if (int_fb_list == NULL || fb == NULL)
+ if (int_fb_list == NULL)
return -1;
// Find a free frame buffer.
@@ -73,12 +73,8 @@ int vp9_get_frame_buffer(void *cb_priv, size_t min_size,
}
int vp9_release_frame_buffer(void *cb_priv, vpx_codec_frame_buffer_t *fb) {
- InternalFrameBuffer *int_fb;
+ InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv;
(void)cb_priv;
- if (fb == NULL)
- return -1;
-
- int_fb = (InternalFrameBuffer *)fb->priv;
int_fb->in_use = 0;
return 0;
}
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index 41750de02..1941fc042 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -60,6 +60,11 @@ struct vpx_codec_alg_priv {
int img_setup;
int img_avail;
int invert_tile_order;
+
+ // External frame buffer info to save for VP9 common.
+ void *ext_priv; // Private data associated with the external frame buffers.
+ vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb;
+ vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
};
static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
@@ -300,16 +305,22 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
VP9D_COMP *const pbi = (VP9D_COMP*)optr;
VP9_COMMON *const cm = &pbi->common;
- cm->get_fb_cb = vp9_get_frame_buffer;
- cm->release_fb_cb = vp9_release_frame_buffer;
-
// Set index to not initialized.
cm->new_fb_idx = -1;
- if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
- vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
- "Failed to initialize internal frame buffers");
- cm->cb_priv = &cm->int_frame_buffers;
+ if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
+ cm->get_fb_cb = ctx->get_ext_fb_cb;
+ cm->release_fb_cb = ctx->release_ext_fb_cb;
+ cm->cb_priv = ctx->ext_priv;
+ } else {
+ cm->get_fb_cb = vp9_get_frame_buffer;
+ cm->release_fb_cb = vp9_release_frame_buffer;
+
+ if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
+ vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+ "Failed to initialize internal frame buffers");
+ cm->cb_priv = &cm->int_frame_buffers;
+ }
ctx->pbi = optr;
}
@@ -350,7 +361,11 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp,
&time_end_stamp, &flags)) {
+ VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi;
+ VP9_COMMON *const cm = &pbi->common;
yuvconfig2image(&ctx->img, &sd, user_priv);
+
+ ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
ctx->img_avail = 1;
}
}
@@ -470,6 +485,24 @@ static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t *ctx,
return img;
}
+static vpx_codec_err_t vp9_set_fb_fn(
+ vpx_codec_alg_priv_t *ctx,
+ vpx_get_frame_buffer_cb_fn_t cb_get,
+ vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
+ if (cb_get == NULL || cb_release == NULL) {
+ return VPX_CODEC_INVALID_PARAM;
+ } else if (ctx->pbi == NULL) {
+ // If the decoder has already been initialized, do not accept changes to
+ // the frame buffer functions.
+ ctx->get_ext_fb_cb = cb_get;
+ ctx->release_ext_fb_cb = cb_release;
+ ctx->ext_priv = cb_priv;
+ return VPX_CODEC_OK;
+ }
+
+ return VPX_CODEC_ERROR;
+}
+
static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx,
vpx_codec_mmap_t *mmap,
vpx_codec_iter_t *iter) {
@@ -703,7 +736,8 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
CODEC_INTERFACE(vpx_codec_vp9_dx) = {
"WebM Project VP9 Decoder" VERSION_STRING,
VPX_CODEC_INTERNAL_ABI_VERSION,
- VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC,
+ VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
+ VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER,
/* vpx_codec_caps_t caps; */
vp9_init, /* vpx_codec_init_fn_t init; */
vp9_destroy, /* vpx_codec_destroy_fn_t destroy; */
@@ -715,6 +749,7 @@ CODEC_INTERFACE(vpx_codec_vp9_dx) = {
vp9_get_si, /* vpx_codec_get_si_fn_t get_si; */
vp9_decode, /* vpx_codec_decode_fn_t decode; */
vp9_get_frame, /* vpx_codec_frame_get_fn_t frame_get; */
+ vp9_set_fb_fn, /* vpx_codec_set_fb_fn_t set_fb_fn; */
},
{ // NOLINT
/* encoder functions */