summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/encoder/onyx_if.c27
-rw-r--r--vp9/encoder/vp9_aq_cyclicrefresh.c67
-rw-r--r--vp9/encoder/vp9_aq_cyclicrefresh.h11
-rw-r--r--vp9/encoder/vp9_encodeframe.c5
-rw-r--r--vp9/encoder/vp9_encoder.c46
-rw-r--r--vp9/encoder/vp9_pickmode.c19
-rw-r--r--vp9/encoder/vp9_rd.c1
-rw-r--r--vp9/encoder/vp9_resize.c4
-rw-r--r--vp9/encoder/x86/vp9_dct_sse2.c2
-rw-r--r--vp9/encoder/x86/vp9_dct_ssse3.c2
-rw-r--r--vp9/vp9_cx_iface.c22
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;
+ }
}
}
}