diff options
-rw-r--r-- | vp8/encoder/onyx_if.c | 27 | ||||
-rw-r--r-- | vp9/encoder/vp9_aq_cyclicrefresh.c | 67 | ||||
-rw-r--r-- | vp9/encoder/vp9_aq_cyclicrefresh.h | 11 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 5 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 46 | ||||
-rw-r--r-- | vp9/encoder/vp9_pickmode.c | 19 | ||||
-rw-r--r-- | vp9/encoder/vp9_rd.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_resize.c | 4 | ||||
-rw-r--r-- | vp9/encoder/x86/vp9_dct_sse2.c | 2 | ||||
-rw-r--r-- | vp9/encoder/x86/vp9_dct_ssse3.c | 2 | ||||
-rw-r--r-- | vp9/vp9_cx_iface.c | 22 |
11 files changed, 137 insertions, 69 deletions
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 53d9fbbde..becc07c1a 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2270,9 +2270,6 @@ void vp8_remove_compressor(VP8_COMP **ptr) if (cpi->b_calculate_psnr) { - YV12_BUFFER_CONFIG *lst_yv12 = - &cpi->common.yv12_fb[cpi->common.lst_fb_idx]; - if (cpi->oxcf.number_of_layers > 1) { int i; @@ -2284,7 +2281,7 @@ void vp8_remove_compressor(VP8_COMP **ptr) double dr = (double)cpi->bytes_in_layer[i] * 8.0 / 1000.0 / time_encoded; double samples = 3.0 / 2 * cpi->frames_in_layer[i] * - lst_yv12->y_width * lst_yv12->y_height; + cpi->common.Width * cpi->common.Height; double total_psnr = vpx_sse_to_psnr(samples, 255.0, cpi->total_error2[i]); @@ -2306,7 +2303,7 @@ void vp8_remove_compressor(VP8_COMP **ptr) else { double samples = 3.0 / 2 * cpi->count * - lst_yv12->y_width * lst_yv12->y_height; + cpi->common.Width * cpi->common.Height; double total_psnr = vpx_sse_to_psnr(samples, 255.0, cpi->total_sq_error); double total_psnr2 = vpx_sse_to_psnr(samples, 255.0, @@ -5673,19 +5670,23 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l double frame_psnr; YV12_BUFFER_CONFIG *orig = cpi->Source; YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; - int y_samples = orig->y_height * orig->y_width ; - int uv_samples = orig->uv_height * orig->uv_width ; + unsigned int y_width = cpi->common.Width; + unsigned int y_height = cpi->common.Height; + unsigned int uv_width = (y_width + 1) / 2; + unsigned int uv_height = (y_height + 1) / 2; + int y_samples = y_height * y_width; + int uv_samples = uv_height * uv_width; int t_samples = y_samples + 2 * uv_samples; double sq_error; ye = calc_plane_error(orig->y_buffer, orig->y_stride, - recon->y_buffer, recon->y_stride, orig->y_width, orig->y_height); + recon->y_buffer, recon->y_stride, y_width, y_height); ue = calc_plane_error(orig->u_buffer, orig->uv_stride, - recon->u_buffer, recon->uv_stride, orig->uv_width, orig->uv_height); + recon->u_buffer, recon->uv_stride, uv_width, uv_height); ve = calc_plane_error(orig->v_buffer, orig->uv_stride, - recon->v_buffer, recon->uv_stride, orig->uv_width, orig->uv_height); + recon->v_buffer, recon->uv_stride, uv_width, uv_height); sq_error = (double)(ye + ue + ve); @@ -5707,13 +5708,13 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l vp8_clear_system_state(); ye = calc_plane_error(orig->y_buffer, orig->y_stride, - pp->y_buffer, pp->y_stride, orig->y_width, orig->y_height); + pp->y_buffer, pp->y_stride, y_width, y_height); ue = calc_plane_error(orig->u_buffer, orig->uv_stride, - pp->u_buffer, pp->uv_stride, orig->uv_width, orig->uv_height); + pp->u_buffer, pp->uv_stride, uv_width, uv_height); ve = calc_plane_error(orig->v_buffer, orig->uv_stride, - pp->v_buffer, pp->uv_stride, orig->uv_width, orig->uv_height); + pp->v_buffer, pp->uv_stride, uv_width, uv_height); sq_error2 = (double)(ye + ue + ve); diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index 958d52acf..4bd083c27 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -30,10 +30,11 @@ struct CYCLIC_REFRESH { // excess of the cycle time, i.e., in the case of all zero motion, block // will be refreshed every (100/percent_refresh + time_for_refresh) frames. int time_for_refresh; - // // Target number of (8x8) blocks that are set for delta-q (segment 1). + // Target number of (8x8) blocks that are set for delta-q. int target_num_seg_blocks; - // Actual number of (8x8) blocks that were applied delta-q (segment 1). - int actual_num_seg_blocks; + // Actual number of (8x8) blocks that were applied delta-q. + int actual_num_seg1_blocks; + int actual_num_seg2_blocks; // RD mult. parameters for segment 1. int rdmult; // Cyclic refresh map. @@ -48,6 +49,8 @@ struct CYCLIC_REFRESH { // Rate target ratio to set q delta. double rate_ratio_qdelta; double low_content_avg; + int qindex_delta_seg1; + int qindex_delta_seg2; }; CYCLIC_REFRESH *vp9_cyclic_refresh_alloc(int mi_rows, int mi_cols) { @@ -110,7 +113,7 @@ static int candidate_refresh_aq(const CYCLIC_REFRESH *cr, mv.col > cr->motion_thresh || mv.col < -cr->motion_thresh || !is_inter_block(mbmi))) return CR_SEGMENT_ID_BASE; - else if (bsize >= BLOCK_32X32 && + else if (bsize >= BLOCK_16X16 && rate < cr->thresh_rate_sb && is_inter_block(mbmi) && mbmi->mv[0].as_int == 0) @@ -146,15 +149,19 @@ int vp9_cyclic_refresh_estimate_bits_at_q(const VP9_COMP *cpi, int num8x8bl = mbs << 2; // Weight for non-base segments: use actual number of blocks refreshed in // previous/just encoded frame. Note number of blocks here is in 8x8 units. - double weight_segment = (double)cr->actual_num_seg_blocks / num8x8bl; - // Compute delta-q that was used in the just encoded frame. - int deltaq = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta); + double weight_segment1 = (double)cr->actual_num_seg1_blocks / num8x8bl; + double weight_segment2 = (double)cr->actual_num_seg2_blocks / num8x8bl; // Take segment weighted average for estimated bits. - estimated_bits = (int)((1.0 - weight_segment) * + estimated_bits = (int)((1.0 - weight_segment1 - weight_segment2) * vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex, mbs, correction_factor, cm->bit_depth) + - weight_segment * - vp9_estimate_bits_at_q(cm->frame_type, cm->base_qindex + deltaq, mbs, + weight_segment1 * + vp9_estimate_bits_at_q(cm->frame_type, + cm->base_qindex + cr->qindex_delta_seg1, mbs, + correction_factor, cm->bit_depth) + + weight_segment2 * + vp9_estimate_bits_at_q(cm->frame_type, + cm->base_qindex + cr->qindex_delta_seg2, mbs, correction_factor, cm->bit_depth)); return estimated_bits; } @@ -170,15 +177,11 @@ int vp9_cyclic_refresh_rc_bits_per_mb(const VP9_COMP *cpi, int i, CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; int bits_per_mb; int num8x8bl = cm->MBs << 2; - // Weight for segment 1 prior to encoding: take the target number for the - // frame to be encoded. Number of blocks here is in 8x8 units. - // Note that this is called in rc_regulate_q, which is called before the - // cyclic_refresh_setup (which sets cr->target_num_seg_blocks). So a mismatch - // may occur between the cr->target_num_seg_blocks value here and the - // cr->target_num_seg_block set for encoding the frame. For the current use - // case of fixed cr->percent_refresh and cr->time_for_refresh = 0, mismatch - // does not occur/is very small. - double weight_segment = (double)cr->target_num_seg_blocks / num8x8bl; + // Weight for segment prior to encoding: take the average of the target + // number for the frame to be encoded and the actual from the previous frame. + double weight_segment = (double)((cr->target_num_seg_blocks + + cr->actual_num_seg1_blocks + cr->actual_num_seg2_blocks) >> 1) / + num8x8bl; // Compute delta-q corresponding to qindex i. int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta); // Take segment weighted average for bits per mb. @@ -198,7 +201,8 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, int mi_row, int mi_col, BLOCK_SIZE bsize, int64_t rate, - int64_t dist) { + int64_t dist, + int skip) { const VP9_COMMON *const cm = &cpi->common; CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; const int bw = num_8x8_blocks_wide_lookup[bsize]; @@ -214,8 +218,12 @@ void vp9_cyclic_refresh_update_segment(VP9_COMP *const cpi, // If this block is labeled for refresh, check if we should reset the // segment_id. - if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) + if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) { mbmi->segment_id = refresh_this_block; + // Reset segment_id if will be skipped. + if (skip) + mbmi->segment_id = CR_SEGMENT_ID_BASE; + } // Update the cyclic refresh map, to be used for setting segmentation map // for the next frame. If the block will be refreshed this frame, mark it @@ -250,12 +258,16 @@ void vp9_cyclic_refresh_postencode(VP9_COMP *const cpi) { CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; unsigned char *const seg_map = cpi->segmentation_map; int mi_row, mi_col; - cr->actual_num_seg_blocks = 0; + cr->actual_num_seg1_blocks = 0; + cr->actual_num_seg2_blocks = 0; for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) { - if (cyclic_refresh_segment_id_boosted( - seg_map[mi_row * cm->mi_cols + mi_col])) - cr->actual_num_seg_blocks++; + if (cyclic_refresh_segment_id( + seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST1) + cr->actual_num_seg1_blocks++; + else if (cyclic_refresh_segment_id( + seg_map[mi_row * cm->mi_cols + mi_col]) == CR_SEGMENT_ID_BOOST2) + cr->actual_num_seg2_blocks++; } } @@ -413,7 +425,7 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { cr->time_for_refresh = 0; // Set rate threshold to some multiple (set to 2 for now) of the target // rate (target is given by sb64_target_rate and scaled by 256). - cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 1; + cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2; // Distortion threshold, quadratic in Q, scale factor to be adjusted. // q will not exceed 457, so (q * q) is within 32bit; see: // vp9_convert_qindex_to_q(), vp9_ac_quant(), ac_qlookup*[]. @@ -442,9 +454,11 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { // Set the q delta for segment BOOST1. qindex_delta = compute_deltaq(cpi, cm->base_qindex, cr->rate_ratio_qdelta); + cr->qindex_delta_seg1 = qindex_delta; // Compute rd-mult for segment BOOST1. qindex2 = clamp(cm->base_qindex + cm->y_dc_delta_q + qindex_delta, 0, MAXQ); + cr->rdmult = vp9_compute_rd_mult(cpi, qindex2); vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta); @@ -453,6 +467,7 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { qindex_delta = compute_deltaq(cpi, cm->base_qindex, MIN(CR_MAX_RATE_TARGET_RATIO, CR_BOOST2_FAC * cr->rate_ratio_qdelta)); + cr->qindex_delta_seg2 = qindex_delta; vp9_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta); // Update the segmentation and refresh map. diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.h b/vp9/encoder/vp9_aq_cyclicrefresh.h index 34224c1d3..21f114b5e 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.h +++ b/vp9/encoder/vp9_aq_cyclicrefresh.h @@ -55,7 +55,7 @@ int vp9_cyclic_refresh_rc_bits_per_mb(const struct VP9_COMP *cpi, int i, void vp9_cyclic_refresh_update_segment(struct VP9_COMP *const cpi, MB_MODE_INFO *const mbmi, int mi_row, int mi_col, BLOCK_SIZE bsize, - int64_t rate, int64_t dist); + int64_t rate, int64_t dist, int skip); // Update the segmentation map, and related quantities: cyclic refresh map, // refresh sb_index, and target number of blocks to be refreshed. @@ -83,6 +83,15 @@ static INLINE int cyclic_refresh_segment_id_boosted(int segment_id) { segment_id == CR_SEGMENT_ID_BOOST2; } +static INLINE int cyclic_refresh_segment_id(int segment_id) { + if (segment_id == CR_SEGMENT_ID_BOOST1) + return CR_SEGMENT_ID_BOOST1; + else if (segment_id == CR_SEGMENT_ID_BOOST2) + return CR_SEGMENT_ID_BOOST2; + else + return CR_SEGMENT_ID_BASE; +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index ac9de21cc..9aeb9f8f7 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -868,7 +868,8 @@ static void update_state(VP9_COMP *cpi, ThreadData *td, // and then update the quantizer. if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi, mi_row, - mi_col, bsize, ctx->rate, ctx->dist); + mi_col, bsize, ctx->rate, ctx->dist, + x->skip); } } @@ -1557,7 +1558,7 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td, } else { // Setting segmentation map for cyclic_refresh. vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize, - ctx->rate, ctx->dist); + ctx->rate, ctx->dist, x->skip); } vp9_init_plane_quantizers(cpi, x); } diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 441fa7d76..43d403469 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -1323,6 +1323,32 @@ static void highbd_set_var_fns(VP9_COMP *const cpi) { } #endif // CONFIG_VP9_HIGHBITDEPTH +static void realloc_segmentation_maps(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + + // Create the encoder segmentation map and set all entries to 0 + vpx_free(cpi->segmentation_map); + CHECK_MEM_ERROR(cm, cpi->segmentation_map, + vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); + + // Create a map used for cyclic background refresh. + if (cpi->cyclic_refresh) + vp9_cyclic_refresh_free(cpi->cyclic_refresh); + CHECK_MEM_ERROR(cm, cpi->cyclic_refresh, + vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols)); + + // Create a map used to mark inactive areas. + vpx_free(cpi->active_map.map); + CHECK_MEM_ERROR(cm, cpi->active_map.map, + vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); + + // And a place holder structure is the coding context + // for use if we want to save and restore it + vpx_free(cpi->coding_context.last_frame_seg_map_copy); + CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy, + vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); +} + void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; @@ -1384,7 +1410,8 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { if (cpi->initial_width) { if (cm->width > cpi->initial_width || cm->height > cpi->initial_height) { vp9_free_context_buffers(cm); - vp9_alloc_context_buffers(cm, cm->width, cm->height); + vp9_alloc_compressor_data(cpi); + realloc_segmentation_maps(cpi); cpi->initial_width = cpi->initial_height = 0; } } @@ -1499,22 +1526,7 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf, cpi->partition_search_skippable_frame = 0; cpi->tile_data = NULL; - // TODO(aconverse): Realloc these tables on frame resize - // Create the encoder segmentation map and set all entries to 0 - CHECK_MEM_ERROR(cm, cpi->segmentation_map, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); - - // Create a map used for cyclic background refresh. - CHECK_MEM_ERROR(cm, cpi->cyclic_refresh, - vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols)); - - CHECK_MEM_ERROR(cm, cpi->active_map.map, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); - - // And a place holder structure is the coding context - // for use if we want to save and restore it - CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy, - vpx_calloc(cm->mi_rows * cm->mi_cols, 1)); + realloc_segmentation_maps(cpi); CHECK_MEM_ERROR(cm, cpi->nmvcosts[0], vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts[0]))); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 7c1a93062..6dfb9eedd 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -681,6 +681,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready; int ref_frame_skip_mask = 0; int idx; + int best_pred_sad = INT_MAX; if (reuse_inter_pred) { int i; @@ -723,12 +724,14 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, #if CONFIG_VP9_TEMPORAL_DENOISING vp9_denoiser_reset_frame_stats(ctx); #endif + if (cpi->rc.frames_since_golden == 0) { - ref_frame_skip_mask |= (1 << GOLDEN_FRAME); + cpi->ref_frame_flags &= (~VP9_GOLD_FLAG); usable_ref_frame = LAST_FRAME; } else { usable_ref_frame = GOLDEN_FRAME; } + for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) { const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); @@ -809,8 +812,11 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, continue; tmp_sad = vp9_int_pro_motion_estimation(cpi, x, bsize); + if (tmp_sad > x->pred_mv_sad[LAST_FRAME]) continue; + if (tmp_sad + (num_pels_log2_lookup[bsize] << 4) > best_pred_sad) + continue; frame_mv[NEWMV][ref_frame].as_int = mbmi->mv[0].as_int; rate_mv = vp9_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, @@ -835,6 +841,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, } } + if (this_mode == NEWMV && ref_frame == LAST_FRAME && + frame_mv[NEWMV][LAST_FRAME].as_int != INVALID_MV) { + const int pre_stride = xd->plane[0].pre[0].stride; + const uint8_t * const pre_buf = xd->plane[0].pre[0].buf + + (frame_mv[NEWMV][LAST_FRAME].as_mv.row >> 3) * pre_stride + + (frame_mv[NEWMV][LAST_FRAME].as_mv.col >> 3); + best_pred_sad = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, + x->plane[0].src.stride, + pre_buf, pre_stride); + } + if (this_mode != NEARESTMV && frame_mv[this_mode][ref_frame].as_int == frame_mv[NEARESTMV][ref_frame].as_int) diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c index caa9cae69..ae5a01226 100644 --- a/vp9/encoder/vp9_rd.c +++ b/vp9/encoder/vp9_rd.c @@ -467,6 +467,7 @@ void vp9_mv_pred(VP9_COMP *cpi, MACROBLOCK *x, pred_mv[0] = mbmi->ref_mvs[ref_frame][0].as_mv; pred_mv[1] = mbmi->ref_mvs[ref_frame][1].as_mv; pred_mv[2] = x->pred_mv[ref_frame]; + assert(num_mv_refs <= (int)(sizeof(pred_mv) / sizeof(pred_mv[0]))); // Get the sad for each candidate reference mv. for (i = 0; i < num_mv_refs; ++i) { diff --git a/vp9/encoder/vp9_resize.c b/vp9/encoder/vp9_resize.c index 3d361d4f2..2ebdff291 100644 --- a/vp9/encoder/vp9_resize.c +++ b/vp9/encoder/vp9_resize.c @@ -516,6 +516,10 @@ void vp9_resize_plane(const uint8_t *const input, uint8_t *tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * (width < height ? height : width)); uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * (height + height2)); + assert(width > 0); + assert(height > 0); + assert(width2 > 0); + assert(height2 > 0); for (i = 0; i < height; ++i) resize_multistep(input + in_stride * i, width, intbuf + width2 * i, width2, tmpbuf); diff --git a/vp9/encoder/x86/vp9_dct_sse2.c b/vp9/encoder/x86/vp9_dct_sse2.c index 279074ce3..564b7955e 100644 --- a/vp9/encoder/x86/vp9_dct_sse2.c +++ b/vp9/encoder/x86/vp9_dct_sse2.c @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <assert.h> #include <emmintrin.h> // SSE2 #include "vp9/common/vp9_idct.h" // for cospi constants #include "vp9/encoder/vp9_dct.h" @@ -610,6 +611,7 @@ void vp9_fdct8x8_quant_sse2(const int16_t *input, int stride, __m128i qcoeff0, qcoeff1; __m128i qtmp0, qtmp1; + assert(index < (int)(sizeof(in) / sizeof(in[0])) - 1); coeff0 = *in[index]; coeff1 = *in[index + 1]; diff --git a/vp9/encoder/x86/vp9_dct_ssse3.c b/vp9/encoder/x86/vp9_dct_ssse3.c index a1a2bda80..bdc75e993 100644 --- a/vp9/encoder/x86/vp9_dct_ssse3.c +++ b/vp9/encoder/x86/vp9_dct_ssse3.c @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <assert.h> #if defined(_MSC_VER) && _MSC_VER <= 1500 // Need to include math.h before calling tmmintrin.h/intrin.h // in certain versions of MSVS. @@ -374,6 +375,7 @@ void vp9_fdct8x8_quant_ssse3(const int16_t *input, int stride, __m128i qcoeff0, qcoeff1; __m128i qtmp0, qtmp1; + assert(index < (int)(sizeof(in) / sizeof(in[0])) - 1); coeff0 = *in[index]; coeff1 = *in[index + 1]; diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 1908ffc7f..eb10da7ac 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -924,22 +924,26 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, vpx_codec_err_t res = VPX_CODEC_OK; VP9_COMP *const cpi = ctx->cpi; const vpx_rational_t *const timebase = &ctx->cfg.g_timebase; + size_t data_sz; if (img != NULL) { res = validate_img(ctx, img); // TODO(jzern) the checks related to cpi's validity should be treated as a // failure condition, encoder setup is done fully in init() currently. - if (res == VPX_CODEC_OK && cpi != NULL && ctx->cx_data == NULL) { + if (res == VPX_CODEC_OK && cpi != NULL) { // There's no codec control for multiple alt-refs so check the encoder // instance for its status to determine the compressed data size. - ctx->cx_data_sz = ctx->cfg.g_w * ctx->cfg.g_h * - get_image_bps(img) / 8 * - (cpi->multi_arf_allowed ? 8 : 2); - if (ctx->cx_data_sz < 4096) ctx->cx_data_sz = 4096; - - ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz); - if (ctx->cx_data == NULL) { - return VPX_CODEC_MEM_ERROR; + data_sz = ctx->cfg.g_w * ctx->cfg.g_h * get_image_bps(img) / 8 * + (cpi->multi_arf_allowed ? 8 : 2); + if (data_sz < 4096) + data_sz = 4096; + if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) { + ctx->cx_data_sz = data_sz; + free(ctx->cx_data); + ctx->cx_data = (unsigned char*)malloc(ctx->cx_data_sz); + if (ctx->cx_data == NULL) { + return VPX_CODEC_MEM_ERROR; + } } } } |