diff options
Diffstat (limited to 'vp8/encoder/onyx_if.c')
-rw-r--r-- | vp8/encoder/onyx_if.c | 417 |
1 files changed, 242 insertions, 175 deletions
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 7662720..56bac0a 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_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. */ @@ -20,7 +21,7 @@ #include "extend.h" #include "ratectrl.h" #include "quant_common.h" -#include "segmentation_common.h" +#include "segmentation.h" #include "g_common.h" #include "vpx_scale/yv12extend.h" #include "postproc.h" @@ -28,6 +29,8 @@ #include "swapyv12buffer.h" #include "threading.h" #include "vpx_ports/vpx_timer.h" +#include "vpxerrors.h" + #include <math.h> #include <stdio.h> #include <limits.h> @@ -136,8 +139,6 @@ extern unsigned int inter_b_modes[15]; extern void (*vp8_short_fdct4x4)(short *input, short *output, int pitch); extern void (*vp8_short_fdct8x4)(short *input, short *output, int pitch); -extern void (*vp8_fast_fdct4x4)(short *input, short *output, int pitch); -extern void (*vp8_fast_fdct8x4)(short *input, short *output, int pitch); extern const int vp8_bits_per_mb[2][QINDEX_RANGE]; @@ -225,6 +226,17 @@ void vp8_dealloc_compressor_data(VP8_COMP *cpi) vpx_free(cpi->tok); cpi->tok = 0; + // Structure used to minitor GF useage + if (cpi->gf_active_flags != 0) + vpx_free(cpi->gf_active_flags); + + cpi->gf_active_flags = 0; + + if(cpi->mb.pip) + vpx_free(cpi->mb.pip); + + cpi->mb.pip = 0; + } static void enable_segmentation(VP8_PTR ptr) @@ -281,7 +293,6 @@ static void segmentation_test_function(VP8_PTR ptr) unsigned char *seg_map; signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - int i, j; // Create a temporary map for segmentation data. CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); @@ -545,7 +556,8 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_NEWG ] = INT_MAX; sf->thresh_mult[THR_SPLITG ] = INT_MAX; } - else if (!(cpi->ref_frame_flags & VP8_ALT_FLAG)) + + if (!(cpi->ref_frame_flags & VP8_ALT_FLAG)) { sf->thresh_mult[THR_NEARESTA ] = INT_MAX; sf->thresh_mult[THR_ZEROA ] = INT_MAX; @@ -597,7 +609,8 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_NEARMV ] = INT_MAX; sf->thresh_mult[THR_SPLITMV ] = INT_MAX; } - else if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG)) + + if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG)) { sf->thresh_mult[THR_NEARESTG ] = INT_MAX; sf->thresh_mult[THR_ZEROG ] = INT_MAX; @@ -605,7 +618,8 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_NEWG ] = INT_MAX; sf->thresh_mult[THR_SPLITG ] = INT_MAX; } - else if (!(cpi->ref_frame_flags & VP8_ALT_FLAG)) + + if (!(cpi->ref_frame_flags & VP8_ALT_FLAG)) { sf->thresh_mult[THR_NEARESTA ] = INT_MAX; sf->thresh_mult[THR_ZEROA ] = INT_MAX; @@ -763,7 +777,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_NEWA] = 4; } - if (cpi->ref_frame_flags & VP8_LAST_FLAG & VP8_GOLD_FLAG) + if (cpi->ref_frame_flags & VP8_GOLD_FLAG) { sf->thresh_mult[THR_NEARESTG ] = 2000; sf->thresh_mult[THR_ZEROG ] = 2000; @@ -771,7 +785,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_NEWG ] = 4000; } - if (cpi->ref_frame_flags & VP8_LAST_FLAG & VP8_ALT_FLAG) + if (cpi->ref_frame_flags & VP8_ALT_FLAG) { sf->thresh_mult[THR_NEARESTA ] = 2000; sf->thresh_mult[THR_ZEROA ] = 2000; @@ -811,7 +825,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->full_freq[1] = 31; sf->search_method = NSTEP; - if (!cpi->ref_frame_flags & VP8_LAST_FLAG) + if (!(cpi->ref_frame_flags & VP8_LAST_FLAG)) { sf->thresh_mult[THR_NEWMV ] = INT_MAX; sf->thresh_mult[THR_NEARESTMV] = INT_MAX; @@ -820,7 +834,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_SPLITMV ] = INT_MAX; } - if (!cpi->ref_frame_flags & VP8_GOLD_FLAG) + if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG)) { sf->thresh_mult[THR_NEARESTG ] = INT_MAX; sf->thresh_mult[THR_ZEROG ] = INT_MAX; @@ -829,7 +843,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_SPLITG ] = INT_MAX; } - if (!cpi->ref_frame_flags & VP8_ALT_FLAG) + if (!(cpi->ref_frame_flags & VP8_ALT_FLAG)) { sf->thresh_mult[THR_NEARESTA ] = INT_MAX; sf->thresh_mult[THR_ZEROA ] = INT_MAX; @@ -1122,40 +1136,33 @@ void vp8_set_speed_features(VP8_COMP *cpi) if (cpi->sf.search_method == NSTEP) { - vp8_init3smotion_compensation(&cpi->mb, cm->last_frame.y_stride); + vp8_init3smotion_compensation(&cpi->mb, cm->yv12_fb[cm->lst_fb_idx].y_stride); } else if (cpi->sf.search_method == DIAMOND) { - vp8_init_dsmotion_compensation(&cpi->mb, cm->last_frame.y_stride); + vp8_init_dsmotion_compensation(&cpi->mb, cm->yv12_fb[cm->lst_fb_idx].y_stride); } if (cpi->sf.improved_dct) { cpi->mb.vp8_short_fdct8x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short8x4); cpi->mb.vp8_short_fdct4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4); - cpi->mb.short_fdct8x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, short8x4); - cpi->mb.short_fdct4x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4); } else { cpi->mb.vp8_short_fdct8x4 = FDCT_INVOKE(&cpi->rtcd.fdct, fast8x4); cpi->mb.vp8_short_fdct4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, fast4x4); - cpi->mb.short_fdct8x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, fast8x4); - cpi->mb.short_fdct4x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, fast4x4); } - cpi->mb.vp8_short_fdct4x4_ptr = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4); cpi->mb.short_walsh4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, walsh_short4x4); if (cpi->sf.improved_quant) { cpi->mb.quantize_b = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb); - cpi->mb.quantize_brd = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb); } else { cpi->mb.quantize_b = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb); - cpi->mb.quantize_brd = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb); } #if CONFIG_RUNTIME_CPU_DETECT @@ -1221,6 +1228,20 @@ static void alloc_raw_frame_buffers(VP8_COMP *cpi) cpi->source_buffer_count = 0; } + +static int vp8_alloc_partition_data(VP8_COMP *cpi) +{ + cpi->mb.pip = vpx_calloc((cpi->common.mb_cols + 1) * + (cpi->common.mb_rows + 1), + sizeof(PARTITION_INFO)); + if(!cpi->mb.pip) + return ALLOC_FAILURE; + + cpi->mb.pi = cpi->mb.pip + cpi->common.mode_info_stride + 1; + + return 0; +} + void vp8_alloc_compressor_data(VP8_COMP *cpi) { VP8_COMMON *cm = & cpi->common; @@ -1232,6 +1253,11 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate frame buffers"); + if (vp8_alloc_partition_data(cpi)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to allocate partition data"); + + if ((width & 0xf) != 0) width += 16 - (width & 0xf); @@ -1262,6 +1288,15 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi) cpi->inter_zz_count = 0; cpi->gf_bad_count = 0; cpi->gf_update_recommended = 0; + + + // Structures used to minitor GF usage + if (cpi->gf_active_flags != 0) + vpx_free(cpi->gf_active_flags); + + CHECK_MEM_ERROR(cpi->gf_active_flags, vpx_calloc(1, cm->mb_rows * cm->mb_cols)); + + cpi->gf_active_count = cm->mb_rows * cm->mb_cols; } @@ -1309,14 +1344,26 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate) cpi->max_gf_interval = 12; - // Special conditions when altr ref frame enabled - if (cpi->oxcf.play_alternate) + // Special conditions when altr ref frame enabled in lagged compress mode + if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) { if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1) cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1; } } + +static int +rescale(int val, int num, int denom) +{ + int64_t llnum = num; + int64_t llden = denom; + int64_t llval = val; + + return llval * llnum / llden; +} + + void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) { VP8_COMP *cpi = (VP8_COMP *)(ptr); @@ -1344,9 +1391,9 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->oxcf.worst_allowed_q = MAXQ; cpi->oxcf.end_usage = USAGE_STREAM_FROM_SERVER; - cpi->oxcf.starting_buffer_level = 4; - cpi->oxcf.optimal_buffer_level = 5; - cpi->oxcf.maximum_buffer_size = 6; + cpi->oxcf.starting_buffer_level = 4000; + cpi->oxcf.optimal_buffer_level = 5000; + cpi->oxcf.maximum_buffer_size = 6000; cpi->oxcf.under_shoot_pct = 90; cpi->oxcf.allow_df = 0; cpi->oxcf.drop_frames_water_mark = 20; @@ -1495,26 +1542,32 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) // local file playback mode == really big buffer if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) { - cpi->oxcf.starting_buffer_level = 60; - cpi->oxcf.optimal_buffer_level = 60; - cpi->oxcf.maximum_buffer_size = 240; + cpi->oxcf.starting_buffer_level = 60000; + cpi->oxcf.optimal_buffer_level = 60000; + cpi->oxcf.maximum_buffer_size = 240000; } // Convert target bandwidth from Kbit/s to Bit/s cpi->oxcf.target_bandwidth *= 1000; - cpi->oxcf.starting_buffer_level *= cpi->oxcf.target_bandwidth; + cpi->oxcf.starting_buffer_level = + rescale(cpi->oxcf.starting_buffer_level, + cpi->oxcf.target_bandwidth, 1000); if (cpi->oxcf.optimal_buffer_level == 0) cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.optimal_buffer_level *= cpi->oxcf.target_bandwidth; + cpi->oxcf.optimal_buffer_level = + rescale(cpi->oxcf.optimal_buffer_level, + cpi->oxcf.target_bandwidth, 1000); if (cpi->oxcf.maximum_buffer_size == 0) cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.maximum_buffer_size *= cpi->oxcf.target_bandwidth; + cpi->oxcf.maximum_buffer_size = + rescale(cpi->oxcf.maximum_buffer_size, + cpi->oxcf.target_bandwidth, 1000); cpi->buffer_level = cpi->oxcf.starting_buffer_level; cpi->bits_off_target = cpi->oxcf.starting_buffer_level; @@ -1570,9 +1623,9 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; } - if (((cm->Width + 15) & 0xfffffff0) != cm->last_frame.y_width || - ((cm->Height + 15) & 0xfffffff0) != cm->last_frame.y_height || - cm->last_frame.y_width == 0) + if (((cm->Width + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_width || + ((cm->Height + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_height || + cm->yv12_fb[cm->lst_fb_idx].y_width == 0) { alloc_raw_frame_buffers(cpi); vp8_alloc_compressor_data(cpi); @@ -1599,13 +1652,6 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS) cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS; - // force play_alternate to 0 if allow_lag is 0, lag_in_frames is too small, Mode is real time or one pass compress enabled. - if (cpi->oxcf.allow_lag == 0 || cpi->oxcf.lag_in_frames <= 5 || (cpi->oxcf.Mode < MODE_SECONDPASS)) - { - cpi->oxcf.play_alternate = 0; - cpi->ref_frame_flags = cpi->ref_frame_flags & ~VP8_ALT_FLAG; - } - // YX Temp cpi->last_alt_ref_sei = -1; cpi->is_src_frame_alt_ref = 0; @@ -1774,26 +1820,32 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) // local file playback mode == really big buffer if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) { - cpi->oxcf.starting_buffer_level = 60; - cpi->oxcf.optimal_buffer_level = 60; - cpi->oxcf.maximum_buffer_size = 240; + cpi->oxcf.starting_buffer_level = 60000; + cpi->oxcf.optimal_buffer_level = 60000; + cpi->oxcf.maximum_buffer_size = 240000; } // Convert target bandwidth from Kbit/s to Bit/s cpi->oxcf.target_bandwidth *= 1000; - cpi->oxcf.starting_buffer_level *= cpi->oxcf.target_bandwidth; + cpi->oxcf.starting_buffer_level = + rescale(cpi->oxcf.starting_buffer_level, + cpi->oxcf.target_bandwidth, 1000); if (cpi->oxcf.optimal_buffer_level == 0) cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.optimal_buffer_level *= cpi->oxcf.target_bandwidth; + cpi->oxcf.optimal_buffer_level = + rescale(cpi->oxcf.optimal_buffer_level, + cpi->oxcf.target_bandwidth, 1000); if (cpi->oxcf.maximum_buffer_size == 0) cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8; else - cpi->oxcf.maximum_buffer_size *= cpi->oxcf.target_bandwidth; + cpi->oxcf.maximum_buffer_size = + rescale(cpi->oxcf.maximum_buffer_size, + cpi->oxcf.target_bandwidth, 1000); cpi->buffer_level = cpi->oxcf.starting_buffer_level; cpi->bits_off_target = cpi->oxcf.starting_buffer_level; @@ -1849,9 +1901,9 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; } - if (((cm->Width + 15) & 0xfffffff0) != cm->last_frame.y_width || - ((cm->Height + 15) & 0xfffffff0) != cm->last_frame.y_height || - cm->last_frame.y_width == 0) + if (((cm->Width + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_width || + ((cm->Height + 15) & 0xfffffff0) != cm->yv12_fb[cm->lst_fb_idx].y_height || + cm->yv12_fb[cm->lst_fb_idx].y_width == 0) { alloc_raw_frame_buffers(cpi); vp8_alloc_compressor_data(cpi); @@ -1878,13 +1930,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS) cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS; - // force play_alternate to 0 if allow_lag is 0, lag_in_frames is too small, Mode is real time or one pass compress enabled. - if (cpi->oxcf.allow_lag == 0 || cpi->oxcf.lag_in_frames <= 5 || (cpi->oxcf.Mode < MODE_SECONDPASS)) - { - cpi->oxcf.play_alternate = 0; - cpi->ref_frame_flags = cpi->ref_frame_flags & ~VP8_ALT_FLAG; - } - // YX Temp cpi->last_alt_ref_sei = -1; cpi->is_src_frame_alt_ref = 0; @@ -1925,7 +1970,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) VP8_COMP *cpi; VP8_PTR ptr; } ctx; - + VP8_COMP *cpi; VP8_COMMON *cm; @@ -2247,12 +2292,13 @@ void vp8_remove_compressor(VP8_PTR *ptr) if (cpi->b_calculate_psnr) { - double samples = 3.0 / 2 * cpi->count * cpi->common.last_frame.y_width * cpi->common.last_frame.y_height; + YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx]; + double samples = 3.0 / 2 * cpi->count * lst_yv12->y_width * lst_yv12->y_height; double total_psnr = vp8_mse2psnr(samples, 255.0, cpi->total_sq_error); double total_psnr2 = vp8_mse2psnr(samples, 255.0, cpi->total_sq_error2); double total_ssim = 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0); - fprintf(f, "Bitrate\AVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\tVPXSSIM\t Time(us)\n"); + fprintf(f, "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\tVPXSSIM\t Time(us)\n"); fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f %8.0f\n", dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim, total_encode_time); @@ -2586,19 +2632,19 @@ int vp8_get_reference(VP8_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONF { VP8_COMP *cpi = (VP8_COMP *)(ptr); VP8_COMMON *cm = &cpi->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 vp8_set_reference(VP8_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) @@ -2606,18 +2652,19 @@ int vp8_set_reference(VP8_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONF VP8_COMP *cpi = (VP8_COMP *)(ptr); VP8_COMMON *cm = &cpi->common; - if (ref_frame_flag == VP8_LAST_FLAG) - vp8_yv12_copy_frame_ptr(sd, &cm->last_frame); + int ref_fb_idx; + if (ref_frame_flag == VP8_LAST_FLAG) + 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; } int vp8_update_entropy(VP8_PTR comp, int update) @@ -2692,8 +2739,8 @@ static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) #endif } // we may need to copy to a buffer so we can extend the image... - else if (cm->Width != cm->last_frame.y_width || - cm->Height != cm->last_frame.y_height) + else if (cm->Width != cm->yv12_fb[cm->lst_fb_idx].y_width || + cm->Height != cm->yv12_fb[cm->lst_fb_idx].y_height) { //vp8_yv12_copy_frame_ptr(sd, &cpi->scaled_source); #if HAVE_ARMV7 @@ -2783,23 +2830,17 @@ static int pick_frame_size(VP8_COMP *cpi) cm->frame_type = KEY_FRAME; } - // Auto key frames (Only two pass will enter here) - else if (cm->frame_type == KEY_FRAME) - { - vp8_calc_auto_iframe_target_size(cpi); - } - // Forced key frames (by interval or an external signal) - else if ((cm->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && (cpi->frames_since_key % cpi->key_frame_frequency == 0))) + // Special case for forced key frames + // The frame sizing here is still far from ideal for 2 pass. + else if (cm->frame_flags & FRAMEFLAGS_KEY) { - // Key frame from VFW/auto-keyframe/first frame cm->frame_type = KEY_FRAME; - resize_key_frame(cpi); - - // Compute target frame size - if (cpi->pass != 2) - vp8_calc_iframe_target_size(cpi); + vp8_calc_iframe_target_size(cpi); + } + else if (cm->frame_type == KEY_FRAME) + { + vp8_calc_auto_iframe_target_size(cpi); } else { @@ -2846,7 +2887,7 @@ static void update_alt_ref_frame_and_stats(VP8_COMP *cpi) VP8_COMMON *cm = &cpi->common; // Update the golden frame buffer - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame); + vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]); // Select an interval before next GF or altref if (!cpi->auto_gold) @@ -2866,8 +2907,8 @@ static void update_alt_ref_frame_and_stats(VP8_COMP *cpi) } // Update data structure that monitors level of reference to last GF - vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); - cm->gf_active_count = cm->mb_rows * cm->mb_cols; + vpx_memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); + cpi->gf_active_count = cm->mb_rows * cm->mb_cols; // this frame refreshes means next frames don't unless specified by user cpi->common.frames_since_golden = 0; @@ -2888,7 +2929,7 @@ static void update_golden_frame_and_stats(VP8_COMP *cpi) if (cm->refresh_golden_frame) { // Update the golden frame buffer - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame); + vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]); // Select an interval before next GF if (!cpi->auto_gold) @@ -2914,8 +2955,8 @@ static void update_golden_frame_and_stats(VP8_COMP *cpi) } // Update data structure that monitors level of reference to last GF - vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); - cm->gf_active_count = cm->mb_rows * cm->mb_cols; + vpx_memset(cpi->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols)); + cpi->gf_active_count = cm->mb_rows * cm->mb_cols; // this frame refreshes means next frames don't unless specified by user cm->refresh_golden_frame = 0; @@ -3220,10 +3261,31 @@ void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) } #endif // return of 0 means drop frame - +#define USE_FILTER_LUT 1 #if VP8_TEMPORAL_ALT_REF + +#if USE_FILTER_LUT +static int modifier_lut[7][19] = +{ + // Strength=0 + {16, 13, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + // Strength=1 + {16, 15, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + // Strength=2 + {16, 15, 13, 9, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + // Strength=3 + {16, 16, 15, 13, 10, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + // Strength=4 + {16, 16, 15, 14, 13, 11, 9, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + // Strength=5 + {16, 16, 16, 15, 15, 14, 13, 11, 10, 8, 7, 5, 3, 0, 0, 0, 0, 0, 0}, + // Strength=6 + {16, 16, 16, 16, 15, 15, 14, 14, 13, 12, 11, 10, 9, 8, 7, 5, 4, 2, 1} +}; +#endif static void vp8cx_temp_blur1_c ( + VP8_COMP *cpi, unsigned char **frames, int frame_count, unsigned char *src, @@ -3237,22 +3299,24 @@ static void vp8cx_temp_blur1_c unsigned char block_size ) { - int byte = 0; // Buffer offset for the current pixel value being filtered + int byte = 0; // Buffer offset for current pixel being filtered int frame = 0; int modifier = 0; int i, j, k; int block_ofset; - int Cols, Rows; + int cols; unsigned char Shift = (block_size == 16) ? 4 : 3; +#if USE_FILTER_LUT + int *lut = modifier_lut[strength]; +#endif - Cols = width / block_size; - Rows = height / block_size; + cols = cpi->common.mb_cols; for (i = 0; i < height; i++) { - block_ofset = (i >> Shift) * Cols; + block_ofset = (i >> Shift) * cols; - for (j = 0; j < Cols; j ++) + for (j = 0; j < cols; j ++) { if (motion_map_ptr[block_ofset] > 2) { @@ -3270,9 +3334,14 @@ static void vp8cx_temp_blur1_c for (frame = 0; frame < frame_count; frame++) { // get current frame pixel value - int pixel_value = frames[frame][byte]; // int pixel_value = *frameptr; - - modifier = src_byte; // modifier = s[byte]; + int pixel_value = frames[frame][byte]; +#if USE_FILTER_LUT + // LUT implementation -- + // improves precision of filter + modifier = abs(src_byte-pixel_value); + modifier = modifier>18 ? 0 : lut[modifier]; +#else + modifier = src_byte; modifier -= pixel_value; modifier *= modifier; modifier >>= strength; @@ -3282,17 +3351,17 @@ static void vp8cx_temp_blur1_c modifier = 16; modifier = 16 - modifier; - +#endif accumulator += modifier * pixel_value; count += modifier; } accumulator += (count >> 1); - accumulator *= fixed_divide[count]; // accumulator *= ppi->fixed_divide[count]; + accumulator *= fixed_divide[count]; accumulator >>= 16; - dst[byte] = accumulator; // d[byte] = accumulator; + dst[byte] = accumulator; // move to next pixel byte++; @@ -3398,7 +3467,8 @@ static void vp8cx_temp_filter_c { if ((frames_to_blur_backward + frames_to_blur_forward) >= max_frames) { - frames_to_blur_backward = max_frames - frames_to_blur_forward - 1; + frames_to_blur_backward + = max_frames - frames_to_blur_forward - 1; } } else @@ -3441,6 +3511,7 @@ static void vp8cx_temp_filter_c // Blur Y vp8cx_temp_blur1_c( + cpi, cpi->frames, frames_to_blur, temp_source_buffer->y_buffer, // cpi->Source->y_buffer, @@ -3455,7 +3526,7 @@ static void vp8cx_temp_filter_c for (frame = 0; frame < frames_to_blur; frame++) { - int which_buffer = cpi->last_alt_ref_sei - frame; + int which_buffer = start_frame - frame; if (which_buffer < 0) which_buffer += cpi->oxcf.lag_in_frames; @@ -3465,6 +3536,7 @@ static void vp8cx_temp_filter_c // Blur U vp8cx_temp_blur1_c( + cpi, cpi->frames, frames_to_blur, temp_source_buffer->u_buffer, @@ -3479,7 +3551,7 @@ static void vp8cx_temp_filter_c for (frame = 0; frame < frames_to_blur; frame++) { - int which_buffer = cpi->last_alt_ref_sei - frame; + int which_buffer = start_frame - frame; if (which_buffer < 0) which_buffer += cpi->oxcf.lag_in_frames; @@ -3489,6 +3561,7 @@ static void vp8cx_temp_filter_c // Blur V vp8cx_temp_blur1_c( + cpi, cpi->frames, frames_to_blur, temp_source_buffer->v_buffer, @@ -4277,7 +4350,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign // Update the GF useage maps. // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter - vp8_update_gf_useage_maps(cm, &cpi->mb.e_mbd); + vp8_update_gf_useage_maps(cpi, cm, &cpi->mb); if (cm->frame_type == KEY_FRAME) cm->refresh_last_frame = 1; @@ -4285,7 +4358,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign if (0) { FILE *f = fopen("gfactive.stt", "a"); - fprintf(f, "%8d %8d %8d %8d %8d\n", cm->current_video_frame, (100 * cpi->common.gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols), cpi->this_iiratio, cpi->next_iiratio, cm->refresh_golden_frame); + fprintf(f, "%8d %8d %8d %8d %8d\n", cm->current_video_frame, (100 * cpi->gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols), cpi->this_iiratio, cpi->next_iiratio, cm->refresh_golden_frame); fclose(f); } @@ -4298,11 +4371,11 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign if (cm->refresh_last_frame) { - vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame); - cm->frame_to_show = &cm->last_frame; + vp8_swap_yv12_buffer(&cm->yv12_fb[cm->lst_fb_idx], &cm->yv12_fb[cm->new_fb_idx]); + cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx]; } else - cm->frame_to_show = &cm->new_frame; + cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; @@ -4352,43 +4425,48 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign } } - - // At this point the new frame has been encoded coded. - // If any buffer copy / swaping is signalled it should be done here. - if (cm->frame_type == KEY_FRAME) { - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame); - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame); - } - else // For non key frames - { - // Code to copy between reference buffers - if (cm->copy_buffer_to_arf) + YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx]; + YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx]; + YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx]; + YV12_BUFFER_CONFIG *alt_yv12 = &cm->yv12_fb[cm->alt_fb_idx]; + // At this point the new frame has been encoded coded. + // If any buffer copy / swaping is signalled it should be done here. + if (cm->frame_type == KEY_FRAME) { - if (cm->copy_buffer_to_arf == 1) + vp8_yv12_copy_frame_ptr(cm->frame_to_show, gld_yv12); + vp8_yv12_copy_frame_ptr(cm->frame_to_show, alt_yv12); + } + else // For non key frames + { + // Code to copy between reference buffers + if (cm->copy_buffer_to_arf) { - if (cm->refresh_last_frame) - // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. - 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); + if (cm->copy_buffer_to_arf == 1) + { + if (cm->refresh_last_frame) + // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. + vp8_yv12_copy_frame_ptr(new_yv12, alt_yv12); + else + vp8_yv12_copy_frame_ptr(lst_yv12, alt_yv12); + } + else if (cm->copy_buffer_to_arf == 2) + vp8_yv12_copy_frame_ptr(gld_yv12, alt_yv12); } - 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->copy_buffer_to_gf) { - if (cm->refresh_last_frame) - // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. - vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame); - else - vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame); + if (cm->copy_buffer_to_gf == 1) + { + if (cm->refresh_last_frame) + // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set. + vp8_yv12_copy_frame_ptr(new_yv12, gld_yv12); + else + vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12); + } + else if (cm->copy_buffer_to_gf == 2) + vp8_yv12_copy_frame_ptr(alt_yv12, gld_yv12); } - else if (cm->copy_buffer_to_gf == 2) - vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame); } } @@ -4591,23 +4669,23 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG; if (cpi->gold_is_last) - cpi->ref_frame_flags &= !VP8_GOLD_FLAG; + cpi->ref_frame_flags &= ~VP8_GOLD_FLAG; if (cpi->alt_is_last) - cpi->ref_frame_flags &= !VP8_ALT_FLAG; + cpi->ref_frame_flags &= ~VP8_ALT_FLAG; if (cpi->gold_is_alt) - cpi->ref_frame_flags &= !VP8_ALT_FLAG; + cpi->ref_frame_flags &= ~VP8_ALT_FLAG; if (cpi->oxcf.error_resilient_mode) { // Is this an alternate reference update if (cpi->common.refresh_alt_ref_frame) - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame); + vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]); if (cpi->common.refresh_golden_frame) - vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame); + vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]); } else { @@ -4659,7 +4737,8 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsign FILE *recon_file; sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame); recon_file = fopen(filename, "wb"); - fwrite(cm->last_frame.buffer_alloc, cm->last_frame.frame_size, 1, recon_file); + fwrite(cm->yv12_fb[cm->lst_fb_idx].buffer_alloc, + cm->yv12_fb[cm->lst_fb_idx].frame_size, 1, recon_file); fclose(recon_file); } @@ -4683,7 +4762,7 @@ int vp8_is_gf_update_needed(VP8_PTR ptr) void vp8_check_gf_quality(VP8_COMP *cpi) { VP8_COMMON *cm = &cpi->common; - int gf_active_pct = (100 * cm->gf_active_count) / (cm->mb_rows * cm->mb_cols); + int gf_active_pct = (100 * cpi->gf_active_count) / (cm->mb_rows * cm->mb_cols); int gf_ref_usage_pct = (cpi->count_mb_ref_frame_usage[GOLDEN_FRAME] * 100) / (cm->mb_rows * cm->mb_cols); int last_ref_zz_useage = (cpi->inter_zz_count * 100) / (cm->mb_rows * cm->mb_cols); @@ -4739,7 +4818,6 @@ void vp8_check_gf_quality(VP8_COMP *cpi) #if !(CONFIG_REALTIME_ONLY) static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) { - double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100); if (!cpi->common.refresh_alt_ref_frame) vp8_second_pass(cpi); @@ -4748,7 +4826,11 @@ static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, cpi->bits_left -= 8 * *size; if (!cpi->common.refresh_alt_ref_frame) + { + double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth + *cpi->oxcf.two_pass_vbrmin_section / 100); cpi->bits_left += (long long)(two_pass_min_rate / cpi->oxcf.frame_rate); + } } #endif @@ -4959,20 +5041,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon { if (cpi->source_encode_index == cpi->last_alt_ref_sei) { -#if VP8_TEMPORAL_ALT_REF - - if (cpi->oxcf.arnr_max_frames == 0) - { - cpi->is_src_frame_alt_ref = 1; // copy alt ref - } - else - { - cpi->is_src_frame_alt_ref = 0; - } - -#else cpi->is_src_frame_alt_ref = 1; -#endif cpi->last_alt_ref_sei = -1; } else @@ -5140,8 +5209,6 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon { // return to normal state - cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG; - cm->refresh_entropy_probs = 1; cm->refresh_alt_ref_frame = 0; cm->refresh_golden_frame = 0; @@ -5402,7 +5469,7 @@ int vp8_calc_low_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, co { for (j = 0; j < source->y_width; j += 16) { - unsigned int sse, sse2, sum2; + unsigned int sse; VARIANCE_INVOKE(rtcd, mse16x16)(src + j, source->y_stride, dst + j, dest->y_stride, &sse); if (sse < 8096) |