Merge changes I8e9692fc,Ifc06110c * changes: vpx_fdctNxN_1_c: remove unnecessary store vpx_fdct32x32_1_c: fix accumulator overflow
diff --git a/vp10/encoder/resize.c b/vp10/encoder/resize.c index e339fa3..353e513 100644 --- a/vp10/encoder/resize.c +++ b/vp10/encoder/resize.c
@@ -445,7 +445,7 @@ int length, uint8_t *output, int olength, - uint8_t *buf) { + uint8_t *otmp) { int steps; if (length == olength) { memcpy(output, input, sizeof(output[0]) * length); @@ -456,16 +456,10 @@ if (steps > 0) { int s; uint8_t *out = NULL; - uint8_t *tmpbuf = NULL; - uint8_t *otmp, *otmp2; + uint8_t *otmp2; int filteredlength = length; - if (!tmpbuf) { - tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * length); - if (tmpbuf == NULL) return; - otmp = tmpbuf; - } else { - otmp = buf; - } + + assert(otmp != NULL); otmp2 = otmp + get_down2_length(length, 1); for (s = 0; s < steps; ++s) { const int proj_filteredlength = get_down2_length(filteredlength, 1); @@ -483,8 +477,6 @@ if (filteredlength != olength) { interpolate(out, filteredlength, output, olength); } - if (tmpbuf) - free(tmpbuf); } else { interpolate(input, length, output, olength); } @@ -520,8 +512,11 @@ uint8_t *intbuf = (uint8_t *)malloc(sizeof(uint8_t) * width2 * height); uint8_t *tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * (width < height ? height : width)); - uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * (height + height2)); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error; + uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * height); + uint8_t *arrbuf2 = (uint8_t *)malloc(sizeof(uint8_t) * height2); + if (intbuf == NULL || tmpbuf == NULL || + arrbuf == NULL || arrbuf2 == NULL) + goto Error; assert(width > 0); assert(height > 0); assert(width2 > 0); @@ -531,14 +526,15 @@ intbuf + width2 * i, width2, tmpbuf); for (i = 0; i < width2; ++i) { fill_col_to_arr(intbuf + i, width2, height, arrbuf); - resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf); - fill_arr_to_col(output + i, out_stride, height2, arrbuf + height); + resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf); + fill_arr_to_col(output + i, out_stride, height2, arrbuf2); } Error: free(intbuf); free(tmpbuf); free(arrbuf); + free(arrbuf2); } #if CONFIG_VP9_HIGHBITDEPTH @@ -741,7 +737,7 @@ int length, uint16_t *output, int olength, - uint16_t *buf, + uint16_t *otmp, int bd) { int steps; if (length == olength) { @@ -753,16 +749,10 @@ if (steps > 0) { int s; uint16_t *out = NULL; - uint16_t *tmpbuf = NULL; - uint16_t *otmp, *otmp2; + uint16_t *otmp2; int filteredlength = length; - if (!tmpbuf) { - tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * length); - if (tmpbuf == NULL) return; - otmp = tmpbuf; - } else { - otmp = buf; - } + + assert(otmp != NULL); otmp2 = otmp + get_down2_length(length, 1); for (s = 0; s < steps; ++s) { const int proj_filteredlength = get_down2_length(filteredlength, 1); @@ -780,8 +770,6 @@ if (filteredlength != olength) { highbd_interpolate(out, filteredlength, output, olength, bd); } - if (tmpbuf) - free(tmpbuf); } else { highbd_interpolate(input, length, output, olength, bd); } @@ -820,24 +808,27 @@ uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height); uint16_t *tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * (width < height ? height : width)); - uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * (height + height2)); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error; + uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * height); + uint16_t *arrbuf2 = (uint16_t *)malloc(sizeof(uint16_t) * height2); + if (intbuf == NULL || tmpbuf == NULL || + arrbuf == NULL || arrbuf2 == NULL) goto Error; for (i = 0; i < height; ++i) { highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width, intbuf + width2 * i, width2, tmpbuf, bd); } for (i = 0; i < width2; ++i) { highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf); - highbd_resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf, + highbd_resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf, bd); highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2, - arrbuf + height); + arrbuf2); } Error: free(intbuf); free(tmpbuf); free(arrbuf); + free(arrbuf2); } #endif // CONFIG_VP9_HIGHBITDEPTH
diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index 5ae44e8..c85251e 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c
@@ -497,7 +497,8 @@ loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index) + int block_index, + int consec_zero_last) { int mv_row; @@ -608,11 +609,6 @@ motion_threshold = denoiser->denoise_pars.scale_motion_thresh * NOISE_MOTION_THRESHOLD; - // If block is considered to be skin area, lower the motion threshold. - // In current version set threshold = 0, so only denoise zero mv on skin. - if (x->is_skin) - motion_threshold = 0; - if (motion_magnitude2 < denoiser->denoise_pars.scale_increase_filter * NOISE_MOTION_THRESHOLD) x->increase_denoising = 1; @@ -624,6 +620,15 @@ if (best_sse > sse_thresh || motion_magnitude2 > motion_threshold) decision = COPY_BLOCK; + // If block is considered skin, don't denoise if the block + // (1) is selected as non-zero motion for current frame, or + // (2) has not been selected as ZERO_LAST mode at least x past frames + // in a row. + // TODO(marpan): Parameter "x" should be varied with framerate. + // In particualar, should be reduced for temporal layers (base layer/LAST). + if (x->is_skin && (consec_zero_last < 2 || motion_magnitude2 > 0)) + decision = COPY_BLOCK; + if (decision == FILTER_BLOCK) { unsigned char *mc_running_avg_y =
diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h index 148ccda..34c561d 100644 --- a/vp8/encoder/denoising.h +++ b/vp8/encoder/denoising.h
@@ -108,7 +108,8 @@ loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index); + int block_index, + int consec_zero_last); #ifdef __cplusplus } // extern "C"
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 51fbe54..0708d65 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c
@@ -36,7 +36,7 @@ extern unsigned int cnt_pm; #endif -#define MODEL_MODE 0 +#define MODEL_MODE 1 extern const int vp8_ref_frame_order[MAX_MODES]; extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES]; @@ -1477,7 +1477,8 @@ vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, recon_yoffset, recon_uvoffset, &cpi->common.lf_info, mb_row, mb_col, - block_index); + block_index, + cpi->consec_zero_last_mvbias[block_index]); // Reevaluate ZEROMV after denoising: for large noise content // (i.e., cpi->mse_source_denoised is above threshold), do this for all
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index ab0ad15..9063cea 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c
@@ -2530,7 +2530,7 @@ vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, recon_yoffset, recon_uvoffset, &cpi->common.lf_info, mb_row, mb_col, - block_index); + block_index, 0); /* Reevaluate ZEROMV after denoising. */ if (best_mode.mbmode.ref_frame == INTRA_FRAME &&
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 9b58f81..9c78de1 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c
@@ -9,6 +9,7 @@ */ +#include <assert.h> #include <stdlib.h> #include <string.h> #include "./vp8_rtcd.h" @@ -154,6 +155,8 @@ { vpx_codec_err_t res = VPX_CODEC_OK; + assert(data != NULL); + if(data + data_sz <= data) { res = VPX_CODEC_INVALID_PARAM;
diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index ae2f66a..3d26fb2 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h
@@ -158,8 +158,8 @@ MODE_INFO *left_mi; MODE_INFO *above_mi; - int up_available; - int left_available; + unsigned int max_blocks_wide; + unsigned int max_blocks_high; const vpx_prob (*partition_probs)[PARTITION_TYPES - 1];
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index fd674cb..3fd935e 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h
@@ -404,20 +404,8 @@ xd->mb_to_right_edge = ((mi_cols - bw - mi_col) * MI_SIZE) * 8; // Are edges available for intra prediction? - xd->up_available = (mi_row != 0); - xd->left_available = (mi_col > tile->mi_col_start); - // TODO(slavarnway): eliminate up/left available ??? - if (xd->up_available) { - xd->above_mi = xd->mi[-xd->mi_stride]; - } else { - xd->above_mi = NULL; - } - - if (xd->left_available) { - xd->left_mi = xd->mi[-1]; - } else { - xd->left_mi = NULL; - } + xd->above_mi = (mi_row != 0) ? xd->mi[-xd->mi_stride] : NULL; + xd->left_mi = (mi_col > tile->mi_col_start) ? xd->mi[-1] : NULL; } static INLINE void update_partition_context(MACROBLOCKD *xd,
diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index c201890..92dc85a 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c
@@ -20,10 +20,10 @@ // left of the entries corresponding to real macroblocks. // The prediction flags in these dummy entries are initialized to 0. const MODE_INFO *const left_mi = xd->left_mi; - const int left_type = xd->left_available && is_inter_block(left_mi) ? + const int left_type = left_mi && is_inter_block(left_mi) ? left_mi->interp_filter : SWITCHABLE_FILTERS; const MODE_INFO *const above_mi = xd->above_mi; - const int above_type = xd->up_available && is_inter_block(above_mi) ? + const int above_type = above_mi && is_inter_block(above_mi) ? above_mi->interp_filter : SWITCHABLE_FILTERS; if (left_type == above_type) @@ -46,8 +46,8 @@ int vp9_get_intra_inter_context(const MACROBLOCKD *xd) { const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = xd->up_available; - const int has_left = xd->left_available; + const int has_above = !!above_mi; + const int has_left = !!left_mi; if (has_above && has_left) { // both edges available const int above_intra = !is_inter_block(above_mi); @@ -66,8 +66,8 @@ int ctx; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = xd->up_available; - const int has_left = xd->left_available; + const int has_above = !!above_mi; + const int has_left = !!left_mi; // Note: // The mode info data structure has a one element border above and to the // left of the entries corresponding to real macroblocks. @@ -109,8 +109,8 @@ int pred_context; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int above_in_image = xd->up_available; - const int left_in_image = xd->left_available; + const int above_in_image = !!above_mi; + const int left_in_image = !!left_mi; // Note: // The mode info data structure has a one element border above and to the @@ -190,8 +190,8 @@ int pred_context; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = xd->up_available; - const int has_left = xd->left_available; + const int has_above = !!above_mi; + const int has_left = !!left_mi; // Note: // The mode info data structure has a one element border above and to the // left of the entries corresponding to real macroblocks. @@ -256,8 +256,8 @@ int pred_context; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = xd->up_available; - const int has_left = xd->left_available; + const int has_above = !!above_mi; + const int has_left = !!left_mi; // Note: // The mode info data structure has a one element border above and to the
diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index 254cb8b..4942862 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h
@@ -113,8 +113,8 @@ const int max_tx_size = max_txsize_lookup[xd->mi[0]->sb_type]; const MODE_INFO *const above_mi = xd->above_mi; const MODE_INFO *const left_mi = xd->left_mi; - const int has_above = xd->up_available; - const int has_left = xd->left_available; + const int has_above = !!above_mi; + const int has_left = !!left_mi; int above_ctx = (has_above && !above_mi->skip) ? (int)above_mi->tx_size : max_tx_size; int left_ctx = (has_left && !left_mi->skip) ? (int)left_mi->tx_size
diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c index 13a95ae..c4d91c8 100644 --- a/vp9/common/vp9_reconintra.c +++ b/vp9/common/vp9_reconintra.c
@@ -425,8 +425,8 @@ int aoff, int loff, int plane) { const int bw = (1 << bwl_in); const int txw = (1 << tx_size); - const int have_top = loff || xd->up_available; - const int have_left = aoff || xd->left_available; + const int have_top = loff || (xd->above_mi != NULL); + const int have_left = aoff || (xd->left_mi != NULL); const int have_right = (aoff + txw) < bw; const int x = aoff * 4; const int y = loff * 4;
diff --git a/vp9/common/vp9_rtcd_defs.pl b/vp9/common/vp9_rtcd_defs.pl index d6a0ce9..1cf636c 100644 --- a/vp9/common/vp9_rtcd_defs.pl +++ b/vp9/common/vp9_rtcd_defs.pl
@@ -276,7 +276,7 @@ $vp9_full_search_sad_sse4_1=vp9_full_search_sadx8; add_proto qw/int vp9_diamond_search_sad/, "const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_variance_vtable *fn_ptr, const struct mv *center_mv"; -specialize qw/vp9_diamond_search_sad avx/; +specialize qw/vp9_diamond_search_sad/; add_proto qw/void vp9_temporal_filter_apply/, "uint8_t *frame1, unsigned int stride, uint8_t *frame2, unsigned int block_width, unsigned int block_height, int strength, int filter_weight, unsigned int *accumulator, uint16_t *count"; specialize qw/vp9_temporal_filter_apply sse2 msa/;
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 32c7219..02962c8 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c
@@ -883,6 +883,9 @@ const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); + xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; + xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; + for (row = 0; row < max_blocks_high; row += step) for (col = 0; col < max_blocks_wide; col += step) predict_and_reconstruct_intra_block(xd, r, mi, plane, @@ -911,6 +914,9 @@ const int max_blocks_high = num_4x4_h + (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); + xd->max_blocks_wide = xd->mb_to_right_edge >= 0 ? 0 : max_blocks_wide; + xd->max_blocks_high = xd->mb_to_bottom_edge >= 0 ? 0 : max_blocks_high; + for (row = 0; row < max_blocks_high; row += step) for (col = 0; col < max_blocks_wide; col += step) eobtotal += reconstruct_inter_block(xd, r, mi, plane, row, col,
diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index dcc75b9..47dc107 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c
@@ -152,65 +152,73 @@ return c; } -// TODO(slavarnway): Decode version of vp9_set_context. Modify vp9_set_context -// after testing is complete, then delete this version. -static -void dec_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, - TX_SIZE tx_size, int has_eob, - int aoff, int loff) { - ENTROPY_CONTEXT *const a = pd->above_context + aoff; - ENTROPY_CONTEXT *const l = pd->left_context + loff; - const int tx_size_in_blocks = 1 << tx_size; - - // above - if (has_eob && xd->mb_to_right_edge < 0) { - int i; - const int blocks_wide = pd->n4_w + - (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); - int above_contexts = tx_size_in_blocks; - if (above_contexts + aoff > blocks_wide) - above_contexts = blocks_wide - aoff; - - for (i = 0; i < above_contexts; ++i) - a[i] = has_eob; - for (i = above_contexts; i < tx_size_in_blocks; ++i) - a[i] = 0; - } else { - memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); +static void get_ctx_shift(MACROBLOCKD *xd, int *ctx_shift_a, int *ctx_shift_l, + int x, int y, unsigned int tx_size_in_blocks) { + if (xd->max_blocks_wide) { + if (tx_size_in_blocks + x > xd->max_blocks_wide) + *ctx_shift_a = (tx_size_in_blocks - (xd->max_blocks_wide - x)) * 8; } - - // left - if (has_eob && xd->mb_to_bottom_edge < 0) { - int i; - const int blocks_high = pd->n4_h + - (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); - int left_contexts = tx_size_in_blocks; - if (left_contexts + loff > blocks_high) - left_contexts = blocks_high - loff; - - for (i = 0; i < left_contexts; ++i) - l[i] = has_eob; - for (i = left_contexts; i < tx_size_in_blocks; ++i) - l[i] = 0; - } else { - memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); + if (xd->max_blocks_high) { + if (tx_size_in_blocks + y > xd->max_blocks_high) + *ctx_shift_l = (tx_size_in_blocks - (xd->max_blocks_high - y)) * 8; } } -int vp9_decode_block_tokens(MACROBLOCKD *xd, - int plane, const scan_order *sc, - int x, int y, - TX_SIZE tx_size, vpx_reader *r, +int vp9_decode_block_tokens(MACROBLOCKD *xd, int plane, const scan_order *sc, + int x, int y, TX_SIZE tx_size, vpx_reader *r, int seg_id) { struct macroblockd_plane *const pd = &xd->plane[plane]; const int16_t *const dequant = pd->seg_dequant[seg_id]; - const int ctx = get_entropy_context(tx_size, pd->above_context + x, - pd->left_context + y); - const int eob = decode_coefs(xd, get_plane_type(plane), - pd->dqcoeff, tx_size, - dequant, ctx, sc->scan, sc->neighbors, r); - dec_set_contexts(xd, pd, tx_size, eob > 0, x, y); + int eob; + ENTROPY_CONTEXT *a = pd->above_context + x; + ENTROPY_CONTEXT *l = pd->left_context + y; + int ctx; + int ctx_shift_a = 0; + int ctx_shift_l = 0; + + switch (tx_size) { + case TX_4X4: + ctx = a[0] != 0; + ctx += l[0] != 0; + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, + dequant, ctx, sc->scan, sc->neighbors, r); + a[0] = l[0] = (eob > 0); + break; + case TX_8X8: + get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_8X8); + ctx = !!*(const uint16_t *)a; + ctx += !!*(const uint16_t *)l; + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, + dequant, ctx, sc->scan, sc->neighbors, r); + *(uint16_t *)a = ((eob > 0) * 0x0101) >> ctx_shift_a; + *(uint16_t *)l = ((eob > 0) * 0x0101) >> ctx_shift_l; + break; + case TX_16X16: + get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_16X16); + ctx = !!*(const uint32_t *)a; + ctx += !!*(const uint32_t *)l; + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, + dequant, ctx, sc->scan, sc->neighbors, r); + *(uint32_t *)a = ((eob > 0) * 0x01010101) >> ctx_shift_a; + *(uint32_t *)l = ((eob > 0) * 0x01010101) >> ctx_shift_l; + break; + case TX_32X32: + get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_32X32); + // NOTE: casting to uint64_t here is safe because the default memory + // alignment is at least 8 bytes and the TX_32X32 is aligned on 8 byte + // boundaries. + ctx = !!*(const uint64_t *)a; + ctx += !!*(const uint64_t *)l; + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, + dequant, ctx, sc->scan, sc->neighbors, r); + *(uint64_t *)a = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a; + *(uint64_t *)l = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l; + break; + default: + assert(0 && "Invalid transform size."); + eob = 0; + break; + } + return eob; } - -
diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index 9eca2a2..3de182f 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c
@@ -195,7 +195,8 @@ PICK_MODE_CONTEXT *ctx, int motion_magnitude, int is_skin, - int *zeromv_filter) { + int *zeromv_filter, + int consec_zeromv) { int mv_col, mv_row; int sse_diff = ctx->zeromv_sse - ctx->newmv_sse; MV_REFERENCE_FRAME frame; @@ -212,7 +213,7 @@ saved_mi = *mi; - if (is_skin && motion_magnitude > 0) + if (is_skin && (motion_magnitude > 0 || consec_zeromv < 4)) return COPY_BLOCK; // If the best reference frame uses inter-prediction and there is enough of a @@ -332,6 +333,7 @@ mi_row, mi_col); struct buf_2d src = mb->plane[0].src; int is_skin = 0; + int consec_zeromv = 0; mv_col = ctx->best_sse_mv.as_mv.col; mv_row = ctx->best_sse_mv.as_mv.row; motion_magnitude = mv_row * mv_row + mv_col * mv_col; @@ -343,7 +345,7 @@ // If motion for current block is small/zero, compute consec_zeromv for // skin detection (early exit in skin detection is done for large // consec_zeromv when current block has small/zero motion). - int consec_zeromv = 0; + consec_zeromv = 0; if (motion_level == 0) { CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; VP9_COMMON * const cm = &cpi->common; @@ -361,8 +363,8 @@ consec_zeromv = VPXMIN(cr->consec_zero_mv[bl_index], consec_zeromv); // No need to keep checking 8x8 blocks if any of the sub-blocks // has small consec_zeromv (since threshold for no_skin based on - // zero/small motion in skin detection is high, i.e, > 5). - if (consec_zeromv < 5) { + // zero/small motion in skin detection is high, i.e, > 4). + if (consec_zeromv < 4) { i = ymis; j = xmis; } @@ -393,7 +395,8 @@ mi_row, mi_col, ctx, motion_magnitude, is_skin, - &zeromv_filter); + &zeromv_filter, + consec_zeromv); if (decision == FILTER_BLOCK) { decision = vp9_denoiser_filter(src.buf, src.stride,
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 40b332a..41b94bf 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c
@@ -1228,10 +1228,10 @@ MODE_INFO *const mi = xd->mi[0]; INTERP_FILTER filter_ref; - if (xd->up_available) - filter_ref = xd->mi[-xd->mi_stride]->interp_filter; - else if (xd->left_available) - filter_ref = xd->mi[-1]->interp_filter; + if (xd->above_mi) + filter_ref = xd->above_mi->interp_filter; + else if (xd->left_mi) + filter_ref = xd->left_mi->interp_filter; else filter_ref = EIGHTTAP; @@ -2266,8 +2266,8 @@ BLOCK_SIZE *max_block_size) { VP9_COMMON *const cm = &cpi->common; MODE_INFO **mi = xd->mi; - const int left_in_image = xd->left_available && mi[-1]; - const int above_in_image = xd->up_available && mi[-xd->mi_stride]; + const int left_in_image = !!xd->left_mi; + const int above_in_image = !!xd->above_mi; const int row8x8_remaining = tile->mi_row_end - mi_row; const int col8x8_remaining = tile->mi_col_end - mi_col; int bh, bw; @@ -2362,7 +2362,7 @@ } } - if (xd->left_available) { + if (xd->left_mi) { for (idy = 0; idy < mi_height; ++idy) { mi = xd->mi[idy * cm->mi_stride - 1]; bs = mi ? mi->sb_type : bsize; @@ -2371,7 +2371,7 @@ } } - if (xd->up_available) { + if (xd->above_mi) { for (idx = 0; idx < mi_width; ++idx) { mi = xd->mi[idx - cm->mi_stride]; bs = mi ? mi->sb_type : bsize;
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 10fd6c0..3ad175e 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c
@@ -563,6 +563,7 @@ double intra_factor; double brightness_factor; BufferPool *const pool = cm->buffer_pool; + MODE_INFO mi_above, mi_left; // First pass code requires valid last and new frame buffers. assert(new_yv12 != NULL); @@ -695,6 +696,12 @@ mb_row << 1, num_8x8_blocks_high_lookup[bsize], mb_col << 1, num_8x8_blocks_wide_lookup[bsize], cm->mi_rows, cm->mi_cols); + // Are edges available for intra prediction? + // Since the firstpass does not populate the mi_grid_visible, + // above_mi/left_mi must be overwritten with a nonzero value when edges + // are available. Required by vp9_predict_intra_block(). + xd->above_mi = (mb_row != 0) ? &mi_above : NULL; + xd->left_mi = (mb_col > tile.mi_col_start) ? &mi_left : NULL; // Do intra 16x16 prediction. x->skip_encode = 0;
diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c index 7ce86b4..3ae5b21 100644 --- a/vp9/encoder/vp9_mbgraph.c +++ b/vp9/encoder/vp9_mbgraph.c
@@ -243,13 +243,16 @@ int mb_y_offset = 0, arf_y_offset = 0, gld_y_offset = 0; MV gld_top_mv = {0, 0}; MODE_INFO mi_local; + MODE_INFO mi_above, mi_left; vp9_zero(mi_local); // Set up limit values for motion vectors to prevent them extending outside // the UMV borders. x->mv_row_min = -BORDER_MV_PIXELS_B16; x->mv_row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16; - xd->up_available = 0; + // Signal to vp9_predict_intra_block() that above is not available + xd->above_mi = NULL; + xd->plane[0].dst.stride = buf->y_stride; xd->plane[0].pre[0].stride = buf->y_stride; xd->plane[1].dst.stride = buf->uv_stride; @@ -268,7 +271,8 @@ // the UMV borders. x->mv_col_min = -BORDER_MV_PIXELS_B16; x->mv_col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16; - xd->left_available = 0; + // Signal to vp9_predict_intra_block() that left is not available + xd->left_mi = NULL; for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col]; @@ -280,14 +284,19 @@ if (mb_col == 0) { gld_top_mv = gld_left_mv; } - xd->left_available = 1; + // Signal to vp9_predict_intra_block() that left is available + xd->left_mi = &mi_left; + mb_y_in_offset += 16; gld_y_in_offset += 16; arf_y_in_offset += 16; x->mv_col_min -= 16; x->mv_col_max -= 16; } - xd->up_available = 1; + + // Signal to vp9_predict_intra_block() that above is available + xd->above_mi = &mi_above; + mb_y_offset += buf->y_stride * 16; gld_y_offset += golden_ref->y_stride * 16; if (alt_ref)
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 8b2e985..2057dca 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c
@@ -1017,8 +1017,8 @@ tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); MODE_INFO *const mic = xd->mi[0]; int *bmode_costs; - const MODE_INFO *above_mi = xd->mi[-xd->mi_stride]; - const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL; + const MODE_INFO *above_mi = xd->above_mi; + const MODE_INFO *left_mi = xd->left_mi; const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0); const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0); bmode_costs = cpi->y_mode_costs[A][L]; @@ -1242,10 +1242,10 @@ x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; x->skip = 0; - if (xd->up_available) - filter_ref = xd->mi[-xd->mi_stride]->interp_filter; - else if (xd->left_available) - filter_ref = xd->mi[-1]->interp_filter; + if (xd->above_mi) + filter_ref = xd->above_mi->interp_filter; + else if (xd->left_mi) + filter_ref = xd->left_mi->interp_filter; else filter_ref = cm->interp_filter;
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 508c596..a304182 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c
@@ -2460,10 +2460,10 @@ if (pred_filter_search) { INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE; - if (xd->up_available) - af = xd->mi[-xd->mi_stride]->interp_filter; - if (xd->left_available) - lf = xd->mi[-1]->interp_filter; + if (xd->above_mi) + af = xd->above_mi->interp_filter; + if (xd->left_mi) + lf = xd->left_mi->interp_filter; if ((this_mode != NEWMV) || (af == lf)) best_filter = af;
diff --git a/vp9/encoder/vp9_resize.c b/vp9/encoder/vp9_resize.c index 63f0ce2..307a112 100644 --- a/vp9/encoder/vp9_resize.c +++ b/vp9/encoder/vp9_resize.c
@@ -446,7 +446,7 @@ int length, uint8_t *output, int olength, - uint8_t *buf) { + uint8_t *otmp) { int steps; if (length == olength) { memcpy(output, input, sizeof(output[0]) * length); @@ -457,16 +457,10 @@ if (steps > 0) { int s; uint8_t *out = NULL; - uint8_t *tmpbuf = NULL; - uint8_t *otmp, *otmp2; + uint8_t *otmp2; int filteredlength = length; - if (!tmpbuf) { - tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * length); - if (tmpbuf == NULL) return; - otmp = tmpbuf; - } else { - otmp = buf; - } + + assert(otmp != NULL); otmp2 = otmp + get_down2_length(length, 1); for (s = 0; s < steps; ++s) { const int proj_filteredlength = get_down2_length(filteredlength, 1); @@ -484,8 +478,6 @@ if (filteredlength != olength) { interpolate(out, filteredlength, output, olength); } - if (tmpbuf) - free(tmpbuf); } else { interpolate(input, length, output, olength); } @@ -521,25 +513,29 @@ uint8_t *intbuf = (uint8_t *)malloc(sizeof(uint8_t) * width2 * height); uint8_t *tmpbuf = (uint8_t *)malloc(sizeof(uint8_t) * (width < height ? height : width)); - uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * (height + height2)); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error; + uint8_t *arrbuf = (uint8_t *)malloc(sizeof(uint8_t) * height); + uint8_t *arrbuf2 = (uint8_t *)malloc(sizeof(uint8_t) * height2); + if (intbuf == NULL || tmpbuf == NULL || + arrbuf == NULL || arrbuf2 == NULL) + goto Error; 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); + intbuf + width2 * i, width2, tmpbuf); for (i = 0; i < width2; ++i) { fill_col_to_arr(intbuf + i, width2, height, arrbuf); - resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf); - fill_arr_to_col(output + i, out_stride, height2, arrbuf + height); + resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf); + fill_arr_to_col(output + i, out_stride, height2, arrbuf2); } Error: free(intbuf); free(tmpbuf); free(arrbuf); + free(arrbuf2); } #if CONFIG_VP9_HIGHBITDEPTH @@ -742,7 +738,7 @@ int length, uint16_t *output, int olength, - uint16_t *buf, + uint16_t *otmp, int bd) { int steps; if (length == olength) { @@ -754,16 +750,10 @@ if (steps > 0) { int s; uint16_t *out = NULL; - uint16_t *tmpbuf = NULL; - uint16_t *otmp, *otmp2; + uint16_t *otmp2; int filteredlength = length; - if (!tmpbuf) { - tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * length); - if (tmpbuf == NULL) return; - otmp = tmpbuf; - } else { - otmp = buf; - } + + assert(otmp != NULL); otmp2 = otmp + get_down2_length(length, 1); for (s = 0; s < steps; ++s) { const int proj_filteredlength = get_down2_length(filteredlength, 1); @@ -781,8 +771,6 @@ if (filteredlength != olength) { highbd_interpolate(out, filteredlength, output, olength, bd); } - if (tmpbuf) - free(tmpbuf); } else { highbd_interpolate(input, length, output, olength, bd); } @@ -821,24 +809,28 @@ uint16_t *intbuf = (uint16_t *)malloc(sizeof(uint16_t) * width2 * height); uint16_t *tmpbuf = (uint16_t *)malloc(sizeof(uint16_t) * (width < height ? height : width)); - uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * (height + height2)); - if (intbuf == NULL || tmpbuf == NULL || arrbuf == NULL) goto Error; + uint16_t *arrbuf = (uint16_t *)malloc(sizeof(uint16_t) * height); + uint16_t *arrbuf2 = (uint16_t *)malloc(sizeof(uint16_t) * height2); + if (intbuf == NULL || tmpbuf == NULL || + arrbuf == NULL || arrbuf2 == NULL) + goto Error; for (i = 0; i < height; ++i) { highbd_resize_multistep(CONVERT_TO_SHORTPTR(input + in_stride * i), width, intbuf + width2 * i, width2, tmpbuf, bd); } for (i = 0; i < width2; ++i) { highbd_fill_col_to_arr(intbuf + i, width2, height, arrbuf); - highbd_resize_multistep(arrbuf, height, arrbuf + height, height2, tmpbuf, + highbd_resize_multistep(arrbuf, height, arrbuf2, height2, tmpbuf, bd); highbd_fill_arr_to_col(CONVERT_TO_SHORTPTR(output + i), out_stride, height2, - arrbuf + height); + arrbuf2); } Error: free(intbuf); free(tmpbuf); free(arrbuf); + free(arrbuf2); } #endif // CONFIG_VP9_HIGHBITDEPTH
diff --git a/vpx_ports/mem_ops.h b/vpx_ports/mem_ops.h index d4a3d77..1f8f914 100644 --- a/vpx_ports/mem_ops.h +++ b/vpx_ports/mem_ops.h
@@ -168,8 +168,8 @@ static VPX_INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 8) & 0xff; - mem[1] = (val >> 0) & 0xff; + mem[0] = (MAU_T)((val >> 8) & 0xff); + mem[1] = (MAU_T)((val >> 0) & 0xff); } #undef mem_put_be24 @@ -177,9 +177,9 @@ static VPX_INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 16) & 0xff; - mem[1] = (val >> 8) & 0xff; - mem[2] = (val >> 0) & 0xff; + mem[0] = (MAU_T)((val >> 16) & 0xff); + mem[1] = (MAU_T)((val >> 8) & 0xff); + mem[2] = (MAU_T)((val >> 0) & 0xff); } #undef mem_put_be32 @@ -187,10 +187,10 @@ static VPX_INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 24) & 0xff; - mem[1] = (val >> 16) & 0xff; - mem[2] = (val >> 8) & 0xff; - mem[3] = (val >> 0) & 0xff; + mem[0] = (MAU_T)((val >> 24) & 0xff); + mem[1] = (MAU_T)((val >> 16) & 0xff); + mem[2] = (MAU_T)((val >> 8) & 0xff); + mem[3] = (MAU_T)((val >> 0) & 0xff); } #undef mem_put_le16 @@ -198,8 +198,8 @@ static VPX_INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 0) & 0xff; - mem[1] = (val >> 8) & 0xff; + mem[0] = (MAU_T)((val >> 0) & 0xff); + mem[1] = (MAU_T)((val >> 8) & 0xff); } #undef mem_put_le24 @@ -207,9 +207,9 @@ static VPX_INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 0) & 0xff; - mem[1] = (val >> 8) & 0xff; - mem[2] = (val >> 16) & 0xff; + mem[0] = (MAU_T)((val >> 0) & 0xff); + mem[1] = (MAU_T)((val >> 8) & 0xff); + mem[2] = (MAU_T)((val >> 16) & 0xff); } #undef mem_put_le32 @@ -217,10 +217,10 @@ static VPX_INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val) { MAU_T *mem = (MAU_T *)vmem; - mem[0] = (val >> 0) & 0xff; - mem[1] = (val >> 8) & 0xff; - mem[2] = (val >> 16) & 0xff; - mem[3] = (val >> 24) & 0xff; + mem[0] = (MAU_T)((val >> 0) & 0xff); + mem[1] = (MAU_T)((val >> 8) & 0xff); + mem[2] = (MAU_T)((val >> 16) & 0xff); + mem[3] = (MAU_T)((val >> 24) & 0xff); } #endif // VPX_PORTS_MEM_OPS_H_
diff --git a/vpx_ports/mem_ops_aligned.h b/vpx_ports/mem_ops_aligned.h index c16111f..46f6173 100644 --- a/vpx_ports/mem_ops_aligned.h +++ b/vpx_ports/mem_ops_aligned.h
@@ -28,8 +28,8 @@ * could redefine these macros. */ #define swap_endian_16(val,raw) do {\ - val = ((raw>>8) & 0x00ff) \ - | ((raw<<8) & 0xff00);\ + val = (uint16_t)(((raw>>8) & 0x00ff) \ + | ((raw<<8) & 0xff00));\ } while(0) #define swap_endian_32(val,raw) do {\ val = ((raw>>24) & 0x000000ff) \