diff options
Diffstat (limited to 'vp8/decoder/onyxd_if.c')
-rw-r--r-- | vp8/decoder/onyxd_if.c | 322 |
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; } |