summaryrefslogtreecommitdiff
path: root/vp9/decoder/vp9_onyxd_if.c
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2012-11-27 13:59:17 -0800
committerJohn Koleszar <jkoleszar@google.com>2012-11-27 14:12:30 -0800
commitfcccbcbb395ce4cf31b54ce1245cc28e5e3ef4c1 (patch)
tree68e128e48e3f5ab1de1c163fa3a12ea47f5d8d51 /vp9/decoder/vp9_onyxd_if.c
parent3bf7b131c8ebb6b4d63a8b70d69066dcbc4ed896 (diff)
downloadlibvpx-fcccbcbb395ce4cf31b54ce1245cc28e5e3ef4c1.tar
libvpx-fcccbcbb395ce4cf31b54ce1245cc28e5e3ef4c1.tar.gz
libvpx-fcccbcbb395ce4cf31b54ce1245cc28e5e3ef4c1.tar.bz2
libvpx-fcccbcbb395ce4cf31b54ce1245cc28e5e3ef4c1.zip
Add vp9_ prefix to all vp9 files
Support for gyp which doesn't support multiple objects in the same static library having the same basename. Change-Id: Ib947eefbaf68f8b177a796d23f875ccdfa6bc9dc
Diffstat (limited to 'vp9/decoder/vp9_onyxd_if.c')
-rw-r--r--vp9/decoder/vp9_onyxd_if.c505
1 files changed, 505 insertions, 0 deletions
diff --git a/vp9/decoder/vp9_onyxd_if.c b/vp9/decoder/vp9_onyxd_if.c
new file mode 100644
index 000000000..70671683b
--- /dev/null
+++ b/vp9/decoder/vp9_onyxd_if.c
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+#include "vp9/common/vp9_onyxc_int.h"
+#if CONFIG_POSTPROC
+#include "vp9/common/vp9_postproc.h"
+#endif
+#include "vp9/common/vp9_onyxd.h"
+#include "vp9_onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vp9/common/vp9_alloccommon.h"
+#include "vp9/common/vp9_loopfilter.h"
+#include "vp9/common/vp9_swapyv12buffer.h"
+#include <stdio.h>
+#include <assert.h>
+
+#include "vp9/common/vp9_quant_common.h"
+#include "vpx_scale/vpxscale.h"
+#include "vp9/common/vp9_systemdependent.h"
+#include "vpx_ports/vpx_timer.h"
+#include "vp9/decoder/vp9_decodframe.h"
+#include "vp9_detokenize.h"
+#if ARCH_ARM
+#include "vpx_ports/arm.h"
+#endif
+
+static int get_free_fb(VP9_COMMON *cm);
+static void ref_cnt_fb(int *buf, int *idx, int new_idx);
+
+#define WRITE_RECON_BUFFER 0
+#if WRITE_RECON_BUFFER == 1
+static void recon_write_yuv_frame(char *name, YV12_BUFFER_CONFIG *s) {
+ FILE *yuv_file = fopen((char *)name, "ab");
+ unsigned char *src = s->y_buffer;
+ int h = s->y_height;
+
+ do {
+ fwrite(src, s->y_width, 1, yuv_file);
+ src += s->y_stride;
+ } while (--h);
+
+ src = s->u_buffer;
+ h = s->uv_height;
+
+ do {
+ fwrite(src, s->uv_width, 1, yuv_file);
+ src += s->uv_stride;
+ } while (--h);
+
+ src = s->v_buffer;
+ h = s->uv_height;
+
+ do {
+ fwrite(src, s->uv_width, 1, yuv_file);
+ src += s->uv_stride;
+ } while (--h);
+
+ fclose(yuv_file);
+}
+#endif
+#if WRITE_RECON_BUFFER == 2
+void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) {
+
+ // write the frame
+ FILE *yframe;
+ int i;
+ char filename[255];
+
+ sprintf(filename, "dx\\y%04d.raw", this_frame);
+ yframe = fopen(filename, "wb");
+
+ for (i = 0; i < frame->y_height; i++)
+ fwrite(frame->y_buffer + i * frame->y_stride,
+ frame->y_width, 1, yframe);
+
+ fclose(yframe);
+ sprintf(filename, "dx\\u%04d.raw", this_frame);
+ yframe = fopen(filename, "wb");
+
+ for (i = 0; i < frame->uv_height; i++)
+ fwrite(frame->u_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
+
+ fclose(yframe);
+ sprintf(filename, "dx\\v%04d.raw", this_frame);
+ yframe = fopen(filename, "wb");
+
+ for (i = 0; i < frame->uv_height; i++)
+ fwrite(frame->v_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
+
+ fclose(yframe);
+}
+#endif
+
+void vp9_initialize_dec(void) {
+ static int init_done = 0;
+
+ if (!init_done) {
+ vp9_initialize_common();
+ vp9_init_quant_tables();
+ init_done = 1;
+ }
+}
+
+VP9D_PTR vp9_create_decompressor(VP9D_CONFIG *oxcf) {
+ VP9D_COMP *pbi = vpx_memalign(32, sizeof(VP9D_COMP));
+
+ if (!pbi)
+ return NULL;
+
+ vpx_memset(pbi, 0, sizeof(VP9D_COMP));
+
+ if (setjmp(pbi->common.error.jmp)) {
+ pbi->common.error.setjmp = 0;
+ vp9_remove_decompressor(pbi);
+ return 0;
+ }
+
+ pbi->common.error.setjmp = 1;
+ vp9_initialize_dec();
+
+ vp9_create_common(&pbi->common);
+
+ pbi->common.current_video_frame = 0;
+ pbi->ready_for_new_data = 1;
+
+ /* vp9_init_de_quantizer() is first called here. Add check in
+ * frame_init_dequantizer() to avoid unnecessary calling of
+ * vp9_init_de_quantizer() for every frame.
+ */
+ vp9_init_de_quantizer(pbi);
+
+ vp9_loop_filter_init(&pbi->common);
+
+ pbi->common.error.setjmp = 0;
+
+ pbi->decoded_key_frame = 0;
+
+ return (VP9D_PTR) pbi;
+}
+
+void vp9_remove_decompressor(VP9D_PTR ptr) {
+ VP9D_COMP *pbi = (VP9D_COMP *) ptr;
+
+ if (!pbi)
+ return;
+
+ // Delete sementation map
+ if (pbi->common.last_frame_seg_map != 0)
+ vpx_free(pbi->common.last_frame_seg_map);
+
+ vp9_remove_common(&pbi->common);
+ vpx_free(pbi->mbc);
+ vpx_free(pbi);
+}
+
+
+vpx_codec_err_t vp9_get_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
+ YV12_BUFFER_CONFIG *sd) {
+ VP9D_COMP *pbi = (VP9D_COMP *) ptr;
+ VP9_COMMON *cm = &pbi->common;
+ int ref_fb_idx;
+
+ if (ref_frame_flag == VP9_LAST_FLAG)
+ ref_fb_idx = cm->lst_fb_idx;
+ else if (ref_frame_flag == VP9_GOLD_FLAG)
+ ref_fb_idx = cm->gld_fb_idx;
+ else if (ref_frame_flag == VP9_ALT_FLAG)
+ ref_fb_idx = cm->alt_fb_idx;
+ else {
+ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+ "Invalid reference frame");
+ return pbi->common.error.error_code;
+ }
+
+ if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
+ cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
+ cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
+ cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) {
+ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+ "Incorrect buffer dimensions");
+ } else
+ vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
+
+ return pbi->common.error.error_code;
+}
+
+
+vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
+ YV12_BUFFER_CONFIG *sd) {
+ VP9D_COMP *pbi = (VP9D_COMP *) ptr;
+ VP9_COMMON *cm = &pbi->common;
+ int *ref_fb_ptr = NULL;
+ int free_fb;
+
+ if (ref_frame_flag == VP9_LAST_FLAG)
+ ref_fb_ptr = &cm->lst_fb_idx;
+ else if (ref_frame_flag == VP9_GOLD_FLAG)
+ ref_fb_ptr = &cm->gld_fb_idx;
+ else if (ref_frame_flag == VP9_ALT_FLAG)
+ ref_fb_ptr = &cm->alt_fb_idx;
+ else {
+ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+ "Invalid reference frame");
+ return pbi->common.error.error_code;
+ }
+
+ if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
+ cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
+ cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
+ cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) {
+ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+ "Incorrect buffer dimensions");
+ } else {
+ /* Find an empty frame buffer. */
+ free_fb = get_free_fb(cm);
+ /* Decrease fb_idx_ref_cnt since it will be increased again in
+ * ref_cnt_fb() below. */
+ cm->fb_idx_ref_cnt[free_fb]--;
+
+ /* Manage the reference counters and copy image. */
+ ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
+ vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
+ }
+
+ return pbi->common.error.error_code;
+}
+
+/*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
+#if HAVE_ARMV7
+extern void vp9_push_neon(int64_t *store);
+extern void vp9_pop_neon(int64_t *store);
+#endif
+
+static int get_free_fb(VP9_COMMON *cm) {
+ int i;
+ for (i = 0; i < NUM_YV12_BUFFERS; i++)
+ if (cm->fb_idx_ref_cnt[i] == 0)
+ break;
+
+ assert(i < NUM_YV12_BUFFERS);
+ cm->fb_idx_ref_cnt[i] = 1;
+ return i;
+}
+
+static void ref_cnt_fb(int *buf, int *idx, int new_idx) {
+ if (buf[*idx] > 0)
+ buf[*idx]--;
+
+ *idx = new_idx;
+
+ buf[new_idx]++;
+}
+
+/* If any buffer copy / swapping is signalled it should be done here. */
+static int swap_frame_buffers(VP9_COMMON *cm) {
+ int err = 0;
+
+ /* The alternate reference frame or golden frame can be updated
+ * using the new, last, or golden/alt ref frame. If it
+ * is updated using the newly decoded frame it is a refresh.
+ * An update using the last or golden/alt ref frame is a copy.
+ */
+ if (cm->copy_buffer_to_arf) {
+ int new_fb = 0;
+
+ if (cm->copy_buffer_to_arf == 1)
+ new_fb = cm->lst_fb_idx;
+ else if (cm->copy_buffer_to_arf == 2)
+ new_fb = cm->gld_fb_idx;
+ else
+ err = -1;
+
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
+ }
+
+ if (cm->copy_buffer_to_gf) {
+ int new_fb = 0;
+
+ if (cm->copy_buffer_to_gf == 1)
+ new_fb = cm->lst_fb_idx;
+ else if (cm->copy_buffer_to_gf == 2)
+ new_fb = cm->alt_fb_idx;
+ else
+ err = -1;
+
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
+ }
+
+ if (cm->refresh_golden_frame)
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
+
+ if (cm->refresh_alt_ref_frame)
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
+
+ if (cm->refresh_last_frame) {
+ ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
+
+ cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
+ } else
+ cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
+
+ cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
+
+ return err;
+}
+
+int vp9_receive_compressed_data(VP9D_PTR ptr, unsigned long size,
+ const unsigned char **psource,
+ int64_t time_stamp) {
+#if HAVE_ARMV7
+ int64_t dx_store_reg[8];
+#endif
+ VP9D_COMP *pbi = (VP9D_COMP *) ptr;
+ VP9_COMMON *cm = &pbi->common;
+ const unsigned char *source = *psource;
+ int retcode = 0;
+
+ /*if(pbi->ready_for_new_data == 0)
+ return -1;*/
+
+ if (ptr == 0) {
+ return -1;
+ }
+
+ pbi->common.error.error_code = VPX_CODEC_OK;
+
+ pbi->Source = source;
+ pbi->source_sz = size;
+
+ if (pbi->source_sz == 0) {
+ /* This is used to signal that we are missing frames.
+ * We do not know if the missing frame(s) was supposed to update
+ * any of the reference buffers, but we act conservative and
+ * mark only the last buffer as corrupted.
+ */
+ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
+ }
+
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp9_push_neon(dx_store_reg);
+ }
+#endif
+
+ cm->new_fb_idx = get_free_fb(cm);
+
+ if (setjmp(pbi->common.error.jmp)) {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp9_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.setjmp = 0;
+
+ /* We do not know if the missing frame(s) was supposed to update
+ * any of the reference buffers, but we act conservative and
+ * mark only the last buffer as corrupted.
+ */
+ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
+
+ if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+ cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
+ return -1;
+ }
+
+ pbi->common.error.setjmp = 1;
+
+ retcode = vp9_decode_frame(pbi, psource);
+
+ if (retcode < 0) {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp9_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.error_code = VPX_CODEC_ERROR;
+ pbi->common.error.setjmp = 0;
+ if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+ cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
+ return retcode;
+ }
+
+ {
+ if (swap_frame_buffers(cm)) {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp9_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.error_code = VPX_CODEC_ERROR;
+ pbi->common.error.setjmp = 0;
+ return -1;
+ }
+
+#if WRITE_RECON_BUFFER == 2
+ if (cm->show_frame)
+ write_dx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame);
+ else
+ write_dx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame + 1000);
+#endif
+
+ if (cm->filter_level) {
+ /* Apply the loop filter if appropriate. */
+ vp9_loop_filter_frame(cm, &pbi->mb);
+ }
+ vp8_yv12_extend_frame_borders(cm->frame_to_show);
+ }
+
+#if WRITE_RECON_BUFFER == 1
+ if (cm->show_frame)
+ recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+#endif
+
+ vp9_clear_system_state();
+
+ if (cm->show_frame) {
+ vpx_memcpy(cm->prev_mip, cm->mip,
+ (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
+ } else {
+ vpx_memset(cm->prev_mip, 0,
+ (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
+ }
+
+ /*vp9_print_modes_and_motion_vectors(cm->mi, cm->mb_rows,cm->mb_cols,
+ cm->current_video_frame);*/
+
+ if (cm->show_frame)
+ cm->current_video_frame++;
+
+ pbi->ready_for_new_data = 0;
+ pbi->last_time_stamp = time_stamp;
+ pbi->source_sz = 0;
+
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp9_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.setjmp = 0;
+ return retcode;
+}
+
+int vp9_get_raw_frame(VP9D_PTR ptr, YV12_BUFFER_CONFIG *sd,
+ int64_t *time_stamp, int64_t *time_end_stamp,
+ vp9_ppflags_t *flags) {
+ int ret = -1;
+ VP9D_COMP *pbi = (VP9D_COMP *) ptr;
+
+ if (pbi->ready_for_new_data == 1)
+ return ret;
+
+ /* ie no raw frame to show!!! */
+ if (pbi->common.show_frame == 0)
+ return ret;
+
+ pbi->ready_for_new_data = 1;
+ *time_stamp = pbi->last_time_stamp;
+ *time_end_stamp = 0;
+
+ sd->clrtype = pbi->common.clr_type;
+#if CONFIG_POSTPROC
+ ret = vp9_post_proc_frame(&pbi->common, sd, flags);
+#else
+
+ if (pbi->common.frame_to_show) {
+ *sd = *pbi->common.frame_to_show;
+ sd->y_width = pbi->common.Width;
+ sd->y_height = pbi->common.Height;
+ sd->uv_height = pbi->common.Height / 2;
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+
+#endif /*!CONFIG_POSTPROC*/
+ vp9_clear_system_state();
+ return ret;
+}