From 6126afe62e0044df3664edfed9b84a7f36c23c3a Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 16 Mar 2015 14:49:56 -0700 Subject: [PATCH] Fix external resize memory issues. These were uncovered by the chromoting perftest. Change-Id: Ia5a90fd1718ff757c1484decf3861295260e6722 --- vp9/encoder/vp9_encoder.c | 46 ++++++++++++++++++++++++--------------- vp9/vp9_cx_iface.c | 22 +++++++++++-------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 347570c96..f3c1c1125 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/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; + } } } } -- 2.40.0