summaryrefslogtreecommitdiff
path: root/vp8/decoder/onyxd_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/decoder/onyxd_if.c')
-rw-r--r--vp8/decoder/onyxd_if.c322
1 files changed, 209 insertions, 113 deletions
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 8d2b267a9..063b6a468 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
- * Use of this source code is governed by a BSD-style license and patent
- * grant that can be found in the LICENSE file in the root of the source
- * tree. All contributing project authors may be found in the AUTHORS
- * file in the root of the source tree.
+ * 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.
*/
@@ -23,18 +24,19 @@
#include "threading.h"
#include "decoderthreading.h"
#include <stdio.h>
-#include "segmentation_common.h"
+
#include "quant_common.h"
#include "vpx_scale/vpxscale.h"
#include "systemdependent.h"
#include "vpx_ports/vpx_timer.h"
-
+#include "detokenize.h"
+#if ARCH_ARM
+#include "vpx_ports/arm.h"
+#endif
extern void vp8_init_loop_filter(VP8_COMMON *cm);
-
extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
-// DEBUG code
#if CONFIG_DEBUG
void vp8_recon_write_yuv_frame(unsigned char *name, YV12_BUFFER_CONFIG *s)
{
@@ -110,12 +112,13 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
pbi->common.current_video_frame = 0;
pbi->ready_for_new_data = 1;
- pbi->CPUFreq = 0; //vp8_get_processor_freq();
+ pbi->CPUFreq = 0; /*vp8_get_processor_freq();*/
pbi->max_threads = oxcf->max_threads;
vp8_decoder_create_threads(pbi);
- //vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
- // unnecessary calling of vp8cx_init_de_quantizer() for every frame.
+ /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
+ * unnecessary calling of vp8cx_init_de_quantizer() for every frame.
+ */
vp8cx_init_de_quantizer(pbi);
{
@@ -127,6 +130,9 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
cm->last_sharpness_level = cm->sharpness_level;
}
+#if CONFIG_ARM_ASM_DETOK
+ vp8_init_detokenizer(pbi);
+#endif
pbi->common.error.setjmp = 0;
return (VP8D_PTR) pbi;
}
@@ -142,6 +148,11 @@ void vp8dx_remove_decompressor(VP8D_PTR ptr)
if (pbi->segmentation_map != 0)
vpx_free(pbi->segmentation_map);
#endif
+
+#if CONFIG_MULTITHREAD
+ if (pbi->b_multithreaded_rd)
+ vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
+#endif
vp8_decoder_remove_threads(pbi);
vp8_remove_common(&pbi->common);
vpx_free(pbi);
@@ -181,57 +192,143 @@ int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_C
{
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
VP8_COMMON *cm = &pbi->common;
+ int ref_fb_idx;
if (ref_frame_flag == VP8_LAST_FLAG)
- vp8_yv12_copy_frame_ptr(&cm->last_frame, sd);
-
+ ref_fb_idx = cm->lst_fb_idx;
else if (ref_frame_flag == VP8_GOLD_FLAG)
- vp8_yv12_copy_frame_ptr(&cm->golden_frame, sd);
-
+ ref_fb_idx = cm->gld_fb_idx;
else if (ref_frame_flag == VP8_ALT_FLAG)
- vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, sd);
-
+ ref_fb_idx = cm->alt_fb_idx;
else
return -1;
+ vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
+
return 0;
}
int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
{
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
VP8_COMMON *cm = &pbi->common;
+ int ref_fb_idx;
if (ref_frame_flag == VP8_LAST_FLAG)
- vp8_yv12_copy_frame_ptr(sd, &cm->last_frame);
-
+ ref_fb_idx = cm->lst_fb_idx;
else if (ref_frame_flag == VP8_GOLD_FLAG)
- vp8_yv12_copy_frame_ptr(sd, &cm->golden_frame);
-
+ ref_fb_idx = cm->gld_fb_idx;
else if (ref_frame_flag == VP8_ALT_FLAG)
- vp8_yv12_copy_frame_ptr(sd, &cm->alt_ref_frame);
-
+ ref_fb_idx = cm->alt_fb_idx;
else
return -1;
+ vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[ref_fb_idx]);
+
return 0;
}
-//For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.
+/*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
#if HAVE_ARMV7
extern void vp8_push_neon(INT64 *store);
extern void vp8_pop_neon(INT64 *store);
-static INT64 dx_store_reg[8];
#endif
+
+static int get_free_fb (VP8_COMMON *cm)
+{
+ int i;
+ for (i = 0; i < NUM_YV12_BUFFERS; i++)
+ if (cm->fb_idx_ref_cnt[i] == 0)
+ break;
+
+ 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 (VP8_COMMON *cm)
+{
+ int fb_to_update_with, err = 0;
+
+ if (cm->refresh_last_frame)
+ fb_to_update_with = cm->lst_fb_idx;
+ else
+ fb_to_update_with = cm->new_fb_idx;
+
+ /* 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 = fb_to_update_with;
+ 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 = fb_to_update_with;
+ 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 vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
{
+#if HAVE_ARMV7
+ INT64 dx_store_reg[8];
+#endif
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
VP8_COMMON *cm = &pbi->common;
int retcode = 0;
-
struct vpx_usec_timer timer;
-// if(pbi->ready_for_new_data == 0)
-// return -1;
+ /*if(pbi->ready_for_new_data == 0)
+ return -1;*/
if (ptr == 0)
{
@@ -240,21 +337,38 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->common.error.error_code = VPX_CODEC_OK;
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp8_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
+ {
+ vp8_pop_neon(dx_store_reg);
+ }
+#endif
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 -1;
}
pbi->common.error.setjmp = 1;
-#if HAVE_ARMV7
- vp8_push_neon(dx_store_reg);
-#endif
-
vpx_usec_timer_start(&timer);
- //cm->current_video_frame++;
+ /*cm->current_video_frame++;*/
pbi->Source = source;
pbi->source_sz = size;
@@ -263,103 +377,80 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
if (retcode < 0)
{
#if HAVE_ARMV7
- vp8_pop_neon(dx_store_reg);
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp8_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;
}
- // Update the GF useage maps.
- vp8_update_gf_useage_maps(cm, &pbi->mb);
-
- if (pbi->b_multithreaded_lf && pbi->common.filter_level != 0)
- vp8_stop_lfthread(pbi);
-
- if (cm->refresh_last_frame)
+ if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
{
- vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
-
- cm->frame_to_show = &cm->last_frame;
- }
- else
- {
- cm->frame_to_show = &cm->new_frame;
- }
-
- if (!pbi->b_multithreaded_lf)
+ if (swap_frame_buffers (cm))
+ {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp8_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.error_code = VPX_CODEC_ERROR;
+ pbi->common.error.setjmp = 0;
+ return -1;
+ }
+ } else
{
- struct vpx_usec_timer lpftimer;
- vpx_usec_timer_start(&lpftimer);
- // Apply the loop filter if appropriate.
+ if (swap_frame_buffers (cm))
+ {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp8_pop_neon(dx_store_reg);
+ }
+#endif
+ pbi->common.error.error_code = VPX_CODEC_ERROR;
+ pbi->common.error.setjmp = 0;
+ return -1;
+ }
- if (cm->filter_level > 0)
+ if(pbi->common.filter_level)
{
+ struct vpx_usec_timer lpftimer;
+ vpx_usec_timer_start(&lpftimer);
+ /* Apply the loop filter if appropriate. */
+
vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
+
+ vpx_usec_timer_mark(&lpftimer);
+ pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
+
cm->last_frame_type = cm->frame_type;
cm->last_filter_type = cm->filter_type;
cm->last_sharpness_level = cm->sharpness_level;
-
}
-
- vpx_usec_timer_mark(&lpftimer);
- pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
+ vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
}
- vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
-
-
- // DEBUG code
#if 0
+ /* DEBUG code */
+ /*vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);*/
vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
if (cm->current_video_frame <= 5)
write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
#endif
- // If any buffer copy / swaping is signalled it should be done here.
- if (cm->copy_buffer_to_arf)
- {
- if (cm->copy_buffer_to_arf == 1)
- {
- if (cm->refresh_last_frame)
- vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
- else
- vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
- }
- else if (cm->copy_buffer_to_arf == 2)
- vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
- }
-
- if (cm->copy_buffer_to_gf)
- {
- if (cm->copy_buffer_to_gf == 1)
- {
- if (cm->refresh_last_frame)
- vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame);
- else
- vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
- }
- else if (cm->copy_buffer_to_gf == 2)
- vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame);
- }
-
- // Should the golden or alternate reference frame be refreshed?
- if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
- {
- if (cm->refresh_golden_frame)
- vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
-
- if (cm->refresh_alt_ref_frame)
- vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
-
- //vpx_log("Decoder: recovery frame received \n");
-
- // Update data structures that monitors GF useage
- vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
- cm->gf_active_count = cm->mb_rows * cm->mb_cols;
- }
-
vp8_clear_system_state();
vpx_usec_timer_mark(&timer);
@@ -367,7 +458,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
pbi->time_decoding += pbi->decode_microseconds;
-// vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);
+ /*vp8_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++;
@@ -410,12 +501,17 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#endif
#if HAVE_ARMV7
- vp8_pop_neon(dx_store_reg);
+#if CONFIG_RUNTIME_CPU_DETECT
+ if (cm->rtcd.flags & HAS_NEON)
+#endif
+ {
+ vp8_pop_neon(dx_store_reg);
+ }
#endif
pbi->common.error.setjmp = 0;
return retcode;
}
-int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level, int noise_level, int flags)
+int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags)
{
int ret = -1;
VP8D_COMP *pbi = (VP8D_COMP *) ptr;
@@ -423,7 +519,7 @@ int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp,
if (pbi->ready_for_new_data == 1)
return ret;
- // ie no raw frame to show!!!
+ /* ie no raw frame to show!!! */
if (pbi->common.show_frame == 0)
return ret;
@@ -433,7 +529,7 @@ int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp,
sd->clrtype = pbi->common.clr_type;
#if CONFIG_POSTPROC
- ret = vp8_post_proc_frame(&pbi->common, sd, deblock_level, noise_level, flags);
+ ret = vp8_post_proc_frame(&pbi->common, sd, flags);
#else
if (pbi->common.frame_to_show)
@@ -449,7 +545,7 @@ int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp,
ret = -1;
}
-#endif //!CONFIG_POSTPROC
+#endif /*!CONFIG_POSTPROC*/
vp8_clear_system_state();
return ret;
}