Refactor top linebuf for cdef module
This CL modifies memory allocation and pixel copy of top
linebuf to suit row-level multi-threading implementation.
Change-Id: Iecc028b094be62dfa137e7b3383afd971ad457a4
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index 1ee8a57..174b1f9 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -119,6 +119,7 @@
aom_free(frame_worker_data->pbi->common.tpl_mvs);
frame_worker_data->pbi->common.tpl_mvs = NULL;
av1_remove_common(&frame_worker_data->pbi->common);
+ av1_free_cdef_linebuf(&frame_worker_data->pbi->common);
#if !CONFIG_REALTIME_ONLY
av1_free_restoration_buffers(&frame_worker_data->pbi->common);
#endif
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index cd997cd..1aa0251 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -17,6 +17,7 @@
#include "av1/common/alloccommon.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/blockd.h"
+#include "av1/common/cdef_block.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
@@ -51,6 +52,42 @@
}
}
+void av1_free_cdef_linebuf(AV1_COMMON *const cm) {
+ const int num_planes = av1_num_planes(cm);
+
+ for (uint8_t plane = 0; plane < num_planes; plane++) {
+ if (cm->cdef_info.linebuf[plane] != NULL)
+ aom_free(cm->cdef_info.linebuf[plane]);
+ cm->cdef_info.linebuf[plane] = NULL;
+ }
+}
+
+void av1_alloc_cdef_linebuf(AV1_COMMON *const cm) {
+ const int num_planes = av1_num_planes(cm);
+ const int luma_stride = cm->mi_params.mi_cols << MI_SIZE_LOG2;
+ const int is_frame_scaled =
+ (cm->cdef_info.allocated_mi_cols != cm->mi_params.mi_cols ||
+ cm->cdef_info.allocated_mi_rows != cm->mi_params.mi_rows);
+ // num-bufs=2 represents ping-pong buffers for top linebuf.
+ // this is to avoid linebuf over-write by consecutive row.
+ int num_bufs = 2;
+
+ if (is_frame_scaled) av1_free_cdef_linebuf(cm);
+
+ for (uint8_t plane = 0; plane < num_planes; plane++) {
+ if (cm->cdef_info.linebuf[plane] == NULL) {
+ const int stride =
+ luma_stride >>
+ (plane == AOM_PLANE_Y ? 0 : cm->seq_params.subsampling_x);
+ CHECK_MEM_ERROR(cm, cm->cdef_info.linebuf[plane],
+ aom_malloc(sizeof(*cm->cdef_info.linebuf) * num_bufs *
+ (CDEF_VBORDER << 1) * stride));
+ }
+ }
+ cm->cdef_info.allocated_mi_cols = cm->mi_params.mi_cols;
+ cm->cdef_info.allocated_mi_rows = cm->mi_params.mi_rows;
+}
+
#if !CONFIG_REALTIME_ONLY
// Assumes cm->rst_info[p].restoration_unit_size is already initialized
void av1_alloc_restoration_buffers(AV1_COMMON *cm) {
diff --git a/av1/common/alloccommon.h b/av1/common/alloccommon.h
index e75c226..3d74007 100644
--- a/av1/common/alloccommon.h
+++ b/av1/common/alloccommon.h
@@ -36,6 +36,8 @@
void av1_free_context_buffers(struct AV1Common *cm);
void av1_free_ref_frame_buffers(struct BufferPool *pool);
+void av1_alloc_cdef_linebuf(struct AV1Common *const cm);
+void av1_free_cdef_linebuf(struct AV1Common *const cm);
#if !CONFIG_REALTIME_ONLY
void av1_alloc_restoration_buffers(struct AV1Common *cm);
void av1_free_restoration_buffers(struct AV1Common *cm);
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 0a68cb5..ab82846 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -192,12 +192,17 @@
/*!\brief Parameters related to CDEF */
typedef struct {
+ uint16_t *colbuf[MAX_MB_PLANE]; /*!< CDEF column line buffer */
+ uint16_t *linebuf[MAX_MB_PLANE]; /*!< CDEF top & bottom line buffer */
+ uint16_t *srcbuf; /*!< CDEF intermediate buffer */
int cdef_damping; /*!< CDEF damping factor */
int nb_cdef_strengths; /*!< Number of CDEF strength values */
int cdef_strengths[CDEF_MAX_STRENGTHS]; /*!< CDEF strength values for luma */
int cdef_uv_strengths[CDEF_MAX_STRENGTHS]; /*!< CDEF strength values for
chroma */
- int cdef_bits; /*!< Number of CDEF strength values in bits */
+ int cdef_bits; /*!< Number of CDEF strength values in bits */
+ int allocated_mi_cols; /*!< Number of cols in the frame in 4 pixel */
+ int allocated_mi_rows; /*!< Number of rows in the frame in 4 pixel */
} CdefInfo;
/*!\cond */
diff --git a/av1/common/cdef.c b/av1/common/cdef.c
index d9b5a10..c7ba6c1 100644
--- a/av1/common/cdef.c
+++ b/av1/common/cdef.c
@@ -26,6 +26,7 @@
/*!\brief Parameters related to CDEF Block */
typedef struct {
uint16_t *src;
+ uint16_t *top_linebuf[MAX_MB_PLANE];
uint8_t *dst;
uint16_t *colbuf[MAX_MB_PLANE];
cdef_list dlist[MI_SIZE_64X64 * MI_SIZE_64X64];
@@ -151,20 +152,17 @@
// Inputs:
// cm: Pointer to common structure.
// fb_info: Pointer to the CDEF block-level parameter structure.
-// linebuf: Top feedback buffer for CDEF.
// cdef_left: Left block is filtered or not.
// fbc, fbr: col and row index of a block.
// plane: plane index Y/CB/CR.
-// prev_row_cdef: Top blocks are filtered or not.
// Returns:
// Nothing will be returned.
static void cdef_prepare_fb(AV1_COMMON *cm, CdefBlockInfo *fb_info,
- uint16_t **linebuf, const int *cdef_left, int fbc,
- int fbr, uint8_t plane,
- unsigned char *prev_row_cdef) {
+ const int *cdef_left, int fbc, int fbr,
+ uint8_t plane) {
const CommonModeInfoParams *const mi_params = &cm->mi_params;
uint16_t *src = fb_info->src;
- const int stride = (mi_params->mi_cols << MI_SIZE_LOG2) + 2 * CDEF_HBORDER;
+ const int stride = mi_params->mi_cols << MI_SIZE_LOG2;
const int nvfb = (mi_params->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
const int nhfb = (mi_params->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
int cstart = 0;
@@ -174,6 +172,7 @@
int nvb = AOMMIN(MI_SIZE_64X64, mi_params->mi_rows - MI_SIZE_64X64 * fbr);
int hsize = nhb << fb_info->mi_wide_l2;
int vsize = nvb << fb_info->mi_high_l2;
+ const uint16_t *top_linebuf = fb_info->top_linebuf[plane];
if (fbc == nhfb - 1)
cend = hsize;
@@ -185,12 +184,6 @@
else
rend = vsize + CDEF_VBORDER;
- if (fbc == nhfb - 1) {
- /* On the last superblock column, fill in the right border with
- CDEF_VERY_LARGE to avoid filtering with the outside. */
- fill_rect(&src[cend + CDEF_HBORDER], CDEF_BSTRIDE, rend + CDEF_VBORDER,
- hsize + CDEF_HBORDER - cend, CDEF_VERY_LARGE);
- }
if (fbr == nvfb - 1) {
/* On the last superblock row, fill in the bottom border with
CDEF_VERY_LARGE to avoid filtering with the outside. */
@@ -203,36 +196,23 @@
CDEF_BSTRIDE, fb_info->dst, fb_info->roffset,
fb_info->coffset + cstart, fb_info->dst_stride, rend,
cend - cstart);
- if (!prev_row_cdef[fbc]) {
- copy_sb8_16(cm, &src[CDEF_HBORDER], CDEF_BSTRIDE, fb_info->dst,
- fb_info->roffset - CDEF_VBORDER, fb_info->coffset,
- fb_info->dst_stride, CDEF_VBORDER, hsize);
- } else if (fbr > 0) {
- copy_rect(&src[CDEF_HBORDER], CDEF_BSTRIDE,
- &linebuf[plane][fb_info->coffset], stride, CDEF_VBORDER, hsize);
+ /* Copy in the pixels we need from the current superblock from top buffer.*/
+ if (fbr > 0) {
+ copy_rect(&src[CDEF_HBORDER], CDEF_BSTRIDE, &top_linebuf[fb_info->coffset],
+ stride, CDEF_VBORDER, hsize);
} else {
fill_rect(&src[CDEF_HBORDER], CDEF_BSTRIDE, CDEF_VBORDER, hsize,
CDEF_VERY_LARGE);
}
- if (!prev_row_cdef[fbc - 1]) {
- copy_sb8_16(cm, src, CDEF_BSTRIDE, fb_info->dst,
- fb_info->roffset - CDEF_VBORDER,
- fb_info->coffset - CDEF_HBORDER, fb_info->dst_stride,
- CDEF_VBORDER, CDEF_HBORDER);
- } else if (fbr > 0 && fbc > 0) {
- copy_rect(src, CDEF_BSTRIDE,
- &linebuf[plane][fb_info->coffset - CDEF_HBORDER], stride,
- CDEF_VBORDER, CDEF_HBORDER);
+ if (fbr > 0 && fbc > 0) {
+ copy_rect(src, CDEF_BSTRIDE, &top_linebuf[fb_info->coffset - CDEF_HBORDER],
+ stride, CDEF_VBORDER, CDEF_HBORDER);
} else {
fill_rect(src, CDEF_BSTRIDE, CDEF_VBORDER, CDEF_HBORDER, CDEF_VERY_LARGE);
}
- if (!prev_row_cdef[fbc + 1]) {
- copy_sb8_16(cm, &src[CDEF_HBORDER + hsize], CDEF_BSTRIDE, fb_info->dst,
- fb_info->roffset - CDEF_VBORDER, fb_info->coffset + hsize,
- fb_info->dst_stride, CDEF_VBORDER, CDEF_HBORDER);
- } else if (fbr > 0 && fbc < nhfb - 1) {
+ if (fbr > 0 && fbc < nhfb - 1) {
copy_rect(&src[hsize + CDEF_HBORDER], CDEF_BSTRIDE,
- &linebuf[plane][fb_info->coffset + hsize], stride, CDEF_VBORDER,
+ &top_linebuf[fb_info->coffset + hsize], stride, CDEF_VBORDER,
CDEF_HBORDER);
} else {
fill_rect(&src[hsize + CDEF_HBORDER], CDEF_BSTRIDE, CDEF_VBORDER,
@@ -248,22 +228,11 @@
right. */
copy_rect(fb_info->colbuf[plane], CDEF_HBORDER, src + hsize, CDEF_BSTRIDE,
rend + CDEF_VBORDER, CDEF_HBORDER);
- copy_sb8_16(cm, &linebuf[plane][fb_info->coffset], stride, fb_info->dst,
- (MI_SIZE_64X64 << fb_info->mi_high_l2) * (fbr + 1) - CDEF_VBORDER,
- fb_info->coffset, fb_info->dst_stride, CDEF_VBORDER, hsize);
- if (fb_info->frame_boundary[TOP]) {
- fill_rect(src, CDEF_BSTRIDE, CDEF_VBORDER, hsize + 2 * CDEF_HBORDER,
- CDEF_VERY_LARGE);
- }
if (fb_info->frame_boundary[LEFT]) {
fill_rect(src, CDEF_BSTRIDE, vsize + 2 * CDEF_VBORDER, CDEF_HBORDER,
CDEF_VERY_LARGE);
}
- if (fb_info->frame_boundary[BOTTOM]) {
- fill_rect(&src[(vsize + CDEF_VBORDER) * CDEF_BSTRIDE], CDEF_BSTRIDE,
- CDEF_VBORDER, hsize + 2 * CDEF_HBORDER, CDEF_VERY_LARGE);
- }
if (fb_info->frame_boundary[RIGHT]) {
fill_rect(&src[hsize + CDEF_HBORDER], CDEF_BSTRIDE,
vsize + 2 * CDEF_VBORDER, CDEF_HBORDER, CDEF_VERY_LARGE);
@@ -328,9 +297,8 @@
fb_info->coffset = MI_SIZE_64X64 * fbc << fb_info->mi_wide_l2;
}
-static bool cdef_fb_col(AV1_COMMON *cm, MACROBLOCKD *xd, CdefBlockInfo *fb_info,
- int fbc, int fbr, int *cdef_left, uint16_t **linebuf,
- unsigned char *prev_row_cdef) {
+static void cdef_fb_col(AV1_COMMON *cm, MACROBLOCKD *xd, CdefBlockInfo *fb_info,
+ int *cdef_left, int fbc, int fbr) {
const CommonModeInfoParams *const mi_params = &cm->mi_params;
const int mbmi_cdef_strength =
mi_params
@@ -343,7 +311,7 @@
MI_SIZE_64X64 * fbc] == NULL ||
mbmi_cdef_strength == -1) {
*cdef_left = 0;
- return 0;
+ return;
}
for (uint8_t plane = 0; plane < num_planes; plane++) {
cdef_init_fb_col(xd, &cm->cdef_info, fb_info, mbmi_cdef_strength, fbc, fbr,
@@ -353,20 +321,21 @@
mi_params, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64,
fb_info->dlist, BLOCK_64X64)) == 0) {
*cdef_left = 0;
- return 0;
+ return;
}
- cdef_prepare_fb(cm, fb_info, linebuf, cdef_left, fbc, fbr, plane,
- prev_row_cdef);
+ cdef_prepare_fb(cm, fb_info, cdef_left, fbc, fbr, plane);
cdef_filter_fb(fb_info, plane, cm->seq_params.use_highbitdepth);
}
*cdef_left = 1;
- return 1;
}
-static INLINE void cdef_init_fb_row(CdefBlockInfo *fb_info, int mi_rows,
- int fbr) {
- const int nvfb = (mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
-
+static INLINE void cdef_init_fb_row(AV1_COMMON *cm, const MACROBLOCKD *const xd,
+ CdefBlockInfo *const fb_info,
+ uint16_t **const linebuf, int fbr) {
+ const int num_planes = av1_num_planes(cm);
+ const int nvfb = (cm->mi_params.mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
+ const int stride = cm->mi_params.mi_cols << MI_SIZE_LOG2;
+ const bool ping_pong = fbr & 1;
// for the current filter block, it's top left corner mi structure (mi_tl)
// is first accessed to check whether the top and left boundaries are
// frame boundaries. Then bottom-left and top-right mi structures are
@@ -379,19 +348,33 @@
fb_info->frame_boundary[TOP] = (MI_SIZE_64X64 * fbr == 0) ? 1 : 0;
if (fbr != nvfb - 1)
fb_info->frame_boundary[BOTTOM] =
- (MI_SIZE_64X64 * (fbr + 1) == mi_rows) ? 1 : 0;
+ (MI_SIZE_64X64 * (fbr + 1) == cm->mi_params.mi_rows) ? 1 : 0;
else
fb_info->frame_boundary[BOTTOM] = 1;
+
+ for (uint8_t plane = 0; plane < num_planes; plane++) {
+ const int mi_high_l2 = MI_SIZE_LOG2 - xd->plane[plane].subsampling_y;
+ const int offset = MI_SIZE_64X64 * (fbr + 1) << mi_high_l2;
+ // here ping-pong buffers are maintained for top linebuf
+ // to avoid linebuf over-write by consecutive row.
+ uint16_t *const top_linebuf =
+ &linebuf[plane][ping_pong * CDEF_VBORDER * stride];
+
+ if (fbr != nvfb - 1) // top line buffer copy
+ copy_sb8_16(cm, top_linebuf, stride, xd->plane[plane].dst.buf,
+ offset - CDEF_VBORDER, 0, xd->plane[plane].dst.stride,
+ CDEF_VBORDER, stride);
+ fb_info->top_linebuf[plane] =
+ &linebuf[plane][(!ping_pong) * CDEF_VBORDER * stride];
+ }
}
static void cdef_fb_row(AV1_COMMON *cm, MACROBLOCKD *xd, CdefBlockInfo *fb_info,
- uint16_t **linebuf, int fbr,
- unsigned char *curr_row_cdef,
- unsigned char *prev_row_cdef) {
+ uint16_t **const linebuf, int fbr) {
int cdef_left = 1;
const int nhfb = (cm->mi_params.mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
- cdef_init_fb_row(fb_info, cm->mi_params.mi_rows, fbr);
+ cdef_init_fb_row(cm, xd, fb_info, linebuf, fbr);
for (int fbc = 0; fbc < nhfb; fbc++) {
fb_info->frame_boundary[LEFT] = (MI_SIZE_64X64 * fbc == 0) ? 1 : 0;
if (fbc != nhfb - 1)
@@ -399,8 +382,7 @@
(MI_SIZE_64X64 * (fbc + 1) == cm->mi_params.mi_cols) ? 1 : 0;
else
fb_info->frame_boundary[RIGHT] = 1;
- curr_row_cdef[fbc] = cdef_fb_col(cm, xd, fb_info, fbc, fbr, &cdef_left,
- linebuf, prev_row_cdef);
+ cdef_fb_col(cm, xd, fb_info, &cdef_left, fbc, fbr);
}
}
@@ -411,21 +393,17 @@
// xd: Pointer to common current coding block structure.
// fb_info: Pointer to the CDEF block-level parameter structure.
// src: Intermediate input buffer for CDEF.
-// colbuf: Left feedback buffer for CDEF.
-// linebuf: Top feedback buffer for CDEF.
+// colbuf: Left line buffer for CDEF.
// Returns:
// Nothing will be returned.
static void cdef_prepare_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm,
MACROBLOCKD *xd, CdefBlockInfo *fb_info,
- uint16_t *src, uint16_t **colbuf,
- uint16_t **linebuf) {
+ uint16_t *src, uint16_t **colbuf) {
const int num_planes = av1_num_planes(cm);
- const int stride = (cm->mi_params.mi_cols << MI_SIZE_LOG2) + 2 * CDEF_HBORDER;
av1_setup_dst_planes(xd->plane, cm->seq_params.sb_size, frame, 0, 0, 0,
num_planes);
for (uint8_t plane = 0; plane < num_planes; plane++) {
- linebuf[plane] = aom_malloc(sizeof(*linebuf) * CDEF_VBORDER * stride);
const int mi_high_l2 = MI_SIZE_LOG2 - xd->plane[plane].subsampling_y;
const int block_height = (MI_SIZE_64X64 << mi_high_l2) + 2 * CDEF_VBORDER;
colbuf[plane] = aom_malloc(
@@ -445,13 +423,8 @@
memset(fb_info->var, 0, sizeof(fb_info->var));
}
-static void cdef_free(unsigned char *row_cdef, uint16_t **colbuf,
- uint16_t **linebuf, const int num_planes) {
- aom_free(row_cdef);
- for (uint8_t plane = 0; plane < num_planes; plane++) {
- aom_free(colbuf[plane]);
- aom_free(linebuf[plane]);
- }
+static void cdef_free(uint16_t **colbuf, const int num_planes) {
+ for (uint8_t plane = 0; plane < num_planes; plane++) aom_free(colbuf[plane]);
}
// Perform CDEF on input frame.
@@ -465,25 +438,14 @@
MACROBLOCKD *xd) {
DECLARE_ALIGNED(16, uint16_t, src[CDEF_INBUF_SIZE]);
uint16_t *colbuf[MAX_MB_PLANE] = { NULL };
- uint16_t *linebuf[MAX_MB_PLANE] = { NULL };
CdefBlockInfo fb_info;
- unsigned char *row_cdef, *prev_row_cdef, *curr_row_cdef;
const int num_planes = av1_num_planes(cm);
const int nvfb = (cm->mi_params.mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
- const int nhfb = (cm->mi_params.mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
- row_cdef = aom_malloc(sizeof(*row_cdef) * (nhfb + 2) * 2);
- memset(row_cdef, 1, sizeof(*row_cdef) * (nhfb + 2) * 2);
- prev_row_cdef = row_cdef + 1;
- curr_row_cdef = prev_row_cdef + nhfb + 2;
- cdef_prepare_frame(frame, cm, xd, &fb_info, src, colbuf, linebuf);
+ cdef_prepare_frame(frame, cm, xd, &fb_info, src, colbuf);
- for (int fbr = 0; fbr < nvfb; fbr++) {
- unsigned char *tmp;
- cdef_fb_row(cm, xd, &fb_info, linebuf, fbr, curr_row_cdef, prev_row_cdef);
- tmp = prev_row_cdef;
- prev_row_cdef = curr_row_cdef;
- curr_row_cdef = tmp;
- }
- cdef_free(row_cdef, colbuf, linebuf, num_planes);
+ for (int fbr = 0; fbr < nvfb; fbr++)
+ cdef_fb_row(cm, xd, &fb_info, cm->cdef_info.linebuf, fbr);
+
+ cdef_free(colbuf, num_planes);
}
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 58629e0..42fb925 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -5222,6 +5222,7 @@
static AOM_INLINE void setup_frame_info(AV1Decoder *pbi) {
AV1_COMMON *const cm = &pbi->common;
+ av1_alloc_cdef_linebuf(cm);
#if !CONFIG_REALTIME_ONLY
if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 1e98940..29fb21c 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2092,6 +2092,9 @@
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Failed to allocate frame buffer");
+ const int use_cdef = cm->seq_params.enable_cdef && !cm->tiles.large_scale;
+ if (!is_stat_generation_stage(cpi) && use_cdef) av1_alloc_cdef_linebuf(cm);
+
#if !CONFIG_REALTIME_ONLY
const int use_restoration = cm->seq_params.enable_restoration &&
!cm->features.all_lossless &&
@@ -2108,6 +2111,7 @@
av1_alloc_restoration_buffers(cm);
}
#endif
+
if (!is_stat_generation_stage(cpi)) alloc_util_frame_buffers(cpi);
init_motion_estimation(cpi);
diff --git a/av1/encoder/encoder_alloc.h b/av1/encoder/encoder_alloc.h
index 3655bf9..6049e74 100644
--- a/av1/encoder/encoder_alloc.h
+++ b/av1/encoder/encoder_alloc.h
@@ -252,6 +252,9 @@
#if !CONFIG_REALTIME_ONLY
av1_free_restoration_buffers(cm);
#endif
+ const int use_cdef = cm->seq_params.enable_cdef && !cm->tiles.large_scale;
+ if (use_cdef) av1_free_cdef_linebuf(cm);
+
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/encoder_utils.h b/av1/encoder/encoder_utils.h
index 40652e9..936141e 100644
--- a/av1/encoder/encoder_utils.h
+++ b/av1/encoder/encoder_utils.h
@@ -875,6 +875,15 @@
}
}
+static AOM_INLINE void restore_cdef_coding_context(CdefInfo *const dst,
+ const CdefInfo *const src) {
+ dst->cdef_bits = src->cdef_bits;
+ dst->cdef_damping = src->cdef_damping;
+ av1_copy(dst->cdef_strengths, src->cdef_strengths);
+ av1_copy(dst->cdef_uv_strengths, src->cdef_uv_strengths);
+ dst->nb_cdef_strengths = src->nb_cdef_strengths;
+}
+
// Coding context that only needs to be restored when recode loop includes
// filtering (deblocking, CDEF, superres post-encode upscale and/or loop
// restoraton).
@@ -882,7 +891,7 @@
CODING_CONTEXT *const cc = &cpi->coding_context;
AV1_COMMON *cm = &cpi->common;
cm->lf = cc->lf;
- cm->cdef_info = cc->cdef_info;
+ restore_cdef_coding_context(&cm->cdef_info, &cc->cdef_info);
cpi->rc = cc->rc;
cpi->mv_stats = cc->mv_stats;
}