Fix segfault with loop-restoration on x86. The WienerInfo struct requires a 16-byte alignment on x86, since it contains filter coefficients which are loaded using SSE aligned load instructions. But on 32-bit x86, the default alignment of aom_malloc/aom_realloc is only 8 bytes, leading to occasional segfaults. To fix this, rather than using aom_realloc to resize WienerInfo structures, we always free and re-allocate them using aom_memalign BUG=aomedia:345 Change-Id: Ib1b2a42d4a2fa215dcc81ea481c51271ab068a37
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c index bd20fcf..e7c7f45 100644 --- a/av1/common/alloccommon.c +++ b/av1/common/alloccommon.c
@@ -90,10 +90,10 @@ #if CONFIG_LOOP_RESTORATION void av1_alloc_restoration_buffers(AV1_COMMON *cm) { int p; - av1_alloc_restoration_struct(&cm->rst_info[0], cm->width, cm->height); + av1_alloc_restoration_struct(cm, &cm->rst_info[0], cm->width, cm->height); for (p = 1; p < MAX_MB_PLANE; ++p) av1_alloc_restoration_struct( - &cm->rst_info[p], ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x), + cm, &cm->rst_info[p], ROUND_POWER_OF_TWO(cm->width, cm->subsampling_x), ROUND_POWER_OF_TWO(cm->height, cm->subsampling_y)); cm->rst_internal.tmpbuf = (int32_t *)aom_realloc(cm->rst_internal.tmpbuf, RESTORATION_TMPBUF_SIZE);
diff --git a/av1/common/restoration.c b/av1/common/restoration.c index 8563c09..2b8f565 100644 --- a/av1/common/restoration.c +++ b/av1/common/restoration.c
@@ -47,22 +47,27 @@ int dst_stride); #endif // CONFIG_AOM_HIGHBITDEPTH -int av1_alloc_restoration_struct(RestorationInfo *rst_info, int width, - int height) { +int av1_alloc_restoration_struct(AV1_COMMON *cm, RestorationInfo *rst_info, + int width, int height) { const int ntiles = av1_get_rest_ntiles(width, height, NULL, NULL, NULL, NULL); rst_info->restoration_type = (RestorationType *)aom_realloc( rst_info->restoration_type, sizeof(*rst_info->restoration_type) * ntiles); - rst_info->wiener_info = (WienerInfo *)aom_realloc( - rst_info->wiener_info, sizeof(*rst_info->wiener_info) * ntiles); - assert(rst_info->wiener_info != NULL); + aom_free(rst_info->wiener_info); + CHECK_MEM_ERROR( + cm, rst_info->wiener_info, + (WienerInfo *)aom_memalign(16, sizeof(*rst_info->wiener_info) * ntiles)); memset(rst_info->wiener_info, 0, sizeof(*rst_info->wiener_info) * ntiles); - rst_info->sgrproj_info = (SgrprojInfo *)aom_realloc( - rst_info->sgrproj_info, sizeof(*rst_info->sgrproj_info) * ntiles); - assert(rst_info->sgrproj_info != NULL); + CHECK_MEM_ERROR( + cm, rst_info->sgrproj_info, + (SgrprojInfo *)aom_realloc(rst_info->sgrproj_info, + sizeof(*rst_info->sgrproj_info) * ntiles)); rst_info->domaintxfmrf_info = (DomaintxfmrfInfo *)aom_realloc( rst_info->domaintxfmrf_info, sizeof(*rst_info->domaintxfmrf_info) * ntiles); - assert(rst_info->domaintxfmrf_info != NULL); + CHECK_MEM_ERROR(cm, rst_info->domaintxfmrf_info, + (DomaintxfmrfInfo *)aom_realloc( + rst_info->domaintxfmrf_info, + sizeof(*rst_info->domaintxfmrf_info) * ntiles)); return ntiles; }
diff --git a/av1/common/restoration.h b/av1/common/restoration.h index 11885e8..24455b4 100644 --- a/av1/common/restoration.h +++ b/av1/common/restoration.h
@@ -219,7 +219,8 @@ extern const sgr_params_type sgr_params[SGRPROJ_PARAMS]; -int av1_alloc_restoration_struct(RestorationInfo *rst_info, int width, +int av1_alloc_restoration_struct(struct AV1Common *cm, + RestorationInfo *rst_info, int width, int height); void av1_free_restoration_struct(RestorationInfo *rst_info);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index f4e7531..b0858c0 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -752,7 +752,8 @@ aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate extra rstbuf for restoration"); for (i = 0; i < MAX_MB_PLANE; ++i) - av1_alloc_restoration_struct(&cpi->rst_search[i], cm->width, cm->height); + av1_alloc_restoration_struct(cm, &cpi->rst_search[i], cm->width, + cm->height); #endif // CONFIG_LOOP_RESTORATION if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,