Facilitate deallocation of rusi and dgd_avg buffers In this CL, the local buffers 'rusi' and 'rsc.dgd_avg' allocated in av1_pick_filter_restoration() are added to `AV1LrPickStruct'. This structure is introduced as a member in AV1_COMP to facilitate freeing of these buffers in encoder_destroy() to prevent memory leaks in case of early termination. Bug: aomedia:3276 Change-Id: Ifb7e2566abbe29dd425920c36a10e1844cd3b159
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 92d0840..ee904a1 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -1637,6 +1637,43 @@ } RestoreStateBuffers; /*! + * \brief Parameters related to restoration types. + */ +typedef struct { + /*! + * Stores the best coefficients for Wiener restoration. + */ + WienerInfo wiener; + + /*! + * Stores the best coefficients for Sgrproj restoration. + */ + SgrprojInfo sgrproj; + + /*! + * The rtype to use for this unit given a frame rtype as index. Indices: + * WIENER, SGRPROJ, SWITCHABLE. + */ + RestorationType best_rtype[RESTORE_TYPES - 1]; +} RestUnitSearchInfo; + +/*! + * \brief Buffers used during loop restoration search. + */ +typedef struct { + /*! + * Array of pointers to 'RestUnitSearchInfo' which holds data related to + * restoration types. + */ + RestUnitSearchInfo *rusi[MAX_MB_PLANE]; + + /*! + * Buffer used to hold dgd-avg data during SIMD call of Wiener filter. + */ + int16_t *dgd_avg; +} AV1LrPickStruct; + +/*! * \brief Primary Encoder parameters related to multi-threading. */ typedef struct PrimaryMultiThreadInfo { @@ -3243,6 +3280,11 @@ AV1LrStruct lr_ctxt; /*! + * Loop Restoration context used during pick stage. + */ + AV1LrPickStruct pick_lr_ctxt; + + /*! * Pointer to list of tables with film grain parameters. */ aom_film_grain_table_t *film_grain_table;
diff --git a/av1/encoder/encoder_alloc.h b/av1/encoder/encoder_alloc.h index def0069..d0fd782 100644 --- a/av1/encoder/encoder_alloc.h +++ b/av1/encoder/encoder_alloc.h
@@ -182,7 +182,7 @@ static AOM_INLINE void dealloc_compressor_data(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; TokenInfo *token_info = &cpi->token_info; - + const int num_planes = av1_num_planes(cm); dealloc_context_buffers_ext(&cpi->mbmi_ext_info); aom_free(cpi->tile_data); @@ -240,7 +240,7 @@ cpi->td.mb.rdcost = NULL; #endif - av1_free_pc_tree_recursive(cpi->td.pc_root, av1_num_planes(cm), 0, 0, + av1_free_pc_tree_recursive(cpi->td.pc_root, num_planes, 0, 0, cpi->sf.part_sf.partition_search_type); cpi->td.pc_root = NULL; @@ -264,7 +264,7 @@ aom_free(cpi->td.vt64x64); cpi->td.vt64x64 = NULL; - av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm)); + av1_free_pmc(cpi->td.firstpass_ctx, num_planes); cpi->td.firstpass_ctx = NULL; const int is_highbitdepth = cpi->tf_ctx.is_highbitdepth; @@ -288,7 +288,7 @@ aom_free(cpi->cdef_search_ctx); cpi->cdef_search_ctx = NULL; - av1_dealloc_mb_data(&cpi->td.mb, av1_num_planes(cm)); + av1_dealloc_mb_data(&cpi->td.mb, num_planes); av1_dealloc_mb_wiener_var_pred_buf(&cpi->td); @@ -306,6 +306,13 @@ &cpi->mt_info.cdef_sync); } + for (int plane = 0; plane < num_planes; plane++) { + aom_free(cpi->pick_lr_ctxt.rusi[plane]); + cpi->pick_lr_ctxt.rusi[plane] = NULL; + } + aom_free(cpi->pick_lr_ctxt.dgd_avg); + cpi->pick_lr_ctxt.dgd_avg = NULL; + aom_free_frame_buffer(&cpi->trial_frame_rst); aom_free_frame_buffer(&cpi->scaled_source); aom_free_frame_buffer(&cpi->scaled_last_source);
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c index 1e60742..cf7633b 100644 --- a/av1/encoder/pickrst.c +++ b/av1/encoder/pickrst.c
@@ -105,16 +105,6 @@ } typedef struct { - // The best coefficients for Wiener or Sgrproj restoration - WienerInfo wiener; - SgrprojInfo sgrproj; - - // The rtype to use for this unit given a frame rtype as - // index. Indices: WIENER, SGRPROJ, SWITCHABLE. - RestorationType best_rtype[RESTORE_TYPES - 1]; -} RestUnitSearchInfo; - -typedef struct { const YV12_BUFFER_CONFIG *src; YV12_BUFFER_CONFIG *dst; @@ -2038,10 +2028,9 @@ min_lr_unit_size = AOMMAX(min_lr_unit_size, block_size_wide[cm->seq_params->sb_size]); - RestUnitSearchInfo *rusi[MAX_MB_PLANE] = { 0 }; for (int plane = 0; plane < num_planes; ++plane) { - rusi[plane] = allocate_search_structs(cm, &cm->rst_info[plane], plane > 0, - min_lr_unit_size); + cpi->pick_lr_ctxt.rusi[plane] = allocate_search_structs( + cm, &cm->rst_info[plane], plane > 0, min_lr_unit_size); } x->rdmult = cpi->rd.RDMULT; @@ -2071,10 +2060,12 @@ // bitdepth path. Hence, allocate the same when Wiener filter is enabled in // low bitdepth path. if (!cpi->sf.lpf_sf.disable_wiener_filter && !highbd) { - const int buf_size = sizeof(*rsc.dgd_avg) * 6 * RESTORATION_UNITSIZE_MAX * - RESTORATION_UNITSIZE_MAX; - CHECK_MEM_ERROR(cm, rsc.dgd_avg, (int16_t *)aom_memalign(32, buf_size)); + const int buf_size = sizeof(*cpi->pick_lr_ctxt.dgd_avg) * 6 * + RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX; + CHECK_MEM_ERROR(cm, cpi->pick_lr_ctxt.dgd_avg, + (int16_t *)aom_memalign(32, buf_size)); + rsc.dgd_avg = cpi->pick_lr_ctxt.dgd_avg; // When LRU width isn't multiple of 16, the 256 bits load instruction used // in AVX2 intrinsic can read data beyond valid LRU. Hence, in order to // silence Valgrind warning this buffer is initialized with zero. Overhead @@ -2133,8 +2124,8 @@ for (int plane = plane_start; plane <= plane_end; ++plane) { set_restoration_unit_size(cm, &cm->rst_info[plane], plane > 0, luma_unit_size); - init_rsc(src, &cpi->common, x, lpf_sf, plane, rusi[plane], - &cpi->trial_frame_rst, &rsc); + init_rsc(src, &cpi->common, x, lpf_sf, plane, + cpi->pick_lr_ctxt.rusi[plane], &cpi->trial_frame_rst, &rsc); restoration_search(cm, plane, &rsc, disable_lr_filter); @@ -2177,7 +2168,7 @@ all_none = false; const int plane_num_units = cm->rst_info[plane].num_rest_units; for (int u = 0; u < plane_num_units; ++u) { - copy_unit_info(best_rtype[plane], &rusi[plane][u], + copy_unit_info(best_rtype[plane], &cpi->pick_lr_ctxt.rusi[plane][u], &cm->rst_info[plane].unit_info[u]); } } @@ -2206,10 +2197,12 @@ #if HAVE_AVX || HAVE_NEON if (!cpi->sf.lpf_sf.disable_wiener_filter && !highbd) { - aom_free(rsc.dgd_avg); + aom_free(cpi->pick_lr_ctxt.dgd_avg); + cpi->pick_lr_ctxt.dgd_avg = NULL; } #endif for (int plane = 0; plane < num_planes; plane++) { - aom_free(rusi[plane]); + aom_free(cpi->pick_lr_ctxt.rusi[plane]); + cpi->pick_lr_ctxt.rusi[plane] = NULL; } }