diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 470a9ac84..e0d1d7043 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2029,7 +2029,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE; // Experimental cq target value - cpi->cq_target_quality = oxcf->cq_level; + cpi->cq_target_quality = cpi->oxcf.cq_level; cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth; @@ -3519,14 +3519,29 @@ static BOOL recode_loop_test( VP8_COMP *cpi, { // General over and under shoot tests if ( ((cpi->projected_frame_size > high_limit) && (q < maxq)) || - ((cpi->projected_frame_size < low_limit) && (q > minq)) || - ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (q > cpi->cq_target_quality) && - (cpi->projected_frame_size < - ((cpi->this_frame_target * 7) >> 3))) ) + ((cpi->projected_frame_size < low_limit) && (q > minq)) ) { force_recode = TRUE; } + // Special Constrained quality tests + else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) + { + // Undershoot and below auto cq level + if ( (q > cpi->cq_target_quality) && + (cpi->projected_frame_size < + ((cpi->this_frame_target * 7) >> 3))) + { + force_recode = TRUE; + } + // Severe undershoot and between auto and user cq level + else if ( (q > cpi->oxcf.cq_level) && + (cpi->projected_frame_size < cpi->min_frame_bandwidth) && + (cpi->active_best_quality > cpi->oxcf.cq_level)) + { + force_recode = TRUE; + cpi->active_best_quality = cpi->oxcf.cq_level; + } + } } return force_recode; @@ -3853,7 +3868,13 @@ static void encode_frame_to_data_rate if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && (cpi->active_best_quality < cpi->cq_target_quality) ) { - cpi->active_best_quality = cpi->cq_target_quality; + // If we are strongly undershooting the target rate in the last + // frames then use the user passed in cq value not the auto + // cq value. + if ( cpi->rolling_actual_bits < cpi->min_frame_bandwidth ) + cpi->active_best_quality = cpi->oxcf.cq_level; + else + cpi->active_best_quality = cpi->cq_target_quality; } } @@ -4219,6 +4240,16 @@ static void encode_frame_to_data_rate Q = vp8_regulate_q(cpi, cpi->this_frame_target); + // Special case reset for qlow for constrained quality. + // This should only trigger where there is very substantial + // undershoot on a frame and the auto cq level is above + // the user passsed in value. + if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (Q < q_low) ) + { + q_low = Q; + } + while (((Q > q_high) || (cpi->zbin_over_quant > zbin_oq_high)) && (Retries < 10)) { vp8_update_rate_correction_factors(cpi, 0); diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 8dfca351c..2b0f57508 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -608,8 +608,10 @@ int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int rec memcpy(mdcounts, MDCounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts)); } - //Only consider ZEROMV/ALTREF_FRAME for alt ref frame. - if (cpi->is_src_frame_alt_ref) + // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, + // unless ARNR filtering is enabled in which case we want + // an unfiltered alternative + if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { if (this_mode != ZEROMV || x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) continue; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index bab7ca12d..b2a3e117f 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1849,8 +1849,10 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index]; - //Only consider ZEROMV/ALTREF_FRAME for alt ref frame. - if (cpi->is_src_frame_alt_ref) + // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, + // unless ARNR filtering is enabled in which case we want + // an unfiltered alternative + if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { if (this_mode != ZEROMV || x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) continue; diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c index 396e3390d..f28daaff9 100644 --- a/vp8/encoder/temporal_filter.c +++ b/vp8/encoder/temporal_filter.c @@ -290,8 +290,8 @@ static void vp8_temporal_filter_iterate_c int mb_col, mb_row; unsigned int filter_weight[MAX_LAG_BUFFERS]; unsigned char *mm_ptr = cpi->fp_motion_map; - int cols = cpi->common.mb_cols; - int rows = cpi->common.mb_rows; + int mb_cols = cpi->common.mb_cols; + int mb_rows = cpi->common.mb_rows; int MBs = cpi->common.MBs; int mb_y_offset = 0; int mb_uv_offset = 0; @@ -314,7 +314,7 @@ static void vp8_temporal_filter_iterate_c filter_weight[frame] = 1; } - for (mb_row = 0; mb_row < rows; mb_row++) + for (mb_row = 0; mb_row < mb_rows; mb_row++) { #if ALT_REF_MC_ENABLED // Reduced search extent by 3 for 6-tap filter & smaller UMV border @@ -323,7 +323,7 @@ static void vp8_temporal_filter_iterate_c + (VP8BORDERINPIXELS - 19); #endif - for (mb_col = 0; mb_col < cols; mb_col++) + for (mb_col = 0; mb_col < mb_cols; mb_col++) { int i, j, k, w; int weight_cap; @@ -497,8 +497,8 @@ static void vp8_temporal_filter_iterate_c mb_uv_offset += 8; } - mb_y_offset += 16*f->y_stride-f->y_width; - mb_uv_offset += 8*f->uv_stride-f->uv_width; + mb_y_offset += 16*(f->y_stride-mb_cols); + mb_uv_offset += 8*(f->uv_stride-mb_cols); } // Restore input state