diff --git a/aom_scale/aom_scale.h b/aom_scale/aom_scale.h index 6e089f5aaa13e98896c47a42f8f6f60f69b58c50..a4aef6c654e089b8eaeefbceed2e4b77eda66682 100644 --- a/aom_scale/aom_scale.h +++ b/aom_scale/aom_scale.h @@ -18,6 +18,6 @@ extern void aom_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, unsigned char *temp_area, unsigned char temp_height, unsigned int hscale, unsigned int hratio, unsigned int vscale, unsigned int vratio, - unsigned int interlaced); + unsigned int interlaced, const int num_planes); #endif // AOM_SCALE_AOM_SCALE_H_ diff --git a/aom_scale/aom_scale_rtcd.pl b/aom_scale/aom_scale_rtcd.pl index 62c6b3cb7ca358c8db96b011647029892c6ddac2..f6cfe1322c7cc1c712aaf68d9c3a1ae6398801da 100644 --- a/aom_scale/aom_scale_rtcd.pl +++ b/aom_scale/aom_scale_rtcd.pl @@ -26,9 +26,9 @@ if (aom_config("CONFIG_SPATIAL_RESAMPLING") eq "yes") { add_proto qw/void aom_vertical_band_2_1_scale_i/, "unsigned char *source, int src_pitch, unsigned char *dest, int dest_pitch, unsigned int dest_width"; } -add_proto qw/void aom_yv12_extend_frame_borders/, "struct yv12_buffer_config *ybf"; +add_proto qw/void aom_yv12_extend_frame_borders/, "struct yv12_buffer_config *ybf, const int num_planes"; -add_proto qw/void aom_yv12_copy_frame/, "const struct yv12_buffer_config *src_bc, struct yv12_buffer_config *dst_bc"; +add_proto qw/void aom_yv12_copy_frame/, "const struct yv12_buffer_config *src_bc, struct yv12_buffer_config *dst_bc, const int num_planes"; add_proto qw/void aom_yv12_copy_y/, "const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc"; @@ -37,10 +37,10 @@ add_proto qw/void aom_yv12_copy_u/, "const struct yv12_buffer_config *src_bc, st add_proto qw/void aom_yv12_copy_v/, "const struct yv12_buffer_config *src_bc, struct yv12_buffer_config *dst_bc"; if (aom_config("CONFIG_AV1") eq "yes") { - add_proto qw/void aom_extend_frame_borders/, "struct yv12_buffer_config *ybf"; + add_proto qw/void aom_extend_frame_borders/, "struct yv12_buffer_config *ybf, const int num_planes"; specialize qw/aom_extend_frame_borders dspr2/; - add_proto qw/void aom_extend_frame_inner_borders/, "struct yv12_buffer_config *ybf"; + add_proto qw/void aom_extend_frame_inner_borders/, "struct yv12_buffer_config *ybf, const int num_planes"; specialize qw/aom_extend_frame_inner_borders dspr2/; add_proto qw/void aom_extend_frame_borders_y/, "struct yv12_buffer_config *ybf"; diff --git a/aom_scale/generic/aom_scale.c b/aom_scale/generic/aom_scale.c index d124832b79b8b60470c5199874dab95a53c5f292..1e4adadf65fa5a5fe997d07d3d0cf4250156be21 100644 --- a/aom_scale/generic/aom_scale.c +++ b/aom_scale/generic/aom_scale.c @@ -475,11 +475,11 @@ void aom_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst, unsigned char *temp_area, unsigned char temp_height, unsigned int hscale, unsigned int hratio, unsigned int vscale, unsigned int vratio, - unsigned int interlaced) { + unsigned int interlaced, const int num_planes) { const int dw = (hscale - 1 + src->y_width * hratio) / hscale; const int dh = (vscale - 1 + src->y_height * vratio) / vscale; - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const int is_uv = plane > 0; const int plane_dw = dw >> is_uv; const int plane_dh = dh >> is_uv; diff --git a/aom_scale/generic/yv12extend.c b/aom_scale/generic/yv12extend.c index 3cfed30217a2e38a5b8a6a48cc69690741f9410e..e06022fcbd661868fb3074e5eaba9fcf7b7240a5 100644 --- a/aom_scale/generic/yv12extend.c +++ b/aom_scale/generic/yv12extend.c @@ -98,7 +98,8 @@ static void extend_plane_high(uint8_t *const src8, int src_stride, int width, } } -void aom_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { +void aom_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf, + const int num_planes) { assert(ybf->border % 2 == 0); assert(ybf->y_height - ybf->y_crop_height < 16); assert(ybf->y_width - ybf->y_crop_width < 16); @@ -106,7 +107,7 @@ void aom_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { assert(ybf->y_width - ybf->y_crop_width >= 0); if (ybf->flags & YV12_FLAG_HIGHBITDEPTH) { - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const int is_uv = plane > 0; const int plane_border = ybf->border >> is_uv; extend_plane_high( @@ -117,7 +118,7 @@ void aom_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { } return; } - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const int is_uv = plane > 0; const int plane_border = ybf->border >> is_uv; extend_plane(ybf->buffers[plane], ybf->strides[is_uv], @@ -129,7 +130,8 @@ void aom_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { } #if CONFIG_AV1 -static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { +static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size, + const int num_planes) { const int ss_x = ybf->uv_width < ybf->y_width; const int ss_y = ybf->uv_height < ybf->y_height; @@ -139,7 +141,7 @@ static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { assert(ybf->y_width - ybf->y_crop_width >= 0); if (ybf->flags & YV12_FLAG_HIGHBITDEPTH) { - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const int is_uv = plane > 0; const int top = ext_size >> (is_uv ? ss_y : 0); const int left = ext_size >> (is_uv ? ss_x : 0); @@ -151,7 +153,7 @@ static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { } return; } - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const int is_uv = plane > 0; const int top = ext_size >> (is_uv ? ss_y : 0); const int left = ext_size >> (is_uv ? ss_x : 0); @@ -163,15 +165,16 @@ static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { } } -void aom_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { - extend_frame(ybf, ybf->border); +void aom_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf, const int num_planes) { + extend_frame(ybf, ybf->border, num_planes); } -void aom_extend_frame_inner_borders_c(YV12_BUFFER_CONFIG *ybf) { +void aom_extend_frame_inner_borders_c(YV12_BUFFER_CONFIG *ybf, + const int num_planes) { const int inner_bw = (ybf->border > AOMINNERBORDERINPIXELS) ? AOMINNERBORDERINPIXELS : ybf->border; - extend_frame(ybf, inner_bw); + extend_frame(ybf, inner_bw, num_planes); } void aom_extend_frame_borders_y_c(YV12_BUFFER_CONFIG *ybf) { @@ -205,7 +208,7 @@ static void memcpy_short_addr(uint8_t *dst8, const uint8_t *src8, int num) { // destination's UMV borders. // Note: The frames are assumed to be identical in size. void aom_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_bc, - YV12_BUFFER_CONFIG *dst_bc) { + YV12_BUFFER_CONFIG *dst_bc, const int num_planes) { #if 0 /* These assertions are valid in the codec, but the libaom-tester uses * this code slightly differently. @@ -218,7 +221,7 @@ void aom_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_bc, (dst_bc->flags & YV12_FLAG_HIGHBITDEPTH)); if (src_bc->flags & YV12_FLAG_HIGHBITDEPTH) { - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const uint8_t *plane_src = src_bc->buffers[plane]; uint8_t *plane_dst = dst_bc->buffers[plane]; const int is_uv = plane > 0; @@ -229,10 +232,10 @@ void aom_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_bc, plane_dst += dst_bc->strides[is_uv]; } } - aom_yv12_extend_frame_borders_c(dst_bc); + aom_yv12_extend_frame_borders_c(dst_bc, num_planes); return; } - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const uint8_t *plane_src = src_bc->buffers[plane]; uint8_t *plane_dst = dst_bc->buffers[plane]; const int is_uv = plane > 0; @@ -243,7 +246,7 @@ void aom_yv12_copy_frame_c(const YV12_BUFFER_CONFIG *src_bc, plane_dst += dst_bc->strides[is_uv]; } } - aom_yv12_extend_frame_borders_c(dst_bc); + aom_yv12_extend_frame_borders_c(dst_bc, num_planes); } void aom_yv12_copy_y_c(const YV12_BUFFER_CONFIG *src_ybc, diff --git a/aom_scale/mips/dspr2/yv12extend_dspr2.c b/aom_scale/mips/dspr2/yv12extend_dspr2.c index 51192f7b93ec8857bef514f34015deccf8f85059..d03884821808437f5515066750dab490734050c6 100644 --- a/aom_scale/mips/dspr2/yv12extend_dspr2.c +++ b/aom_scale/mips/dspr2/yv12extend_dspr2.c @@ -126,14 +126,16 @@ static void extend_frame(YV12_BUFFER_CONFIG *const ybf, int ext_size) { extend_plane(ybf->v_buffer, ybf->uv_stride, c_w, c_h, c_et, c_el, c_eb, c_er); } -void aom_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf) { - extend_frame(ybf, ybf->border); +void aom_extend_frame_borders_dspr2(YV12_BUFFER_CONFIG *ybf, + const int num_planes) { + extend_frame(ybf, ybf->border, num_planes); } -void aom_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf) { +void aom_extend_frame_inner_borders_dspr2(YV12_BUFFER_CONFIG *ybf, + const int num_planes) { const int inner_bw = (ybf->border > AOMINNERBORDERINPIXELS) ? AOMINNERBORDERINPIXELS : ybf->border; - extend_frame(ybf, inner_bw); + extend_frame(ybf, inner_bw, num_planes); } #endif diff --git a/aom_util/debug_util.c b/aom_util/debug_util.c index 4f9bdc1df208f9eff09c494cca1644e2215a5e72..cf3fb24d838709841ced6fe75f5d28871e27142d 100644 --- a/aom_util/debug_util.c +++ b/aom_util/debug_util.c @@ -98,8 +98,8 @@ void mismatch_move_frame_idx_w() { } } -void mismatch_reset_frame() { - for (int plane = 0; plane < 3; ++plane) { +void mismatch_reset_frame(int num_planes) { + for (int plane = 0; plane < num_planes; ++plane) { memset(frame_pre[frame_buf_idx_w][plane], 0, sizeof(frame_pre[frame_buf_idx_w][plane][0]) * frame_size); memset(frame_tx[frame_buf_idx_w][plane], 0, diff --git a/aom_util/debug_util.h b/aom_util/debug_util.h index 11c1296e0bf69e6e5f7a8a701f1fefe5b858c824..0b2ea050dfd58619787e5889b08320d8b8818656 100644 --- a/aom_util/debug_util.h +++ b/aom_util/debug_util.h @@ -46,7 +46,7 @@ void bitstream_queue_set_skip_read(int skip); #if CONFIG_MISMATCH_DEBUG void mismatch_move_frame_idx_w(); void mismatch_move_frame_idx_r(); -void mismatch_reset_frame(); +void mismatch_reset_frame(int num_planes); void mismatch_record_block_pre(const uint8_t *src, int src_stride, int plane, int pixel_c, int pixel_r, int blk_w, int blk_h); void mismatch_record_block_tx(const uint8_t *src, int src_stride, int plane, diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c index ab0f98b423fac476f55c30237d6d7a005f360be7..ccc7851f4f9b62bb133be8419fc3203c3d2fc733 100644 --- a/av1/av1_dx_iface.c +++ b/av1/av1_dx_iface.c @@ -886,6 +886,7 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx, yuvconfig2image(&ctx->img, &sd, frame_worker_data->user_priv); #if CONFIG_EXT_TILE + const int num_planes = av1_num_planes(cm); if (cm->single_tile_decoding && frame_worker_data->pbi->dec_tile_row >= 0) { const int tile_row = @@ -894,9 +895,11 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx, const int ssy = ctx->img.y_chroma_shift; int plane; ctx->img.planes[0] += mi_row * MI_SIZE * ctx->img.stride[0]; - for (plane = 1; plane < MAX_MB_PLANE; ++plane) { - ctx->img.planes[plane] += - mi_row * (MI_SIZE >> ssy) * ctx->img.stride[plane]; + if (num_planes > 1) { + for (plane = 1; plane < MAX_MB_PLANE; ++plane) { + ctx->img.planes[plane] += + mi_row * (MI_SIZE >> ssy) * ctx->img.stride[plane]; + } } ctx->img.d_h = AOMMIN(cm->tile_height, cm->mi_rows - mi_row) * MI_SIZE; @@ -910,8 +913,10 @@ static aom_image_t *decoder_get_frame(aom_codec_alg_priv_t *ctx, const int ssx = ctx->img.x_chroma_shift; int plane; ctx->img.planes[0] += mi_col * MI_SIZE; - for (plane = 1; plane < MAX_MB_PLANE; ++plane) { - ctx->img.planes[plane] += mi_col * (MI_SIZE >> ssx); + if (num_planes > 1) { + for (plane = 1; plane < MAX_MB_PLANE; ++plane) { + ctx->img.planes[plane] += mi_col * (MI_SIZE >> ssx); + } } ctx->img.d_w = AOMMIN(cm->tile_width, cm->mi_cols - mi_col) * MI_SIZE; diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c index 5e072bc240e54130a1cae82baaacf1b7d25cd993..5e3e68152fb559b4c229343b6dfcf44eafa51a17 100644 --- a/av1/common/alloccommon.c +++ b/av1/common/alloccommon.c @@ -109,7 +109,8 @@ void av1_free_ref_frame_buffers(BufferPool *pool) { #if CONFIG_LOOP_RESTORATION // Assumes cm->rst_info[p].restoration_unit_size is already initialized void av1_alloc_restoration_buffers(AV1_COMMON *cm) { - for (int p = 0; p < MAX_MB_PLANE; ++p) + const int num_planes = av1_num_planes(cm); + for (int p = 0; p < num_planes; ++p) av1_alloc_restoration_struct(cm, &cm->rst_info[p], p > 0); aom_free(cm->rst_tmpbuf); CHECK_MEM_ERROR(cm, cm->rst_tmpbuf, @@ -148,7 +149,7 @@ void av1_alloc_restoration_buffers(AV1_COMMON *cm) { #endif // CONFIG_HORZONLY_FRAME_SUPERRES const int use_highbd = cm->use_highbitdepth ? 1 : 0; - for (int p = 0; p < MAX_MB_PLANE; ++p) { + for (int p = 0; p < num_planes; ++p) { const int is_uv = p > 0; const int ss_x = is_uv && cm->subsampling_x; const int plane_w = ((frame_w + ss_x) >> ss_x) + 2 * RESTORATION_EXTRA_HORZ; @@ -170,13 +171,14 @@ void av1_alloc_restoration_buffers(AV1_COMMON *cm) { } void av1_free_restoration_buffers(AV1_COMMON *cm) { + const int num_planes = av1_num_planes(cm); int p; - for (p = 0; p < MAX_MB_PLANE; ++p) + for (p = 0; p < num_planes; ++p) av1_free_restoration_struct(&cm->rst_info[p]); aom_free(cm->rst_tmpbuf); cm->rst_tmpbuf = NULL; #if CONFIG_STRIPED_LOOP_RESTORATION - for (p = 0; p < MAX_MB_PLANE; ++p) { + for (p = 0; p < num_planes; ++p) { RestorationStripeBoundaries *boundaries = &cm->rst_info[p].boundaries; aom_free(boundaries->stripe_boundary_above); aom_free(boundaries->stripe_boundary_below); @@ -188,6 +190,7 @@ void av1_free_restoration_buffers(AV1_COMMON *cm) { #endif // CONFIG_LOOP_RESTORATION void av1_free_context_buffers(AV1_COMMON *cm) { + const int num_planes = av1_num_planes(cm); int i; cm->free_mi(cm); @@ -198,7 +201,7 @@ void av1_free_context_buffers(AV1_COMMON *cm) { #if !CONFIG_SEGMENT_PRED_LAST free_seg_map(cm); #endif - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { aom_free(cm->above_context[i]); cm->above_context[i] = NULL; } @@ -208,13 +211,14 @@ void av1_free_context_buffers(AV1_COMMON *cm) { aom_free(cm->above_txfm_context); cm->above_txfm_context = NULL; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { aom_free(cm->top_txfm_context[i]); cm->top_txfm_context[i] = NULL; } } int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) { + const int num_planes = av1_num_planes(cm); int new_mi_size; av1_set_mb_mi(cm, width, height); @@ -250,7 +254,7 @@ int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) { ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2); int i; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { aom_free(cm->above_context[i]); cm->above_context[i] = (ENTROPY_CONTEXT *)aom_calloc( aligned_mi_cols << (MI_SIZE_LOG2 - tx_size_wide_log2[0]), @@ -268,7 +272,7 @@ int av1_alloc_context_buffers(AV1_COMMON *cm, int width, int height) { aligned_mi_cols << TX_UNIT_WIDE_LOG2, sizeof(*cm->above_txfm_context)); if (!cm->above_txfm_context) goto fail; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { aom_free(cm->top_txfm_context[i]); cm->top_txfm_context[i] = (TXFM_CONTEXT *)aom_calloc(aligned_mi_cols << TX_UNIT_WIDE_LOG2, diff --git a/av1/common/av1_loopfilter.c b/av1/common/av1_loopfilter.c index 805133d45f1b91bb45b63d946918a4e46119be89..eef33dbd55536a3b21a5b9c52aaa5e3f76ec925d 100644 --- a/av1/common/av1_loopfilter.c +++ b/av1/common/av1_loopfilter.c @@ -2394,6 +2394,7 @@ static void av1_filter_block_plane_horz( void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm, struct macroblockd_plane *planes, int start, int stop, int y_only) { + const int num_planes = av1_num_planes(cm); #if CONFIG_LOOPFILTER_LEVEL // y_only no longer has its original meaning. // Here it means which plane to filter @@ -2402,9 +2403,9 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm, const int plane_start = y_only; const int plane_end = plane_start + 1; #else - const int num_planes = y_only ? 1 : MAX_MB_PLANE; + const int nplanes = y_only ? 1 : num_planes; const int plane_start = 0; - const int plane_end = num_planes; + const int plane_end = nplanes; #endif // CONFIG_LOOPFILTER_LEVEL #if CONFIG_PARALLEL_DEBLOCKING const int col_start = 0; @@ -2414,11 +2415,11 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm, int plane; #if !CONFIG_PARALLEL_DEBLOCKING - for (int i = 0; i < MAX_MB_PLANE; ++i) + for (int i = 0; i < nplanes; ++i) memset(cm->top_txfm_context[i], TX_32X32, cm->mi_cols << TX_UNIT_WIDE_LOG2); for (mi_row = start; mi_row < stop; mi_row += cm->mib_size) { MODE_INFO **mi = cm->mi_grid_visible + mi_row * cm->mi_stride; - for (int i = 0; i < MAX_MB_PLANE; ++i) + for (int i = 0; i < nplanes; ++i) memset(cm->left_txfm_context[i], TX_32X32, MAX_MIB_SIZE << TX_UNIT_HIGH_LOG2); for (mi_col = 0; mi_col < cm->mi_cols; mi_col += cm->mib_size) { @@ -2437,7 +2438,8 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm, // filter all vertical edges in every 64x64 super block for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) { for (mi_col = col_start; mi_col < col_end; mi_col += MAX_MIB_SIZE) { - av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col); + av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col, + num_planes); for (plane = plane_start; plane < plane_end; ++plane) { av1_filter_block_plane_vert(cm, plane, &planes[plane], mi_row, mi_col); } @@ -2447,7 +2449,8 @@ void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, AV1_COMMON *cm, // filter all horizontal edges in every 64x64 super block for (mi_row = start; mi_row < stop; mi_row += MAX_MIB_SIZE) { for (mi_col = col_start; mi_col < col_end; mi_col += MAX_MIB_SIZE) { - av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col); + av1_setup_dst_planes(planes, cm->sb_size, frame_buffer, mi_row, mi_col, + num_planes); for (plane = plane_start; plane < plane_end; ++plane) { av1_filter_block_plane_horz(cm, plane, &planes[plane], mi_row, mi_col); } diff --git a/av1/common/blockd.c b/av1/common/blockd.c index 83a41d7e52dc349b35907aa55112cdd56030b3ec..d6cc975818a58cfc55949cfc567d30ab25717256 100644 --- a/av1/common/blockd.c +++ b/av1/common/blockd.c @@ -85,10 +85,8 @@ void av1_foreach_transformed_block_in_plane( void av1_foreach_transformed_block(const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int mi_row, int mi_col, foreach_transformed_block_visitor visit, - void *arg) { - int plane; - - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { + void *arg, const int num_planes) { + for (int plane = 0; plane < num_planes; ++plane) { if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y)) @@ -136,14 +134,14 @@ void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, } } void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize) { + BLOCK_SIZE bsize, const int num_planes) { int i; int nplanes; int chroma_ref; chroma_ref = is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, xd->plane[1].subsampling_y); - nplanes = 1 + (MAX_MB_PLANE - 1) * chroma_ref; + nplanes = 1 + (num_planes - 1) * chroma_ref; for (i = 0; i < nplanes; i++) { struct macroblockd_plane *const pd = &xd->plane[i]; const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); @@ -155,18 +153,19 @@ void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, } #if CONFIG_LOOP_RESTORATION -void av1_reset_loop_restoration(MACROBLOCKD *xd) { - for (int p = 0; p < MAX_MB_PLANE; ++p) { +void av1_reset_loop_restoration(MACROBLOCKD *xd, const int num_planes) { + for (int p = 0; p < num_planes; ++p) { set_default_wiener(xd->wiener_info + p); set_default_sgrproj(xd->sgrproj_info + p); } } #endif // CONFIG_LOOP_RESTORATION -void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) { +void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y, + const int num_planes) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].plane_type = get_plane_type(i); xd->plane[i].subsampling_x = i ? ss_x : 0; xd->plane[i].subsampling_y = i ? ss_y : 0; diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 3008958cf97b7d38f75b64cec0771b52fbf8a762..5c5d91cc43edfd3e5e066b066e042df4ae9c794c 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h @@ -990,7 +990,8 @@ static INLINE TX_TYPE av1_get_tx_type(PLANE_TYPE plane_type, return intra_type; } -void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y); +void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y, + const int num_planes); static INLINE int bsize_to_max_depth(BLOCK_SIZE bsize, int is_inter) { TX_SIZE tx_size = get_max_rect_tx_size(bsize, is_inter); @@ -1055,10 +1056,10 @@ static INLINE TX_SIZE av1_get_tx_size(int plane, const MACROBLOCKD *xd) { } void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize); + BLOCK_SIZE bsize, const int num_planes); #if CONFIG_LOOP_RESTORATION -void av1_reset_loop_restoration(MACROBLOCKD *xd); +void av1_reset_loop_restoration(MACROBLOCKD *xd, const int num_planes); #endif // CONFIG_LOOP_RESTORATION typedef void (*foreach_transformed_block_visitor)(int plane, int block, @@ -1074,7 +1075,7 @@ void av1_foreach_transformed_block_in_plane( void av1_foreach_transformed_block(const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int mi_row, int mi_col, foreach_transformed_block_visitor visit, - void *arg); + void *arg, const int num_planes); #endif void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, diff --git a/av1/common/cdef.c b/av1/common/cdef.c index d82d060e8c1f65f758599bfb120d94d84e928c02..bd37b2bd4530f46e5f3b804c79cbee8721484177 100644 --- a/av1/common/cdef.c +++ b/av1/common/cdef.c @@ -150,6 +150,7 @@ static INLINE void copy_rect(uint16_t *dst, int dstride, const uint16_t *src, void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, MACROBLOCKD *xd) { + const int num_planes = av1_num_planes(cm); DECLARE_ALIGNED(16, uint16_t, src[CDEF_INBUF_SIZE]); uint16_t *linebuf[3]; uint16_t *colbuf[3]; @@ -163,22 +164,21 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, int xdec[3]; int ydec[3]; int coeff_shift = AOMMAX(cm->bit_depth - 8, 0); - int nplanes = av1_num_planes(cm); const int nvfb = (cm->mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64; const int nhfb = (cm->mi_cols + MI_SIZE_64X64 - 1) / MI_SIZE_64X64; - av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0); + av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0, num_planes); 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; - for (int pli = 0; pli < nplanes; pli++) { + for (int pli = 0; pli < num_planes; pli++) { xdec[pli] = xd->plane[pli].subsampling_x; ydec[pli] = xd->plane[pli].subsampling_y; mi_wide_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_x; mi_high_l2[pli] = MI_SIZE_LOG2 - xd->plane[pli].subsampling_y; } const int stride = (cm->mi_cols << MI_SIZE_LOG2) + 2 * CDEF_HBORDER; - for (int pli = 0; pli < nplanes; pli++) { + for (int pli = 0; pli < num_planes; pli++) { linebuf[pli] = aom_malloc(sizeof(*linebuf) * CDEF_VBORDER * stride); colbuf[pli] = aom_malloc(sizeof(*colbuf) * @@ -186,7 +186,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, CDEF_HBORDER); } for (int fbr = 0; fbr < nvfb; fbr++) { - for (int pli = 0; pli < nplanes; pli++) { + for (int pli = 0; pli < num_planes; pli++) { const int block_height = (MI_SIZE_64X64 << mi_high_l2[pli]) + 2 * CDEF_VBORDER; fill_rect(colbuf[pli], CDEF_HBORDER, block_height, CDEF_HBORDER, @@ -276,7 +276,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, } curr_row_cdef[fbc] = 1; - for (int pli = 0; pli < nplanes; pli++) { + for (int pli = 0; pli < num_planes; pli++) { int coffset; int rend, cend; int pri_damping = cm->cdef_pri_damping; @@ -423,7 +423,7 @@ void av1_cdef_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, } } aom_free(row_cdef); - for (int pli = 0; pli < nplanes; pli++) { + for (int pli = 0; pli < num_planes; pli++) { aom_free(linebuf[pli]); aom_free(colbuf[pli]); } diff --git a/av1/common/obmc.h b/av1/common/obmc.h index 5ad4d2980cdb85590e25e6f0afdf583fdceea814..53301e7ff6d03d474c99b607d90f68393c3ff3af 100644 --- a/av1/common/obmc.h +++ b/av1/common/obmc.h @@ -14,13 +14,14 @@ typedef void (*overlappable_nb_visitor_t)(MACROBLOCKD *xd, int rel_mi_pos, uint8_t nb_mi_size, MODE_INFO *nb_mi, - void *fun_ctxt); + void *fun_ctxt, const int num_planes); static INLINE void foreach_overlappable_nb_above(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_col, int nb_max, overlappable_nb_visitor_t fun, void *fun_ctxt) { + const int num_planes = av1_num_planes(cm); if (!xd->up_available) return; int nb_count = 0; @@ -49,7 +50,7 @@ static INLINE void foreach_overlappable_nb_above(const AV1_COMMON *cm, if (is_neighbor_overlappable(above_mbmi)) { ++nb_count; fun(xd, above_mi_col - mi_col, AOMMIN(xd->n8_w, mi_step), *above_mi, - fun_ctxt); + fun_ctxt, num_planes); } } } @@ -59,6 +60,7 @@ static INLINE void foreach_overlappable_nb_left(const AV1_COMMON *cm, int nb_max, overlappable_nb_visitor_t fun, void *fun_ctxt) { + const int num_planes = av1_num_planes(cm); if (!xd->left_available) return; int nb_count = 0; @@ -82,7 +84,7 @@ static INLINE void foreach_overlappable_nb_left(const AV1_COMMON *cm, if (is_neighbor_overlappable(left_mbmi)) { ++nb_count; fun(xd, left_mi_row - mi_row, AOMMIN(xd->n8_h, mi_step), *left_mi, - fun_ctxt); + fun_ctxt, num_planes); } } } diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index d8d3ed0e8e05a277e1ab757a034dc8f335fc7e60..dbf08398a583b01368983ee1999fe5401a133d8f 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h @@ -757,7 +757,8 @@ static INLINE int av1_num_planes(const AV1_COMMON *cm) { static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd, tran_low_t *dqcoeff) { - for (int i = 0; i < MAX_MB_PLANE; ++i) { + const int num_planes = av1_num_planes(cm); + for (int i = 0; i < num_planes; ++i) { xd->plane[i].dqcoeff = dqcoeff; xd->above_context[i] = cm->above_context[i]; if (xd->plane[i].plane_type == PLANE_TYPE_Y) { @@ -807,11 +808,12 @@ static INLINE void av1_init_macroblockd(AV1_COMMON *cm, MACROBLOCKD *xd, #endif } -static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) { +static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, + const int num_planes) { int i; int row_offset = mi_row; int col_offset = mi_col; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { struct macroblockd_plane *const pd = &xd->plane[i]; // Offset the buffer pointer const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; @@ -832,9 +834,10 @@ static INLINE int calc_mi_size(int len) { return len + MAX_MIB_SIZE; } -static INLINE void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh) { +static INLINE void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh, + const int num_planes) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].width = (bw * MI_SIZE) >> xd->plane[i].subsampling_x; xd->plane[i].height = (bh * MI_SIZE) >> xd->plane[i].subsampling_y; @@ -1160,6 +1163,7 @@ static INLINE int max_intra_block_height(const MACROBLOCKD *xd, static INLINE void av1_zero_above_context(AV1_COMMON *const cm, int mi_col_start, int mi_col_end) { + const int num_planes = av1_num_planes(cm); const int width = mi_col_end - mi_col_start; const int aligned_width = ALIGN_POWER_OF_TWO(width, cm->mib_size_log2); @@ -1169,8 +1173,10 @@ static INLINE void av1_zero_above_context(AV1_COMMON *const cm, const int width_uv = width_y >> cm->subsampling_x; av1_zero_array(cm->above_context[0] + offset_y, width_y); - av1_zero_array(cm->above_context[1] + offset_uv, width_uv); - av1_zero_array(cm->above_context[2] + offset_uv, width_uv); + if (num_planes > 1) { + av1_zero_array(cm->above_context[1] + offset_uv, width_uv); + av1_zero_array(cm->above_context[2] + offset_uv, width_uv); + } av1_zero_array(cm->above_seg_context + mi_col_start, aligned_width); diff --git a/av1/common/quant_common.c b/av1/common/quant_common.c index c9241169957af5c3415d0058f325fed1c679749a..bb9997a12d3aeb1e3ff040e9e2ce1486696ed919 100644 --- a/av1/common/quant_common.c +++ b/av1/common/quant_common.c @@ -600,10 +600,11 @@ static const uint16_t wt_matrix_ref[NUM_QM_LEVELS][2][QM_TOTAL_SIZE]; static const uint16_t iwt_matrix_ref[NUM_QM_LEVELS][2][QM_TOTAL_SIZE]; void aom_qm_init(AV1_COMMON *cm) { + const int num_planes = av1_num_planes(cm); int q, c, t; int current; for (q = 0; q < NUM_QM_LEVELS; ++q) { - for (c = 0; c < av1_num_planes(cm); ++c) { + for (c = 0; c < num_planes; ++c) { current = 0; for (t = 0; t < TX_SIZES_ALL; ++t) { const int size = tx_size_2d[t]; diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c index e96abd4c29bc7dfd867f1caaf0a382fe5d3f41cb..b709793653db3073830310f33e50bf3f67e47707 100644 --- a/av1/common/reconinter.c +++ b/av1/common/reconinter.c @@ -1304,46 +1304,39 @@ void av1_build_inter_predictors_sbuv(const AV1_COMMON *cm, MACROBLOCKD *xd, void av1_build_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col, BUFFER_SET *ctx, BLOCK_SIZE bsize) { + const int num_planes = av1_num_planes(cm); av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize); - av1_build_inter_predictors_sbuv(cm, xd, mi_row, mi_col, ctx, bsize); + if (num_planes > 1) + av1_build_inter_predictors_sbuv(cm, xd, mi_row, mi_col, ctx, bsize); } void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize, - const YV12_BUFFER_CONFIG *src, int mi_row, - int mi_col) { - const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width, - src->uv_crop_width }; - const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height, - src->uv_crop_height }; - const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, - src->uv_stride }; - int i; - - for (i = 0; i < MAX_MB_PLANE; ++i) { + const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, + const int num_planes) { + // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet + // the static analysis warnings. + for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); ++i) { struct macroblockd_plane *const pd = &planes[i]; - setup_pred_plane(&pd->dst, bsize, src->buffers[i], widths[i], heights[i], - strides[i], mi_row, mi_col, NULL, pd->subsampling_x, - pd->subsampling_y); + const int is_uv = i > 0; + setup_pred_plane(&pd->dst, bsize, src->buffers[i], src->crop_widths[is_uv], + src->crop_heights[is_uv], src->strides[is_uv], mi_row, + mi_col, NULL, pd->subsampling_x, pd->subsampling_y); } } void av1_setup_pre_planes(MACROBLOCKD *xd, int idx, const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *sf) { + const struct scale_factors *sf, + const int num_planes) { if (src != NULL) { - int i; - uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width, - src->uv_crop_width }; - const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height, - src->uv_crop_height }; - const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, - src->uv_stride }; - for (i = 0; i < MAX_MB_PLANE; ++i) { + // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet + // the static analysis warnings. + for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); ++i) { struct macroblockd_plane *const pd = &xd->plane[i]; - setup_pred_plane(&pd->pre[idx], xd->mi[0]->mbmi.sb_type, buffers[i], - widths[i], heights[i], strides[i], mi_row, mi_col, sf, + const int is_uv = i > 0; + setup_pred_plane(&pd->pre[idx], xd->mi[0]->mbmi.sb_type, src->buffers[i], + src->crop_widths[is_uv], src->crop_heights[is_uv], + src->strides[is_uv], mi_row, mi_col, sf, pd->subsampling_x, pd->subsampling_y); } } @@ -1392,12 +1385,13 @@ const uint8_t *av1_get_obmc_mask(int length) { static INLINE void increment_int_ptr(MACROBLOCKD *xd, int rel_mi_rc, uint8_t mi_hw, MODE_INFO *mi, - void *fun_ctxt) { + void *fun_ctxt, const int num_planes) { (void)xd; (void)rel_mi_rc; (void)mi_hw; (void)mi; ++*(int *)fun_ctxt; + (void)num_planes; } void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd, @@ -1448,7 +1442,8 @@ struct obmc_inter_pred_ctxt { static INLINE void build_obmc_inter_pred_above(MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, MODE_INFO *above_mi, - void *fun_ctxt) { + void *fun_ctxt, + const int num_planes) { (void)above_mi; struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt; const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; @@ -1456,7 +1451,7 @@ static INLINE void build_obmc_inter_pred_above(MACROBLOCKD *xd, int rel_mi_col, const int overlap = AOMMIN(block_size_high[bsize], block_size_high[BLOCK_64X64]) >> 1; - for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; const int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x; const int bh = overlap >> pd->subsampling_y; @@ -1482,7 +1477,8 @@ static INLINE void build_obmc_inter_pred_above(MACROBLOCKD *xd, int rel_mi_col, static INLINE void build_obmc_inter_pred_left(MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height, MODE_INFO *left_mi, - void *fun_ctxt) { + void *fun_ctxt, + const int num_planes) { (void)left_mi; struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt; const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; @@ -1490,7 +1486,7 @@ static INLINE void build_obmc_inter_pred_left(MACROBLOCKD *xd, int rel_mi_row, AOMMIN(block_size_wide[bsize], block_size_wide[BLOCK_64X64]) >> 1; const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0; - for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; const int bw = overlap >> pd->subsampling_x; const int bh = (left_mi_height * MI_SIZE) >> pd->subsampling_y; @@ -1561,11 +1557,9 @@ struct build_prediction_ctxt { int mb_to_far_edge; }; -static INLINE void build_prediction_by_above_pred(MACROBLOCKD *xd, - int rel_mi_col, - uint8_t above_mi_width, - MODE_INFO *above_mi, - void *fun_ctxt) { +static INLINE void build_prediction_by_above_pred( + MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, + MODE_INFO *above_mi, void *fun_ctxt, const int num_planes) { MB_MODE_INFO *above_mbmi = &above_mi->mbmi; const BLOCK_SIZE a_bsize = AOMMAX(BLOCK_8X8, above_mbmi->sb_type); struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; @@ -1574,7 +1568,7 @@ static INLINE void build_prediction_by_above_pred(MACROBLOCKD *xd, MB_MODE_INFO backup_mbmi = *above_mbmi; modify_neighbor_predictor_for_obmc(above_mbmi); - for (int j = 0; j < MAX_MB_PLANE; ++j) { + for (int j = 0; j < num_planes; ++j) { struct macroblockd_plane *const pd = &xd->plane[j]; setup_pred_plane(&pd->dst, a_bsize, ctxt->tmp_buf[j], ctxt->tmp_width[j], ctxt->tmp_height[j], ctxt->tmp_stride[j], 0, rel_mi_col, @@ -1593,7 +1587,7 @@ static INLINE void build_prediction_by_above_pred(MACROBLOCKD *xd, aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, "Reference frame has invalid dimensions"); av1_setup_pre_planes(xd, ref, ref_buf->buf, ctxt->mi_row, above_mi_col, - &ref_buf->sf); + &ref_buf->sf, num_planes); } xd->mb_to_left_edge = 8 * MI_SIZE * (-above_mi_col); @@ -1605,7 +1599,7 @@ static INLINE void build_prediction_by_above_pred(MACROBLOCKD *xd, const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; - for (int j = 0; j < MAX_MB_PLANE; ++j) { + for (int j = 0; j < num_planes; ++j) { const struct macroblockd_plane *pd = &xd->plane[j]; int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x; int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4, @@ -1647,11 +1641,9 @@ void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, xd->mb_to_bottom_edge -= (this_height - pred_height) * 8; } -static INLINE void build_prediction_by_left_pred(MACROBLOCKD *xd, - int rel_mi_row, - uint8_t left_mi_height, - MODE_INFO *left_mi, - void *fun_ctxt) { +static INLINE void build_prediction_by_left_pred( + MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height, MODE_INFO *left_mi, + void *fun_ctxt, const int num_planes) { MB_MODE_INFO *left_mbmi = &left_mi->mbmi; const BLOCK_SIZE l_bsize = AOMMAX(BLOCK_8X8, left_mbmi->sb_type); struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; @@ -1660,7 +1652,7 @@ static INLINE void build_prediction_by_left_pred(MACROBLOCKD *xd, MB_MODE_INFO backup_mbmi = *left_mbmi; modify_neighbor_predictor_for_obmc(left_mbmi); - for (int j = 0; j < MAX_MB_PLANE; ++j) { + for (int j = 0; j < num_planes; ++j) { struct macroblockd_plane *const pd = &xd->plane[j]; setup_pred_plane(&pd->dst, l_bsize, ctxt->tmp_buf[j], ctxt->tmp_width[j], ctxt->tmp_height[j], ctxt->tmp_stride[j], rel_mi_row, 0, @@ -1679,7 +1671,7 @@ static INLINE void build_prediction_by_left_pred(MACROBLOCKD *xd, aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, "Reference frame has invalid dimensions"); av1_setup_pre_planes(xd, ref, ref_buf->buf, left_mi_row, ctxt->mi_col, - &ref_buf->sf); + &ref_buf->sf, num_planes); } xd->mb_to_top_edge = 8 * MI_SIZE * (-left_mi_row); @@ -1692,7 +1684,7 @@ static INLINE void build_prediction_by_left_pred(MACROBLOCKD *xd, const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; - for (int j = 0; j < MAX_MB_PLANE; ++j) { + for (int j = 0; j < num_planes; ++j) { const struct macroblockd_plane *pd = &xd->plane[j]; int bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4, block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1)); @@ -1736,6 +1728,7 @@ void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col) { + const int num_planes = av1_num_planes(cm); DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE]; @@ -1767,7 +1760,7 @@ void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2, dst_width2, dst_height2, dst_stride2); av1_setup_dst_planes(xd->plane, xd->mi[0]->mbmi.sb_type, - get_frame_new_buffer(cm), mi_row, mi_col); + get_frame_new_buffer(cm), mi_row, mi_col, num_planes); av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1, dst_buf2, dst_stride2); } diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h index cd6e8bb4c1f4e1621b349653dade1890010063f7..df92cfe53a43412749cebf92796f6fb6084e387a 100644 --- a/av1/common/reconinter.h +++ b/av1/common/reconinter.h @@ -355,12 +355,12 @@ static INLINE void setup_pred_plane(struct buf_2d *dst, BLOCK_SIZE bsize, } void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize, - const YV12_BUFFER_CONFIG *src, int mi_row, - int mi_col); + const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, + const int num_planes); void av1_setup_pre_planes(MACROBLOCKD *xd, int idx, const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, - const struct scale_factors *sf); + const struct scale_factors *sf, const int num_planes); // Detect if the block have sub-pixel level motion vectors // per component. diff --git a/av1/common/resize.c b/av1/common/resize.c index 0bbecbc7956a351ece725d0fed3557a8663b9de2..5abdabb29e4bc1e633212c9b738073fef342e1f6 100644 --- a/av1/common/resize.c +++ b/av1/common/resize.c @@ -1080,33 +1080,26 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride, } void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int bd) { + YV12_BUFFER_CONFIG *dst, int bd, + const int num_planes) { // TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t - int i; - const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer, - src->v_buffer }; - const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - const int src_widths[3] = { src->y_crop_width, src->uv_crop_width, - src->uv_crop_width }; - const int src_heights[3] = { src->y_crop_height, src->uv_crop_height, - src->uv_crop_height }; - uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer }; - const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride }; - const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width, - dst->uv_crop_width }; - const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height, - dst->uv_crop_height }; - - for (i = 0; i < MAX_MB_PLANE; ++i) { + + // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet + // the static analysis warnings. + for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); ++i) { + const int is_uv = i > 0; if (src->flags & YV12_FLAG_HIGHBITDEPTH) - highbd_resize_plane(srcs[i], src_heights[i], src_widths[i], - src_strides[i], dsts[i], dst_heights[i], - dst_widths[i], dst_strides[i], bd); + highbd_resize_plane(src->buffers[i], src->crop_heights[is_uv], + src->crop_widths[is_uv], src->strides[is_uv], + dst->buffers[i], dst->crop_heights[is_uv], + dst->crop_widths[is_uv], dst->strides[is_uv], bd); else - resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i], - dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]); + resize_plane(src->buffers[i], src->crop_heights[is_uv], + src->crop_widths[is_uv], src->strides[is_uv], + dst->buffers[i], dst->crop_heights[is_uv], + dst->crop_widths[is_uv], dst->strides[is_uv]); } - aom_extend_frame_borders(dst); + aom_extend_frame_borders(dst, num_planes); } #if CONFIG_HORZONLY_FRAME_SUPERRES @@ -1183,23 +1176,26 @@ void av1_upscale_normative_rows(const AV1_COMMON *cm, const uint8_t *src, void av1_upscale_normative_and_extend_frame(const AV1_COMMON *cm, const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst) { - for (int i = 0; i < MAX_MB_PLANE; ++i) { + const int num_planes = av1_num_planes(cm); + for (int i = 0; i < num_planes; ++i) { const int is_uv = (i > 0); av1_upscale_normative_rows(cm, src->buffers[i], src->strides[is_uv], dst->buffers[i], dst->strides[is_uv], i, src->crop_heights[is_uv]); } - aom_extend_frame_borders(dst); + aom_extend_frame_borders(dst, num_planes); } #endif // CONFIG_HORZONLY_FRAME_SUPERRES YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled) { + const int num_planes = av1_num_planes(cm); if (cm->width != unscaled->y_crop_width || cm->height != unscaled->y_crop_height) { - av1_resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth); + av1_resize_and_extend_frame(unscaled, scaled, (int)cm->bit_depth, + num_planes); return scaled; } else { return unscaled; @@ -1243,6 +1239,7 @@ void av1_calculate_unscaled_superres_size(int *width, int *height, int denom) { // TODO(afergs): aom_ vs av1_ functions? Which can I use? // Upscale decoded image. void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool) { + const int num_planes = av1_num_planes(cm); if (av1_superres_unscaled(cm)) return; YV12_BUFFER_CONFIG copy_buffer; @@ -1258,7 +1255,7 @@ void av1_superres_upscale(AV1_COMMON *cm, BufferPool *const pool) { "Failed to allocate copy buffer for superres upscaling"); // Copy function assumes the frames are the same size, doesn't copy bit_depth. - aom_yv12_copy_frame(frame_to_show, ©_buffer); + aom_yv12_copy_frame(frame_to_show, ©_buffer, num_planes); copy_buffer.bit_depth = frame_to_show->bit_depth; assert(copy_buffer.y_crop_width == cm->width); assert(copy_buffer.y_crop_height == cm->height); diff --git a/av1/common/resize.h b/av1/common/resize.h index 7c7505e21014269d83824a9de97d19cb93e1ebb1..e54eff8dba78ac5b16299ee10bb0ec732e970f81 100644 --- a/av1/common/resize.h +++ b/av1/common/resize.h @@ -61,7 +61,8 @@ void av1_highbd_resize_frame444(const uint8_t *const y, int y_stride, uint8_t *ov, int ouv_stride, int oheight, int owidth, int bd); void av1_resize_and_extend_frame(const YV12_BUFFER_CONFIG *src, - YV12_BUFFER_CONFIG *dst, int bd); + YV12_BUFFER_CONFIG *dst, int bd, + const int num_planes); #if CONFIG_HORZONLY_FRAME_SUPERRES void av1_upscale_normative_rows(const AV1_COMMON *cm, const uint8_t *src, diff --git a/av1/common/restoration.c b/av1/common/restoration.c index 45a516c2ae5ccef5e773ec2ee594ed57673b52e3..946725a46756c5b2b2e5afefc7d6dd17995ca476 100644 --- a/av1/common/restoration.c +++ b/av1/common/restoration.c @@ -1447,6 +1447,7 @@ static void filter_frame_on_unit(const RestorationTileLimits *limits, void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm) { + const int num_planes = av1_num_planes(cm); typedef void (*copy_fun)(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst); static const copy_fun copy_funs[3] = { aom_yv12_copy_y, aom_yv12_copy_u, @@ -1469,7 +1470,7 @@ void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame, const int bit_depth = cm->bit_depth; const int highbd = cm->use_highbitdepth; - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const RestorationInfo *rsi = &cm->rst_info[plane]; RestorationType rtype = rsi->frame_restoration_type; if (rtype == RESTORE_NONE) { @@ -1505,7 +1506,7 @@ void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame, filter_frame_on_unit, &ctxt); } - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { copy_funs[plane](&dst, frame); } aom_free_frame_buffer(&dst); @@ -1936,8 +1937,9 @@ static void save_tile_row_boundary_lines(const YV12_BUFFER_CONFIG *frame, // lines are saved in rst_internal.stripe_boundary_lines void av1_loop_restoration_save_boundary_lines(const YV12_BUFFER_CONFIG *frame, AV1_COMMON *cm, int after_cdef) { + const int num_planes = av1_num_planes(cm); const int use_highbd = cm->use_highbitdepth; - for (int p = 0; p < MAX_MB_PLANE; ++p) { + for (int p = 0; p < num_planes; ++p) { TileInfo tile_info; for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { av1_tile_init(&tile_info, cm, tile_row, 0); diff --git a/av1/common/thread_common.c b/av1/common/thread_common.c index d515912312f119388052bcb1366dc04bd5f5748a..0f8a06e5c466575df6bd705858a21313df928174 100644 --- a/av1/common/thread_common.c +++ b/av1/common/thread_common.c @@ -161,7 +161,8 @@ static int loop_filter_ver_row_worker(AV1LfSync *const lf_sync, int plane; av1_setup_dst_planes(lf_data->planes, lf_data->cm->sb_size, - lf_data->frame_buffer, mi_row, mi_col); + lf_data->frame_buffer, mi_row, mi_col, + av1_num_planes(lf_data->cm)); av1_setup_mask(lf_data->cm, mi_row, mi_col, mi + mi_col, lf_data->cm->mi_stride, &lfm); @@ -207,7 +208,8 @@ static int loop_filter_hor_row_worker(AV1LfSync *const lf_sync, sync_read(lf_sync, r, c); av1_setup_dst_planes(lf_data->planes, lf_data->cm->sb_size, - lf_data->frame_buffer, mi_row, mi_col); + lf_data->frame_buffer, mi_row, mi_col, + av1_num_planes(lf_data->cm)); av1_setup_mask(lf_data->cm, mi_row, mi_col, mi + mi_col, lf_data->cm->mi_stride, &lfm); #if CONFIG_EXT_PARTITION_TYPES diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index d2d5ae7f3f73fa067eb2e5ee6b48d85231af31cc..025afdf122d4450b6e6fddecca8fdef3cd44b20e 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -282,6 +282,8 @@ static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd, static void set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd, BLOCK_SIZE bsize, int mi_row, int mi_col, int bw, int bh, int x_mis, int y_mis) { + const int num_planes = av1_num_planes(cm); + const int offset = mi_row * cm->mi_stride + mi_col; const TileInfo *const tile = &xd->tile; @@ -307,8 +309,8 @@ static void set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd, idx += cm->mi_stride; } - set_plane_n4(xd, bw, bh); - set_skip_context(xd, mi_row, mi_col); + set_plane_n4(xd, bw, bh, num_planes); + set_skip_context(xd, mi_row, mi_col, num_planes); // Distance of Mb to the various image edges. These are specified to 8th pel // as they are always compared to values that are in 1/8th pel units @@ -319,7 +321,7 @@ static void set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd, cm->mi_rows, cm->mi_cols); av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row, - mi_col); + mi_col, num_planes); } static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd, @@ -359,6 +361,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, int mi_col, aom_reader *r, BLOCK_SIZE bsize) { AV1_COMMON *const cm = &pbi->common; + const int num_planes = av1_num_planes(cm); const int bw = mi_size_wide[bsize]; const int bh = mi_size_high[bsize]; const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col); @@ -380,7 +383,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, #else const int current_qindex = xd->current_qindex; #endif // CONFIG_EXT_DELTA_Q - for (int j = 0; j < av1_num_planes(cm); ++j) { + for (int j = 0; j < num_planes; ++j) { const int dc_delta_q = j == 0 ? cm->y_dc_delta_q : (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q); @@ -393,10 +396,9 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, } } } - if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize); + if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes); if (!is_inter_block(mbmi)) { - const int num_planes = av1_num_planes(cm); for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) { if (mbmi->palette_mode_info.palette_size[plane]) av1_decode_palette_tokens(xd, plane, r); @@ -461,7 +463,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, "Reference frame has invalid dimensions"); av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, - &ref_buf->sf); + &ref_buf->sf, num_planes); } } @@ -472,7 +474,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, } #if CONFIG_MISMATCH_DEBUG - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; int pixel_c, pixel_r; mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0, @@ -505,7 +507,7 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, for (row = 0; row < max_blocks_high; row += mu_blocks_high) { for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) { - for (int plane = 0; plane < av1_num_planes(cm); ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *const pd = &xd->plane[plane]; if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x, pd->subsampling_y)) @@ -521,7 +523,6 @@ static void decode_token_and_recon_block(AV1Decoder *const pbi, int block = 0; int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size]; - int blk_row, blk_col; const int unit_height = ROUND_POWER_OF_TWO( AOMMIN(mu_blocks_high + row, max_blocks_high), @@ -607,6 +608,7 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, int mi_row, int mi_col, aom_reader *r, BLOCK_SIZE bsize) { AV1_COMMON *const cm = &pbi->common; + const int num_planes = av1_num_planes(cm); const int num_8x8_wh = mi_size_wide[bsize]; const int hbs = num_8x8_wh >> 1; PARTITION_TYPE partition; @@ -621,7 +623,7 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd, if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; #if CONFIG_LOOP_RESTORATION - for (int plane = 0; plane < av1_num_planes(cm); ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { int rcol0, rcol1, rrow0, rrow1, tile_tl_idx; if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, &rcol0, &rcol1, &rrow0, &rrow1, @@ -820,11 +822,12 @@ static void setup_segmentation(AV1_COMMON *const cm, #if CONFIG_LOOP_RESTORATION static void decode_restoration_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC int all_none = 1, chroma_none = 1; - for (int p = 0; p < av1_num_planes(cm); ++p) { + for (int p = 0; p < num_planes; ++p) { RestorationInfo *rsi = &cm->rst_info[p]; if (aom_rb_read_bit(rb)) { rsi->frame_restoration_type = @@ -840,7 +843,7 @@ static void decode_restoration_mode(AV1_COMMON *cm, } if (!all_none) { const int qsize = RESTORATION_TILESIZE_MAX >> 2; - for (int p = 0; p < MAX_MB_PLANE; ++p) + for (int p = 0; p < num_planes; ++p) cm->rst_info[p].restoration_unit_size = qsize; RestorationInfo *rsi = &cm->rst_info[0]; @@ -850,11 +853,11 @@ static void decode_restoration_mode(AV1_COMMON *cm, } } else { const int size = RESTORATION_TILESIZE_MAX; - for (int p = 0; p < MAX_MB_PLANE; ++p) + for (int p = 0; p < num_planes; ++p) cm->rst_info[p].restoration_unit_size = size; } - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { int s = AOMMIN(cm->subsampling_x, cm->subsampling_y); if (s && !chroma_none) { cm->rst_info[1].restoration_unit_size = @@ -987,6 +990,7 @@ static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm, #endif // CONFIG_LOOP_RESTORATION static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC @@ -994,7 +998,7 @@ static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { #if CONFIG_LOOPFILTER_LEVEL lf->filter_level[0] = aom_rb_read_literal(rb, 6); lf->filter_level[1] = aom_rb_read_literal(rb, 6); - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { if (lf->filter_level[0] || lf->filter_level[1]) { lf->filter_level_u = aom_rb_read_literal(rb, 6); lf->filter_level_v = aom_rb_read_literal(rb, 6); @@ -1025,6 +1029,7 @@ static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { } static void setup_cdef(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC @@ -1033,9 +1038,8 @@ static void setup_cdef(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) { cm->nb_cdef_strengths = 1 << cm->cdef_bits; for (int i = 0; i < cm->nb_cdef_strengths; i++) { cm->cdef_strengths[i] = aom_rb_read_literal(rb, CDEF_STRENGTH_BITS); - cm->cdef_uv_strengths[i] = av1_num_planes(cm) > 1 - ? aom_rb_read_literal(rb, CDEF_STRENGTH_BITS) - : 0; + cm->cdef_uv_strengths[i] = + num_planes > 1 ? aom_rb_read_literal(rb, CDEF_STRENGTH_BITS) : 0; } } @@ -1045,9 +1049,10 @@ static INLINE int read_delta_q(struct aom_read_bit_buffer *rb) { static void setup_quantization(AV1_COMMON *const cm, struct aom_read_bit_buffer *rb) { + const int num_planes = av1_num_planes(cm); cm->base_qindex = aom_rb_read_literal(rb, QINDEX_BITS); cm->y_dc_delta_q = read_delta_q(rb); - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { int diff_uv_delta = 0; #if CONFIG_EXT_QM if (cm->separate_uv_delta_q) diff_uv_delta = aom_rb_read_bit(rb); @@ -1916,6 +1921,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, const uint8_t *data_end, int startTile, int endTile) { AV1_COMMON *const cm = &pbi->common; + const int num_planes = av1_num_planes(cm); #if !CONFIG_LOOPFILTER_LEVEL const AVxWorkerInterface *const winterface = aom_get_worker_interface(); #endif @@ -2075,7 +2081,7 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, av1_zero_above_context(cm, tile_info.mi_col_start, tile_info.mi_col_end); #endif #if CONFIG_LOOP_RESTORATION - av1_reset_loop_restoration(&td->xd); + av1_reset_loop_restoration(&td->xd, num_planes); #endif // CONFIG_LOOP_RESTORATION #if CONFIG_LOOPFILTERING_ACROSS_TILES || CONFIG_LOOPFILTERING_ACROSS_TILES_EXT @@ -2122,12 +2128,14 @@ static const uint8_t *decode_tiles(AV1Decoder *pbi, const uint8_t *data, av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, cm->lf.filter_level[0], cm->lf.filter_level[1], 0, 0); - av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, - cm->lf.filter_level_u, cm->lf.filter_level_u, 1, - 0); - av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, - cm->lf.filter_level_v, cm->lf.filter_level_v, 2, - 0); + if (num_planes > 1) { + av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, + cm->lf.filter_level_u, cm->lf.filter_level_u, 1, + 0); + av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, + cm->lf.filter_level_v, cm->lf.filter_level_v, 2, + 0); + } } #else av1_loop_filter_frame(get_frame_new_buffer(cm), cm, &pbi->mb, @@ -3263,6 +3271,7 @@ int av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data, const uint8_t *data_end, const uint8_t **p_data_end) { AV1_COMMON *const cm = &pbi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &pbi->mb; #if CONFIG_BITSTREAM_DEBUG @@ -3338,7 +3347,7 @@ int av1_decode_frame_headers_and_setup(AV1Decoder *pbi, const uint8_t *data, av1_setup_motion_field(cm); #endif // CONFIG_MFMV - av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y); + av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y, num_planes); #if CONFIG_NO_FRAME_CONTEXT_SIGNALING if (cm->error_resilient_mode || frame_is_intra_only(cm)) { // use the default frame context values @@ -3410,6 +3419,7 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data, const uint8_t **p_data_end, int startTile, int endTile, int initialize_flag) { AV1_COMMON *const cm = &pbi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &pbi->mb; if (initialize_flag) setup_frame_info(pbi); @@ -3418,7 +3428,7 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data, #if CONFIG_MONO_VIDEO // If the bit stream is monochrome, set the U and V buffers to a constant. - if (av1_num_planes(cm) < 3) { + if (num_planes < 3) { const int bytes_per_sample = cm->use_highbitdepth ? 2 : 1; YV12_BUFFER_CONFIG *cur_buf = (YV12_BUFFER_CONFIG *)xd->cur_buf; diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c index 326015b4c4a20f8af8510996b8b617eed3e470cf..1e38429693b95aea35f86083d3d0c5efb9e4c8c2 100644 --- a/av1/decoder/decoder.c +++ b/av1/decoder/decoder.c @@ -175,6 +175,7 @@ static int equal_dimensions(const YV12_BUFFER_CONFIG *a, aom_codec_err_t av1_copy_reference_dec(AV1Decoder *pbi, int idx, YV12_BUFFER_CONFIG *sd) { AV1_COMMON *cm = &pbi->common; + const int num_planes = av1_num_planes(cm); const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, idx); if (cfg == NULL) { @@ -185,13 +186,14 @@ aom_codec_err_t av1_copy_reference_dec(AV1Decoder *pbi, int idx, aom_internal_error(&cm->error, AOM_CODEC_ERROR, "Incorrect buffer dimensions"); else - aom_yv12_copy_frame(cfg, sd); + aom_yv12_copy_frame(cfg, sd, num_planes); return cm->error.error_code; } aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm, int idx, YV12_BUFFER_CONFIG *sd) { + const int num_planes = av1_num_planes(cm); YV12_BUFFER_CONFIG *ref_buf = NULL; // Get the destination reference buffer. @@ -207,7 +209,7 @@ aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm, int idx, "Incorrect buffer dimensions"); } else { // Overwrite the reference frame buffer. - aom_yv12_copy_frame(sd, ref_buf); + aom_yv12_copy_frame(sd, ref_buf, num_planes); } return cm->error.error_code; @@ -268,6 +270,7 @@ static void swap_frame_buffers(AV1Decoder *pbi) { int av1_receive_compressed_data(AV1Decoder *pbi, size_t size, const uint8_t **psource) { AV1_COMMON *volatile const cm = &pbi->common; + volatile const int num_planes = av1_num_planes(cm); BufferPool *volatile const pool = cm->buffer_pool; RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs; const uint8_t *source = *psource; @@ -406,8 +409,8 @@ int av1_receive_compressed_data(AV1Decoder *pbi, size_t size, #endif // CONFIG_EXT_TILE // TODO(debargha): Fix encoder side mv range, so that we can use the // inner border extension. As of now use the larger extension. - // aom_extend_frame_inner_borders(cm->frame_to_show); - aom_extend_frame_borders(cm->frame_to_show); + // aom_extend_frame_inner_borders(cm->frame_to_show, num_planes); + aom_extend_frame_borders(cm->frame_to_show, num_planes); aom_clear_system_state(); diff --git a/av1/encoder/aq_complexity.c b/av1/encoder/aq_complexity.c index 201691d2afb845ab7fc8d55280f5e27134c855ce..cb08ef598446ea7b30027c2d24caddacc379b3fb 100644 --- a/av1/encoder/aq_complexity.c +++ b/av1/encoder/aq_complexity.c @@ -122,6 +122,7 @@ void av1_setup_in_frame_q_adj(AV1_COMP *cpi) { void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs, int mi_row, int mi_col, int projected_rate) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int mi_offset = mi_row * cm->mi_cols + mi_col; const int xmis = AOMMIN(cm->mi_cols - mi_col, mi_size_wide[bs]); @@ -148,7 +149,7 @@ void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs, MIN_DEFAULT_LV_THRESH) : DEFAULT_LV_THRESH; - av1_setup_src_planes(mb, cpi->source, mi_row, mi_col); + av1_setup_src_planes(mb, cpi->source, mi_row, mi_col, num_planes); logvar = av1_log_block_var(cpi, mb, bs); segment = AQ_C_SEGMENTS - 1; // Just in case no break out below. diff --git a/av1/encoder/bgsprite.c b/av1/encoder/bgsprite.c index 0a79f33544fb049f42ebf7a6586cb0a2fd19738f..36f31feaacc200585ba2dc91150ef7a71ce14404 100644 --- a/av1/encoder/bgsprite.c +++ b/av1/encoder/bgsprite.c @@ -943,6 +943,8 @@ static void stitch_images(AV1_COMP *cpi, YV12_BUFFER_CONFIG **const frames, const int *const y_min, const int *const y_max, int pano_x_min, int pano_x_max, int pano_y_min, int pano_y_max, YV12_BUFFER_CONFIG *panorama) { + AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int width = pano_x_max - pano_x_min + 1; const int height = pano_y_max - pano_y_min + 1; @@ -984,7 +986,7 @@ static void stitch_images(AV1_COMP *cpi, YV12_BUFFER_CONFIG **const frames, frames[0]->subsampling_x, frames[0]->subsampling_y, frames[0]->flags & YV12_FLAG_HIGHBITDEPTH, frames[0]->border, 0); - aom_yv12_copy_frame(frames[0], &bgsprite); + aom_yv12_copy_frame(frames[0], &bgsprite, num_planes); bgsprite.bit_depth = frames[0]->bit_depth; resample_panorama(blended_img, center_idx, x_min, y_min, pano_x_min, pano_x_max, pano_y_min, pano_y_max, &bgsprite); @@ -996,7 +998,7 @@ static void stitch_images(AV1_COMP *cpi, YV12_BUFFER_CONFIG **const frames, &temporal_bgsprite, frames[0]->y_width, frames[0]->y_height, frames[0]->subsampling_x, frames[0]->subsampling_y, frames[0]->flags & YV12_FLAG_HIGHBITDEPTH, frames[0]->border, 0); - aom_yv12_copy_frame(frames[0], &temporal_bgsprite); + aom_yv12_copy_frame(frames[0], &temporal_bgsprite, num_planes); temporal_bgsprite.bit_depth = frames[0]->bit_depth; av1_temporal_filter(cpi, &bgsprite, &temporal_bgsprite, distance); @@ -1033,7 +1035,7 @@ static void stitch_images(AV1_COMP *cpi, YV12_BUFFER_CONFIG **const frames, frames[0]->subsampling_x, frames[0]->subsampling_y, frames[0]->flags & YV12_FLAG_HIGHBITDEPTH, frames[0]->border, 0); - aom_yv12_copy_frame(frames[0], &temporal_arf); + aom_yv12_copy_frame(frames[0], &temporal_arf, num_planes); temporal_arf.bit_depth = frames[0]->bit_depth; av1_temporal_filter(cpi, NULL, &temporal_arf, distance); diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 25eac0a3abe27498273e2365dba7c39c9eb6be63..cbcb346e68de794d273c83c8a20aa0e459c930f7 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -970,6 +970,7 @@ static void write_palette_colors_uv(const MACROBLOCKD *const xd, static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, const MODE_INFO *const mi, int mi_row, int mi_col, aom_writer *w) { + const int num_planes = av1_num_planes(cm); const MB_MODE_INFO *const mbmi = &mi->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; assert(av1_allow_palette(cm->allow_screen_content_tools, bsize)); @@ -991,7 +992,7 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, } const int uv_dc_pred = - av1_num_planes(cm) > 1 && mbmi->uv_mode == UV_DC_PRED && + num_planes > 1 && mbmi->uv_mode == UV_DC_PRED && is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, xd->plane[1].subsampling_y); if (uv_dc_pred) { @@ -1869,6 +1870,7 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, const TOKENEXTRA *const tok_end, int mi_row, int mi_col) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; const int mi_offset = mi_row * cm->mi_stride + mi_col; MODE_INFO *const m = *(cm->mi_grid_visible + mi_offset); @@ -1895,7 +1897,6 @@ static void write_tokens_b(AV1_COMP *cpi, const TileInfo *const tile, #endif // CONFIG_DEPENDENT_HORZTILES cm->mi_rows, cm->mi_cols); - const int num_planes = av1_num_planes(cm); for (plane = 0; plane < AOMMIN(2, num_planes); ++plane) { const uint8_t palette_size_plane = mbmi->palette_mode_info.palette_size[plane]; @@ -2025,6 +2026,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, const TOKENEXTRA *const tok_end, int mi_row, int mi_col, BLOCK_SIZE bsize) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; const int hbs = mi_size_wide[bsize] / 2; #if CONFIG_EXT_PARTITION_TYPES @@ -2037,7 +2039,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile, if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; #if CONFIG_LOOP_RESTORATION - for (int plane = 0; plane < av1_num_planes(cm); ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { int rcol0, rcol1, rrow0, rrow1, tile_tl_idx; if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize, &rcol0, &rcol1, &rrow0, &rrow1, @@ -2172,11 +2174,12 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile, #if CONFIG_LOOP_RESTORATION static void encode_restoration_mode(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC int all_none = 1, chroma_none = 1; - for (int p = 0; p < av1_num_planes(cm); ++p) { + for (int p = 0; p < num_planes; ++p) { RestorationInfo *rsi = &cm->rst_info[p]; if (rsi->frame_restoration_type != RESTORE_NONE) { all_none = 0; @@ -2212,7 +2215,7 @@ static void encode_restoration_mode(AV1_COMMON *cm, } } - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { int s = AOMMIN(cm->subsampling_x, cm->subsampling_y); if (s && !chroma_none) { aom_wb_write_bit(wb, @@ -2333,6 +2336,7 @@ static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm, #endif // CONFIG_LOOP_RESTORATION static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC @@ -2343,7 +2347,7 @@ static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { #if CONFIG_LOOPFILTER_LEVEL aom_wb_write_literal(wb, lf->filter_level[0], 6); aom_wb_write_literal(wb, lf->filter_level[1], 6); - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { if (lf->filter_level[0] || lf->filter_level[1]) { aom_wb_write_literal(wb, lf->filter_level_u, 6); aom_wb_write_literal(wb, lf->filter_level_v, 6); @@ -2385,6 +2389,7 @@ static void encode_loopfilter(AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { } static void encode_cdef(const AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { + const int num_planes = av1_num_planes(cm); #if CONFIG_INTRABC if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return; #endif // CONFIG_INTRABC @@ -2394,7 +2399,7 @@ static void encode_cdef(const AV1_COMMON *cm, struct aom_write_bit_buffer *wb) { aom_wb_write_literal(wb, cm->cdef_bits, 2); for (i = 0; i < cm->nb_cdef_strengths; i++) { aom_wb_write_literal(wb, cm->cdef_strengths[i], CDEF_STRENGTH_BITS); - if (av1_num_planes(cm) > 1) + if (num_planes > 1) aom_wb_write_literal(wb, cm->cdef_uv_strengths[i], CDEF_STRENGTH_BITS); } } @@ -2410,9 +2415,11 @@ static void write_delta_q(struct aom_write_bit_buffer *wb, int delta_q) { static void encode_quantization(const AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { + const int num_planes = av1_num_planes(cm); + aom_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS); write_delta_q(wb, cm->y_dc_delta_q); - if (av1_num_planes(cm) > 1) { + if (num_planes > 1) { int diff_uv_delta = (cm->u_dc_delta_q != cm->v_dc_delta_q) || (cm->u_ac_delta_q != cm->v_ac_delta_q); #if CONFIG_EXT_QM @@ -4404,6 +4411,7 @@ static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst, #endif int insert_frame_header_obu_flag) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); aom_writer mode_bc; int tile_row, tile_col; TOKENEXTRA *(*const tok_buffers)[MAX_TILE_COLS] = cpi->tile_tok; @@ -4602,7 +4610,7 @@ static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst, cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx; mode_bc.allow_update_cdf = 1; #if CONFIG_LOOP_RESTORATION - av1_reset_loop_restoration(&cpi->td.mb.e_mbd); + av1_reset_loop_restoration(&cpi->td.mb.e_mbd, num_planes); #endif // CONFIG_LOOP_RESTORATION aom_start_encode(&mode_bc, dst + total_size); diff --git a/av1/encoder/context_tree.c b/av1/encoder/context_tree.c index ec68cb1ba0c982fd6f93f8c1e20e70dc5ec5cb7d..c06df8b05f42e1e0c65626efd82e1b3837f346f9 100644 --- a/av1/encoder/context_tree.c +++ b/av1/encoder/context_tree.c @@ -21,11 +21,12 @@ static const BLOCK_SIZE square[MAX_SB_SIZE_LOG2 - 1] = { static void alloc_mode_context(AV1_COMMON *cm, int num_pix, PICK_MODE_CONTEXT *ctx) { + const int num_planes = av1_num_planes(cm); int i; const int num_blk = num_pix / 16; ctx->num_4x4_blk = num_blk; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { CHECK_MEM_ERROR(cm, ctx->blk_skip[i], aom_calloc(num_blk, sizeof(uint8_t))); CHECK_MEM_ERROR(cm, ctx->coeff[i], aom_memalign(32, num_pix * sizeof(*ctx->coeff[i]))); @@ -51,9 +52,9 @@ static void alloc_mode_context(AV1_COMMON *cm, int num_pix, } } -static void free_mode_context(PICK_MODE_CONTEXT *ctx) { +static void free_mode_context(PICK_MODE_CONTEXT *ctx, const int num_planes) { int i; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { aom_free(ctx->blk_skip[i]); ctx->blk_skip[i] = 0; aom_free(ctx->coeff[i]); @@ -112,25 +113,25 @@ static void alloc_tree_contexts(AV1_COMMON *cm, PC_TREE *tree, int num_pix, #endif // CONFIG_EXT_PARTITION_TYPES } -static void free_tree_contexts(PC_TREE *tree) { +static void free_tree_contexts(PC_TREE *tree, const int num_planes) { #if CONFIG_EXT_PARTITION_TYPES int i; for (i = 0; i < 3; i++) { - free_mode_context(&tree->horizontala[i]); - free_mode_context(&tree->horizontalb[i]); - free_mode_context(&tree->verticala[i]); - free_mode_context(&tree->verticalb[i]); + free_mode_context(&tree->horizontala[i], num_planes); + free_mode_context(&tree->horizontalb[i], num_planes); + free_mode_context(&tree->verticala[i], num_planes); + free_mode_context(&tree->verticalb[i], num_planes); } for (i = 0; i < 4; ++i) { - free_mode_context(&tree->horizontal4[i]); - free_mode_context(&tree->vertical4[i]); + free_mode_context(&tree->horizontal4[i], num_planes); + free_mode_context(&tree->vertical4[i], num_planes); } #endif // CONFIG_EXT_PARTITION_TYPES - free_mode_context(&tree->none); - free_mode_context(&tree->horizontal[0]); - free_mode_context(&tree->horizontal[1]); - free_mode_context(&tree->vertical[0]); - free_mode_context(&tree->vertical[1]); + free_mode_context(&tree->none, num_planes); + free_mode_context(&tree->horizontal[0], num_planes); + free_mode_context(&tree->horizontal[1], num_planes); + free_mode_context(&tree->vertical[0], num_planes); + free_mode_context(&tree->vertical[1], num_planes); } // This function sets up a tree of contexts such that at each square @@ -193,7 +194,7 @@ void av1_setup_pc_tree(AV1_COMMON *cm, ThreadData *td) { } } -void av1_free_pc_tree(ThreadData *td) { +void av1_free_pc_tree(ThreadData *td, const int num_planes) { #if CONFIG_EXT_PARTITION const int tree_nodes_inc = 1024; #else @@ -206,7 +207,8 @@ void av1_free_pc_tree(ThreadData *td) { const int tree_nodes = tree_nodes_inc + 64 + 16 + 4 + 1; #endif // CONFIG_EXT_PARTITION int i; - for (i = 0; i < tree_nodes; ++i) free_tree_contexts(&td->pc_tree[i]); + for (i = 0; i < tree_nodes; ++i) + free_tree_contexts(&td->pc_tree[i], num_planes); aom_free(td->pc_tree); td->pc_tree = NULL; } diff --git a/av1/encoder/context_tree.h b/av1/encoder/context_tree.h index 385225185e7a0964a45c8ea0db4570511243c923..d374ec819cad27a89be9cb795040b3a7a274d70e 100644 --- a/av1/encoder/context_tree.h +++ b/av1/encoder/context_tree.h @@ -81,7 +81,7 @@ typedef struct PC_TREE { } PC_TREE; void av1_setup_pc_tree(struct AV1Common *cm, struct ThreadData *td); -void av1_free_pc_tree(struct ThreadData *td); +void av1_free_pc_tree(struct ThreadData *td, const int num_planes); #ifdef __cplusplus } // extern "C" diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 84ea271d7c47f9a9325ee000ecbe7d46646fa756..81b3e29afc9dca6db4cbe07c154fab5fb5b9a096 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c @@ -253,13 +253,14 @@ static void set_offsets_without_segment_id(const AV1_COMP *const cpi, MACROBLOCK *const x, int mi_row, int mi_col, BLOCK_SIZE bsize) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; const int mi_width = mi_size_wide[bsize]; const int mi_height = mi_size_high[bsize]; set_mode_info_offsets(cpi, x, xd, mi_row, mi_col); - set_skip_context(xd, mi_row, mi_col); + set_skip_context(xd, mi_row, mi_col, num_planes); xd->above_txfm_context = cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2); xd->left_txfm_context = xd->left_txfm_context_buffer + @@ -267,7 +268,7 @@ static void set_offsets_without_segment_id(const AV1_COMP *const cpi, // Set up destination pointers. av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row, - mi_col); + mi_col, num_planes); // Set up limit values for MV components. // Mv beyond the range do not produce new/different prediction block. @@ -277,7 +278,7 @@ static void set_offsets_without_segment_id(const AV1_COMP *const cpi, x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND; x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND; - set_plane_n4(xd, mi_width, mi_height); + set_plane_n4(xd, mi_width, mi_height, num_planes); // Set up distance of MB to edge of frame in 1/8th pel units. assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); @@ -288,7 +289,7 @@ static void set_offsets_without_segment_id(const AV1_COMP *const cpi, cm->mi_rows, cm->mi_cols); // Set up source buffers. - av1_setup_src_planes(x, cpi->source, mi_row, mi_col); + av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes); // R/D setup. x->rdmult = cpi->rd.RDMULT; @@ -446,6 +447,7 @@ static void update_state(const AV1_COMP *const cpi, TileDataEnc *tile_data, int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run) { int i, x_idx, y; const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); RD_COUNTS *const rdc = &td->rd_counts; MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; @@ -494,7 +496,7 @@ static void update_state(const AV1_COMP *const cpi, TileDataEnc *tile_data, } } - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { p[i].coeff = ctx->coeff[i]; p[i].qcoeff = ctx->qcoeff[i]; pd[i].dqcoeff = ctx->dqcoeff[i]; @@ -587,32 +589,28 @@ static void update_state(const AV1_COMP *const cpi, TileDataEnc *tile_data, } void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, - int mi_row, int mi_col) { - uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer }; - const int widths[3] = { src->y_crop_width, src->uv_crop_width, - src->uv_crop_width }; - const int heights[3] = { src->y_crop_height, src->uv_crop_height, - src->uv_crop_height }; - const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride }; - int i; - + int mi_row, int mi_col, const int num_planes) { // Set current frame pointer. x->e_mbd.cur_buf = src; - for (i = 0; i < MAX_MB_PLANE; i++) - setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type, buffers[i], - widths[i], heights[i], strides[i], mi_row, mi_col, NULL, - x->e_mbd.plane[i].subsampling_x, + // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet + // the static analysis warnings. + for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); i++) { + const int is_uv = i > 0; + setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type, + src->buffers[i], src->crop_widths[is_uv], + src->crop_heights[is_uv], src->strides[is_uv], mi_row, + mi_col, NULL, x->e_mbd.plane[i].subsampling_x, x->e_mbd.plane[i].subsampling_y); + } } static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x, int8_t segment_id) { - int segment_qindex; const AV1_COMMON *const cm = &cpi->common; av1_init_plane_quantizers(cpi, x, segment_id); aom_clear_system_state(); - segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex); + int segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex); return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q); } @@ -625,6 +623,7 @@ static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *mbmi; @@ -646,7 +645,7 @@ static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data, mbmi->partition = partition; #endif - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { p[i].coeff = ctx->coeff[i]; p[i].qcoeff = ctx->qcoeff[i]; pd[i].dqcoeff = ctx->dqcoeff[i]; @@ -1356,7 +1355,8 @@ typedef struct { static void restore_context(MACROBLOCK *x, const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row, - int mi_col, BLOCK_SIZE bsize) { + int mi_col, BLOCK_SIZE bsize, + const int num_planes) { MACROBLOCKD *xd = &x->e_mbd; int p; const int num_4x4_blocks_wide = @@ -1365,7 +1365,7 @@ static void restore_context(MACROBLOCK *x, block_size_high[bsize] >> tx_size_high_log2[0]; int mi_width = mi_size_wide[bsize]; int mi_height = mi_size_high[bsize]; - for (p = 0; p < MAX_MB_PLANE; p++) { + for (p = 0; p < num_planes; p++) { int tx_col; int tx_row; tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]); @@ -1392,7 +1392,8 @@ static void restore_context(MACROBLOCK *x, } static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx, - int mi_row, int mi_col, BLOCK_SIZE bsize) { + int mi_row, int mi_col, BLOCK_SIZE bsize, + const int num_planes) { const MACROBLOCKD *xd = &x->e_mbd; int p; const int num_4x4_blocks_wide = @@ -1403,7 +1404,7 @@ static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_height = mi_size_high[bsize]; // buffer the above/left context information of the block in search. - for (p = 0; p < MAX_MB_PLANE; ++p) { + for (p = 0; p < num_planes; ++p) { int tx_col; int tx_row; tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]); @@ -1699,6 +1700,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, BLOCK_SIZE bsize, int *rate, int64_t *dist, int do_recon, PC_TREE *pc_tree) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; @@ -1735,7 +1737,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2); xd->left_txfm_context = xd->left_txfm_context_buffer + ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2); - save_context(x, &x_ctx, mi_row, mi_col, bsize); + save_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); if (bsize == BLOCK_16X16 && cpi->vaq_refresh) { set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize); @@ -1774,7 +1776,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, none_rdc.rdcost = RDCOST(x->rdmult, none_rdc.rate, none_rdc.dist); } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); mib[0]->mbmi.sb_type = bs_type; pc_tree->partitioning = partition; } @@ -1896,7 +1898,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, chosen_rdc.rate = 0; chosen_rdc.dist = 0; - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); pc_tree->partitioning = PARTITION_SPLIT; // Split partition. @@ -1908,7 +1910,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) continue; - save_context(x, &x_ctx, mi_row, mi_col, bsize); + save_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); pc_tree->split[i]->partitioning = PARTITION_NONE; rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx, &tmp_rdc, @@ -1917,7 +1919,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, #endif split_subsize, &pc_tree->split[i]->none, INT64_MAX); - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { av1_invalid_rd_stats(&chosen_rdc); break; @@ -1950,7 +1952,7 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td, chosen_rdc = none_rdc; } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); // We must have chosen a partitioning and encoding or we'll fail later on. // No other opportunities for success. @@ -2352,6 +2354,8 @@ static void rd_test_partition3(const AV1_COMP *const cpi, ThreadData *td, static int64_t dist_8x8_yuv(const AV1_COMP *const cpi, MACROBLOCK *const x, uint8_t *src_plane_8x8[MAX_MB_PLANE], uint8_t *dst_plane_8x8[MAX_MB_PLANE]) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; int64_t dist_8x8, dist_8x8_uv, total_dist; const int src_stride = x->plane[0].src.stride; @@ -2366,16 +2370,18 @@ static int64_t dist_8x8_yuv(const AV1_COMP *const cpi, MACROBLOCK *const x, // Compute chroma distortion for a luma 8x8 block dist_8x8_uv = 0; - for (plane = 1; plane < MAX_MB_PLANE; ++plane) { - unsigned sse; - const int src_stride_uv = x->plane[plane].src.stride; - const int dst_stride_uv = xd->plane[plane].dst.stride; - const BLOCK_SIZE plane_bsize = - get_plane_block_size(BLOCK_8X8, &xd->plane[plane]); - - cpi->fn_ptr[plane_bsize].vf(src_plane_8x8[plane], src_stride_uv, - dst_plane_8x8[plane], dst_stride_uv, &sse); - dist_8x8_uv += (int64_t)sse << 4; + if (num_planes > 1) { + for (plane = 1; plane < MAX_MB_PLANE; ++plane) { + unsigned sse; + const int src_stride_uv = x->plane[plane].src.stride; + const int dst_stride_uv = xd->plane[plane].dst.stride; + const BLOCK_SIZE plane_bsize = + get_plane_block_size(BLOCK_8X8, &xd->plane[plane]); + + cpi->fn_ptr[plane_bsize].vf(src_plane_8x8[plane], src_stride_uv, + dst_plane_8x8[plane], dst_stride_uv, &sse); + dist_8x8_uv += (int64_t)sse << 4; + } } return total_dist = dist_8x8 + dist_8x8_uv; @@ -2391,6 +2397,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, RD_STATS *rd_cost, int64_t best_rd, PC_TREE *pc_tree, int64_t *none_rd) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; @@ -2516,7 +2523,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2); xd->left_txfm_context = xd->left_txfm_context_buffer + ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2); - save_context(x, &x_ctx, mi_row, mi_col, bsize); + save_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); #if CONFIG_FP_MB_STATS if (cpi->use_fp_mb_stats) { @@ -2665,7 +2672,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, } } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // store estimated motion vector @@ -2677,7 +2684,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, uint8_t *src_plane_8x8[MAX_MB_PLANE], *dst_plane_8x8[MAX_MB_PLANE]; if (x->using_dist_8x8 && bsize == BLOCK_8X8) { - for (int i = 0; i < MAX_MB_PLANE; i++) { + for (int i = 0; i < num_planes; i++) { src_plane_8x8[i] = x->plane[i].src.buf; dst_plane_8x8[i] = xd->plane[i].dst.buf; } @@ -2743,7 +2750,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, do_rectangular_split &= !partition_none_allowed; } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // if (do_split) // PARTITION_HORZ @@ -2822,7 +2829,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, } } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // PARTITION_VERT @@ -2903,7 +2910,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, } } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } #if CONFIG_EXT_PARTITION_TYPES @@ -2957,7 +2964,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, PARTITION_HORZ_A, mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2, mi_row + mi_step, mi_col, subsize); - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // PARTITION_HORZ_B if (partition_horz_allowed && horzb_partition_allowed) { @@ -2967,7 +2974,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, PARTITION_HORZ_B, mi_row, mi_col, subsize, mi_row + mi_step, mi_col, bsize2, mi_row + mi_step, mi_col + mi_step, bsize2); - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } int verta_partition_allowed = vertab_partition_allowed; @@ -2987,7 +2994,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, PARTITION_VERT_A, mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2, mi_row, mi_col + mi_step, subsize); - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // PARTITION_VERT_B if (partition_vert_allowed && vertb_partition_allowed) { @@ -2997,7 +3004,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, PARTITION_VERT_B, mi_row, mi_col, subsize, mi_row, mi_col + mi_step, bsize2, mi_row + mi_step, mi_col + mi_step, bsize2); - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // PARTITION_HORZ_4 @@ -3039,7 +3046,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, pc_tree->partitioning = PARTITION_HORZ_4; } } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } // PARTITION_VERT_4 @@ -3081,7 +3088,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td, pc_tree->partitioning = PARTITION_VERT_4; } } - restore_context(x, &x_ctx, mi_row, mi_col, bsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); } #endif // CONFIG_EXT_PARTITION_TYPES @@ -3130,6 +3137,7 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td, TileDataEnc *tile_data, int mi_row, TOKENEXTRA **tp) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const TileInfo *const tile_info = &tile_data->tile_info; MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; @@ -3173,7 +3181,7 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td, PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2]; #if CONFIG_LV_MAP - av1_fill_coeff_costs(&td->mb, xd->tile_ctx); + av1_fill_coeff_costs(&td->mb, xd->tile_ctx, num_planes); #else av1_fill_token_costs_from_cdf(x->token_head_costs, x->e_mbd.tile_ctx->coef_head_cdfs); @@ -3295,14 +3303,15 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td, } static void init_encode_frame_mb_context(AV1_COMP *cpi) { - MACROBLOCK *const x = &cpi->td.mb; AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); + MACROBLOCK *const x = &cpi->td.mb; MACROBLOCKD *const xd = &x->e_mbd; // Copy data over into macro block data structures. - av1_setup_src_planes(x, cpi->source, 0, 0); + av1_setup_src_planes(x, cpi->source, 0, 0, num_planes); - av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y); + av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y, num_planes); } static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) { @@ -3346,6 +3355,7 @@ static TX_MODE select_tx_mode(const AV1_COMP *cpi) { void av1_init_tile_data(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int tile_cols = cm->tile_cols; const int tile_rows = cm->tile_rows; int tile_col, tile_row; @@ -3383,7 +3393,7 @@ void av1_init_tile_data(AV1_COMP *cpi) { cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok; pre_tok = cpi->tile_tok[tile_row][tile_col]; tile_tok = allocated_tokens(*tile_info, cm->mib_size_log2 + MI_SIZE_LOG2, - av1_num_planes(cm)); + num_planes); #if CONFIG_EXT_TILE tile_data->allow_update_cdf = !cm->large_scale_tile; @@ -4099,6 +4109,7 @@ static void make_consistent_compound_tools(AV1_COMMON *cm) { void av1_encode_frame(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); // Indicates whether or not to use a default reduced set for ext-tx // rather than the potential full set of 16 transforms cm->reduced_tx_set_used = 0; @@ -4130,7 +4141,9 @@ void av1_encode_frame(AV1_COMP *cpi) { #endif // CONFIG_FRAME_MARKER #if CONFIG_MISMATCH_DEBUG - mismatch_reset_frame(); + mismatch_reset_frame(num_planes); +#else + (void)num_planes; #endif cpi->allow_comp_inter_inter = av1_is_compound_reference_allowed(cm); @@ -4441,6 +4454,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, int mi_row, int mi_col, BLOCK_SIZE bsize, int *rate) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MODE_INFO **mi_8x8 = xd->mi; @@ -4452,7 +4466,6 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, const int mi_width = mi_size_wide[bsize]; const int mi_height = mi_size_high[bsize]; const int is_inter = is_inter_block(mbmi); - const int num_planes = av1_num_planes(cm); if (!is_inter) { #if CONFIG_CFL @@ -4501,7 +4514,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, assert(cfg != NULL); #endif // !CONFIG_INTRABC av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col, - &xd->block_refs[ref]->sf); + &xd->block_refs[ref]->sf, num_planes); } av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize); @@ -4512,7 +4525,7 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, #if CONFIG_MISMATCH_DEBUG if (dry_run == OUTPUT_ENABLED) { - for (int plane = 0; plane < 3; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblockd_plane *pd = &xd->plane[plane]; int pixel_c, pixel_r; mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0, @@ -4524,6 +4537,8 @@ static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data, pixel_r, pd->width, pd->height); } } +#else + (void)num_planes; #endif av1_encode_sb(cpi, x, bsize, mi_row, mi_col, dry_run); diff --git a/av1/encoder/encodeframe.h b/av1/encoder/encodeframe.h index 38a2fbb142389e243b0b06881f555543e7d02517..e54b2783d0e255c8265adfde78f717339d58496b 100644 --- a/av1/encoder/encodeframe.h +++ b/av1/encoder/encodeframe.h @@ -27,7 +27,7 @@ struct ThreadData; void av1_setup_src_planes(struct macroblock *x, const struct yv12_buffer_config *src, int mi_row, - int mi_col); + int mi_col, const int num_planes); void av1_encode_frame(struct AV1_COMP *cpi); diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c index 1940badd45959e2117772d4f81ef65488851a083..1d08265c16e50810f6d36a90c8d9cd805fc51c9d 100644 --- a/av1/encoder/encodemb.c +++ b/av1/encoder/encodemb.c @@ -765,6 +765,8 @@ void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) { void av1_encode_sb(const struct AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, RUN_TYPE dry_run) { (void)dry_run; + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; struct optimize_ctx ctx; MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; @@ -776,7 +778,7 @@ void av1_encode_sb(const struct AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, if (x->skip) return; - for (plane = 0; plane < MAX_MB_PLANE; ++plane) { + for (plane = 0; plane < num_planes; ++plane) { const int subsampling_x = xd->plane[plane].subsampling_x; const int subsampling_y = xd->plane[plane].subsampling_y; diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 7a4e9b14763ec9d1c89ebe1ce125f00195785df8..ed8193179796763e17434e35036c973faf04f1b7 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c @@ -481,6 +481,7 @@ static void alloc_context_buffers_ext(AV1_COMP *cpi) { static void dealloc_compressor_data(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); dealloc_context_buffers_ext(cpi); @@ -533,7 +534,7 @@ static void dealloc_compressor_data(AV1_COMP *cpi) { aom_free(cpi->tile_tok[0][0]); cpi->tile_tok[0][0] = 0; - av1_free_pc_tree(&cpi->td); + av1_free_pc_tree(&cpi->td, num_planes); aom_free(cpi->td.mb.palette_buffer); } @@ -803,6 +804,7 @@ static void alloc_util_frame_buffers(AV1_COMP *cpi) { static void alloc_compressor_data(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); av1_alloc_context_buffers(cm, cm->width, cm->height); @@ -815,8 +817,8 @@ static void alloc_compressor_data(AV1_COMP *cpi) { aom_free(cpi->tile_tok[0][0]); { - unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols, - MAX_SB_SIZE_LOG2, av1_num_planes(cm)); + unsigned int tokens = + get_token_alloc(cm->mb_rows, cm->mb_cols, MAX_SB_SIZE_LOG2, num_planes); CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0], aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0]))); } @@ -3074,6 +3076,7 @@ void set_compound_tools(AV1_COMMON *cm) { void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); RATE_CONTROL *const rc = &cpi->rc; MACROBLOCK *const x = &cpi->td.mb; @@ -3179,7 +3182,7 @@ void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) { if (cm->width > cpi->initial_width || cm->height > cpi->initial_height || cm->sb_size != sb_size) { av1_free_context_buffers(cm); - av1_free_pc_tree(&cpi->td); + av1_free_pc_tree(&cpi->td, num_planes); alloc_compressor_data(cpi); realloc_segmentation_maps(cpi); cpi->initial_width = cpi->initial_height = 0; @@ -3789,6 +3792,8 @@ void av1_remove_compressor(AV1_COMP *cpi) { if (!cpi) return; cm = &cpi->common; + const int num_planes = av1_num_planes(cm); + if (cm->current_video_frame > 0) { #if CONFIG_ENTROPY_STATS if (cpi->oxcf.pass != 1) { @@ -3893,7 +3898,7 @@ void av1_remove_compressor(AV1_COMP *cpi) { aom_free(thread_data->td->wsrc_buf); aom_free(thread_data->td->mask_buf); aom_free(thread_data->td->counts); - av1_free_pc_tree(thread_data->td); + av1_free_pc_tree(thread_data->td, num_planes); aom_free(thread_data->td); } } @@ -3983,9 +3988,10 @@ void av1_update_reference(AV1_COMP *cpi, int ref_frame_upd_flags) { int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx); if (cfg) { - aom_yv12_copy_frame(cfg, sd); + aom_yv12_copy_frame(cfg, sd, num_planes); return 0; } else { return -1; @@ -3994,9 +4000,10 @@ int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) { int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); YV12_BUFFER_CONFIG *cfg = get_ref_frame(cm, idx); if (cfg) { - aom_yv12_copy_frame(sd, cfg); + aom_yv12_copy_frame(sd, cfg, num_planes); return 0; } else { return -1; @@ -4544,6 +4551,7 @@ static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, int buffer_idx) { static void scale_references(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MV_REFERENCE_FRAME ref_frame; const AOM_REFFRAME ref_mask[INTER_REFS_PER_FRAME] = { AOM_LAST_FLAG, AOM_LAST2_FLAG, AOM_LAST3_FLAG, AOM_GOLD_FLAG, @@ -4580,8 +4588,8 @@ static void scale_references(AV1_COMP *cpi) { cm->byte_alignment, NULL, NULL, NULL)) aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR, "Failed to allocate frame buffer"); - av1_resize_and_extend_frame(ref, &new_fb_ptr->buf, - (int)cm->bit_depth); + av1_resize_and_extend_frame(ref, &new_fb_ptr->buf, (int)cm->bit_depth, + num_planes); cpi->scaled_ref_idx[ref_frame - 1] = new_fb; alloc_frame_mvs(cm, new_fb); } @@ -4852,6 +4860,7 @@ static void check_initial_width(AV1_COMP *cpi, int use_highbitdepth, // Returns 1 if the assigned width or height was <= 0. static int set_size_literal(AV1_COMP *cpi, int width, int height) { AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); check_initial_width(cpi, cm->use_highbitdepth, cm->subsampling_x, cm->subsampling_y); @@ -4863,7 +4872,7 @@ static int set_size_literal(AV1_COMP *cpi, int width, int height) { if (cpi->initial_width && cpi->initial_height && (cm->width > cpi->initial_width || cm->height > cpi->initial_height)) { av1_free_context_buffers(cm); - av1_free_pc_tree(&cpi->td); + av1_free_pc_tree(&cpi->td, num_planes); alloc_compressor_data(cpi); realloc_segmentation_maps(cpi); cpi->initial_width = cpi->initial_height = 0; @@ -4875,6 +4884,7 @@ static int set_size_literal(AV1_COMP *cpi, int width, int height) { static void set_frame_size(AV1_COMP *cpi, int width, int height) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; int ref_frame; @@ -4908,7 +4918,7 @@ static void set_frame_size(AV1_COMP *cpi, int width, int height) { #endif // CONFIG_HORZONLY_FRAME_SUPERRES set_restoration_unit_size(frame_width, frame_height, cm->subsampling_x, cm->subsampling_y, cm->rst_info); - for (int i = 0; i < MAX_MB_PLANE; ++i) + for (int i = 0; i < num_planes; ++i) cm->rst_info[i].frame_restoration_type = RESTORE_NONE; av1_alloc_restoration_buffers(cm); @@ -4928,7 +4938,8 @@ static void set_frame_size(AV1_COMP *cpi, int width, int height) { av1_setup_scale_factors_for_frame( &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width, cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0); - if (av1_is_scaled(&ref_buf->sf)) aom_extend_frame_borders(buf); + if (av1_is_scaled(&ref_buf->sf)) + aom_extend_frame_borders(buf, num_planes); } else { ref_buf->buf = NULL; } @@ -5123,6 +5134,7 @@ static void setup_frame_size(AV1_COMP *cpi) { #if CONFIG_HORZONLY_FRAME_SUPERRES static void superres_post_encode(AV1_COMP *cpi) { AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); if (av1_superres_unscaled(cm)) return; @@ -5149,13 +5161,14 @@ static void superres_post_encode(AV1_COMP *cpi) { assert(cpi->scaled_source.y_crop_width == cm->superres_upscaled_width); assert(cpi->scaled_source.y_crop_height == cm->superres_upscaled_height); av1_resize_and_extend_frame(cpi->unscaled_source, &cpi->scaled_source, - (int)cm->bit_depth); + (int)cm->bit_depth, num_planes); cpi->source = &cpi->scaled_source; } } #endif // CONFIG_HORZONLY_FRAME_SUPERRES static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) { + const int num_planes = av1_num_planes(cm); MACROBLOCKD *xd = &cpi->td.mb.e_mbd; struct loopfilter *lf = &cm->lf; int no_loopfilter = 0; @@ -5218,10 +5231,12 @@ static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) { #if CONFIG_LOOPFILTER_LEVEL av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level[0], lf->filter_level[1], 0, 0); - av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level_u, - lf->filter_level_u, 1, 0); - av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level_v, - lf->filter_level_v, 2, 0); + if (num_planes > 1) { + av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level_u, + lf->filter_level_u, 1, 0); + av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level_v, + lf->filter_level_v, 2, 0); + } #else av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0); @@ -5269,8 +5284,8 @@ static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) { } #endif // CONFIG_LOOP_RESTORATION // TODO(debargha): Fix mv search range on encoder side - // aom_extend_frame_inner_borders(cm->frame_to_show); - aom_extend_frame_borders(cm->frame_to_show); + // aom_extend_frame_inner_borders(cm->frame_to_show, num_planes); + aom_extend_frame_borders(cm->frame_to_show, num_planes); } static void encode_without_recode_loop(AV1_COMP *cpi) { @@ -6715,6 +6730,7 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags, int64_t *time_end, int flush) { const AV1EncoderConfig *const oxcf = &cpi->oxcf; AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); BufferPool *const pool = cm->buffer_pool; RATE_CONTROL *const rc = &cpi->rc; struct aom_usec_timer cmptimer; @@ -6863,7 +6879,7 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags, NULL, &cpi->alt_ref_buffer, #endif // CONFIG_BGSPRITE arf_src_index); - aom_extend_frame_borders(&cpi->alt_ref_buffer); + aom_extend_frame_borders(&cpi->alt_ref_buffer, num_planes); force_src_buffer = &cpi->alt_ref_buffer; } @@ -6908,7 +6924,7 @@ int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags, NULL, NULL, #endif // CONFIG_BGSPRITE arf_src_index); - aom_extend_frame_borders(&cpi->alt_ref_buffer); + aom_extend_frame_borders(&cpi->alt_ref_buffer, num_planes); force_src_buffer = &cpi->alt_ref_buffer; } diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index fe0509de87765656f20cb9911002bddc8bb80f52..1e47e946d2320798f7b8d38efa71b42a4c64e6ae 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h @@ -712,7 +712,8 @@ static INLINE int enc_is_ref_frame_buf(AV1_COMP *cpi, RefCntBuffer *frame_buf) { } static INLINE unsigned int get_token_alloc(int mb_rows, int mb_cols, - int sb_size_log2, int num_planes) { + int sb_size_log2, + const int num_planes) { // Calculate the maximum number of max superblocks in the image. const int shift = sb_size_log2 - 4; const int sb_size = 1 << sb_size_log2; diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c index ef9fc0f52d5b1c74277226598e483af654930661..714c7a39a5676e58f092218fc15160e7b68047c3 100644 --- a/av1/encoder/encodetxb.c +++ b/av1/encoder/encodetxb.c @@ -58,13 +58,14 @@ typedef struct LevelDownStats { void av1_alloc_txb_buf(AV1_COMP *cpi) { #if 0 AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); int mi_block_size = 1 << MI_SIZE_LOG2; // TODO(angiebird): Make sure cm->subsampling_x/y is set correctly, and then // use precise buffer size according to cm->subsampling_x/y int pixel_stride = mi_block_size * cm->mi_cols; int pixel_height = mi_block_size * cm->mi_rows; int i; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { CHECK_MEM_ERROR( cm, cpi->tcoeff_buf[i], aom_malloc(sizeof(*cpi->tcoeff_buf[i]) * pixel_stride * pixel_height)); @@ -84,7 +85,9 @@ void av1_alloc_txb_buf(AV1_COMP *cpi) { void av1_free_txb_buf(AV1_COMP *cpi) { #if 0 int i; - for (i = 0; i < MAX_MB_PLANE; ++i) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); + for (i = 0; i < num_planes; ++i) { aom_free(cpi->tcoeff_buf[i]); } #else @@ -94,12 +97,14 @@ void av1_free_txb_buf(AV1_COMP *cpi) { void av1_set_coeff_buffer(const AV1_COMP *const cpi, MACROBLOCK *const x, int mi_row, int mi_col) { - int mib_size_log2 = cpi->common.mib_size_log2; - int stride = (cpi->common.mi_cols >> mib_size_log2) + 1; + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); + int mib_size_log2 = cm->mib_size_log2; + int stride = (cm->mi_cols >> mib_size_log2) + 1; int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2); CB_COEFF_BUFFER *coeff_buf = &cpi->coeff_buffer_base[offset]; const int txb_offset = x->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN); - for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { x->mbmi_ext->tcoeff[plane] = coeff_buf->tcoeff[plane] + x->cb_offset; x->mbmi_ext->eobs[plane] = coeff_buf->eobs[plane] + txb_offset; x->mbmi_ext->txb_skip_ctx[plane] = @@ -2335,6 +2340,8 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row, void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td, RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate, int mi_row, int mi_col, uint8_t allow_update_cdf) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; @@ -2343,16 +2350,17 @@ void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td, (void)mi_row; (void)mi_col; if (mbmi->skip) { - av1_reset_skip_context(xd, mi_row, mi_col, bsize); + av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes); return; } if (!dry_run) { av1_foreach_transformed_block(xd, bsize, mi_row, mi_col, - av1_update_and_record_txb_context, &arg); + av1_update_and_record_txb_context, &arg, + num_planes); } else if (dry_run == DRY_RUN_NORMAL) { av1_foreach_transformed_block(xd, bsize, mi_row, mi_col, - av1_update_txb_context_b, &arg); + av1_update_txb_context_b, &arg, num_planes); } else { printf("DRY_RUN_COSTCOEFFS is not supported yet\n"); assert(0); diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c index 3af8c7a20af81777a145ee988bd166850afe57c1..8fdb0cbe813e10300bb369485cb1ac233e74b163 100644 --- a/av1/encoder/firstpass.c +++ b/av1/encoder/firstpass.c @@ -484,6 +484,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { int mb_row, mb_col; MACROBLOCK *const x = &cpi->td.mb; AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; TileInfo tile; struct macroblock_plane *const p = x->plane; @@ -552,13 +553,14 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { set_first_pass_params(cpi); av1_set_quantizer(cm, qindex); - av1_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); + av1_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y, + num_planes); - av1_setup_src_planes(x, cpi->source, 0, 0); - av1_setup_dst_planes(xd->plane, cm->sb_size, new_yv12, 0, 0); + av1_setup_src_planes(x, cpi->source, 0, 0, num_planes); + av1_setup_dst_planes(xd->plane, cm->sb_size, new_yv12, 0, 0, num_planes); if (!frame_is_intra_only(cm)) { - av1_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL); + av1_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL, num_planes); } xd->mi = cm->mi_grid_visible; @@ -570,7 +572,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { #endif // CONFIG_CFL av1_frame_init_quantizer(cpi); - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { p[i].coeff = ctx->coeff[i]; p[i].qcoeff = ctx->qcoeff[i]; pd[i].dqcoeff = ctx->dqcoeff[i]; @@ -633,7 +635,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { #endif // CONFIG_DEPENDENT_HORZTILES cm->mi_rows, cm->mi_cols); - set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize]); + set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize], num_planes); // Do intra 16x16 prediction. xd->mi[0]->mbmi.segment_id = 0; @@ -1054,7 +1056,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { ++twopass->sr_update_lag; } - aom_extend_frame_borders(new_yv12); + aom_extend_frame_borders(new_yv12, num_planes); // The frame we just compressed now becomes the last frame. ref_cnt_fb(pool->frame_bufs, diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c index 69a0d2171fa38e0e49467e6b4a2dcf2aa0fc54f3..649f354dfa4b4760116ba9e8f401890927d8df63 100644 --- a/av1/encoder/mcomp.c +++ b/av1/encoder/mcomp.c @@ -1921,6 +1921,8 @@ static const MV search_pos[4] = { unsigned int av1_int_pro_motion_estimation(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } }; @@ -1943,8 +1945,9 @@ unsigned int av1_int_pro_motion_estimation(const AV1_COMP *cpi, MACROBLOCK *x, // Swap out the reference frame for a version that's been scaled to // match the resolution of the current frame, allowing the existing // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0]; - av1_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); + for (i = 0; i < num_planes; i++) backup_yv12[i] = xd->plane[i].pre[0]; + av1_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL, + num_planes); } { @@ -1956,7 +1959,7 @@ unsigned int av1_int_pro_motion_estimation(const AV1_COMP *cpi, MACROBLOCK *x, if (scaled_ref_frame) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; + for (i = 0; i < num_planes; i++) xd->plane[i].pre[0] = backup_yv12[i]; } return this_sad; } @@ -2040,7 +2043,7 @@ unsigned int av1_int_pro_motion_estimation(const AV1_COMP *cpi, MACROBLOCK *x, if (scaled_ref_frame) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) xd->plane[i].pre[0] = backup_yv12[i]; + for (i = 0; i < num_planes; i++) xd->plane[i].pre[0] = backup_yv12[i]; } return best_sad; diff --git a/av1/encoder/pickcdef.c b/av1/encoder/pickcdef.c index 7821617da0bdb02e90f388888c16719939073a09..ab831ca88e9a18a85ae1b052209ee78400782c1d 100644 --- a/av1/encoder/pickcdef.c +++ b/av1/encoder/pickcdef.c @@ -316,7 +316,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, int nb_strength_bits; int quantizer; double lambda; - int nplanes = av1_num_planes(cm); + const int num_planes = av1_num_planes(cm); const int total_strengths = fast ? REDUCED_TOTAL_STRENGTHS : TOTAL_STRENGTHS; DECLARE_ALIGNED(32, uint16_t, inbuf[CDEF_INBUF_SIZE]); uint16_t *in; @@ -325,10 +325,10 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, av1_ac_quant_Q3(cm->base_qindex, 0, cm->bit_depth) >> (cm->bit_depth - 8); lambda = .12 * quantizer * quantizer / 256.; - av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0); + av1_setup_dst_planes(xd->plane, cm->sb_size, frame, 0, 0, num_planes); mse[0] = aom_malloc(sizeof(**mse) * nvfb * nhfb); mse[1] = aom_malloc(sizeof(**mse) * nvfb * nhfb); - for (pli = 0; pli < nplanes; pli++) { + for (pli = 0; pli < num_planes; pli++) { uint8_t *ref_buffer; int ref_stride; switch (pli) { @@ -417,7 +417,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, cdef_count = sb_compute_cdef_list(cm, fbr * MI_SIZE_64X64, fbc * MI_SIZE_64X64, dlist); #endif - for (pli = 0; pli < nplanes; pli++) { + for (pli = 0; pli < num_planes; pli++) { for (i = 0; i < CDEF_INBUF_SIZE; i++) inbuf[i] = CDEF_VERY_LARGE; for (gi = 0; gi < total_strengths; gi++) { int threshold; @@ -469,7 +469,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, int best_lev0[CDEF_MAX_STRENGTHS]; int best_lev1[CDEF_MAX_STRENGTHS] = { 0 }; nb_strengths = 1 << i; - if (nplanes >= 3) + if (num_planes >= 3) tot_mse = joint_strength_search_dual(best_lev0, best_lev1, nb_strengths, mse, sb_count, fast); else @@ -499,7 +499,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, best_gi = 0; for (gi = 0; gi < cm->nb_cdef_strengths; gi++) { uint64_t curr = mse[0][i][cm->cdef_strengths[gi]]; - if (nplanes >= 3) curr += mse[1][i][cm->cdef_uv_strengths[gi]]; + if (num_planes >= 3) curr += mse[1][i][cm->cdef_uv_strengths[gi]]; if (curr < best_mse) { best_gi = gi; best_mse = curr; @@ -525,7 +525,7 @@ void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, cm->cdef_sec_damping = sec_damping; aom_free(mse[0]); aom_free(mse[1]); - for (pli = 0; pli < nplanes; pli++) { + for (pli = 0; pli < num_planes; pli++) { aom_free(src[pli]); aom_free(ref_coeff[pli]); } diff --git a/av1/encoder/picklpf.c b/av1/encoder/picklpf.c index 89c102b6f68e629909043ad1a1e921f9fac116e3..69d67b10c7f0132a1aa20e4172eb0a771f468d3a 100644 --- a/av1/encoder/picklpf.c +++ b/av1/encoder/picklpf.c @@ -212,6 +212,7 @@ static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi, void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi, LPF_PICK_METHOD method) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); struct loopfilter *const lf = &cm->lf; (void)sd; @@ -274,10 +275,12 @@ void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi, lf->filter_level[1] = search_filter_level( sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 0, 1); - lf->filter_level_u = search_filter_level( - sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 1, 0); - lf->filter_level_v = search_filter_level( - sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 2, 0); + if (num_planes > 1) { + lf->filter_level_u = search_filter_level( + sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 1, 0); + lf->filter_level_v = search_filter_level( + sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL, 2, 0); + } #else lf->filter_level = search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, NULL); diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c index 87f1246aeeca1f77f9a00a4b7579974961760b65..1a1f81bd3591432a7e9b4605912ae2e3fbc961e8 100644 --- a/av1/encoder/pickrst.c +++ b/av1/encoder/pickrst.c @@ -1148,6 +1148,7 @@ static int rest_tiles_in_plane(const AV1_COMMON *cm, int plane) { void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); int ntiles[2]; for (int is_uv = 0; is_uv < 2; ++is_uv) @@ -1165,7 +1166,9 @@ void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi) { memset(rusi, 0, sizeof(*rusi) * ntiles[0]); RestSearchCtxt rsc; - for (int plane = AOM_PLANE_Y; plane <= AOM_PLANE_V; ++plane) { + const int plane_start = AOM_PLANE_Y; + const int plane_end = num_planes > 1 ? AOM_PLANE_V : AOM_PLANE_Y; + for (int plane = plane_start; plane <= plane_end; ++plane) { init_rsc(src, &cpi->common, &cpi->td.mb, plane, rusi, &cpi->trial_frame_rst, &rsc); diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c index 58969f325546c43b13d833b4ce46dca8c4667bbb..8db6bb8c76b33fb307cf97e25b9bb4fd5e3e1976 100644 --- a/av1/encoder/rd.c +++ b/av1/encoder/rd.c @@ -488,9 +488,11 @@ void av1_set_mvcost(MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame, int ref, } #if CONFIG_LV_MAP -void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc) { +void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc, + const int num_planes) { + const int nplanes = AOMMIN(num_planes, PLANE_TYPES); for (int eob_multi_size = 0; eob_multi_size < 7; ++eob_multi_size) { - for (int plane = 0; plane < PLANE_TYPES; ++plane) { + for (int plane = 0; plane < nplanes; ++plane) { LV_MAP_EOB_COST *pcost = &x->eob_costs[eob_multi_size][plane]; for (int ctx = 0; ctx < 2; ++ctx) { @@ -517,7 +519,7 @@ void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc) { } } for (int tx_size = 0; tx_size < TX_SIZES; ++tx_size) { - for (int plane = 0; plane < PLANE_TYPES; ++plane) { + for (int plane = 0; plane < nplanes; ++plane) { LV_MAP_COEFF_COST *pcost = &x->coeff_costs[tx_size][plane]; for (int ctx = 0; ctx < TXB_SKIP_CONTEXTS; ++ctx) @@ -937,7 +939,8 @@ void av1_setup_pred_block(const MACROBLOCKD *xd, struct buf_2d dst[MAX_MB_PLANE], const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, const struct scale_factors *scale, - const struct scale_factors *scale_uv) { + const struct scale_factors *scale_uv, + const int num_planes) { int i; dst[0].buf = src->y_buffer; @@ -946,7 +949,7 @@ void av1_setup_pred_block(const MACROBLOCKD *xd, dst[2].buf = src->v_buffer; dst[1].stride = dst[2].stride = src->uv_stride; - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { setup_pred_plane(dst + i, xd->mi[0]->mbmi.sb_type, dst[i].buf, i ? src->uv_crop_width : src->y_crop_width, i ? src->uv_crop_height : src->y_crop_height, diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h index b192a4d877d8af9372df13980c6f1242ad6efde8..31057cd6070f734121a890f9ac1511c84d641815 100644 --- a/av1/encoder/rd.h +++ b/av1/encoder/rd.h @@ -304,6 +304,8 @@ static INLINE void av1_init_rd_stats(RD_STATS *rd_stats) { rd_stats->invalid_rate = 0; rd_stats->ref_rdcost = INT64_MAX; #if CONFIG_RD_DEBUG + // This may run into problems when monochrome video is + // encoded, as there will only be 1 plane for (plane = 0; plane < MAX_MB_PLANE; ++plane) { rd_stats->txb_coeff_cost[plane] = 0; { @@ -329,6 +331,8 @@ static INLINE void av1_invalid_rd_stats(RD_STATS *rd_stats) { rd_stats->invalid_rate = 1; rd_stats->ref_rdcost = INT64_MAX; #if CONFIG_RD_DEBUG + // This may run into problems when monochrome video is + // encoded, as there will only be 1 plane for (plane = 0; plane < MAX_MB_PLANE; ++plane) { rd_stats->txb_coeff_cost[plane] = INT_MAX; { @@ -354,6 +358,8 @@ static INLINE void av1_merge_rd_stats(RD_STATS *rd_stats_dst, rd_stats_dst->skip &= rd_stats_src->skip; rd_stats_dst->invalid_rate &= rd_stats_src->invalid_rate; #if CONFIG_RD_DEBUG + // This may run into problems when monochrome video is + // encoded, as there will only be 1 plane for (plane = 0; plane < MAX_MB_PLANE; ++plane) { rd_stats_dst->txb_coeff_cost[plane] += rd_stats_src->txb_coeff_cost[plane]; { @@ -446,7 +452,8 @@ void av1_setup_pred_block(const MACROBLOCKD *xd, struct buf_2d dst[MAX_MB_PLANE], const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, const struct scale_factors *scale, - const struct scale_factors *scale_uv); + const struct scale_factors *scale_uv, + const int num_planes); int av1_get_intra_cost_penalty(int qindex, int qdelta, aom_bit_depth_t bit_depth); @@ -455,7 +462,8 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x, FRAME_CONTEXT *fc); #if CONFIG_LV_MAP -void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc); +void av1_fill_coeff_costs(MACROBLOCK *x, FRAME_CONTEXT *fc, + const int num_planes); #endif void av1_fill_token_costs_from_cdf(av1_coeff_cost *cost, diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index 572cea85e6df0d765d3d5cd84203cc2856cb1691..62911d08f27637903919e801d765873bb68f440c 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c @@ -5625,6 +5625,7 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, const uint8_t *mask, int mask_stride, int *rate_mv, const int block) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int pw = block_size_wide[bsize]; const int ph = block_size_high[bsize]; MACROBLOCKD *xd = &x->e_mbd; @@ -5668,10 +5669,10 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, // Swap out the reference frame for a version that's been scaled to // match the resolution of the current frame, allowing the existing // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) + for (i = 0; i < num_planes; i++) backup_yv12[ref][i] = xd->plane[i].pre[ref]; - av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, - NULL); + av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, NULL, + num_planes); } } @@ -5816,7 +5817,7 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, if (scaled_ref_frame[ref]) { // Restore the prediction frame pointers to their unscaled versions. int i; - for (i = 0; i < MAX_MB_PLANE; i++) + for (i = 0; i < num_planes; i++) xd->plane[i].pre[ref] = backup_yv12[ref][i]; } @@ -6046,6 +6047,7 @@ static void setup_buffer_inter( int_mv frame_near_mv[TOTAL_REFS_PER_FRAME], struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) { const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame); MACROBLOCKD *const xd = &x->e_mbd; MODE_INFO *const mi = xd->mi[0]; @@ -6057,7 +6059,8 @@ static void setup_buffer_inter( // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this // use the UV scaling factors. - av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf); + av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf, + num_planes); // Gets an initial list of candidate vectors from neighbours and orders them av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame], @@ -6087,6 +6090,7 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, int ref_idx, int *rate_mv) { MACROBLOCKD *xd = &x->e_mbd; const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } }; int bestsme = INT_MAX; @@ -6112,10 +6116,10 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, // Swap out the reference frame for a version that's been scaled to // match the resolution of the current frame, allowing the existing // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) - backup_yv12[i] = xd->plane[i].pre[ref_idx]; + for (i = 0; i < num_planes; i++) backup_yv12[i] = xd->plane[i].pre[ref_idx]; - av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL); + av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL, + num_planes); } av1_set_mvcost( @@ -6163,7 +6167,7 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, if (scaled_ref_frame) { int j; - for (j = 0; j < MAX_MB_PLANE; ++j) + for (j = 0; j < num_planes; ++j) xd->plane[j].pre[ref_idx] = backup_yv12[j]; } return; @@ -6292,14 +6296,14 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, if (scaled_ref_frame) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) - xd->plane[i].pre[ref_idx] = backup_yv12[i]; + for (i = 0; i < num_planes; i++) xd->plane[i].pre[ref_idx] = backup_yv12[i]; } } -static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) { +static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst, + const int num_planes) { int i; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].dst.buf = dst.plane[i]; xd->plane[i].dst.stride = dst.stride[i]; } @@ -6310,6 +6314,7 @@ static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x, int mi_row, int mi_col, const int block, int ref_idx, uint8_t *second_pred) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int pw = block_size_wide[bsize]; const int ph = block_size_high[bsize]; MACROBLOCKD *xd = &x->e_mbd; @@ -6337,9 +6342,10 @@ static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x, // Swap out the reference frame for a version that's been scaled to // match the resolution of the current frame, allowing the existing // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) + for (i = 0; i < num_planes; i++) backup_yv12[i] = xd->plane[i].pre[!ref_idx]; - av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL); + av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL, + num_planes); } // Since we have scaled the reference frames to match the size of the current @@ -6380,7 +6386,7 @@ static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x, if (scaled_ref_frame) { // Restore the prediction frame pointers to their unscaled versions. int i; - for (i = 0; i < MAX_MB_PLANE; i++) + for (i = 0; i < num_planes; i++) xd->plane[i].pre[!ref_idx] = backup_yv12[i]; } } @@ -6393,6 +6399,8 @@ static void compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, const uint8_t *second_pred, const uint8_t *mask, int mask_stride, int *rate_mv, int ref_idx) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const int pw = block_size_wide[bsize]; const int ph = block_size_high[bsize]; MACROBLOCKD *xd = &x->e_mbd; @@ -6414,9 +6422,9 @@ static void compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, // Swap out the reference frame for a version that's been scaled to // match the resolution of the current frame, allowing the existing // motion search code to be used without additional modifications. - for (i = 0; i < MAX_MB_PLANE; i++) - backup_yv12[i] = xd->plane[i].pre[ref_idx]; - av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL); + for (i = 0; i < num_planes; i++) backup_yv12[i] = xd->plane[i].pre[ref_idx]; + av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL, + num_planes); } struct buf_2d orig_yv12; @@ -6492,8 +6500,7 @@ static void compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, if (scaled_ref_frame) { // Restore the prediction frame pointers to their unscaled versions. int i; - for (i = 0; i < MAX_MB_PLANE; i++) - xd->plane[i].pre[ref_idx] = backup_yv12[i]; + for (i = 0; i < num_planes; i++) xd->plane[i].pre[ref_idx] = backup_yv12[i]; } av1_set_mvcost( @@ -7192,6 +7199,7 @@ static int64_t interpolation_filter_search( int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb, int64_t *const skip_sse_sb) { const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; int i; @@ -7217,7 +7225,7 @@ static int64_t interpolation_filter_search( *switchable_rate = av1_get_switchable_rate(cm, x, xd); av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, skip_txfm_sb, skip_sse_sb); *rd = RDCOST(x->rdmult, *switchable_rate + tmp_rate, tmp_dist); @@ -7231,7 +7239,7 @@ static int64_t interpolation_filter_search( #endif // CONFIG_DUAL_FILTER int best_in_temp = 0; InterpFilters best_filters = mbmi->interp_filters; - restore_dst_buf(xd, *tmp_dst); + restore_dst_buf(xd, *tmp_dst, num_planes); #if CONFIG_DUAL_FILTER // Speed feature use_fast_interpolation_filter_search if (cpi->sf.use_fast_interpolation_filter_search) { @@ -7254,7 +7262,7 @@ static int64_t interpolation_filter_search( tmp_rs = av1_get_switchable_rate(cm, x, xd); av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, &tmp_skip_sb, &tmp_skip_sse); tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); @@ -7268,9 +7276,9 @@ static int64_t interpolation_filter_search( *skip_sse_sb = tmp_skip_sse; best_in_temp = !best_in_temp; if (best_in_temp) { - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); } else { - restore_dst_buf(xd, *tmp_dst); + restore_dst_buf(xd, *tmp_dst, num_planes); } } } @@ -7287,7 +7295,7 @@ static int64_t interpolation_filter_search( tmp_rs = av1_get_switchable_rate(cm, x, xd); av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, &tmp_skip_sb, &tmp_skip_sse); tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); @@ -7299,9 +7307,9 @@ static int64_t interpolation_filter_search( *skip_sse_sb = tmp_skip_sse; best_in_temp = !best_in_temp; if (best_in_temp) { - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); } else { - restore_dst_buf(xd, *tmp_dst); + restore_dst_buf(xd, *tmp_dst, num_planes); } } } @@ -7322,7 +7330,7 @@ static int64_t interpolation_filter_search( tmp_rs = av1_get_switchable_rate(cm, x, xd); av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, &tmp_skip_sb, &tmp_skip_sse); tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); @@ -7334,9 +7342,9 @@ static int64_t interpolation_filter_search( *skip_sse_sb = tmp_skip_sse; best_in_temp = !best_in_temp; if (best_in_temp) { - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); } else { - restore_dst_buf(xd, *tmp_dst); + restore_dst_buf(xd, *tmp_dst, num_planes); } } } @@ -7345,9 +7353,9 @@ static int64_t interpolation_filter_search( #endif // CONFIG_DUAL_FILTER Speed feature use_fast_interpolation_filter_search if (best_in_temp) { - restore_dst_buf(xd, *tmp_dst); + restore_dst_buf(xd, *tmp_dst, num_planes); } else { - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); } mbmi->interp_filters = best_filters; } else { @@ -7384,6 +7392,7 @@ static int64_t motion_mode_rd( int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi, int rate_mv_bmc, int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *xd = &x->e_mbd; MODE_INFO *mi = xd->mi[0]; MB_MODE_INFO *mbmi = &mi->mbmi; @@ -7468,7 +7477,7 @@ static int64_t motion_mode_rd( av1_build_obmc_inter_prediction( cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride, args->left_pred_buf, args->left_pred_stride); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, skip_txfm_sb, skip_sse_sb); } @@ -7548,7 +7557,7 @@ static int64_t motion_mode_rd( } av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, skip_txfm_sb, skip_sse_sb); } else { continue; @@ -7586,7 +7595,7 @@ static int64_t motion_mode_rd( xd->plane[0].dst.stride = bw; av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, NULL, bsize); - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); mbmi->ref_frame[1] = INTRA_FRAME; mbmi->use_wedge_interintra = 0; for (j = 0; j < INTERINTRA_MODES; ++j) { @@ -7700,9 +7709,9 @@ static int64_t motion_mode_rd( mbmi->use_wedge_interintra = 0; } } // if (is_interintra_wedge_used(bsize)) - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, skip_txfm_sb, skip_sse_sb); } @@ -7765,7 +7774,7 @@ static int64_t motion_mode_rd( mbmi->ref_frame[1] == INTRA_FRAME) { continue; } else { - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); return INT64_MAX; } } @@ -7774,15 +7783,19 @@ static int64_t motion_mode_rd( rdcosty = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist); rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, 0, rd_stats->sse)); - /* clang-format off */ - is_cost_valid_uv = - inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty, - 0); - if (!is_cost_valid_uv) { - continue; + if (num_planes > 1) { + /* clang-format off */ + is_cost_valid_uv = + inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty, + 0); + if (!is_cost_valid_uv) { + continue; + } + /* clang-format on */ + av1_merge_rd_stats(rd_stats, rd_stats_uv); + } else { + av1_init_rd_stats(rd_stats_uv); } - /* clang-format on */ - av1_merge_rd_stats(rd_stats, rd_stats_uv); #if CONFIG_RD_DEBUG // record transform block coefficient cost // TODO(angiebird): So far rd_debug tool only detects discrepancy of @@ -7849,8 +7862,8 @@ static int64_t motion_mode_rd( best_rd = tmp_rd; best_rd_stats = *rd_stats; best_rd_stats_y = *rd_stats_y; - best_rd_stats_uv = *rd_stats_uv; - for (int i = 0; i < MAX_MB_PLANE; ++i) + if (num_planes > 1) best_rd_stats_uv = *rd_stats_uv; + for (int i = 0; i < num_planes; ++i) memcpy(best_blk_skip[i], x->blk_skip[i], sizeof(best_blk_skip[i][0]) * xd->n8_h * xd->n8_w * 4); best_xskip = x->skip; @@ -7860,20 +7873,20 @@ static int64_t motion_mode_rd( if (best_rd == INT64_MAX) { av1_invalid_rd_stats(rd_stats); - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); return INT64_MAX; } *mbmi = best_mbmi; *rd_stats = best_rd_stats; *rd_stats_y = best_rd_stats_y; - *rd_stats_uv = best_rd_stats_uv; - for (int i = 0; i < MAX_MB_PLANE; ++i) + if (num_planes > 1) *rd_stats_uv = best_rd_stats_uv; + for (int i = 0; i < num_planes; ++i) memcpy(x->blk_skip[i], best_blk_skip[i], sizeof(x->blk_skip[i][0]) * xd->n8_h * xd->n8_w * 4); x->skip = best_xskip; *disable_skip = best_disable_skip; - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); return 0; } @@ -7882,13 +7895,14 @@ static int64_t skip_mode_rd(const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize, int mi_row, int mi_col, BUFFER_SET *const orig_dst) { const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); int64_t total_sse = 0; - for (int plane = 0; plane < MAX_MB_PLANE; ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { const struct macroblock_plane *const p = &x->plane[plane]; const struct macroblockd_plane *const pd = &xd->plane[plane]; const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); @@ -7913,7 +7927,7 @@ static int64_t skip_mode_rd(const AV1_COMP *const cpi, MACROBLOCK *const x, // Save the mode index x->skip_mode_index = x->skip_mode_index_candidate; - restore_dst_buf(xd, *orig_dst); + restore_dst_buf(xd, *orig_dst, num_planes); return 0; } #endif // CONFIG_EXT_SKIP @@ -7924,6 +7938,7 @@ static int64_t handle_inter_mode( int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row, int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) { const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *xd = &x->e_mbd; MODE_INFO *mi = xd->mi[0]; MB_MODE_INFO *mbmi = &mi->mbmi; @@ -8164,16 +8179,23 @@ static int64_t handle_inter_mode( } } + // Initialise tmp_dst and orig_dst buffers to prevent "may be used + // uninitialized" warnings in GCC when the stream is monochrome. + memset(tmp_dst.plane, 0, sizeof(tmp_dst.plane)); + memset(tmp_dst.stride, 0, sizeof(tmp_dst.stride)); + memset(orig_dst.plane, 0, sizeof(tmp_dst.plane)); + memset(orig_dst.stride, 0, sizeof(tmp_dst.stride)); + // do first prediction into the destination buffer. Do the next // prediction into a temporary buffer. Then keep track of which one // of these currently holds the best predictor, and use the other // one for future predictions. In the end, copy from tmp_buf to // dst if necessary. - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE; tmp_dst.stride[i] = MAX_SB_SIZE; } - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { orig_dst.plane[i] = xd->plane[i].dst.buf; orig_dst.stride[i] = xd->plane[i].dst.stride; } @@ -8386,7 +8408,7 @@ static int64_t handle_inter_mode( } if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) { - restore_dst_buf(xd, orig_dst); + restore_dst_buf(xd, orig_dst, num_planes); #if CONFIG_JNT_COMP early_terminate = INT64_MAX; continue; @@ -8404,7 +8426,7 @@ static int64_t handle_inter_mode( int tmp_rate; int64_t tmp_dist; av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, &skip_txfm_sb, &skip_sse_sb); rd = RDCOST(x->rdmult, rs + tmp_rate, tmp_dist); } @@ -8420,7 +8442,7 @@ static int64_t handle_inter_mode( const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]], args->modelled_rd[mode1][refs[1]]); if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) { - restore_dst_buf(xd, orig_dst); + restore_dst_buf(xd, orig_dst, num_planes); #if CONFIG_JNT_COMP early_terminate = INT64_MAX; continue; @@ -8437,7 +8459,7 @@ static int64_t handle_inter_mode( // if current pred_error modeled rd is substantially more than the best // so far, do not bother doing full rd if (rd / 2 > ref_best_rd) { - restore_dst_buf(xd, orig_dst); + restore_dst_buf(xd, orig_dst, num_planes); #if CONFIG_JNT_COMP early_terminate = INT64_MAX; continue; @@ -8476,7 +8498,7 @@ static int64_t handle_inter_mode( best_ret_val = ret_val; best_rd = tmp_rd; best_mbmi = *mbmi; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(best_blk_skip[i], x->blk_skip[i], sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4); } @@ -8490,7 +8512,7 @@ static int64_t handle_inter_mode( mbmi->compound_idx = best_compound_idx; ret_val = best_ret_val; *mbmi = best_mbmi; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(x->blk_skip[i], best_blk_skip[i], sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4); } @@ -8507,6 +8529,7 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x, int64_t best_rd) { const AV1_COMMON *const cm = &cpi->common; if (!av1_allow_intrabc(cm)) return INT64_MAX; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; const TileInfo *tile = &xd->tile; @@ -8542,8 +8565,9 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x, mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref; struct buf_2d yv12_mb[MAX_MB_PLANE]; - av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL); - for (int i = 0; i < MAX_MB_PLANE; ++i) { + av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL, + num_planes); + for (int i = 0; i < num_planes; ++i) { xd->plane[i].pre[0] = yv12_mb[i]; } @@ -8709,6 +8733,7 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x, int mi_row, const AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; + const int num_planes = av1_num_planes(cm); int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0; int y_skip = 0, uv_skip = 0; int64_t dist_y = 0, dist_uv = 0; @@ -8745,11 +8770,13 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x, int mi_row, xd->cfl.store_y = 0; } #endif // CONFIG_CFL - max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd); - init_sbuv_mode(mbmi); - if (!x->skip_chroma_rd) - rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv, - &uv_skip, bsize, max_uv_tx_size); + if (num_planes > 1) { + max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd); + init_sbuv_mode(mbmi); + if (!x->skip_chroma_rd) + rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv, + &uv_skip, bsize, max_uv_tx_size); + } if (y_skip && (uv_skip || x->skip_chroma_rd)) { rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly + @@ -8906,6 +8933,7 @@ static void estimate_skip_mode_rdcost( int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext; @@ -9005,13 +9033,13 @@ static void estimate_skip_mode_rdcost( set_default_interp_filters(mbmi, cm->interp_filter); set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]); - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i]; xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i]; } BUFFER_SET orig_dst; - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { orig_dst.plane[i] = xd->plane[i].dst.buf; orig_dst.stride[i] = xd->plane[i].dst.stride; } @@ -9028,6 +9056,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, RD_STATS *rd_cost, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); const RD_OPT *const rd_opt = &cpi->rd; const SPEED_FEATURES *const sf = &cpi->sf; MACROBLOCKD *const xd = &x->e_mbd; @@ -9222,7 +9251,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, args.left_pred_buf, dst_width2, dst_height2, args.left_pred_stride); av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row, - mi_col); + mi_col, num_planes); calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0], args.above_pred_stride[0], args.left_pred_buf[0], args.left_pred_stride[0]); @@ -9542,7 +9571,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); // Select prediction reference frames. - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i]; } @@ -9697,26 +9726,28 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, if (rate_y == INT_MAX) continue; - uv_tx = av1_get_tx_size(AOM_PLANE_U, xd); - if (rate_uv_intra[uv_tx] == INT_MAX) { - choose_intra_uv_mode(cpi, x, bsize, uv_tx, &rate_uv_intra[uv_tx], - &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx], - &skip_uvs[uv_tx], &mode_uv[uv_tx]); - if (try_palette) pmi_uv[uv_tx] = *pmi; - uv_angle_delta[uv_tx] = mbmi->angle_delta[1]; - } + if (num_planes > 1) { + uv_tx = av1_get_tx_size(AOM_PLANE_U, xd); + if (rate_uv_intra[uv_tx] == INT_MAX) { + choose_intra_uv_mode(cpi, x, bsize, uv_tx, &rate_uv_intra[uv_tx], + &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx], + &skip_uvs[uv_tx], &mode_uv[uv_tx]); + if (try_palette) pmi_uv[uv_tx] = *pmi; + uv_angle_delta[uv_tx] = mbmi->angle_delta[1]; + } - rate_uv = rate_uv_tokenonly[uv_tx]; - distortion_uv = dist_uvs[uv_tx]; - skippable = skippable && skip_uvs[uv_tx]; - mbmi->uv_mode = mode_uv[uv_tx]; - if (try_palette) { - pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1]; - memcpy(pmi->palette_colors + PALETTE_MAX_SIZE, - pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE, - 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0])); + rate_uv = rate_uv_tokenonly[uv_tx]; + distortion_uv = dist_uvs[uv_tx]; + skippable = skippable && skip_uvs[uv_tx]; + mbmi->uv_mode = mode_uv[uv_tx]; + if (try_palette) { + pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1]; + memcpy(pmi->palette_colors + PALETTE_MAX_SIZE, + pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE, + 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0])); + } + mbmi->angle_delta[1] = uv_angle_delta[uv_tx]; } - mbmi->angle_delta[1] = uv_angle_delta[uv_tx]; rate2 = rate_y + intra_mode_info_cost_y(cpi, x, mbmi, bsize, intra_mode_cost[mbmi->mode]); @@ -9727,7 +9758,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, // not the tokenonly rate. rate_y -= tx_size_cost(cm, x, bsize, mbmi->tx_size); } - if (!x->skip_chroma_rd) { + if (num_planes > 1 && !x->skip_chroma_rd) { const int uv_mode_cost = #if CONFIG_CFL x->intra_uv_mode_cost[is_cfl_allowed(mbmi)][mbmi->mode] @@ -9855,7 +9886,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, rate_y - rate_uv, total_sse); } - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(x->blk_skip_drl[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); @@ -9976,7 +10007,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, tmp_ref_rd = tmp_alt_rd; backup_mbmi = *mbmi; backup_skip = x->skip; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(x->blk_skip_drl[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); } else { @@ -9988,7 +10019,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, frame_mv[NEARMV][ref_frame] = backup_mv; frame_mv[NEWMV][ref_frame] = backup_fmv[0]; if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1]; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(x->blk_skip[i], x->blk_skip_drl[i], sizeof(uint8_t) * ctx->num_4x4_blk); } @@ -10092,7 +10123,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, rate_y + x->skip_cost[av1_get_skip_context(xd)][this_skip2 || skippable]; best_rate_uv = rate_uv; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(ctx->blk_skip[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); } @@ -10177,7 +10208,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]); // Select prediction reference frames. - for (i = 0; i < MAX_MB_PLANE; i++) { + for (i = 0; i < num_planes; i++) { xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i]; if (has_second_ref(mbmi)) xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i]; @@ -10235,7 +10266,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, for (idx = 0; idx < xd->n8_w; ++idx) best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx]; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(ctx->blk_skip[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); @@ -10317,7 +10348,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, best_mbmode = *mbmi; best_skip2 = 0; best_mode_skippable = skippable; - for (i = 0; i < MAX_MB_PLANE; ++i) + for (i = 0; i < num_planes; ++i) memcpy(ctx->blk_skip[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); } @@ -10414,7 +10445,7 @@ PALETTE_EXIT: x->skip = 1; #if 0 // TODO(zoeliu): To investigate why following cause performance drop. - for (i = 0; i < MAX_MB_PLANE; ++i) { + for (i = 0; i < num_planes; ++i) { memset(x->blk_skip[i], x->skip, sizeof(uint8_t) * ctx->num_4x4_blk); memcpy(ctx->blk_skip[i], x->blk_skip[i], sizeof(uint8_t) * ctx->num_4x4_blk); @@ -10768,12 +10799,11 @@ struct calc_target_weighted_pred_ctxt { int overlap; }; -static INLINE void calc_target_weighted_pred_above(MACROBLOCKD *xd, - int rel_mi_col, - uint8_t nb_mi_width, - MODE_INFO *nb_mi, - void *fun_ctxt) { +static INLINE void calc_target_weighted_pred_above( + MACROBLOCKD *xd, int rel_mi_col, uint8_t nb_mi_width, MODE_INFO *nb_mi, + void *fun_ctxt, const int num_planes) { (void)nb_mi; + (void)num_planes; struct calc_target_weighted_pred_ctxt *ctxt = (struct calc_target_weighted_pred_ctxt *)fun_ctxt; @@ -10816,12 +10846,11 @@ static INLINE void calc_target_weighted_pred_above(MACROBLOCKD *xd, } } -static INLINE void calc_target_weighted_pred_left(MACROBLOCKD *xd, - int rel_mi_row, - uint8_t nb_mi_height, - MODE_INFO *nb_mi, - void *fun_ctxt) { +static INLINE void calc_target_weighted_pred_left( + MACROBLOCKD *xd, int rel_mi_row, uint8_t nb_mi_height, MODE_INFO *nb_mi, + void *fun_ctxt, const int num_planes) { (void)nb_mi; + (void)num_planes; struct calc_target_weighted_pred_ctxt *ctxt = (struct calc_target_weighted_pred_ctxt *)fun_ctxt; diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c index e47e3486eb278f4e57f80e7609eb5b24f77e84d0..987f34c495503b5051f9aa1a19469f62619019e2 100644 --- a/av1/encoder/temporal_filter.c +++ b/av1/encoder/temporal_filter.c @@ -296,6 +296,8 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi, int frame_count, int alt_ref_index, int strength, struct scale_factors *scale) { + const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); int byte; int frame; int mb_col, mb_row; @@ -324,7 +326,7 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi, predictor = predictor8; } - for (i = 0; i < MAX_MB_PLANE; i++) input_buffer[i] = mbd->plane[i].pre[0].buf; + for (i = 0; i < num_planes; i++) input_buffer[i] = mbd->plane[i].pre[0].buf; for (mb_row = 0; mb_row < mb_rows; mb_row++) { // Source frames are extended to 16 pixels. This is different than @@ -525,7 +527,7 @@ static void temporal_filter_iterate_c(AV1_COMP *cpi, } // Restore input state - for (i = 0; i < MAX_MB_PLANE; i++) mbd->plane[i].pre[0].buf = input_buffer[i]; + for (i = 0; i < num_planes; i++) mbd->plane[i].pre[0].buf = input_buffer[i]; } // Apply buffer limits and context specific adjustments to arnr filter. diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c index e93e4d0f49771e512517fd58d3fa2f8b7935e563..d60f965b07aefca7e6a7599e4d4738df070b6489 100644 --- a/av1/encoder/tokenize.c +++ b/av1/encoder/tokenize.c @@ -546,6 +546,7 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, BLOCK_SIZE bsize, int *rate, uint8_t allow_update_cdf) { const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; @@ -558,7 +559,7 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; if (mbmi->skip) { - av1_reset_skip_context(xd, mi_row, mi_col, bsize); + av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes); #if !CONFIG_LV_MAP if (dry_run) *t = t_backup; #endif @@ -570,7 +571,7 @@ void av1_tokenize_sb_vartx(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, *t = t_backup; #endif - for (int plane = 0; plane < av1_num_planes(cm); ++plane) { + for (int plane = 0; plane < num_planes; ++plane) { if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y)) { @@ -634,16 +635,17 @@ void av1_tokenize_sb(const AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate, const int mi_row, const int mi_col, uint8_t allow_update_cdf) { + const AV1_COMMON *const cm = &cpi->common; + const int num_planes = av1_num_planes(cm); MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; struct tokenize_b_args arg = { cpi, td, t, 0, allow_update_cdf }; if (mbmi->skip) { - av1_reset_skip_context(xd, mi_row, mi_col, bsize); + av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes); return; } - const int num_planes = av1_num_planes(&cpi->common); if (!dry_run) { for (int plane = 0; plane < num_planes; ++plane) { if (!is_chroma_reference(mi_row, mi_col, bsize,