CWG-E023 (SDP extension) Extend SDP from intra frames to inter frames.
diff --git a/apps/aomenc.c b/apps/aomenc.c index feb7a46..5e5a200 100644 --- a/apps/aomenc.c +++ b/apps/aomenc.c
@@ -39,6 +39,9 @@ #include "common/stream_iter.h" #include "common/tools_common.h" #include "common/warnings.h" +#if CONFIG_EXTENDED_SDP +#include "av1/common/blockd.h" +#endif // CONFIG_EXTENDED_SDP #if CONFIG_WEBM_IO #include "common/webmenc.h"
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h index 5183035..54cf83a 100644 --- a/av1/common/av1_common_int.h +++ b/av1/common/av1_common_int.h
@@ -1967,6 +1967,16 @@ cm->current_frame.frame_type == INTRA_ONLY_FRAME; } +#if CONFIG_EXTENDED_SDP +// Check whether this is chroma component of an intra region in inter frame +static INLINE int is_inter_sdp_chroma(const AV1_COMMON *const cm, + REGION_TYPE cur_region_type, + TREE_TYPE cur_tree_type) { + return !frame_is_intra_only(cm) && cur_region_type == INTRA_REGION && + cur_tree_type == CHROMA_PART; +} +#endif // CONFIG_EXTENDED_SDP + static INLINE int frame_is_sframe(const AV1_COMMON *cm) { return cm->current_frame.frame_type == S_FRAME; } @@ -2575,6 +2585,24 @@ #endif // CONFIG_EXT_RECUR_PARTITIONS } +#if CONFIG_EXTENDED_SDP +static INLINE int get_intra_region_context(BLOCK_SIZE bsize) { + const int width = block_size_wide[bsize]; + const int height = block_size_high[bsize]; + const int num_samples = width * height; + if (num_samples <= 64) + return 0; + else if (num_samples <= 128) + return 1; + else if (num_samples <= 256) + return 2; + else if (num_samples <= 512) + return 3; + else + return 4; +} +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_BLOCK_256 /*!\brief Returns the context used by \ref PARTITION_SPLIT. */ static INLINE int square_split_context(const MACROBLOCKD *xd, int mi_row, @@ -2672,6 +2700,7 @@ } av1_zero_array(above_contexts->partition[0][tile_row] + mi_col_start, aligned_width); + if (num_planes > 1) { if (above_contexts->partition[1][tile_row] && above_contexts->partition[2][tile_row]) {
diff --git a/av1/common/av1_loopfilter.c b/av1/common/av1_loopfilter.c index 2c0fbc2..17dcc75 100644 --- a/av1/common/av1_loopfilter.c +++ b/av1/common/av1_loopfilter.c
@@ -521,6 +521,8 @@ params->filter_length = 0; TREE_TYPE tree_type = SHARED_PART; + +#if !CONFIG_EXTENDED_SDP const bool is_sdp_eligible = frame_is_intra_only(cm) && !cm->seq_params.monochrome && cm->seq_params.enable_sdp; @@ -528,6 +530,7 @@ tree_type = (plane == AOM_PLANE_Y) ? LUMA_PART : CHROMA_PART; } const int plane_type = is_sdp_eligible && plane > 0; +#endif // !CONFIG_EXTENDED_SDP // no deblocking is required const uint32_t width = plane_ptr->dst.width; @@ -553,6 +556,16 @@ // it not set up. if (mbmi == NULL) return TX_INVALID; +#if CONFIG_EXTENDED_SDP + const bool is_sdp_eligible = cm->seq_params.enable_sdp && + !cm->seq_params.monochrome && + mbmi->region_type == INTRA_REGION; + if (is_sdp_eligible) { + tree_type = (plane == AOM_PLANE_Y) ? LUMA_PART : CHROMA_PART; + } + const int plane_type = is_sdp_eligible && plane > 0; +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_LF_SUB_PU TX_SIZE ts = get_transform_size(xd, mi[0], edge_dir, mi_row, mi_col, plane, tree_type, plane_ptr); @@ -595,9 +608,28 @@ const int pv_col = (VERT_EDGE == edge_dir) ? (mi_col - (1 << scale_horz)) : (mi_col); +#if CONFIG_EXTENDED_SDP + TREE_TYPE prev_tree_type = SHARED_PART; + const bool is_prev_sdp_eligible = + cm->seq_params.enable_sdp && !cm->seq_params.monochrome && + mi_prev->region_type == INTRA_REGION; + // With SDP in inter frames, the tree type of current block can be + // different with previous block, so we can't copy the tree type of + // current block to previous block, and we need to fetch the tree type + // of a previous block. + if (is_prev_sdp_eligible) { + prev_tree_type = (plane == AOM_PLANE_Y) ? LUMA_PART : CHROMA_PART; + } + const TX_SIZE pv_ts = + get_transform_size(xd, mi_prev, edge_dir, pv_row, pv_col, plane, + prev_tree_type, plane_ptr); +#else + const TX_SIZE pv_ts = get_transform_size(xd, mi_prev, edge_dir, pv_row, pv_col, plane, tree_type, plane_ptr); +#endif // CONFIG_EXTENDED_SDP + const uint32_t pv_q = av1_get_filter_q(&cm->lf_info, edge_dir, plane, mi_prev); const uint32_t pv_side =
diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 204d7c4..835d34a 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h
@@ -430,6 +430,10 @@ /*! \brief The partition type of the current coding block. */ PARTITION_TYPE partition; /*! \brief The prediction mode used */ +#if CONFIG_EXTENDED_SDP + /*! \brief The region type used for the current block. */ + REGION_TYPE region_type; +#endif // CONFIG_EXTENDED_SDP PREDICTION_MODE mode; /*! \brief The JMVD scaling mode for the current coding block. The supported * scale modes for JOINT_NEWMV mode is 0, 1, 2, 3, and 4. The supported scale @@ -746,6 +750,12 @@ struct PARTITION_TREE *sub_tree[4]; /*! \brief The partition type used to split the current block. */ PARTITION_TYPE partition; +#if CONFIG_EXTENDED_SDP + /*! \brief The region type used for the current block. */ + REGION_TYPE region_type; + /*! \brief Whethe SDP is allowed for one block in inter frame. */ + int inter_sdp_allowed_flag; +#endif // CONFIG_EXTENDED_SDP /*! \brief Block size of the current block. */ BLOCK_SIZE bsize; /*! \brief Whether the chroma block info is ready. */ @@ -1363,6 +1373,61 @@ info->bsize_base = bsize; } +#if CONFIG_EXTENDED_SDP +static INLINE int is_bsize_allowed_for_inter_sdp(BLOCK_SIZE bsize, + PARTITION_TYPE partition) { + const int bw = block_size_wide[bsize]; + const int bh = block_size_high[bsize]; + return bw <= 32 && bh <= 32 && bw >= 8 && bh >= 8 && + partition < PARTITION_HORZ_4A; +} +// Decide whether SDP is allowed for one block in inter frame. +static INLINE int is_inter_sdp_allowed(BLOCK_SIZE parent_bsize, + PARTITION_TYPE parent_partition) { + const int bw = block_size_wide[parent_bsize]; + const int bh = block_size_high[parent_bsize]; + // Check if block width/height is less than 4. + const int bw_gt_4 = bw > 4; + const int bh_gt_4 = bh > 4; + // Check if half block width/height is less than 8. + const int hbw_gt_4 = bw > 8; + const int hbh_gt_4 = bh > 8; +#if CONFIG_EXT_RECUR_PARTITIONS + // Check if quarter block width/height is less than 16. + const int qbw_gt_4 = bw > 16; + const int qbh_gt_4 = bh > 16; +#endif // !CONFIG_UNEVEN_4WAY || CONFIG_EXT_RECUR_PARTITIONS + // Check if one-eighth block width/height is less than 32. + const int ebw_gt_4 = bw > 32; + const int ebh_gt_4 = bh > 32; + switch (parent_partition) { + case PARTITION_NONE: return 1; + case PARTITION_HORZ: return bw_gt_4 && hbh_gt_4; + case PARTITION_VERT: return hbw_gt_4 && bh_gt_4; + case PARTITION_SPLIT: return hbw_gt_4 && hbh_gt_4; +#if CONFIG_EXT_RECUR_PARTITIONS + case PARTITION_HORZ_4A: + case PARTITION_HORZ_4B: return bw_gt_4 && ebh_gt_4; + case PARTITION_VERT_4A: + case PARTITION_VERT_4B: return ebw_gt_4 && bh_gt_4; + case PARTITION_HORZ_3: return hbw_gt_4 && qbh_gt_4; + case PARTITION_VERT_3: return qbw_gt_4 && hbh_gt_4; +#else // CONFIG_EXT_RECUR_PARTITIONS + case PARTITION_HORZ_A: + case PARTITION_HORZ_B: + case PARTITION_VERT_A: + case PARTITION_VERT_B: return hbw_less_than_4 || hbh_less_than_4; + case PARTITION_HORZ_4: return bw_less_than_4 || qbh_less_than_4; + case PARTITION_VERT_4: return qbw_less_than_4 || bh_less_than_4; +#endif // CONFIG_EXT_RECUR_PARTITIONS + default: + assert(0 && "Invalid partition type!"); + return 0; + break; + } +} +#endif // CONFIG_EXTENDED_SDP + // Decide whether a block needs coding multiple chroma coding blocks in it at // once to get around sub-4x4 coding. static INLINE int have_nz_chroma_ref_offset(BLOCK_SIZE bsize, @@ -2334,6 +2399,7 @@ * This is a pointer into 'left_txfm_context_buffer'. */ TXFM_CONTEXT *left_txfm_context; + /*! * left_txfm_context_buffer[i] is the left transform context for ith mi_row * in this *superblock*.
diff --git a/av1/common/entropy.c b/av1/common/entropy.c index 85b7241..5c8d60a 100644 --- a/av1/common/entropy.c +++ b/av1/common/entropy.c
@@ -387,6 +387,12 @@ RESET_CDF_COUNTER(fc->uv_mode_cdf[1], UV_INTRA_MODES); #endif // CONFIG_UV_CFL +#if CONFIG_EXTENDED_SDP + for (int i = 0; i < INTER_SDP_BSIZE_GROUP; i++) { + RESET_CDF_COUNTER(fc->region_type_cdf[i], REGION_TYPES); + } +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_EXT_RECUR_PARTITIONS for (int plane_index = 0; plane_index < PARTITION_STRUCTURE_NUM; plane_index++) {
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c index 99629fb..279bfad 100644 --- a/av1/common/entropymode.c +++ b/av1/common/entropymode.c
@@ -454,6 +454,22 @@ 9875, 10521, 29048) } } }; #endif // CONFIG_AIMC + +#if CONFIG_EXTENDED_SDP +static aom_cdf_prob default_region_type_cdf[INTER_SDP_BSIZE_GROUP] + [CDF_SIZE(REGION_TYPES)] = { + // w * h <= 64 + { AOM_CDF2(16384), 0 }, + // w * h <= 128 + { AOM_CDF2(16384), 0 }, + // w * h <= 256 + { AOM_CDF2(16384), 0 }, + // w * h <= 512 + { AOM_CDF2(16384), 0 }, + // w * h <= 1024 + { AOM_CDF2(16384), 0 } + }; +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS // clang-format off #if CONFIG_FLEX_PARTITION @@ -7324,6 +7340,9 @@ av1_copy(fc->filter_dir_cdf, default_filter_dir_cdf); #endif // CONFIG_ENABLE_MHCCP av1_copy(fc->switchable_interp_cdf, default_switchable_interp_cdf); +#if CONFIG_EXTENDED_SDP + av1_copy(fc->region_type_cdf, default_region_type_cdf); +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS av1_copy(fc->do_split_cdf, default_do_split_cdf); #if CONFIG_BLOCK_256
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h index f8c15e4..1e8de90 100644 --- a/av1/common/entropymode.h +++ b/av1/common/entropymode.h
@@ -537,6 +537,10 @@ #endif // CONFIG_BLOCK_256 aom_cdf_prob rect_type_cdf[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS] [CDF_SIZE(2)]; +#if CONFIG_EXTENDED_SDP + aom_cdf_prob region_type_cdf[INTER_SDP_BSIZE_GROUP][CDF_SIZE(REGION_TYPES)]; +#endif // CONFIG_EXTENDED_SDP + aom_cdf_prob do_ext_partition_cdf[PARTITION_STRUCTURE_NUM][NUM_RECT_PARTS] [PARTITION_CONTEXTS][CDF_SIZE(2)]; aom_cdf_prob do_uneven_4way_partition_cdf[PARTITION_STRUCTURE_NUM]
diff --git a/av1/common/enums.h b/av1/common/enums.h index 3fdca21..a959da6 100644 --- a/av1/common/enums.h +++ b/av1/common/enums.h
@@ -355,6 +355,14 @@ TREES_TYPES, } UENUM1BYTE(TREE_TYPE); +#if CONFIG_EXTENDED_SDP +enum { + INTRA_REGION = 0, + MIXED_INTER_INTRA_REGION = 1, + REGION_TYPES = 2, +} UENUM1BYTE(REGION_TYPE); +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_BLOCK_256 // 4X4, 8X8, 16X16, 32X32, 64X64, 128X128, 256X256 #define SQR_BLOCK_SIZES 7 @@ -479,6 +487,13 @@ #define PARTITION_BLOCK_SIZES 5 #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP +// Extended SDP is only allowed for block samples >= 64 and <= 1024. The allowed +// block size group is 64, 128, 256, 512, 1024, so the number of block size +// group is 5 in total. +#define INTER_SDP_BSIZE_GROUP 5 +#endif // CONFIG_EXTENDED_SDP + #define PARTITION_CONTEXTS (PARTITION_BLOCK_SIZES * PARTITION_PLOFFSET) // block transform size @@ -1146,6 +1161,10 @@ #endif // CONFIG_NEW_TX_PARTITION typedef uint16_t TXFM_CONTEXT; +#if CONFIG_EXTENDED_SDP +typedef uint8_t INTRA_REGION_CONTEXT; +#endif // CONFIG_EXTENDED_SDP + #define TIP_CONTEXTS 3 #define INTER_REFS_PER_FRAME 7
diff --git a/av1/common/reconintra.h b/av1/common/reconintra.h index 8f10cf3..16a5c27 100644 --- a/av1/common/reconintra.h +++ b/av1/common/reconintra.h
@@ -99,12 +99,25 @@ return bsize >= BLOCK_8X8; } -static INLINE int av1_allow_intrabc(const AV1_COMMON *const cm) { +static INLINE int av1_allow_intrabc(const AV1_COMMON *const cm, + const MACROBLOCKD *const xd) { +#if CONFIG_EXTENDED_SDP + int cur_region_type = MIXED_INTER_INTRA_REGION; + if (xd->mi != NULL) cur_region_type = xd->mi[0]->region_type; +#endif #if CONFIG_IBC_SR_EXT return (frame_is_intra_only(cm) || cm->features.allow_local_intrabc) && +#if CONFIG_EXTENDED_SDP + xd->tree_type != CHROMA_PART && + (frame_is_intra_only(cm) || cur_region_type != INTRA_REGION) && +#endif // CONFIG_EXTENDED_SDP cm->features.allow_screen_content_tools && cm->features.allow_intrabc; #else return frame_is_intra_only(cm) && cm->features.allow_screen_content_tools && +#if CONFIG_EXTENDED_SDP + xd->tree_type != CHROMA_PART && + xd->mi[0]->region_type != INTRA_REGION && +#endif // CONFIG_EXTENDED_SDP cm->features.allow_intrabc; #endif // CONFIG_IBC_SR_EXT }
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 9662d7d..c54b4c6 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -1252,6 +1252,10 @@ set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, parent, index); xd->mi[0]->partition = partition; +#if CONFIG_EXTENDED_SDP + // set region_type for each mbmi + xd->mi[0]->region_type = parent->region_type; +#endif // CONFIG_EXTENDED_SDP av1_read_mode_info(pbi, dcb, r, x_mis, y_mis); #if CONFIG_EXT_RECUR_PARTITIONS @@ -1354,7 +1358,7 @@ #if CONFIG_MORPH_PRED if (mbmi->morph_pred) { - assert(av1_allow_intrabc(cm)); + assert(av1_allow_intrabc(cm, xd)); assert(is_intrabc_block(mbmi, xd->tree_type)); av1_build_morph_pred(cm, xd, bsize, mi_row, mi_col); } @@ -2295,6 +2299,7 @@ AV1_COMMON *cm = &pbi->common; const int num_planes = av1_num_planes(cm); MB_MODE_INFO *mbmi = xd->mi[0]; + int inter_block_tx = is_inter_block(mbmi, xd->tree_type) || is_intrabc_block(mbmi, xd->tree_type); if (xd->tree_type != CHROMA_PART) { @@ -2711,6 +2716,18 @@ parse_decode_block }; const int is_sb_root = bsize == cm->sb_size; +#if CONFIG_EXTENDED_SDP + if (is_sb_root) { + if (!frame_is_intra_only(cm)) { + ptree->region_type = MIXED_INTER_INTRA_REGION; + ptree->inter_sdp_allowed_flag = 1; + } else { + ptree->region_type = INTRA_REGION; + ptree->inter_sdp_allowed_flag = 0; + } + } +#endif // CONFIG_EXTENDED_SDP + if (parse_decode_flag & 1) { if (is_sb_root) { set_sb_mv_precision(sbi, pbi); @@ -2767,6 +2784,30 @@ ptree->partition = partition; +#if CONFIG_EXTENDED_SDP + if (!is_sb_root && parent) { + if (parent->inter_sdp_allowed_flag == 1) + ptree->inter_sdp_allowed_flag = + is_inter_sdp_allowed(parent->bsize, parent->partition); + else + ptree->inter_sdp_allowed_flag = 0; + if (!frame_is_intra_only(cm) && ptree->partition && + parent->region_type != INTRA_REGION && + ptree->inter_sdp_allowed_flag && + is_bsize_allowed_for_inter_sdp(bsize, ptree->partition)) { + const int ctx = get_intra_region_context(bsize); + ptree->region_type = + aom_read_symbol(reader, xd->tile_ctx->region_type_cdf[ctx], + REGION_TYPES, ACCT_INFO("region_type")); + if (ptree->region_type == INTRA_REGION) xd->tree_type = LUMA_PART; + } else if (!frame_is_intra_only(cm)) { + ptree->region_type = parent->region_type; + } else { + ptree->region_type = INTRA_REGION; + } + } +#endif // CONFIG_EXTENDED_SDP + switch (partition) { #if CONFIG_EXT_RECUR_PARTITIONS case PARTITION_HORZ_4A: @@ -3031,6 +3072,21 @@ default: assert(0 && "Invalid partition type"); } +#if CONFIG_EXTENDED_SDP + PARTITION_TREE *parent = ptree->parent; + if (!is_sb_root && parent) { + if (!frame_is_intra_only(cm) && !cm->seq_params.monochrome && + ptree->partition && parent->region_type != INTRA_REGION && + ptree->region_type == INTRA_REGION) { + // decode chroma part in one intra region + xd->tree_type = CHROMA_PART; + DEC_BLOCK(mi_row, mi_col, bsize, 0); + // reset back to shared part + xd->tree_type = SHARED_PART; + } + } +#endif // CONFIG_EXTENDED_SDP + #undef DEC_PARTITION #undef DEC_BLOCK #undef DEC_BLOCK_EPT_ARG @@ -8411,7 +8467,7 @@ (uint32_t)aom_rb_bytes_read(rb); // Size of the uncompressed header YV12_BUFFER_CONFIG *new_fb = &cm->cur_frame->buf; xd->cur_buf = new_fb; - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { av1_setup_scale_factors_for_frame( &cm->sf_identity, xd->cur_buf->y_crop_width, xd->cur_buf->y_crop_height, xd->cur_buf->y_crop_width, xd->cur_buf->y_crop_height);
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index 62d2ae1..af72c4e 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c
@@ -888,7 +888,10 @@ aom_reader *r, int skip) { struct segmentation *const seg = &cm->seg; if (!seg->enabled) return 0; // Default for disabled segmentation - assert(seg->update_map && !seg->temporal_update); +#if CONFIG_EXTENDED_SDP + if (frame_is_intra_only(cm)) +#endif // CONFIG_EXTENDED_SDP + assert(seg->update_map && !seg->temporal_update); const CommonModeInfoParams *const mi_params = &cm->mi_params; const int mi_row = xd->mi_row; @@ -1888,7 +1891,11 @@ FRAME_CONTEXT *ec_ctx = xd->tile_ctx; - if (seg->segid_preskip) + if (seg->segid_preskip +#if CONFIG_EXTENDED_SDP + && !(!frame_is_intra_only(cm) && xd->tree_type == CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + ) mbmi->segment_id = read_intra_segment_id(cm, xd, bsize, r, 0); #if CONFIG_SKIP_MODE_ENHANCEMENT @@ -1899,7 +1906,7 @@ #endif // CONFIG_MORPH_PRED #if CONFIG_SKIP_TXFM_OPT - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { #if CONFIG_NEW_CONTEXT_MODELING mbmi->use_intrabc[0] = 0; mbmi->use_intrabc[1] = 0; @@ -1923,10 +1930,18 @@ read_skip_txfm(cm, xd, mbmi->segment_id, r); #endif // CONFIG_SKIP_TXFM_OPT - if (!seg->segid_preskip) + if (!seg->segid_preskip +#if CONFIG_EXTENDED_SDP + && !(!frame_is_intra_only(cm) && xd->tree_type == CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + ) mbmi->segment_id = read_intra_segment_id( cm, xd, bsize, r, mbmi->skip_txfm[xd->tree_type == CHROMA_PART]); +#if CONFIG_EXTENDED_SDP + mbmi->seg_id_predicted = 0; +#endif // CONFIG_EXTENDED_SDP + if (xd->tree_type != CHROMA_PART) read_cdef(cm, r, xd); #if CONFIG_CCSO @@ -1958,7 +1973,7 @@ xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK); #endif // !CONFIG_TX_PARTITION_CTX - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { read_intrabc_info(cm, dcb, r); if (is_intrabc_block(mbmi, xd->tree_type)) { #if CONFIG_LOSSLESS_DPCM @@ -4309,7 +4324,6 @@ #endif // CONFIG_REFINEMV mbmi->segment_id = read_inter_segment_id(cm, xd, 1, r); - mbmi->skip_mode = read_skip_mode(cm, xd, mbmi->segment_id, r); mbmi->fsc_mode[PLANE_TYPE_Y] = 0; @@ -4336,7 +4350,8 @@ } #if CONFIG_IBC_SR_EXT - if (!inter_block && av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (!inter_block && av1_allow_intrabc(cm, xd) && + xd->tree_type != CHROMA_PART) { #if CONFIG_NEW_CONTEXT_MODELING mbmi->use_intrabc[0] = 0; mbmi->use_intrabc[1] = 0; @@ -4408,7 +4423,8 @@ #endif // !CONFIG_TX_PARTITION_CTX #if CONFIG_IBC_SR_EXT - if (!inter_block && av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (!inter_block && av1_allow_intrabc(cm, xd) && + xd->tree_type != CHROMA_PART) { mbmi->ref_frame[0] = INTRA_FRAME; mbmi->ref_frame[1] = NONE_FRAME; mbmi->palette_mode_info.palette_size[0] = 0; @@ -4465,7 +4481,11 @@ if (xd->tree_type == SHARED_PART) mi->sb_type[PLANE_TYPE_UV] = mi->sb_type[PLANE_TYPE_Y]; - if (frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm) +#if CONFIG_EXTENDED_SDP + || mi->region_type == INTRA_REGION +#endif // CONFIG_EXTENDED_SDP + ) { read_intra_frame_mode_info(cm, dcb, r); #if CONFIG_IBC_BV_IMPROVEMENT if (cm->seq_params.enable_refmvbank) {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 4e82142..68a55ec 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -2410,7 +2410,6 @@ int ref; write_inter_segment_id(cpi, w, seg, segp, 0, 1); - write_skip_mode(cm, xd, segment_id, mbmi, w); #if CONFIG_SKIP_TXFM_OPT @@ -2418,7 +2417,8 @@ write_is_inter(cm, xd, mbmi->segment_id, w, is_inter); #if CONFIG_IBC_SR_EXT - if (!is_inter && av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (!is_inter && av1_allow_intrabc(cm, xd) && + xd->tree_type != CHROMA_PART) { const int use_intrabc = is_intrabc_block(mbmi, xd->tree_type); if (xd->tree_type == CHROMA_PART) assert(use_intrabc == 0); #if CONFIG_NEW_CONTEXT_MODELING @@ -2517,7 +2517,7 @@ #endif // !CONFIG_SKIP_TXFM_OPT #if CONFIG_IBC_SR_EXT - if (!is_inter && av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (!is_inter && av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { write_intrabc_info( #if CONFIG_IBC_BV_IMPROVEMENT && CONFIG_IBC_MAX_DRL cm->features.max_bvp_drl_bits, @@ -3101,11 +3101,15 @@ struct segmentation_probs *const segp = &ec_ctx->seg; const MB_MODE_INFO *const mbmi = xd->mi[0]; - if (seg->segid_preskip && seg->update_map) + if (seg->segid_preskip && seg->update_map +#if CONFIG_EXTENDED_SDP + && !(!frame_is_intra_only(cm) && xd->tree_type == CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + ) write_segment_id(cpi, mbmi, w, seg, segp, 0); #if CONFIG_SKIP_TXFM_OPT - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { const int use_intrabc = is_intrabc_block(mbmi, xd->tree_type); if (xd->tree_type == CHROMA_PART) assert(use_intrabc == 0); #if CONFIG_NEW_CONTEXT_MODELING @@ -3123,7 +3127,11 @@ #else const int skip = write_skip(cm, xd, mbmi->segment_id, mbmi, w); #endif // CONFIG_SKIP_TXFM_OPT - if (!seg->segid_preskip && seg->update_map) + if (!seg->segid_preskip && seg->update_map +#if CONFIG_EXTENDED_SDP + && !(!frame_is_intra_only(cm) && xd->tree_type == CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + ) write_segment_id(cpi, mbmi, w, seg, segp, skip); if (xd->tree_type != CHROMA_PART) write_cdef(cm, xd, w, skip); @@ -3140,8 +3148,7 @@ #endif write_delta_q_params(cpi, skip, w); - - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { write_intrabc_info( #if CONFIG_IBC_BV_IMPROVEMENT && CONFIG_IBC_MAX_DRL cm->features.max_bvp_drl_bits, @@ -3252,7 +3259,11 @@ MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; MB_MODE_INFO *m = xd->mi[0]; - if (frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm) +#if CONFIG_EXTENDED_SDP + || m->region_type == INTRA_REGION +#endif // CONFIG_EXTENDED_SDP + ) { write_mb_modes_kf(cpi, xd, cpi->td.mb.mbmi_ext_frame, w); } else { // has_subpel_mv_component needs the ref frame buffers set up to look @@ -3713,6 +3724,21 @@ #else write_partition(cm, xd, mi_row, mi_col, partition, bsize, w); #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + const int is_sb_root = bsize == cm->sb_size; + PARTITION_TREE *parent = ptree->parent; + if (!is_sb_root && !frame_is_intra_only(cm) && parent && partition && + parent->region_type != INTRA_REGION && ptree->inter_sdp_allowed_flag && + is_bsize_allowed_for_inter_sdp(bsize, ptree->partition)) { + const int ctx = get_intra_region_context(bsize); + assert(xd->tree_type != CHROMA_PART); + aom_write_symbol(w, ptree->region_type, xd->tile_ctx->region_type_cdf[ctx], + REGION_TYPES); + if (ptree->region_type == INTRA_REGION) { + xd->tree_type = LUMA_PART; + } + } +#endif // CONFIG_EXTENDED_SDP switch (partition) { case PARTITION_NONE: write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); @@ -3921,6 +3947,17 @@ #endif // CONFIG_EXT_RECUR_PARTITIONS default: assert(0); break; } +#if CONFIG_EXTENDED_SDP + if (!is_sb_root && !frame_is_intra_only(cm) && !cm->seq_params.monochrome && + parent && partition && parent->region_type != INTRA_REGION && + ptree->region_type == INTRA_REGION) { + // run chroma part in luma region + xd->tree_type = CHROMA_PART; + write_modes_b(cpi, tile, w, tok, tok_end, mi_row, mi_col); + // reset back to shared part + xd->tree_type = SHARED_PART; + } +#endif // CONFIG_EXTENDED_SDP // update partition context update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
diff --git a/av1/encoder/block.h b/av1/encoder/block.h index 5ff0559..4165df3 100644 --- a/av1/encoder/block.h +++ b/av1/encoder/block.h
@@ -835,6 +835,10 @@ * \name Partition Costs ****************************************************************************/ /**@{*/ +#if CONFIG_EXTENDED_SDP + //! Cost for coding the region type. + int region_type_cost[INTER_SDP_BSIZE_GROUP][REGION_TYPES]; +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS /*! Cost for sending split token. */ int do_split_cost[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS][2];
diff --git a/av1/encoder/context_tree.c b/av1/encoder/context_tree.c index ddcb0d7..75f0307 100644 --- a/av1/encoder/context_tree.c +++ b/av1/encoder/context_tree.c
@@ -224,6 +224,18 @@ pc_tree->parent = parent; pc_tree->index = index; pc_tree->partitioning = PARTITION_NONE; +#if CONFIG_EXTENDED_SDP + if (parent) { + pc_tree->region_type = parent->region_type; + if (parent->inter_sdp_allowed_flag == 1) + pc_tree->inter_sdp_allowed_flag = + is_inter_sdp_allowed(parent->block_size, parent_partition); + else + pc_tree->inter_sdp_allowed_flag = 0; + } else { + pc_tree->inter_sdp_allowed_flag = 1; + } +#endif // CONFIG_EXTENDED_SDP pc_tree->block_size = bsize; pc_tree->is_last_subblock = is_last; av1_invalid_rd_stats(&pc_tree->rd_cost); @@ -236,8 +248,49 @@ parent ? &parent->chroma_ref_info : NULL, parent ? parent->block_size : BLOCK_INVALID, parent_partition, subsampling_x, subsampling_y); - +#if CONFIG_EXTENDED_SDP + pc_tree->none[INTRA_REGION] = NULL; + pc_tree->none[MIXED_INTER_INTRA_REGION] = NULL; + pc_tree->none_chroma = NULL; +#else pc_tree->none = NULL; +#endif // CONFIG_EXTENDED_SDP +#if CONFIG_EXTENDED_SDP + for (REGION_TYPE cur_region_type = INTRA_REGION; + cur_region_type < REGION_TYPES; ++cur_region_type) { + for (int i = 0; i < 2; ++i) { + pc_tree->horizontal[cur_region_type][i] = NULL; + pc_tree->vertical[cur_region_type][i] = NULL; + } +#if CONFIG_EXT_RECUR_PARTITIONS + for (int i = 0; i < 4; ++i) { + pc_tree->horizontal4a[cur_region_type][i] = NULL; + pc_tree->horizontal4b[cur_region_type][i] = NULL; + pc_tree->vertical4a[cur_region_type][i] = NULL; + pc_tree->vertical4b[cur_region_type][i] = NULL; + } + for (int i = 0; i < 4; ++i) { + pc_tree->horizontal3[cur_region_type][i] = NULL; + pc_tree->vertical3[cur_region_type][i] = NULL; + } +#else + for (int i = 0; i < 3; ++i) { + pc_tree->horizontala[cur_region_type][i] = NULL; + pc_tree->horizontalb[cur_region_type][i] = NULL; + pc_tree->verticala[cur_region_type][i] = NULL; + pc_tree->verticalb[cur_region_type][i] = NULL; + } +#endif // CONFIG_EXT_RECUR_PARTITIONS + for (int i = 0; i < 4; ++i) { +#if !CONFIG_EXT_RECUR_PARTITIONS + pc_tree->horizontal4[cur_region_type][i] = NULL; + pc_tree->vertical4[cur_region_type][i] = NULL; +#endif // !CONFIG_EXT_RECUR_PARTITIONS + pc_tree->split[cur_region_type][i] = NULL; + } + } + +#else // CONFIG_EXTENDED_SDP for (int i = 0; i < 2; ++i) { pc_tree->horizontal[i] = NULL; pc_tree->vertical[i] = NULL; @@ -268,7 +321,7 @@ #endif // !CONFIG_EXT_RECUR_PARTITIONS pc_tree->split[i] = NULL; } - +#endif // CONFIG_EXTENDED_SDP return pc_tree; } @@ -284,9 +337,135 @@ const PARTITION_TYPE partition = pc_tree->partitioning; +#if CONFIG_EXTENDED_SDP + PC_TREE *parent = pc_tree->parent; + if (!keep_none && + (!keep_best || (pc_tree->region_type != INTRA_REGION || + (parent && parent->region_type == INTRA_REGION)))) + FREE_PMC_NODE(pc_tree->none_chroma); + + for (int cur_region_type = INTRA_REGION; cur_region_type < REGION_TYPES; + ++cur_region_type) { + if (!keep_none && (!keep_best || (partition != PARTITION_NONE))) + FREE_PMC_NODE(pc_tree->none[cur_region_type]); + + for (int i = 0; i < 2; ++i) { +#if CONFIG_EXT_RECUR_PARTITIONS + if ((!keep_best || (partition != PARTITION_HORZ) || + (cur_region_type != pc_tree->region_type)) && + pc_tree->horizontal[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->horizontal[cur_region_type][i], + num_planes, 0, 0); + pc_tree->horizontal[cur_region_type][i] = NULL; + } + if ((!keep_best || (partition != PARTITION_VERT) || + (cur_region_type != pc_tree->region_type)) && + pc_tree->vertical[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->vertical[cur_region_type][i], + num_planes, 0, 0); + pc_tree->vertical[cur_region_type][i] = NULL; + } +#else + if (!keep_best || (partition != PARTITION_HORZ)) + FREE_PMC_NODE(pc_tree->horizontal[cur_region_type][i]); + if (!keep_best || (partition != PARTITION_VERT)) + FREE_PMC_NODE(pc_tree->vertical[cur_region_type][i]); +#endif // CONFIG_EXT_RECUR_PARTITIONS + } +#if CONFIG_EXT_RECUR_PARTITIONS + + if (!keep_best || (partition != PARTITION_HORZ_4A) || + (cur_region_type != pc_tree->region_type)) { + for (int i = 0; i < 4; ++i) { + if (pc_tree->horizontal4a[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->horizontal4a[cur_region_type][i], + num_planes, 0, 0); + pc_tree->horizontal4a[cur_region_type][i] = NULL; + } + } + } + + if (!keep_best || (partition != PARTITION_HORZ_4B) || + (cur_region_type != pc_tree->region_type)) { + for (int i = 0; i < 4; ++i) { + if (pc_tree->horizontal4b[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->horizontal4b[cur_region_type][i], + num_planes, 0, 0); + pc_tree->horizontal4b[cur_region_type][i] = NULL; + } + } + } + + if (!keep_best || (partition != PARTITION_VERT_4A) || + (cur_region_type != pc_tree->region_type)) { + for (int i = 0; i < 4; ++i) { + if (pc_tree->vertical4a[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->vertical4a[cur_region_type][i], + num_planes, 0, 0); + pc_tree->vertical4a[cur_region_type][i] = NULL; + } + } + } + + if (!keep_best || (partition != PARTITION_VERT_4B) || + (cur_region_type != pc_tree->region_type)) { + for (int i = 0; i < 4; ++i) { + if (pc_tree->vertical4b[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->vertical4b[cur_region_type][i], + num_planes, 0, 0); + pc_tree->vertical4b[cur_region_type][i] = NULL; + } + } + } + for (int i = 0; i < 4; ++i) { + if ((!keep_best || (partition != PARTITION_HORZ_3) || + (cur_region_type != pc_tree->region_type)) && + pc_tree->horizontal3[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->horizontal3[cur_region_type][i], + num_planes, 0, 0); + pc_tree->horizontal3[cur_region_type][i] = NULL; + } + if ((!keep_best || (partition != PARTITION_VERT_3) || + (cur_region_type != pc_tree->region_type)) && + pc_tree->vertical3[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->vertical3[cur_region_type][i], + num_planes, 0, 0); + pc_tree->vertical3[cur_region_type][i] = NULL; + } + } +#else + for (int i = 0; i < 3; ++i) { + if (!keep_best || (partition != PARTITION_HORZ_A)) + FREE_PMC_NODE(pc_tree->horizontala[cur_region_type][i]); + if (!keep_best || (partition != PARTITION_HORZ_B)) + FREE_PMC_NODE(pc_tree->horizontalb[cur_region_type][i]); + if (!keep_best || (partition != PARTITION_VERT_A)) + FREE_PMC_NODE(pc_tree->verticala[cur_region_type][i]); + if (!keep_best || (partition != PARTITION_VERT_B)) + FREE_PMC_NODE(pc_tree->verticalb[cur_region_type][i]); + } + for (int i = 0; i < 4; ++i) { + if (!keep_best || (partition != PARTITION_HORZ_4)) + FREE_PMC_NODE(pc_tree->horizontal4[cur_region_type][i]); + if (!keep_best || (partition != PARTITION_VERT_4)) + FREE_PMC_NODE(pc_tree->vertical4[cur_region_type][i]); + } +#endif // CONFIG_EXT_RECUR_PARTITIONS + + if (!keep_best || (partition != PARTITION_SPLIT) || + (cur_region_type != pc_tree->region_type)) { + for (int i = 0; i < 4; ++i) { + if (pc_tree->split[cur_region_type][i] != NULL) { + av1_free_pc_tree_recursive(pc_tree->split[cur_region_type][i], + num_planes, 0, 0); + pc_tree->split[cur_region_type][i] = NULL; + } + } + } + } // region type index +#else // CONFIG_EXTENDED_SDP if (!keep_none && (!keep_best || (partition != PARTITION_NONE))) FREE_PMC_NODE(pc_tree->none); - for (int i = 0; i < 2; ++i) { #if CONFIG_EXT_RECUR_PARTITIONS if ((!keep_best || (partition != PARTITION_HORZ)) && @@ -381,7 +560,7 @@ } } } - +#endif // CONFIG_EXTENDED_SDP if (!keep_best && !keep_none) aom_free(pc_tree); } @@ -393,6 +572,11 @@ // Copy the best partition type. For basic information like bsize and index, // we assume they have been set properly when initializing the dst PC_TREE dst->partitioning = src->partitioning; +#if CONFIG_EXTENDED_SDP + dst->region_type = src->region_type; + dst->inter_sdp_allowed_flag = src->inter_sdp_allowed_flag; + REGION_TYPE cur_region_type = src->region_type; +#endif // CONFIG_EXTENDED_SDP dst->rd_cost = src->rd_cost; dst->none_rd = src->none_rd; dst->skippable = src->skippable; @@ -402,9 +586,46 @@ const int mi_row = src->mi_row; const int mi_col = src->mi_col; +#if CONFIG_EXTENDED_SDP + PC_TREE *src_parent = src->parent; + if ((src->region_type == INTRA_REGION && + (src_parent && src_parent->region_type == MIXED_INTER_INTRA_REGION))) { + if (dst->none_chroma) av1_free_pmc(dst->none_chroma, num_planes); + dst->none_chroma = NULL; + if (src->none_chroma) { + dst->none_chroma = + av1_alloc_pmc(cm, tree_type, mi_row, mi_col, bsize, dst, + PARTITION_NONE, 0, ss_x, ss_y, shared_bufs); + av1_copy_tree_context(dst->none_chroma, src->none_chroma); + } + } +#endif // CONFIG_EXTENDED_SDP + switch (src->partitioning) { // PARTITION_NONE case PARTITION_NONE: +#if CONFIG_EXTENDED_SDP + if (dst->none[cur_region_type]) + av1_free_pmc(dst->none[cur_region_type], num_planes); + dst->none[cur_region_type] = NULL; + if (src->none[cur_region_type]) { + dst->none[cur_region_type] = + av1_alloc_pmc(cm, tree_type, mi_row, mi_col, bsize, dst, + PARTITION_NONE, 0, ss_x, ss_y, shared_bufs); + av1_copy_tree_context(dst->none[cur_region_type], + src->none[cur_region_type]); +#if CONFIG_MVP_IMPROVEMENT + if (is_inter_block(&src->none[cur_region_type]->mic, xd->tree_type)) { +#if WARP_CU_BANK + av1_update_warp_param_bank(cm, xd, &dst->none[cur_region_type]->mic); +#endif // WARP_CU_BANK + if (cm->seq_params.enable_refmvbank) { + av1_update_ref_mv_bank(cm, xd, &dst->none[cur_region_type]->mic); + } + } +#endif // CONFIG_MVP_IMPROVEMENT + } +#else if (dst->none) av1_free_pmc(dst->none, num_planes); dst->none = NULL; if (src->none) { @@ -422,11 +643,30 @@ } #endif // CONFIG_MVP_IMPROVEMENT } +#endif // CONFIG_EXTENDED_SDP break; // PARTITION_SPLIT case PARTITION_SPLIT: if (is_partition_valid(bsize, PARTITION_SPLIT)) { for (int i = 0; i < 4; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->split[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->split[cur_region_type][i], + num_planes, 0, 0); + dst->split[cur_region_type][i] = NULL; + } + if (src->split[cur_region_type][i]) { + const int x_idx = (i & 1) * (mi_size_wide[bsize] >> 1); + const int y_idx = (i >> 1) * (mi_size_high[bsize] >> 1); + dst->split[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row + y_idx, mi_col + x_idx, subsize, dst, + PARTITION_SPLIT, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive(xd, cm, dst->split[cur_region_type][i], + src->split[cur_region_type][i], ss_x, + ss_y, shared_bufs, tree_type, + num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->split[i]) { av1_free_pc_tree_recursive(dst->split[i], num_planes, 0, 0); dst->split[i] = NULL; @@ -441,6 +681,7 @@ ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -448,6 +689,23 @@ case PARTITION_HORZ: if (is_partition_valid(bsize, PARTITION_HORZ)) { for (int i = 0; i < 2; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->horizontal[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->horizontal[cur_region_type][i], + num_planes, 0, 0); + dst->horizontal[cur_region_type][i] = NULL; + } + if (src->horizontal[cur_region_type][i]) { + const int this_mi_row = mi_row + i * (mi_size_high[bsize] >> 1); + dst->horizontal[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, this_mi_row, mi_col, subsize, dst, PARTITION_HORZ, i, + i == 1, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->horizontal[cur_region_type][i], + src->horizontal[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else if (dst->horizontal[i]) { av1_free_pc_tree_recursive(dst->horizontal[i], num_planes, 0, 0); dst->horizontal[i] = NULL; @@ -461,6 +719,7 @@ src->horizontal[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -468,6 +727,23 @@ case PARTITION_VERT: if (is_partition_valid(bsize, PARTITION_VERT)) { for (int i = 0; i < 2; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->vertical[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->vertical[cur_region_type][i], + num_planes, 0, 0); + dst->vertical[cur_region_type][i] = NULL; + } + if (src->vertical[cur_region_type][i]) { + const int this_mi_col = mi_col + i * (mi_size_wide[bsize] >> 1); + dst->vertical[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row, this_mi_col, subsize, dst, PARTITION_VERT, i, + i == 1, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->vertical[cur_region_type][i], + src->vertical[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else if (dst->vertical[i]) { av1_free_pc_tree_recursive(dst->vertical[i], num_planes, 0, 0); dst->vertical[i] = NULL; @@ -481,6 +757,7 @@ src->vertical[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -497,6 +774,22 @@ const BLOCK_SIZE subsizes[4] = { subsize, bsize_med, bsize_big, subsize }; for (int i = 0; i < 4; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->horizontal4a[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->horizontal4a[cur_region_type][i], + num_planes, 0, 0); + dst->horizontal4a[cur_region_type][i] = NULL; + } + if (src->horizontal4a[cur_region_type][i]) { + dst->horizontal4a[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_rows[i], mi_col, subsizes[i], dst, + PARTITION_HORZ_4A, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->horizontal4a[cur_region_type][i], + src->horizontal4a[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else if (dst->horizontal4a[i]) { av1_free_pc_tree_recursive(dst->horizontal4a[i], num_planes, 0, 0); dst->horizontal4a[i] = NULL; @@ -509,6 +802,7 @@ src->horizontal4a[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -525,6 +819,22 @@ const BLOCK_SIZE subsizes[4] = { subsize, bsize_big, bsize_med, subsize }; for (int i = 0; i < 4; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->horizontal4b[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->horizontal4b[cur_region_type][i], + num_planes, 0, 0); + dst->horizontal4b[cur_region_type][i] = NULL; + } + if (src->horizontal4b[cur_region_type][i]) { + dst->horizontal4b[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_rows[i], mi_col, subsizes[i], dst, + PARTITION_HORZ_4B, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->horizontal4b[cur_region_type][i], + src->horizontal4b[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->horizontal4b[i]) { av1_free_pc_tree_recursive(dst->horizontal4b[i], num_planes, 0, 0); dst->horizontal4b[i] = NULL; @@ -537,6 +847,7 @@ src->horizontal4b[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -553,6 +864,22 @@ const BLOCK_SIZE subsizes[4] = { subsize, bsize_med, bsize_big, subsize }; for (int i = 0; i < 4; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->vertical4a[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->vertical4a[cur_region_type][i], + num_planes, 0, 0); + dst->vertical4a[cur_region_type][i] = NULL; + } + if (src->vertical4a[cur_region_type][i]) { + dst->vertical4a[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row, mi_cols[i], subsizes[i], dst, + PARTITION_VERT_4A, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->vertical4a[cur_region_type][i], + src->vertical4a[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->vertical4a[i]) { av1_free_pc_tree_recursive(dst->vertical4a[i], num_planes, 0, 0); dst->vertical4a[i] = NULL; @@ -565,6 +892,7 @@ src->vertical4a[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -581,6 +909,22 @@ const BLOCK_SIZE subsizes[4] = { subsize, bsize_big, bsize_med, subsize }; for (int i = 0; i < 4; ++i) { +#if CONFIG_EXTENDED_SDP + if (dst->vertical4b[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->vertical4b[cur_region_type][i], + num_planes, 0, 0); + dst->vertical4b[cur_region_type][i] = NULL; + } + if (src->vertical4b[cur_region_type][i]) { + dst->vertical4b[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row, mi_cols[i], subsizes[i], dst, + PARTITION_VERT_4B, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->vertical4b[cur_region_type][i], + src->vertical4b[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->vertical4b[i]) { av1_free_pc_tree_recursive(dst->vertical4b[i], num_planes, 0, 0); dst->vertical4b[i] = NULL; @@ -593,6 +937,7 @@ src->vertical4b[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -607,7 +952,22 @@ get_h_partition_offset_mi_row(bsize, i, PARTITION_HORZ_3); const int offset_mc = get_h_partition_offset_mi_col(bsize, i, PARTITION_HORZ_3); - +#if CONFIG_EXTENDED_SDP + if (dst->horizontal3[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->horizontal3[cur_region_type][i], + num_planes, 0, 0); + dst->horizontal3[cur_region_type][i] = NULL; + } + if (src->horizontal3[cur_region_type][i]) { + dst->horizontal3[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row + offset_mr, mi_col + offset_mc, this_subsize, + dst, PARTITION_HORZ_3, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->horizontal3[cur_region_type][i], + src->horizontal3[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->horizontal3[i]) { av1_free_pc_tree_recursive(dst->horizontal3[i], num_planes, 0, 0); dst->horizontal3[i] = NULL; @@ -620,6 +980,7 @@ src->horizontal3[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -633,7 +994,22 @@ get_h_partition_offset_mi_row(bsize, i, PARTITION_VERT_3); const int offset_mc = get_h_partition_offset_mi_col(bsize, i, PARTITION_VERT_3); - +#if CONFIG_EXTENDED_SDP + if (dst->vertical3[cur_region_type][i]) { + av1_free_pc_tree_recursive(dst->vertical3[cur_region_type][i], + num_planes, 0, 0); + dst->vertical3[cur_region_type][i] = NULL; + } + if (src->vertical3[cur_region_type][i]) { + dst->vertical3[cur_region_type][i] = av1_alloc_pc_tree_node( + tree_type, mi_row + offset_mr, mi_col + offset_mc, this_subsize, + dst, PARTITION_VERT_3, i, i == 3, ss_x, ss_y); + av1_copy_pc_tree_recursive( + xd, cm, dst->vertical3[cur_region_type][i], + src->vertical3[cur_region_type][i], ss_x, ss_y, shared_bufs, + tree_type, num_planes); + } +#else // CONFIG_EXTENDED_SDP if (dst->vertical3[i]) { av1_free_pc_tree_recursive(dst->vertical3[i], num_planes, 0, 0); dst->vertical3[i] = NULL; @@ -646,6 +1022,7 @@ src->vertical3[i], ss_x, ss_y, shared_bufs, tree_type, num_planes); } +#endif // CONFIG_EXTENDED_SDP } } break; @@ -782,6 +1159,36 @@ if (pc_tree == NULL || pc_tree == target) return NULL; PC_TREE *result; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; + result = + look_for_counterpart_helper(pc_tree->split[cur_region_type][0], target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->horizontal[cur_region_type][0], + target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->vertical[cur_region_type][0], + target); + if (result) return result; + result = look_for_counterpart_helper( + pc_tree->horizontal4a[cur_region_type][0], target); + if (result) return result; + result = look_for_counterpart_helper( + pc_tree->horizontal4b[cur_region_type][0], target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->vertical4a[cur_region_type][0], + target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->vertical4b[cur_region_type][0], + target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->horizontal3[cur_region_type][0], + target); + if (result) return result; + result = look_for_counterpart_helper(pc_tree->vertical3[cur_region_type][0], + target); + if (result) return result; +#else result = look_for_counterpart_helper(pc_tree->split[0], target); if (result) return result; result = look_for_counterpart_helper(pc_tree->horizontal[0], target); @@ -800,6 +1207,7 @@ if (result) return result; result = look_for_counterpart_helper(pc_tree->vertical3[0], target); if (result) return result; +#endif // CONFIG_EXTENDED_SDP return NULL; }
diff --git a/av1/encoder/context_tree.h b/av1/encoder/context_tree.h index 2016b4d..37c8744 100644 --- a/av1/encoder/context_tree.h +++ b/av1/encoder/context_tree.h
@@ -71,7 +71,37 @@ typedef struct PC_TREE { PARTITION_TYPE partitioning; +#if CONFIG_EXTENDED_SDP + /*! \brief The region type used for the current block. */ + REGION_TYPE region_type; +#endif // CONFIG_EXTENDED_SDP BLOCK_SIZE block_size; +#if CONFIG_EXTENDED_SDP + int inter_sdp_allowed_flag; + PICK_MODE_CONTEXT *none[REGION_TYPES]; + // record the chroma information in intra region. + PICK_MODE_CONTEXT *none_chroma; +#if CONFIG_EXT_RECUR_PARTITIONS + struct PC_TREE *horizontal[REGION_TYPES][2]; + struct PC_TREE *vertical[REGION_TYPES][2]; + struct PC_TREE *horizontal4a[REGION_TYPES][4]; + struct PC_TREE *horizontal4b[REGION_TYPES][4]; + struct PC_TREE *vertical4a[REGION_TYPES][4]; + struct PC_TREE *vertical4b[REGION_TYPES][4]; + struct PC_TREE *horizontal3[REGION_TYPES][4]; + struct PC_TREE *vertical3[REGION_TYPES][4]; +#else + PICK_MODE_CONTEXT *horizontal[REGION_TYPES][2]; + PICK_MODE_CONTEXT *vertical[REGION_TYPES][2]; + PICK_MODE_CONTEXT *horizontala[REGION_TYPES][3]; + PICK_MODE_CONTEXT *horizontalb[REGION_TYPES][3]; + PICK_MODE_CONTEXT *verticala[REGION_TYPES][3]; + PICK_MODE_CONTEXT *verticalb[REGION_TYPES][3]; + PICK_MODE_CONTEXT *horizontal4[REGION_TYPES][4]; + PICK_MODE_CONTEXT *vertical4[REGION_TYPES][4]; +#endif // CONFIG_EXT_RECUR_PARTITIONS + struct PC_TREE *split[REGION_TYPES][4]; +#else PICK_MODE_CONTEXT *none; #if CONFIG_EXT_RECUR_PARTITIONS struct PC_TREE *horizontal[2]; @@ -93,6 +123,7 @@ PICK_MODE_CONTEXT *vertical4[4]; #endif // CONFIG_EXT_RECUR_PARTITIONS struct PC_TREE *split[4]; +#endif // CONFIG_EXTENDED_SDP struct PC_TREE *parent; int mi_row; int mi_col;
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 0bb84cb..978dea1 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -566,6 +566,13 @@ PC_TREE *const pc_root = av1_alloc_pc_tree_node(xd->tree_type, mi_row, mi_col, sb_size, NULL, PARTITION_NONE, 0, 1, ss_x, ss_y); +#if CONFIG_EXTENDED_SDP + if (!frame_is_intra_only(cm)) { + pc_root->region_type = MIXED_INTER_INTRA_REGION; + } else { + pc_root->region_type = INTRA_REGION; + } +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS const PARTITION_TREE *template_tree = multi_pass_params ? multi_pass_params->template_tree : NULL; @@ -579,8 +586,11 @@ int force_prune_flags[3] = { 0, 0, 0 }; #endif // CONFIG_ML_PART_SPLIT av1_rd_pick_partition( - cpi, td, tile_data, tp, mi_row, mi_col, sb_size, &dummy_rdc, dummy_rdc, - pc_root, + cpi, td, tile_data, tp, mi_row, mi_col, sb_size, +#if CONFIG_EXTENDED_SDP + PARTITION_NONE, +#endif // CONFIG_EXTENDED_SDP + &dummy_rdc, dummy_rdc, pc_root, #if CONFIG_EXT_RECUR_PARTITIONS xd->tree_type == CHROMA_PART ? xd->sbi->ptree_root[0] : NULL, template_tree, INT_MAX,
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c index cbb9c29..c352e68 100644 --- a/av1/encoder/encodeframe_utils.c +++ b/av1/encoder/encodeframe_utils.c
@@ -1715,6 +1715,14 @@ UV_INTRA_MODES - 1, CDF_SIZE(UV_INTRA_MODES)); AVERAGE_CDF(ctx_left->uv_mode_cdf[1], ctx_tr->uv_mode_cdf[1], UV_INTRA_MODES); #endif // CONFIG_UV_CFL + +#if CONFIG_EXTENDED_SDP + for (int i = 0; i < INTER_SDP_BSIZE_GROUP; i++) { + AVERAGE_CDF(ctx_left->region_type_cdf[i], ctx_tr->region_type_cdf[i], + REGION_TYPES); + } +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_EXT_RECUR_PARTITIONS for (int plane_index = 0; plane_index < PARTITION_STRUCTURE_NUM; plane_index++) {
diff --git a/av1/encoder/encodeframe_utils.h b/av1/encoder/encodeframe_utils.h index c714e9c..1eea6ef 100644 --- a/av1/encoder/encodeframe_utils.h +++ b/av1/encoder/encodeframe_utils.h
@@ -173,6 +173,11 @@ // Pointer to partition cost buffer const int *partition_cost; +#if CONFIG_EXTENDED_SDP + // Pointer to region type cost buffer + int *region_type_cost; +#endif // CONFIG_EXTENDED_SDP + // RD costs for different partition types. int64_t none_rd; int64_t split_rd[SUB_PARTITIONS_SPLIT];
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index aae2e02..b5f78aa 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -1374,6 +1374,9 @@ unsigned int palette_uv_color_index[PALETTE_SIZES] [PALETTE_COLOR_INDEX_CONTEXTS] [PALETTE_COLORS]; +#if CONFIG_EXTENDED_SDP + unsigned int region_type[INTER_SDP_BSIZE_GROUP][REGION_TYPES]; +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS unsigned int do_split[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS][2]; unsigned int do_square_split[PARTITION_STRUCTURE_NUM][SQUARE_SPLIT_CONTEXTS]
diff --git a/av1/encoder/intra_mode_search.c b/av1/encoder/intra_mode_search.c index f392009..e8254f7 100644 --- a/av1/encoder/intra_mode_search.c +++ b/av1/encoder/intra_mode_search.c
@@ -612,7 +612,10 @@ // Only store reconstructed luma when there's chroma RDO. When there's no // chroma RDO, the reconstructed luma will be stored in encode_superblock(). - xd->cfl.store_y = store_cfl_required_rdo(cm, x); +#if CONFIG_EXTENDED_SDP + if (frame_is_intra_only(cm) || xd->tree_type != CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + xd->cfl.store_y = store_cfl_required_rdo(cm, x); if (xd->tree_type == SHARED_PART) { if (xd->cfl.store_y) { av1_encode_intra_block_plane(cpi, x, mbmi->sb_type[PLANE_TYPE_Y], @@ -1251,7 +1254,7 @@ mode_cost += ref_frame_cost; mode_cost += mrl_idx_cost; } -#else // CONFIG_LOSSLESS_DPCM +#else // CONFIG_LOSSLESS_DPCM const int context = get_y_mode_idx_ctx(xd); int mode_set_index = mbmi->y_mode_idx < FIRST_MODE_COUNT ? 0 : 1; mode_set_index += ((mbmi->y_mode_idx - FIRST_MODE_COUNT) / SECOND_MODE_COUNT); @@ -1265,7 +1268,10 @@ [mbmi->y_mode_idx - FIRST_MODE_COUNT - SECOND_MODE_COUNT * (mode_set_index - 1)]; } - mode_cost += ref_frame_cost; +#if CONFIG_EXTENDED_SDP + if (mbmi->region_type != INTRA_REGION) +#endif // CONFIG_EXTENDED_SDP + mode_cost += ref_frame_cost; mode_cost += mrl_idx_cost; #endif // CONFIG_LOSSLESS_DPCM #else
diff --git a/av1/encoder/intra_mode_search_utils.h b/av1/encoder/intra_mode_search_utils.h index 6304ccc..c853a3a 100644 --- a/av1/encoder/intra_mode_search_utils.h +++ b/av1/encoder/intra_mode_search_utils.h
@@ -279,7 +279,7 @@ } } #endif // !CONFIG_AIMC - if (av1_allow_intrabc(&cpi->common) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(&cpi->common, xd) && xd->tree_type != CHROMA_PART) { #if CONFIG_NEW_CONTEXT_MODELING const int intrabc_ctx = get_intrabc_ctx(xd); total_rate += mode_costs->intrabc_cost[intrabc_ctx][use_intrabc];
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c index 67faefc..fc1851d 100644 --- a/av1/encoder/partition_search.c +++ b/av1/encoder/partition_search.c
@@ -586,12 +586,11 @@ } if (!dry_run) { - if (av1_allow_intrabc(cm) && is_intrabc_block(mbmi, xd->tree_type)) + if (av1_allow_intrabc(cm, xd) && is_intrabc_block(mbmi, xd->tree_type)) td->intrabc_used = 1; #if CONFIG_MORPH_PRED if (mbmi->morph_pred) { - assert(av1_allow_intrabc(cm)); - assert(is_intrabc_block(mbmi, xd->tree_type)); + assert(av1_allow_intrabc(cm, xd)); } #endif // CONFIG_MORPH_PRED if (txfm_params->tx_mode_search_type == TX_MODE_SELECT && @@ -653,12 +652,21 @@ } else { intra_tx_size = mbmi->tx_size; } - - for (j = 0; j < mi_height; j++) - for (i = 0; i < mi_width; i++) - if (mi_col + i < cm->mi_params.mi_cols && - mi_row + j < cm->mi_params.mi_rows) - mi_4x4[mis * j + i]->tx_size = intra_tx_size; +#if CONFIG_EXTENDED_SDP + // Since transform partitioning is only allowed for luma component, + // and tx_size variable represents the transform size of the luma + // component in one coded block, so chroma block should not change the + // tx_size. + if (xd->tree_type != CHROMA_PART || frame_is_intra_only(cm)) { +#endif // CONFIG_EXTENDED_SDP + for (j = 0; j < mi_height; j++) + for (i = 0; i < mi_width; i++) + if (mi_col + i < cm->mi_params.mi_cols && + mi_row + j < cm->mi_params.mi_rows) + mi_4x4[mis * j + i]->tx_size = intra_tx_size; +#if CONFIG_EXTENDED_SDP + } +#endif // CONFIG_EXTENDED_SDP if (intra_tx_size != max_txsize_rect_lookup[bsize]) ++x->txfm_search_info.txb_split_count; @@ -844,6 +852,11 @@ av1_set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize, chroma_ref_info); +#if CONFIG_EXTENDED_SDP + // Don't set up segment ID for chroma part in SDP of inter frame + if (!frame_is_intra_only(cm) && xd->tree_type == CHROMA_PART) return; +#endif // CONFIG_EXTENDED_SDP + // Setup segment ID. mbmi = xd->mi[0]; mbmi->segment_id = 0; @@ -881,6 +894,7 @@ * \param[in] rd_cost Pointer to structure holding rate and distortion * stats for the current block * \param[in] partition Partition mode of the parent block + * \param[in] cur_region_type Region type of the current block * \param[in] bsize Current block size * \param[in] ctx Pointer to structure holding coding contexts and * chosen modes for the current block @@ -894,6 +908,9 @@ static void pick_sb_modes(AV1_COMP *const cpi, TileDataEnc *tile_data, MACROBLOCK *const x, int mi_row, int mi_col, RD_STATS *rd_cost, PARTITION_TYPE partition, +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type, +#endif // CONFIG_EXTENDED_SDP BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, RD_STATS best_rd) { if (best_rd.rdcost < 0) { @@ -912,6 +929,10 @@ av1_set_offsets(cpi, &tile_data->tile_info, x, mi_row, mi_col, bsize, &ctx->chroma_ref_info); +#if CONFIG_EXTENDED_SDP + xd->mi[0]->region_type = cur_region_type; +#endif // CONFIG_EXTENDED_SDP + if (ctx->rd_mode_is_ready) { assert(ctx->mic.sb_type[plane_type] == bsize); assert(ctx->mic.partition == partition); @@ -998,7 +1019,11 @@ // Find best coding mode & reconstruct the MB so it is available // as a predictor for MBs that follow in the SB - if (frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm) +#if CONFIG_EXTENDED_SDP + || mbmi->region_type == INTRA_REGION +#endif // CONFIG_EXTENDED_SDP + ) { #if CONFIG_COLLECT_COMPONENT_TIMING start_timing(cpi, av1_rd_pick_intra_mode_sb_time); #endif @@ -1280,6 +1305,9 @@ const int seg_ref_active = 0; if (current_frame->skip_mode_info.skip_mode_flag && !seg_ref_active && +#if CONFIG_EXTENDED_SDP + mbmi->region_type != INTRA_REGION && +#endif // CONFIG_EXTENDED_SDP is_comp_ref_allowed(bsize)) { const int skip_mode_ctx = av1_get_skip_mode_context(xd); #if CONFIG_ENTROPY_STATS @@ -1291,15 +1319,19 @@ #if CONFIG_SKIP_TXFM_OPT const int use_intrabc = is_intrabc_block(mbmi, xd->tree_type); if (!seg_ref_active) { - if (!mbmi->skip_mode && !frame_is_intra_only(cm)) { + if (!mbmi->skip_mode && !frame_is_intra_only(cm) +#if CONFIG_EXTENDED_SDP + && mbmi->region_type != INTRA_REGION +#endif // CONFIG_EXTENDED_SDP + ) { const int intra_inter_ctx = av1_get_intra_inter_context(xd); #if CONFIG_ENTROPY_STATS td->counts->intra_inter[intra_inter_ctx][inter_block]++; #endif // CONFIG_ENTROPY_STATS update_cdf(fc->intra_inter_cdf[intra_inter_ctx], inter_block, 2); } - - if (!inter_block && av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (!inter_block && av1_allow_intrabc(cm, xd) && + xd->tree_type != CHROMA_PART) { #if CONFIG_NEW_CONTEXT_MODELING const int intrabc_ctx = get_intrabc_ctx(xd); update_cdf(fc->intrabc_cdf[intrabc_ctx], use_intrabc, 2); @@ -1393,7 +1425,7 @@ if (!is_inter_block(mbmi, xd->tree_type)) { av1_sum_intra_stats(cm, td->counts, xd, mbmi); } - if (av1_allow_intrabc(cm) && xd->tree_type != CHROMA_PART) { + if (av1_allow_intrabc(cm, xd) && xd->tree_type != CHROMA_PART) { #if !CONFIG_SKIP_TXFM_OPT const int use_intrabc = is_intrabc_block(mbmi, xd->tree_type); #if CONFIG_NEW_CONTEXT_MODELING @@ -2806,6 +2838,21 @@ ptree->bsize = bsize; ptree->mi_row = mi_row; ptree->mi_col = mi_col; +#if CONFIG_EXTENDED_SDP + ptree->region_type = pc_tree->region_type; + const int is_sb_root = bsize == cm->sb_size; + ptree->inter_sdp_allowed_flag = pc_tree->inter_sdp_allowed_flag; + if (!frame_is_intra_only(cm) && !is_sb_root && + partition != PARTITION_NONE && parent && + parent->region_type != INTRA_REGION && xd->tree_type != CHROMA_PART && + ptree->inter_sdp_allowed_flag && + is_bsize_allowed_for_inter_sdp(bsize, partition)) { + assert(xd->tree_type != CHROMA_PART); + const int intra_region_ctx = get_intra_region_context(bsize); + update_cdf(xd->tile_ctx->region_type_cdf[intra_region_ctx], + ptree->region_type, REGION_TYPES); + } +#endif // CONFIG_EXTENDED_SDP const int ss_x = xd->plane[1].subsampling_x; const int ss_y = xd->plane[1].subsampling_y; set_chroma_ref_info( @@ -2860,19 +2907,45 @@ } } #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + // encode both the luma and chroma blocks in one intra region + int encode_sdp_intra_region_yuv = 0; + if (!frame_is_intra_only(cm) && xd->tree_type == SHARED_PART && + pc_tree->region_type == INTRA_REGION) { + encode_sdp_intra_region_yuv = 1; + xd->tree_type = LUMA_PART; + } +#endif // CONFIG_EXTENDED_SDP switch (partition) { case PARTITION_NONE: encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, subsize, - partition, pc_tree->none, rate); + partition, +#if CONFIG_EXTENDED_SDP + pc_tree->none[pc_tree->region_type], +#else + pc_tree->none, +#endif // CONFIG_EXTENDED_SDP + rate); break; case PARTITION_VERT: #if CONFIG_EXT_RECUR_PARTITIONS encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->vertical[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[pc_tree->region_type][0], +#else + pc_tree->vertical[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_col + hbs_w < cm->mi_params.mi_cols) { encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + hbs_w, dry_run, - subsize, pc_tree->vertical[1], sub_tree[1], + subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[pc_tree->region_type][1], +#else + pc_tree->vertical[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); } #else // CONFIG_EXT_RECUR_PARTITIONS @@ -2887,11 +2960,22 @@ case PARTITION_HORZ: #if CONFIG_EXT_RECUR_PARTITIONS encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->horizontal[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[pc_tree->region_type][0], +#else + pc_tree->horizontal[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_row + hbs_h < cm->mi_params.mi_rows) { encode_sb(cpi, td, tile_data, tp, mi_row + hbs_h, mi_col, dry_run, - subsize, pc_tree->horizontal[1], sub_tree[1], + subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[pc_tree->region_type][1], +#else + pc_tree->horizontal[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); } #else // CONFIG_EXT_RECUR_PARTITIONS @@ -2909,20 +2993,41 @@ const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big]; assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]); encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->horizontal4a[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[pc_tree->region_type][0], +#else + pc_tree->horizontal4a[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_row + ebs_h >= cm->mi_params.mi_rows) break; - encode_sb(cpi, td, tile_data, tp, mi_row + ebs_h, mi_col, dry_run, - bsize_med, pc_tree->horizontal4a[1], sub_tree[1], - track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row + ebs_h, mi_col, dry_run, bsize_med, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[pc_tree->region_type][1], +#else + pc_tree->horizontal4a[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); if (mi_row + 3 * ebs_h >= cm->mi_params.mi_rows) break; encode_sb(cpi, td, tile_data, tp, mi_row + 3 * ebs_h, mi_col, dry_run, - bsize_big, pc_tree->horizontal4a[2], sub_tree[2], - track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); + bsize_big, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[pc_tree->region_type][2], +#else + pc_tree->horizontal4a[2], +#endif // CONFIG_EXTENDED_SDP + sub_tree[2], track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, + rate); if (mi_row + 7 * ebs_h >= cm->mi_params.mi_rows) break; - encode_sb(cpi, td, tile_data, tp, mi_row + 7 * ebs_h, mi_col, dry_run, - subsize, pc_tree->horizontal4a[3], sub_tree[3], - track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row + 7 * ebs_h, mi_col, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[pc_tree->region_type][3], +#else + pc_tree->horizontal4a[3], +#endif // CONFIG_EXTENDED_SDP + sub_tree[3], track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); break; } case PARTITION_HORZ_4B: { @@ -2930,20 +3035,41 @@ const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big]; assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]); encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->horizontal4b[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[pc_tree->region_type][0], +#else + pc_tree->horizontal4b[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_row + ebs_h >= cm->mi_params.mi_rows) break; - encode_sb(cpi, td, tile_data, tp, mi_row + ebs_h, mi_col, dry_run, - bsize_big, pc_tree->horizontal4b[1], sub_tree[1], - track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row + ebs_h, mi_col, dry_run, bsize_big, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[pc_tree->region_type][1], +#else + pc_tree->horizontal4b[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); if (mi_row + 5 * ebs_h >= cm->mi_params.mi_rows) break; encode_sb(cpi, td, tile_data, tp, mi_row + 5 * ebs_h, mi_col, dry_run, - bsize_med, pc_tree->horizontal4b[2], sub_tree[2], - track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); + bsize_med, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[pc_tree->region_type][2], +#else + pc_tree->horizontal4b[2], +#endif // CONFIG_EXTENDED_SDP + sub_tree[2], track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, + rate); if (mi_row + 7 * ebs_h >= cm->mi_params.mi_rows) break; - encode_sb(cpi, td, tile_data, tp, mi_row + 7 * ebs_h, mi_col, dry_run, - subsize, pc_tree->horizontal4b[3], sub_tree[3], - track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row + 7 * ebs_h, mi_col, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[pc_tree->region_type][3], +#else + pc_tree->horizontal4b[3], +#endif // CONFIG_EXTENDED_SDP + sub_tree[3], track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); break; } case PARTITION_VERT_4A: { @@ -2951,20 +3077,41 @@ const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big]; assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]); encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->vertical4a[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[pc_tree->region_type][0], +#else + pc_tree->vertical4a[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_col + ebs_w >= cm->mi_params.mi_cols) break; - encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + ebs_w, dry_run, - bsize_med, pc_tree->vertical4a[1], sub_tree[1], - track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row, mi_col + ebs_w, dry_run, bsize_med, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[pc_tree->region_type][1], +#else + pc_tree->vertical4a[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); if (mi_col + 3 * ebs_w >= cm->mi_params.mi_cols) break; encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + 3 * ebs_w, dry_run, - bsize_big, pc_tree->vertical4a[2], sub_tree[2], - track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); + bsize_big, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[pc_tree->region_type][2], +#else + pc_tree->vertical4a[2], +#endif // CONFIG_EXTENDED_SDP + sub_tree[2], track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, + rate); if (mi_col + 7 * ebs_w >= cm->mi_params.mi_cols) break; - encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + 7 * ebs_w, dry_run, - subsize, pc_tree->vertical4a[3], sub_tree[3], - track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row, mi_col + 7 * ebs_w, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[pc_tree->region_type][3], +#else + pc_tree->vertical4a[3], +#endif // CONFIG_EXTENDED_SDP + sub_tree[3], track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); break; } case PARTITION_VERT_4B: { @@ -2972,20 +3119,41 @@ const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big]; assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]); encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->vertical4b[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[pc_tree->region_type][0], +#else + pc_tree->vertical4b[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); if (mi_col + ebs_w >= cm->mi_params.mi_cols) break; - encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + ebs_w, dry_run, - bsize_big, pc_tree->vertical4b[1], sub_tree[1], - track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row, mi_col + ebs_w, dry_run, bsize_big, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[pc_tree->region_type][1], +#else + pc_tree->vertical4b[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); if (mi_col + 5 * ebs_w >= cm->mi_params.mi_cols) break; encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + 5 * ebs_w, dry_run, - bsize_med, pc_tree->vertical4b[2], sub_tree[2], - track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); + bsize_med, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[pc_tree->region_type][2], +#else + pc_tree->vertical4b[2], +#endif // CONFIG_EXTENDED_SDP + sub_tree[2], track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, + rate); if (mi_col + 7 * ebs_w >= cm->mi_params.mi_cols) break; - encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + 7 * ebs_w, dry_run, - subsize, pc_tree->vertical4b[3], sub_tree[3], - track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row, mi_col + 7 * ebs_w, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[pc_tree->region_type][3], +#else + pc_tree->vertical4b[3], +#endif // CONFIG_EXTENDED_SDP + sub_tree[3], track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); break; } case PARTITION_HORZ_3: @@ -2997,9 +3165,15 @@ const int offset_c = get_h_partition_offset_mi_col(bsize, i, partition); const int this_mi_row = mi_row + offset_r; const int this_mi_col = mi_col + offset_c; - PC_TREE *this_pc_tree = partition == PARTITION_HORZ_3 - ? pc_tree->horizontal3[i] - : pc_tree->vertical3[i]; + PC_TREE *this_pc_tree = + partition == PARTITION_HORZ_3 +#if CONFIG_EXTENDED_SDP + ? pc_tree->horizontal3[pc_tree->region_type][i] + : pc_tree->vertical3[pc_tree->region_type][i]; +#else + ? pc_tree->horizontal3[i] + : pc_tree->vertical3[i]; +#endif // CONFIG_EXTENDED_SDP if (partition == PARTITION_HORZ_3) { if (this_mi_row >= cm->mi_params.mi_rows) break; @@ -3014,17 +3188,38 @@ } case PARTITION_SPLIT: encode_sb(cpi, td, tile_data, tp, mi_row, mi_col, dry_run, subsize, - pc_tree->split[0], sub_tree[0], - track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, rate); - encode_sb(cpi, td, tile_data, tp, mi_row, mi_col + hbs_w, dry_run, - subsize, pc_tree->split[1], sub_tree[1], - track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); - encode_sb(cpi, td, tile_data, tp, mi_row + hbs_h, mi_col, dry_run, - subsize, pc_tree->split[2], sub_tree[2], - track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][0], +#else + pc_tree->split[0], +#endif // CONFIG_EXTENDED_SDP + sub_tree[0], track_ptree_luma ? ptree_luma->sub_tree[0] : NULL, + rate); + encode_sb( + cpi, td, tile_data, tp, mi_row, mi_col + hbs_w, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][1], +#else + pc_tree->split[1], +#endif // CONFIG_EXTENDED_SDP + sub_tree[1], track_ptree_luma ? ptree_luma->sub_tree[1] : NULL, rate); + encode_sb( + cpi, td, tile_data, tp, mi_row + hbs_h, mi_col, dry_run, subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][2], +#else + pc_tree->split[2], +#endif // CONFIG_EXTENDED_SDP + sub_tree[2], track_ptree_luma ? ptree_luma->sub_tree[2] : NULL, rate); encode_sb(cpi, td, tile_data, tp, mi_row + hbs_h, mi_col + hbs_w, dry_run, - subsize, pc_tree->split[3], sub_tree[3], - track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, rate); + subsize, +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][3], +#else + pc_tree->split[3], +#endif // CONFIG_EXTENDED_SDP + sub_tree[3], track_ptree_luma ? ptree_luma->sub_tree[3] : NULL, + rate); break; #else // CONFIG_EXT_RECUR_PARTITIONS case PARTITION_SPLIT: @@ -3091,6 +3286,16 @@ default: assert(0 && "Invalid partition type."); break; } +#if CONFIG_EXTENDED_SDP + // encode the chroma blocks under one intra region in inter frame + if (encode_sdp_intra_region_yuv && !cm->seq_params.monochrome) { + xd->tree_type = CHROMA_PART; + encode_b(cpi, tile_data, td, tp, mi_row, mi_col, dry_run, bsize, + PARTITION_NONE, pc_tree->none_chroma, rate); + xd->tree_type = SHARED_PART; + } +#endif // CONFIG_EXTENDED_SDP + if (ptree) ptree->is_settled = 1; update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition); } @@ -3348,12 +3553,40 @@ RD_SEARCH_MACROBLOCK_CONTEXT x_ctx; RD_STATS last_part_rdc, invalid_rdc; +#if CONFIG_EXTENDED_SDP + if (!frame_is_intra_only(cm)) + pc_tree->region_type = MIXED_INTER_INTRA_REGION; + else + pc_tree->region_type = INTRA_REGION; + REGION_TYPE cur_region_type = pc_tree->region_type; + if (is_inter_sdp_chroma(cm, cur_region_type, x->e_mbd.tree_type)) { + if (pc_tree->none_chroma == NULL) { + pc_tree->none_chroma = + av1_alloc_pmc(cm, xd->tree_type, mi_row, mi_col, bsize, pc_tree, + PARTITION_NONE, 0, ss_x, ss_y, &td->shared_coeff_buf); + } + } else { + if (pc_tree->none[cur_region_type] == NULL) { + pc_tree->none[cur_region_type] = + av1_alloc_pmc(cm, xd->tree_type, mi_row, mi_col, bsize, pc_tree, + PARTITION_NONE, 0, ss_x, ss_y, &td->shared_coeff_buf); + } + } +#else if (pc_tree->none == NULL) { pc_tree->none = av1_alloc_pmc(cm, xd->tree_type, mi_row, mi_col, bsize, pc_tree, PARTITION_NONE, 0, ss_x, ss_y, &td->shared_coeff_buf); } +#endif // CONFIG_EXTENDED_SDP +#if CONFIG_EXTENDED_SDP + PICK_MODE_CONTEXT *ctx_none = + is_inter_sdp_chroma(cm, cur_region_type, x->e_mbd.tree_type) + ? pc_tree->none_chroma + : pc_tree->none[pc_tree->region_type]; +#else PICK_MODE_CONTEXT *ctx_none = pc_tree->none; +#endif // CONFIG_EXTENDED_SDP if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return; @@ -3398,20 +3631,36 @@ switch (partition) { case PARTITION_NONE: pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - PARTITION_NONE, bsize, ctx_none, invalid_rdc); + PARTITION_NONE, +#if CONFIG_EXTENDED_SDP + pc_tree->region_type, +#endif // CONFIG_EXTENDED_SDP + bsize, ctx_none, invalid_rdc); break; case PARTITION_HORZ: #if CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][0] = +#else pc_tree->horizontal[0] = +#endif // CONFIG_EXTENDED_SDP av1_alloc_pc_tree_node(xd->tree_type, mi_row, mi_col, subsize, pc_tree, PARTITION_HORZ, 0, 0, ss_x, ss_y); +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][1] = +#else pc_tree->horizontal[1] = +#endif // CONFIG_EXTENDED_SDP av1_alloc_pc_tree_node(xd->tree_type, mi_row + hbh, mi_col, subsize, pc_tree, PARTITION_HORZ, 1, 1, ss_x, ss_y); av1_rd_use_partition(cpi, td, tile_data, mib, tp, mi_row, mi_col, subsize, &last_part_rdc.rate, &last_part_rdc.dist, 1, ptree ? ptree->sub_tree[0] : NULL, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][0]); +#else pc_tree->horizontal[0]); +#endif // CONFIG_EXTENDED_SDP #else // CONFIG_EXT_RECUR_PARTITIONS for (int i = 0; i < SUB_PARTITIONS_RECT; ++i) { if (pc_tree->horizontal[i] == NULL) { @@ -3429,10 +3678,15 @@ RD_STATS tmp_rdc; av1_init_rd_stats(&tmp_rdc); #if CONFIG_EXT_RECUR_PARTITIONS - av1_rd_use_partition( - cpi, td, tile_data, mib + hbh * mi_params->mi_stride, tp, - mi_row + hbh, mi_col, subsize, &tmp_rdc.rate, &tmp_rdc.dist, 0, - ptree ? ptree->sub_tree[1] : NULL, pc_tree->horizontal[1]); + av1_rd_use_partition(cpi, td, tile_data, + mib + hbh * mi_params->mi_stride, tp, mi_row + hbh, + mi_col, subsize, &tmp_rdc.rate, &tmp_rdc.dist, 0, + ptree ? ptree->sub_tree[1] : NULL, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][1]); +#else + pc_tree->horizontal[1]); +#endif // CONFIG_EXTENDED_SDP #else // CONFIG_EXT_RECUR_PARTITIONS const PICK_MODE_CONTEXT *const ctx_h = pc_tree->horizontal[0]; av1_update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1); @@ -3453,16 +3707,28 @@ break; case PARTITION_VERT: #if CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][0] = +#else pc_tree->vertical[0] = +#endif // CONFIG_EXTENDED_SDP av1_alloc_pc_tree_node(xd->tree_type, mi_row, mi_col, subsize, pc_tree, PARTITION_VERT, 0, 0, ss_x, ss_y); +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][1] = +#else pc_tree->vertical[1] = +#endif // CONFIG_EXTENDED_SDP av1_alloc_pc_tree_node(xd->tree_type, mi_row, mi_col + hbw, subsize, pc_tree, PARTITION_VERT, 1, 1, ss_x, ss_y); av1_rd_use_partition(cpi, td, tile_data, mib, tp, mi_row, mi_col, subsize, &last_part_rdc.rate, &last_part_rdc.dist, 1, ptree ? ptree->sub_tree[0] : NULL, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][0]); +#else pc_tree->vertical[0]); +#endif // CONFIG_EXTENDED_SDP #else // CONFIG_EXT_RECUR_PARTITIONS for (int i = 0; i < SUB_PARTITIONS_RECT; ++i) { if (pc_tree->vertical[i] == NULL) { @@ -3482,7 +3748,11 @@ av1_rd_use_partition( cpi, td, tile_data, mib + hbw, tp, mi_row, mi_col + hbw, subsize, &tmp_rdc.rate, &tmp_rdc.dist, 0, ptree ? ptree->sub_tree[1] : NULL, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][1]); +#else pc_tree->vertical[1]); +#endif // CONFIG_EXTENDED_SDP #else // CONFIG_EXT_RECUR_PARTITIONS const PICK_MODE_CONTEXT *const ctx_v = pc_tree->vertical[0]; av1_update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1); @@ -3514,17 +3784,27 @@ if ((mi_row + y_idx >= mi_params->mi_rows) || (mi_col + x_idx >= mi_params->mi_cols)) continue; - pc_tree->split[i] = av1_alloc_pc_tree_node( - xd->tree_type, mi_row + y_idx, mi_col + x_idx, subsize, pc_tree, - PARTITION_SPLIT, i, i == 3, ss_x, ss_y); +#if CONFIG_EXTENDED_SDP + pc_tree->split[cur_region_type][i] +#else + pc_tree->split[i] +#endif // CONFIG_EXTENDED_SDP + = av1_alloc_pc_tree_node(xd->tree_type, mi_row + y_idx, + mi_col + x_idx, subsize, pc_tree, + PARTITION_SPLIT, i, i == 3, ss_x, ss_y); av1_init_rd_stats(&tmp_rdc); - av1_rd_use_partition( - cpi, td, tile_data, - mib + jj * hbs * mi_params->mi_stride + ii * hbs, tp, - mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate, - &tmp_rdc.dist, i != (SUB_PARTITIONS_SPLIT - 1), - ptree ? ptree->sub_tree[i] : NULL, pc_tree->split[i]); + av1_rd_use_partition(cpi, td, tile_data, + mib + jj * hbs * mi_params->mi_stride + ii * hbs, + tp, mi_row + y_idx, mi_col + x_idx, subsize, + &tmp_rdc.rate, &tmp_rdc.dist, + i != (SUB_PARTITIONS_SPLIT - 1), + ptree ? ptree->sub_tree[i] : NULL, +#if CONFIG_EXTENDED_SDP + pc_tree->split[cur_region_type][i]); +#else + pc_tree->split[i]); +#endif // CONFIG_EXTENDED_SDP if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { av1_invalid_rd_stats(&last_part_rdc); break; @@ -3686,6 +3966,9 @@ av1_rd_stats_subtraction(x->rdmult, &best_rdcost, sum_rdc, &rdcost_remaining); RD_STATS this_rdc; pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, partition, +#if CONFIG_EXTENDED_SDP + pc_tree->region_type, +#endif // CONFIG_EXTENDED_SDP subsize, this_ctx, rdcost_remaining); if (this_rdc.rate == INT_MAX) { @@ -3759,6 +4042,12 @@ update_best_level_banks(level_banks, &x->e_mbd); #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK pc_tree->partitioning = partition; +#if CONFIG_EXTENDED_SDP + if (!frame_is_intra_only(cm)) + pc_tree->region_type = MIXED_INTER_INTRA_REGION; + else + pc_tree->region_type = INTRA_REGION; +#endif // CONFIG_EXTENDED_SDP return true; } #endif // !CONFIG_EXT_RECUR_PARTITIONS @@ -3771,6 +4060,9 @@ BLOCK_SIZE parent_bsize, #endif // CONFIG_CB1TO4_SPLIT const PARTITION_TREE *ptree_luma, const PARTITION_TREE *template_tree, +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type, +#endif // CONFIG_EXTENDED_SDP const CHROMA_REF_INFO *chroma_ref_info) { // Partition types forced by bitstream syntax. const MACROBLOCKD *xd = &x->e_mbd; @@ -3796,6 +4088,9 @@ #if CONFIG_CB1TO4_SPLIT && (parent_bsize == BLOCK_INVALID || parent_bsize <= BLOCK_LARGEST) #endif // CONFIG_CB1TO4_SPLIT +#if CONFIG_EXTENDED_SDP + && !is_inter_sdp_chroma(cm, cur_region_type, xd->tree_type) +#endif // CONFIG_EXTENDED_SDP ) { return av1_get_prev_partition(x, mi_row, mi_col, bsize, cm->sb_size); } @@ -3984,6 +4279,7 @@ blk_params->bsize = bsize; #if CONFIG_CB1TO4_SPLIT + assert(pc_tree != NULL); blk_params->parent_bsize = pc_tree->parent ? pc_tree->parent->block_size : BLOCK_INVALID; #endif // CONFIG_CB1TO4_SPLIT @@ -4046,6 +4342,13 @@ } #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + if (xd->tree_type != CHROMA_PART) { + const int ctx = get_intra_region_context(bsize); + part_search_state->region_type_cost = mode_costs->region_type_cost[ctx]; + } +#endif // CONFIG_EXTENDED_SDP + // Initialize HORZ and VERT win flags as true for all split partitions. for (int i = 0; i < SUB_PARTITIONS_SPLIT; i++) { part_search_state->split_part_rect_win[i].rect_part_win[HORZ] = true; @@ -4085,7 +4388,11 @@ #if CONFIG_CB1TO4_SPLIT blk_params->parent_bsize, #endif // CONFIG_CB1TO4_SPLIT - ptree_luma, template_tree, &pc_tree->chroma_ref_info); + ptree_luma, template_tree, +#if CONFIG_EXTENDED_SDP + (pc_tree ? pc_tree->region_type : MIXED_INTER_INTRA_REGION), +#endif // CONFIG_EXTENDED_SDP + &pc_tree->chroma_ref_info); init_allowed_partitions(part_search_state, &cpi->oxcf.part_cfg, &pc_tree->chroma_ref_info, tree_type); @@ -4228,7 +4535,11 @@ // Obtain the best mode for the partition sub-block. pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &part_search_state->this_rdc, - partition_type, bsize, cur_partition_ctx, best_remain_rdcost); + partition_type, +#if CONFIG_EXTENDED_SDP + pc_tree->region_type, +#endif // CONFIG_EXTENDED_SDP + bsize, cur_partition_ctx, best_remain_rdcost); av1_rd_cost_update(x->rdmult, &part_search_state->this_rdc); // Update the partition rd cost with the current sub-block rd. @@ -4254,6 +4565,9 @@ BLOCK_SIZE bsize, const int is_not_edge_block[NUM_RECT_PARTS], SB_MULTI_PASS_MODE multi_pass_mode, const PARTITION_TREE *ptree_luma, const PARTITION_TREE *template_tree, bool *both_blocks_skippable, +#if CONFIG_EXTENDED_SDP + PARTITION_TYPE parent_partition, +#endif // CONFIG_INTER_SDP int max_recursion_depth #if CONFIG_ML_PART_SPLIT , @@ -4264,18 +4578,35 @@ RD_STATS *sum_rdc = &part_search_state->sum_rdc; sum_rdc->rate = part_search_state->partition_cost[partition_type]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, parent_partition) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_HORZ)) + sum_rdc->rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc->rdcost = RDCOST(x->rdmult, sum_rdc->rate, 0); RD_STATS this_rdc; RD_STATS best_remain_rdcost; +#if CONFIG_EXTENDED_SDP + PC_TREE **sub_tree = (rect_type == HORZ) + ? pc_tree->horizontal[pc_tree->region_type] + : pc_tree->vertical[pc_tree->region_type]; +#else PC_TREE **sub_tree = (rect_type == HORZ) ? pc_tree->horizontal : pc_tree->vertical; +#endif // CONFIG_EXTENDED_SDP *both_blocks_skippable = true; av1_rd_stats_subtraction(x->rdmult, best_rdc, sum_rdc, &best_remain_rdcost); bool partition_found = av1_rd_pick_partition( cpi, td, tile_data, tp, mi_pos_rect[rect_type][0][0], - mi_pos_rect[rect_type][0][1], bsize, &this_rdc, best_remain_rdcost, - sub_tree[0], get_partition_subtree_const(ptree_luma, 0), + mi_pos_rect[rect_type][0][1], bsize, +#if CONFIG_EXTENDED_SDP + (rect_type == HORZ ? PARTITION_HORZ : PARTITION_VERT), +#endif // CONFIG_EXTENDED_SDP + &this_rdc, best_remain_rdcost, sub_tree[0], + get_partition_subtree_const(ptree_luma, 0), get_partition_subtree_const(template_tree, 0), max_recursion_depth, NULL, NULL, multi_pass_mode, NULL #if CONFIG_ML_PART_SPLIT @@ -4299,8 +4630,12 @@ av1_rd_stats_subtraction(x->rdmult, best_rdc, sum_rdc, &best_remain_rdcost); partition_found = av1_rd_pick_partition( cpi, td, tile_data, tp, mi_pos_rect[rect_type][1][0], - mi_pos_rect[rect_type][1][1], bsize, &this_rdc, best_remain_rdcost, - sub_tree[1], get_partition_subtree_const(ptree_luma, 1), + mi_pos_rect[rect_type][1][1], bsize, +#if CONFIG_EXTENDED_SDP + (rect_type == HORZ ? PARTITION_HORZ : PARTITION_VERT), +#endif // CONFIG_EXTENDED_SDP + &this_rdc, best_remain_rdcost, sub_tree[1], + get_partition_subtree_const(ptree_luma, 1), get_partition_subtree_const(template_tree, 1), max_recursion_depth, NULL, NULL, multi_pass_mode, NULL #if CONFIG_ML_PART_SPLIT @@ -4397,6 +4732,9 @@ #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK LevelBanksRDO *level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK +#if CONFIG_EXTENDED_SDP + PARTITION_TYPE parent_partition, +#endif // CONFIG_INTER_SDP int64_t part_none_rd #if CONFIG_ML_PART_SPLIT , @@ -4515,7 +4853,13 @@ continue; } +#if CONFIG_EXTENDED_SDP + const REGION_TYPE cur_region_type = pc_tree->region_type; + PC_TREE **sub_tree = (i == HORZ) ? pc_tree->horizontal[cur_region_type] + : pc_tree->vertical[cur_region_type]; +#else PC_TREE **sub_tree = (i == HORZ) ? pc_tree->horizontal : pc_tree->vertical; +#endif // CONFIG_EXTENDED_SDP assert(sub_tree); const int num_planes = av1_num_planes(cm); @@ -4543,7 +4887,11 @@ cpi, td, tile_data, tp, x, pc_tree, part_search_state, best_rdc, i, mi_pos_rect, blk_params.subsize, is_not_edge_block, multi_pass_mode, track_ptree_luma ? ptree_luma : NULL, template_tree, - &both_blocks_skippable, max_recursion_depth + &both_blocks_skippable, +#if CONFIG_EXTENDED_SDP + parent_partition, +#endif // CONFIG_INTER_SDP + max_recursion_depth #if CONFIG_ML_PART_SPLIT , next_force_prune_flags[i] @@ -4965,6 +5313,12 @@ #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK part_search_state->found_best_partition = true; pc_tree->partitioning = partition_type; +#if CONFIG_EXTENDED_SDP + if (!frame_is_intra_only(cm)) + pc_tree->region_type = MIXED_INTER_INTRA_REGION; + else + pc_tree->region_type = INTRA_REGION; +#endif // CONFIG_EXTENDED_SDP } #if CONFIG_COLLECT_PARTITION_STATS if (partition_timer_on) { @@ -5078,6 +5432,9 @@ #if CONFIG_EXT_RECUR_PARTITIONS TREE_TYPE tree_type, #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + int sdp_inter_chroma_flag, +#endif // CONFIG_EXTENDED_SDP PartitionSearchState *part_search_state) { PartitionBlkParams blk_params = part_search_state->part_blk_params; #if CONFIG_EXT_RECUR_PARTITIONS @@ -5086,6 +5443,12 @@ return; } #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + if (sdp_inter_chroma_flag) { + part_search_state->partition_none_allowed = 1; + return; + } +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS if (is_bsize_geq(blk_params.min_partition_size, blk_params.bsize) && blk_params.has_rows && blk_params.has_cols) @@ -5118,15 +5481,37 @@ PartitionBlkParams blk_params = part_search_state->part_blk_params; RD_STATS partition_rdcost; // Set PARTITION_NONE context. +#if CONFIG_EXTENDED_SDP + if (is_inter_sdp_chroma(cm, pc_tree->region_type, x->e_mbd.tree_type)) { + if (pc_tree->none_chroma == NULL) { + pc_tree->none_chroma = av1_alloc_pmc( + cm, x->e_mbd.tree_type, blk_params.mi_row, blk_params.mi_col, + blk_params.bsize, pc_tree, PARTITION_NONE, 0, part_search_state->ss_x, + part_search_state->ss_y, &td->shared_coeff_buf); + } + } else { + if (pc_tree->none[pc_tree->region_type] == NULL) { + pc_tree->none[pc_tree->region_type] = av1_alloc_pmc( + cm, x->e_mbd.tree_type, blk_params.mi_row, blk_params.mi_col, + blk_params.bsize, pc_tree, PARTITION_NONE, 0, part_search_state->ss_x, + part_search_state->ss_y, &td->shared_coeff_buf); + } + } +#else if (pc_tree->none == NULL) pc_tree->none = av1_alloc_pmc( cm, x->e_mbd.tree_type, blk_params.mi_row, blk_params.mi_col, blk_params.bsize, pc_tree, PARTITION_NONE, 0, part_search_state->ss_x, part_search_state->ss_y, &td->shared_coeff_buf); +#endif // CONFIG_EXTENDED_SDP // Set PARTITION_NONE type cost. if (part_search_state->partition_none_allowed) { - if (part_search_state->is_block_splittable) { + if (part_search_state->is_block_splittable +#if CONFIG_EXTENDED_SDP + && !is_inter_sdp_chroma(cm, pc_tree->region_type, x->e_mbd.tree_type) +#endif // CONFIG_EXTENDED_SDP + ) { *pt_cost = part_search_state->partition_cost[PARTITION_NONE] < INT_MAX ? part_search_state->partition_cost[PARTITION_NONE] : 0; @@ -5290,6 +5675,50 @@ } #endif +#if CONFIG_EXTENDED_SDP +static void inter_sdp_copy_luma_mode_info(PC_TREE *pc_tree, + PICK_MODE_CONTEXT *ctx_chroma_none, + MB_MODE_INFO *mbmi) { + PC_TREE *cur_pc_tree = pc_tree; + PARTITION_TYPE partition = cur_pc_tree->partitioning; + while (partition) { + switch (partition) { + case PARTITION_HORZ: + cur_pc_tree = cur_pc_tree->horizontal[INTRA_REGION][0]; + break; + case PARTITION_VERT: + cur_pc_tree = cur_pc_tree->vertical[INTRA_REGION][0]; + break; + case PARTITION_SPLIT: + cur_pc_tree = cur_pc_tree->split[INTRA_REGION][0]; + break; + case PARTITION_HORZ_4A: + cur_pc_tree = cur_pc_tree->horizontal4a[INTRA_REGION][0]; + break; + case PARTITION_HORZ_4B: + cur_pc_tree = cur_pc_tree->horizontal4b[INTRA_REGION][0]; + break; + case PARTITION_VERT_4A: + cur_pc_tree = cur_pc_tree->vertical4a[INTRA_REGION][0]; + break; + case PARTITION_VERT_4B: + cur_pc_tree = cur_pc_tree->vertical4b[INTRA_REGION][0]; + break; + case PARTITION_VERT_3: + cur_pc_tree = cur_pc_tree->vertical3[INTRA_REGION][0]; + break; + case PARTITION_HORZ_3: + cur_pc_tree = cur_pc_tree->horizontal3[INTRA_REGION][0]; + break; + default: assert(0 && "Invalid partition type!"); break; + } + partition = cur_pc_tree->partitioning; + } + ctx_chroma_none->mic = cur_pc_tree->none[INTRA_REGION]->mic; + *mbmi = cur_pc_tree->none[INTRA_REGION]->mic; +} +#endif // CONFIG_EXTENDED_SDP + // PARTITION_NONE search. static void none_partition_search( AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data, MACROBLOCK *x, @@ -5315,17 +5744,29 @@ return; } #endif // CONFIG_EXT_RECUR_PARTITIONS + +#if CONFIG_EXTENDED_SDP + int sdp_inter_chroma_flag = + is_inter_sdp_chroma(cm, pc_tree->region_type, x->e_mbd.tree_type); +#endif // CONFIG_EXTENDED_SDP // Set PARTITION_NONE allowed flag. set_part_none_allowed_flag(cpi, #if CONFIG_EXT_RECUR_PARTITIONS x->e_mbd.tree_type, #endif // CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + sdp_inter_chroma_flag, +#endif // CONFIG_EXTENDED_SDP part_search_state); if (!part_search_state->partition_none_allowed) { return; } #if CONFIG_EXT_RECUR_PARTITIONS - if (part_search_state->prune_partition_none) { + if (part_search_state->prune_partition_none +#if CONFIG_EXTENDED_SDP + && !sdp_inter_chroma_flag +#endif // CONFIG_EXTENDED_SDP + ) { return; } #endif // CONFIG_EXT_RECUR_PARTITIONS @@ -5337,6 +5778,16 @@ set_none_partition_params(cm, td, x, pc_tree, part_search_state, &best_remain_rdcost, best_rdc, &pt_cost); +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; + PICK_MODE_CONTEXT *ctx_none = sdp_inter_chroma_flag + ? pc_tree->none_chroma + : pc_tree->none[pc_tree->region_type]; + if (sdp_inter_chroma_flag) { + inter_sdp_copy_luma_mode_info(pc_tree, ctx_none, x->e_mbd.mi[0]); + } +#endif // CONFIG_EXTENDED_SDP + #if CONFIG_COLLECT_PARTITION_STATS // Timer start for partition None. if (best_remain_rdcost >= 0) { @@ -5353,11 +5804,30 @@ // PARTITION_NONE evaluation and cost update. pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, this_rdc, PARTITION_NONE, - bsize, pc_tree->none, best_remain_rdcost); +#if CONFIG_EXTENDED_SDP + pc_tree->region_type, +#endif // CONFIG_EXTENDED_SDP + bsize, +#if CONFIG_EXTENDED_SDP + ctx_none, +#else + pc_tree->none, +#endif // CONFIG_EXTENDED_SDP + best_remain_rdcost); #if CONFIG_EXT_RECUR_PARTITIONS x->inter_mode_cache = NULL; - if (this_rdc->rate != INT_MAX) { - av1_add_mode_search_context_to_cache(sms_data, pc_tree->none); + if (this_rdc->rate != INT_MAX +#if CONFIG_EXTENDED_SDP + && !is_inter_sdp_chroma(cm, cur_region_type, x->e_mbd.tree_type) +#endif // CONFIG_EXTENDED_SDP + ) { + av1_add_mode_search_context_to_cache(sms_data, +#if CONFIG_EXTENDED_SDP + pc_tree->none[pc_tree->region_type] +#else + pc_tree->none +#endif // CONFIG_EXTENDED_SDP + ); } #endif // CONFIG_EXT_RECUR_PARTITIONS av1_rd_cost_update(x->rdmult, this_rdc); @@ -5375,21 +5845,44 @@ if (none_rd) *none_rd = this_rdc->rdcost; part_search_state->none_rd = this_rdc->rdcost; #if CONFIG_EXT_RECUR_PARTITIONS - pc_tree->none_rd = *this_rdc; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION || + frame_is_intra_only(cm)) +#endif // CONFIG_EXTENDED_SDP + pc_tree->none_rd = *this_rdc; #endif // CONFIG_EXT_RECUR_PARTITIONS if (this_rdc->rate != INT_MAX) { #if CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + pc_tree->skippable = sdp_inter_chroma_flag + ? pc_tree->none_chroma->skippable + : pc_tree->none[pc_tree->region_type]->skippable; +#else pc_tree->skippable = pc_tree->none->skippable; +#endif // CONFIG_EXTENDED_SDP #endif // CONFIG_EXT_RECUR_PARTITIONS // Record picked ref frame to prune ref frames for other partition types. - if (cpi->sf.inter_sf.prune_ref_frames) { + if (cpi->sf.inter_sf.prune_ref_frames +#if CONFIG_EXTENDED_SDP + && x->e_mbd.tree_type != CHROMA_PART +#endif // CONFIG_EXTENDED_SDP + ) { +#if CONFIG_EXTENDED_SDP + const int ref_type = av1_ref_frame_type( + pc_tree->none[pc_tree->region_type]->mic.ref_frame); +#else const int ref_type = av1_ref_frame_type(pc_tree->none->mic.ref_frame); +#endif // CONFIG_EXTENDED_SDP av1_update_picked_ref_frames_mask(x, ref_type, bsize, cm->mib_size, mi_row, mi_col); } // Calculate the total cost and update the best partition. - if (part_search_state->is_block_splittable) { + if (part_search_state->is_block_splittable +#if CONFIG_EXTENDED_SDP + && !sdp_inter_chroma_flag +#endif // CONFIG_EXTENDED_SDP + ) { this_rdc->rate += pt_cost; this_rdc->rdcost = RDCOST(x->rdmult, this_rdc->rate, this_rdc->dist); } @@ -5405,14 +5898,26 @@ pc_tree->partitioning = PARTITION_NONE; } #else - pc_tree->partitioning = PARTITION_NONE; +#if CONFIG_EXTENDED_SDP + if (!sdp_inter_chroma_flag) +#endif // CONFIG_EXTENDED_SDP + pc_tree->partitioning = PARTITION_NONE; #endif // !CONFIG_EXT_RECUR_PARTITIONS // Disable split and rectangular partition search // based on PARTITION_NONE cost. - prune_partitions_after_none(cpi, x, sms_tree, pc_tree->none, - part_search_state, best_rdc, - pb_source_variance); +#if CONFIG_EXTENDED_SDP + if (frame_is_intra_only(cm) || cur_region_type != INTRA_REGION || + x->e_mbd.tree_type != CHROMA_PART) +#endif // CONFIG_EXTENDED_SDP + prune_partitions_after_none(cpi, x, sms_tree, +#if CONFIG_EXTENDED_SDP + pc_tree->none[pc_tree->region_type], +#else + pc_tree->none, +#endif // CONFIG_EXTENDED_SDP + part_search_state, best_rdc, + pb_source_variance); } } av1_restore_context(cm, x, x_ctx, mi_row, mi_col, bsize, av1_num_planes(cm)); @@ -5469,7 +5974,11 @@ } const int num_planes = av1_num_planes(cm); +#if CONFIG_EXTENDED_SDP + PC_TREE **sub_tree = pc_tree->split[pc_tree->region_type]; +#else PC_TREE **sub_tree = pc_tree->split; +#endif // CONFIG_EXTENDED_SDP assert(sub_tree); for (int idx = 0; idx < SUB_PARTITIONS_SPLIT; idx++) { if (sub_tree[idx]) { @@ -5509,9 +6018,16 @@ if (mi_row + y_idx >= mi_params->mi_rows || mi_col + x_idx >= mi_params->mi_cols) continue; - +#if CONFIG_EXTENDED_SDP + if (pc_tree->split[pc_tree->region_type][idx] == NULL) { +#else if (pc_tree->split[idx] == NULL) { +#endif // CONFIG_EXTENDED_SDP +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][idx] = av1_alloc_pc_tree_node( +#else pc_tree->split[idx] = av1_alloc_pc_tree_node( +#endif x->e_mbd.tree_type, mi_row + y_idx, mi_col + x_idx, subsize, pc_tree, PARTITION_SPLIT, idx, idx == 3, part_search_state->ss_x, part_search_state->ss_y); @@ -5538,6 +6054,9 @@ #endif // CONFIG_ML_PART_SPLIT if (!av1_rd_pick_partition( cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize, +#if CONFIG_EXTENDED_SDP + PARTITION_SPLIT, +#endif // CONFIG_EXTENDED_SDP &part_search_state->this_rdc, best_remain_rdcost, sub_tree[idx], track_ptree_luma ? ptree_luma->sub_tree[idx] : NULL, get_partition_subtree_const(template_tree, idx), @@ -5569,8 +6088,21 @@ // Set split ctx as ready for use. if (idx <= 1 && (bsize <= BLOCK_8X8 || - pc_tree->split[idx]->partitioning == PARTITION_NONE)) { +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][idx]->partitioning == + PARTITION_NONE +#else + pc_tree->split[idx]->partitioning == PARTITION_NONE +#endif // CONFIG_EXTENDED_SDP + )) { +#if CONFIG_EXTENDED_SDP + const MB_MODE_INFO *const mbmi = + &pc_tree->split[pc_tree->region_type][idx] + ->none[pc_tree->region_type] + ->mic; +#else const MB_MODE_INFO *const mbmi = &pc_tree->split[idx]->none->mic; +#endif // CONFIG_EXTENDED_SDP const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info; // Neither palette mode nor cfl predicted. if (pmi->palette_size[0] == 0 && pmi->palette_size[1] == 0) { @@ -5687,6 +6219,9 @@ int force_prune_flags[3] = { 0, 0, 0 }; #endif // CONFIG_ML_PART_SPLIT if (!av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, +#if CONFIG_EXTENDED_SDP + rdo_data->partition, +#endif // CONFIG_EXTENDED_SDP &this_rdc, rdcost_remaining, rdo_data->pc_tree, rdo_data->ptree_luma, rdo_data->template_tree, max_recursion_depth, NULL, NULL, multi_pass_mode, @@ -5739,6 +6274,9 @@ const int ebs_w = mi_size_wide[bsize] / 8; const int ebs_h = mi_size_high[bsize] / 8; const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition); +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP switch (partition) { case PARTITION_NONE: for (int col = 0; col < mi_width; col++) { @@ -5751,52 +6289,113 @@ } break; case PARTITION_HORZ: - trace_partition_boundary(partition_boundaries, pc_tree->horizontal[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][0], +#else + pc_tree->horizontal[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, get_partition_subsize(bsize, PARTITION_HORZ)); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][1], +#else + pc_tree->horizontal[1], +#endif // CONFIG_EXTENDED_SDP mi_row + mi_height / 2, mi_col, get_partition_subsize(bsize, PARTITION_HORZ)); break; case PARTITION_VERT: - trace_partition_boundary(partition_boundaries, pc_tree->vertical[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][0], +#else + pc_tree->vertical[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, get_partition_subsize(bsize, PARTITION_VERT)); - trace_partition_boundary(partition_boundaries, pc_tree->vertical[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][1], +#else + pc_tree->vertical[1], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + mi_width / 2, get_partition_subsize(bsize, PARTITION_VERT)); break; case PARTITION_HORZ_3: trace_partition_boundary( - partition_boundaries, pc_tree->horizontal3[0], mi_row, mi_col, - get_h_partition_subsize(bsize, 0, PARTITION_HORZ_3)); + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal3[cur_region_type][0], +#else + pc_tree->horizontal3[0], +#endif // CONFIG_EXTENDED_SDP + mi_row, mi_col, get_h_partition_subsize(bsize, 0, PARTITION_HORZ_3)); trace_partition_boundary( - partition_boundaries, pc_tree->horizontal3[1], mi_row + mi_height / 4, - mi_col, get_h_partition_subsize(bsize, 1, PARTITION_HORZ_3)); - trace_partition_boundary( - partition_boundaries, pc_tree->horizontal3[2], mi_row + mi_height / 4, - mi_col + mi_width / 2, + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal3[cur_region_type][1], +#else + pc_tree->horizontal3[1], +#endif // CONFIG_EXTENDED_SDP + mi_row + mi_height / 4, mi_col, get_h_partition_subsize(bsize, 1, PARTITION_HORZ_3)); trace_partition_boundary( - partition_boundaries, pc_tree->horizontal3[3], + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal3[cur_region_type][2], +#else + pc_tree->horizontal3[2], +#endif // CONFIG_EXTENDED_SDP + mi_row + mi_height / 4, mi_col + mi_width / 2, + get_h_partition_subsize(bsize, 1, PARTITION_HORZ_3)); + trace_partition_boundary( + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal3[cur_region_type][3], +#else + pc_tree->horizontal3[3], +#endif // CONFIG_EXTENDED_SDP mi_row + 3 * mi_height / 4, mi_col, get_h_partition_subsize(bsize, 0, PARTITION_HORZ_3)); break; case PARTITION_VERT_3: trace_partition_boundary( - partition_boundaries, pc_tree->vertical3[0], mi_row, mi_col, - get_h_partition_subsize(bsize, 0, PARTITION_VERT_3)); + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical3[cur_region_type][0], +#else + pc_tree->vertical3[0], +#endif // CONFIG_EXTENDED_SDP + mi_row, mi_col, get_h_partition_subsize(bsize, 0, PARTITION_VERT_3)); trace_partition_boundary( - partition_boundaries, pc_tree->vertical3[1], mi_row, - mi_col + mi_width / 4, + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical3[cur_region_type][1], +#else + pc_tree->vertical3[1], +#endif // CONFIG_EXTENDED_SDP + mi_row, mi_col + mi_width / 4, get_h_partition_subsize(bsize, 1, PARTITION_VERT_3)); trace_partition_boundary( - partition_boundaries, pc_tree->vertical3[2], mi_row + mi_height / 2, - mi_col + mi_width / 4, + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical3[cur_region_type][2], +#else + pc_tree->vertical3[2], +#endif // CONFIG_EXTENDED_SDP + mi_row + mi_height / 2, mi_col + mi_width / 4, get_h_partition_subsize(bsize, 1, PARTITION_VERT_3)); trace_partition_boundary( - partition_boundaries, pc_tree->vertical3[3], mi_row, - mi_col + 3 * mi_width / 4, + partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical3[cur_region_type][3], +#else + pc_tree->vertical3[3], +#endif // CONFIG_EXTENDED_SDP + mi_row, mi_col + 3 * mi_width / 4, get_h_partition_subsize(bsize, 0, PARTITION_VERT_3)); break; case PARTITION_HORZ_4A: { @@ -5804,13 +6403,33 @@ assert(bsize_big < BLOCK_SIZES_ALL); const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big]; assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4a[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[cur_region_type][0], +#else + pc_tree->horizontal4a[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, subsize); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4a[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[cur_region_type][1], +#else + pc_tree->horizontal4a[1], +#endif // CONFIG_EXTENDED_SDP mi_row + ebs_h, mi_col, bsize_med); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4a[2], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[cur_region_type][2], +#else + pc_tree->horizontal4a[2], +#endif // CONFIG_EXTENDED_SDP mi_row + 3 * ebs_h, mi_col, bsize_big); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4a[3], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[cur_region_type][3], +#else + pc_tree->horizontal4a[3], +#endif // CONFIG_EXTENDED_SDP mi_row + 7 * ebs_h, mi_col, subsize); break; } @@ -5819,13 +6438,33 @@ assert(bsize_big < BLOCK_SIZES_ALL); const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big]; assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4b[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[cur_region_type][0], +#else + pc_tree->horizontal4b[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, subsize); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4b[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[cur_region_type][1], +#else + pc_tree->horizontal4b[1], +#endif // CONFIG_EXTENDED_SDP mi_row + ebs_h, mi_col, bsize_big); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4b[2], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[cur_region_type][2], +#else + pc_tree->horizontal4b[2], +#endif // CONFIG_EXTENDED_SDP mi_row + 5 * ebs_h, mi_col, bsize_med); - trace_partition_boundary(partition_boundaries, pc_tree->horizontal4b[3], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[cur_region_type][3], +#else + pc_tree->horizontal4b[3], +#endif // CONFIG_EXTENDED_SDP mi_row + 7 * ebs_h, mi_col, subsize); break; } @@ -5834,13 +6473,33 @@ assert(bsize_big < BLOCK_SIZES_ALL); const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big]; assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4a[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[cur_region_type][0], +#else + pc_tree->vertical4a[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, subsize); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4a[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[cur_region_type][1], +#else + pc_tree->vertical4a[1], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + ebs_w, bsize_med); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4a[2], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[cur_region_type][2], +#else + pc_tree->vertical4a[2], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + 3 * ebs_w, bsize_big); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4a[3], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[cur_region_type][3], +#else + pc_tree->vertical4a[3], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + 7 * ebs_w, subsize); break; } @@ -5849,13 +6508,33 @@ assert(bsize_big < BLOCK_SIZES_ALL); const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big]; assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4b[0], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[cur_region_type][0], +#else + pc_tree->vertical4b[0], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col, subsize); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4b[1], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[cur_region_type][1], +#else + pc_tree->vertical4b[1], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + ebs_w, bsize_big); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4b[2], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[cur_region_type][2], +#else + pc_tree->vertical4b[2], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + 5 * ebs_w, bsize_med); - trace_partition_boundary(partition_boundaries, pc_tree->vertical4b[3], + trace_partition_boundary(partition_boundaries, +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[cur_region_type][3], +#else + pc_tree->vertical4b[3], +#endif // CONFIG_EXTENDED_SDP mi_row, mi_col + 7 * ebs_w, subsize); break; } @@ -6058,6 +6737,10 @@ return; } +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + // Prune horz 3 with speed features if (part_search_state->partition_3_allowed[HORZ] && !frame_is_intra_only(cm) && forced_partition != PARTITION_HORZ_3) { @@ -6070,13 +6753,29 @@ // Prune if the best partition is rect but the subtrees did not further // split in horz if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][0] && + pc_tree->horizontal[cur_region_type][1] && + !node_uses_horz(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_horz(pc_tree->horizontal[cur_region_type][1]) +#else !node_uses_horz(pc_tree->horizontal[0]) && - !node_uses_horz(pc_tree->horizontal[1])) { + !node_uses_horz(pc_tree->horizontal[1]) +#endif // CONFIG_EXTENDED_SDP + ) { part_search_state->prune_partition_3[HORZ] = 1; } if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][0] && + pc_tree->vertical[cur_region_type][1] && + !node_uses_horz(pc_tree->vertical[cur_region_type][0]) && + !node_uses_horz(pc_tree->vertical[cur_region_type][1]) +#else !node_uses_horz(pc_tree->vertical[0]) && - !node_uses_horz(pc_tree->vertical[1])) { + !node_uses_horz(pc_tree->vertical[1]) +#endif // CONFIG_EXTENDED_SDP + ) { part_search_state->prune_partition_3[HORZ] = 1; } } @@ -6093,13 +6792,29 @@ // Prune if the best partition is rect but the subtrees did not further // split in vert if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + pc_tree->vertical[cur_region_type][0] && + pc_tree->vertical[cur_region_type][1] && + !node_uses_vert(pc_tree->vertical[cur_region_type][0]) && + !node_uses_vert(pc_tree->vertical[cur_region_type][1]) +#else !node_uses_vert(pc_tree->vertical[0]) && - !node_uses_vert(pc_tree->vertical[1])) { + !node_uses_vert(pc_tree->vertical[1]) +#endif // CONFIG_EXTENDED_SDP + ) { part_search_state->prune_partition_3[VERT] = 1; } if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal[cur_region_type][0] && + pc_tree->horizontal[cur_region_type][1] && + !node_uses_vert(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_vert(pc_tree->horizontal[cur_region_type][1]) +#else !node_uses_vert(pc_tree->horizontal[0]) && - !node_uses_vert(pc_tree->horizontal[1])) { + !node_uses_vert(pc_tree->horizontal[1]) +#endif // CONFIG_EXTENDED_SDP + ) { part_search_state->prune_partition_3[VERT] = 1; } } @@ -6126,6 +6841,205 @@ } } +#if CONFIG_EXTENDED_SDP +// Early termination of SDP for intra blocks in inter frames +static INLINE void early_termination_inter_sdp(PC_TREE *pc_tree, + float *total_count, + float *inter_mode_count) { + REGION_TYPE cur_region_type = pc_tree->region_type; + if (pc_tree->partitioning == PARTITION_NONE) { + if (pc_tree->none[cur_region_type] == NULL) return; + const MB_MODE_INFO *const mi = &(pc_tree->none[cur_region_type])->mic; + if (mi == NULL) return; + *total_count += 1; + if (mi->mode >= NEARMV && mi->mode < MB_MODE_COUNT) *inter_mode_count += 1; + return; + } + switch (pc_tree->partitioning) { + case PARTITION_HORZ: + early_termination_inter_sdp(pc_tree->horizontal[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal[cur_region_type][1], + total_count, inter_mode_count); + break; + case PARTITION_VERT: + early_termination_inter_sdp(pc_tree->vertical[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical[cur_region_type][1], + total_count, inter_mode_count); + break; + case PARTITION_HORZ_4A: + early_termination_inter_sdp(pc_tree->horizontal4a[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4a[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4a[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4a[cur_region_type][3], + total_count, inter_mode_count); + break; + case PARTITION_HORZ_4B: + early_termination_inter_sdp(pc_tree->horizontal4b[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4b[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4b[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal4b[cur_region_type][3], + total_count, inter_mode_count); + break; + case PARTITION_VERT_4A: + early_termination_inter_sdp(pc_tree->vertical4a[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4a[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4a[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4a[cur_region_type][3], + total_count, inter_mode_count); + break; + case PARTITION_VERT_4B: + early_termination_inter_sdp(pc_tree->vertical4b[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4b[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4b[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical4b[cur_region_type][3], + total_count, inter_mode_count); + break; + case PARTITION_HORZ_3: + early_termination_inter_sdp(pc_tree->horizontal3[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal3[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal3[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->horizontal3[cur_region_type][3], + total_count, inter_mode_count); + break; + case PARTITION_VERT_3: + early_termination_inter_sdp(pc_tree->vertical3[cur_region_type][0], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical3[cur_region_type][1], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical3[cur_region_type][2], + total_count, inter_mode_count); + early_termination_inter_sdp(pc_tree->vertical3[cur_region_type][3], + total_count, inter_mode_count); + break; + default: break; + } +} + +// Search SDP for intra blocks in inter frames +static INLINE void search_intra_region_partitioning( + PartitionSearchState *search_state, AV1_COMP *const cpi, ThreadData *td, + TileDataEnc *tile_data, TokenExtra **tp, RD_STATS *best_rdc, + PC_TREE *pc_tree, const PARTITION_TREE *ptree_luma, + const PARTITION_TREE *template_tree, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx, + PartitionSearchState *part_search_state, +#if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + LevelBanksRDO *level_banks, +#endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + SB_MULTI_PASS_MODE multi_pass_mode, int max_recursion_depth, + PARTITION_TYPE parent_partition) { + const AV1_COMMON *const cm = &cpi->common; + MACROBLOCK *const x = &td->mb; + const int num_planes = av1_num_planes(cm); + MACROBLOCKD *const xd = &x->e_mbd; + + // Add one encoder fast method for early terminating inter-sdp + float total_count = 0; + float inter_mode_count = 0; + early_termination_inter_sdp(pc_tree, &total_count, &inter_mode_count); + // if over 60% of the coded blocks under this region are inter coded blocks, + // skip the rdo for inter-sdp + if (total_count * 0.7 < inter_mode_count) return; + + pc_tree->region_type = INTRA_REGION; + // store the current best partitioning + PARTITION_TYPE cur_best_partitioning = pc_tree->partitioning; + pc_tree->partitioning = PARTITION_NONE; + + RD_STATS *sum_rdc = &part_search_state->sum_rdc; + av1_init_rd_stats(sum_rdc); + + sum_rdc->rate = part_search_state->region_type_cost[pc_tree->region_type]; + sum_rdc->rdcost = RDCOST(x->rdmult, sum_rdc->rate, 0); + + RD_STATS best_remain_rdcost; + + av1_rd_stats_subtraction(x->rdmult, best_rdc, sum_rdc, &best_remain_rdcost); + + const PartitionBlkParams *blk_params = &search_state->part_blk_params; + const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; + const BLOCK_SIZE bsize = blk_params->bsize; + + RD_STATS this_rdc; + av1_init_rd_stats(&this_rdc); + + // Encoder RDO for luma component in intra region + xd->tree_type = LUMA_PART; + if (!av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, +#if CONFIG_EXTENDED_SDP + parent_partition, +#endif // CONFIG_EXTENDED_SDP + &this_rdc, best_remain_rdcost, pc_tree, ptree_luma, + template_tree, max_recursion_depth, NULL, NULL, + multi_pass_mode, NULL)) { + av1_invalid_rd_stats(&this_rdc); + av1_invalid_rd_stats(sum_rdc); + } + // Encoder RDO for chroma component in intra region + if (this_rdc.rdcost != INT64_MAX && !cm->seq_params.monochrome) { + sum_rdc->rate += this_rdc.rate; + sum_rdc->dist += this_rdc.dist; + av1_rd_cost_update(x->rdmult, sum_rdc); + xd->tree_type = CHROMA_PART; + av1_rd_stats_subtraction(x->rdmult, best_rdc, sum_rdc, &best_remain_rdcost); + av1_init_rd_stats(&this_rdc); + if (!av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize, +#if CONFIG_EXTENDED_SDP + parent_partition, +#endif // CONFIG_EXTENDED_SDP + &this_rdc, best_remain_rdcost, pc_tree, + ptree_luma, template_tree, max_recursion_depth, + NULL, NULL, multi_pass_mode, NULL)) { + av1_invalid_rd_stats(&this_rdc); + av1_invalid_rd_stats(sum_rdc); + } + if (this_rdc.rdcost != INT64_MAX) { + sum_rdc->rate += this_rdc.rate; + sum_rdc->dist += this_rdc.dist; + av1_rd_cost_update(x->rdmult, sum_rdc); + } + } + // reset tree_type to shared_part + xd->tree_type = SHARED_PART; + // compare current rd cost with best rd cost + if (sum_rdc->rdcost < best_rdc->rdcost) { +#if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + update_best_level_banks(level_banks, &x->e_mbd); +#endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + *best_rdc = *sum_rdc; + search_state->found_best_partition = true; +#if CONFIG_EXTENDED_SDP + pc_tree->region_type = INTRA_REGION; +#endif // CONFIG_EXTENDED_SDP + } else { + // set back to the previous stored region_type and partitioning type + pc_tree->region_type = MIXED_INTER_INTRA_REGION; + pc_tree->partitioning = cur_best_partitioning; + } + + av1_restore_context(cm, x, x_ctx, mi_row, mi_col, bsize, num_planes); +#if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + restore_level_banks(&x->e_mbd, level_banks); +#endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK +} +#endif // CONFIG_EXTENDED_SDP + // Pruning logic for PARTITION_HORZ_4A/B and PARTITION_VERT_4A/B. static AOM_INLINE void prune_ext_partitions_4way( AV1_COMP *const cpi, PC_TREE *pc_tree, @@ -6134,6 +7048,10 @@ const PARTITION_SPEED_FEATURES *part_sf = &cpi->sf.part_sf; const PARTITION_TYPE forced_partition = part_search_state->forced_partition; +#if CONFIG_EXTENDED_SDP + const int cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + // Prune HORZ 4A with speed features if (part_search_state->partition_4a_allowed[HORZ] && forced_partition != PARTITION_HORZ_4A) { @@ -6147,27 +7065,47 @@ // Prune if the best partition is rect but subtrees did not further split // in horz if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_horz(pc_tree->horizontal[cur_region_type][1])) { +#else !node_uses_horz(pc_tree->horizontal[0]) && !node_uses_horz(pc_tree->horizontal[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4a[HORZ] = 1; } if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->vertical[cur_region_type][0]) && + !node_uses_horz(pc_tree->vertical[cur_region_type][1])) { +#else !node_uses_horz(pc_tree->vertical[0]) && !node_uses_horz(pc_tree->vertical[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4a[HORZ] = 1; } } if (part_sf->prune_part_4_with_part_3 && !frame_is_intra_only(cm)) { if (pc_tree->partitioning == PARTITION_HORZ_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->horizontal3[cur_region_type][0]) && + !node_uses_horz(pc_tree->horizontal3[cur_region_type][3])) { +#else !node_uses_horz(pc_tree->horizontal3[0]) && !node_uses_horz(pc_tree->horizontal3[3])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is horizontal H, but first and last // subpartitions did not further split in horizontal direction. part_search_state->prune_partition_4a[HORZ] = 1; } if (pc_tree->partitioning == PARTITION_VERT_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->vertical3[cur_region_type][1]) && + !node_uses_horz(pc_tree->vertical3[cur_region_type][2])) { +#else !node_uses_horz(pc_tree->vertical3[1]) && !node_uses_horz(pc_tree->vertical3[2])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is vertical H, but middle two // subpartitions did not further split in horizontal direction. part_search_state->prune_partition_4a[HORZ] = 1; @@ -6211,27 +7149,47 @@ // Prune if the best partition is rect but subtrees did not further split // in horz if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_horz(pc_tree->horizontal[cur_region_type][1])) { +#else !node_uses_horz(pc_tree->horizontal[0]) && !node_uses_horz(pc_tree->horizontal[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4b[HORZ] = 1; } if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->vertical[cur_region_type][0]) && + !node_uses_horz(pc_tree->vertical[cur_region_type][1])) { +#else !node_uses_horz(pc_tree->vertical[0]) && !node_uses_horz(pc_tree->vertical[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4b[HORZ] = 1; } } if (part_sf->prune_part_4_with_part_3 && !frame_is_intra_only(cm)) { if (pc_tree->partitioning == PARTITION_HORZ_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->horizontal3[cur_region_type][0]) && + !node_uses_horz(pc_tree->horizontal3[cur_region_type][3])) { +#else !node_uses_horz(pc_tree->horizontal3[0]) && !node_uses_horz(pc_tree->horizontal3[3])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is horizontal H, but first and last // subpartitions did not further split in horizontal direction. part_search_state->prune_partition_4b[HORZ] = 1; } if (pc_tree->partitioning == PARTITION_VERT_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_horz(pc_tree->vertical3[cur_region_type][1]) && + !node_uses_horz(pc_tree->vertical3[cur_region_type][2])) { +#else !node_uses_horz(pc_tree->vertical3[1]) && !node_uses_horz(pc_tree->vertical3[2])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is vertical H, but middle two // subpartitions did not further split in horizontal direction. part_search_state->prune_partition_4b[HORZ] = 1; @@ -6275,27 +7233,47 @@ // Prune if the best partition is rect but subtrees did not further split // in vert if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->vertical[cur_region_type][0]) && + !node_uses_vert(pc_tree->vertical[cur_region_type][1])) { +#else !node_uses_vert(pc_tree->vertical[0]) && !node_uses_vert(pc_tree->vertical[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4a[VERT] = 1; } if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_vert(pc_tree->horizontal[cur_region_type][1])) { +#else !node_uses_vert(pc_tree->horizontal[0]) && !node_uses_vert(pc_tree->horizontal[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4a[VERT] = 1; } } if (part_sf->prune_part_4_with_part_3 && !frame_is_intra_only(cm)) { if (pc_tree->partitioning == PARTITION_VERT_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->vertical3[cur_region_type][0]) && + !node_uses_vert(pc_tree->vertical3[cur_region_type][3])) { +#else !node_uses_vert(pc_tree->vertical3[0]) && !node_uses_vert(pc_tree->vertical3[3])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is vertical H, but first and last // subpartitions did not further split in vertical direction. part_search_state->prune_partition_4a[VERT] = 1; } if (pc_tree->partitioning == PARTITION_HORZ_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->horizontal3[cur_region_type][1]) && + !node_uses_vert(pc_tree->horizontal3[cur_region_type][2])) { +#else !node_uses_vert(pc_tree->horizontal3[1]) && !node_uses_vert(pc_tree->horizontal3[2])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is horizontal H, but middle two // subpartitions did not further split in vertical direction. part_search_state->prune_partition_4a[VERT] = 1; @@ -6339,27 +7317,47 @@ // Prune if the best partition is rect but subtrees did not further split // in vert if (pc_tree->partitioning == PARTITION_VERT && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->vertical[cur_region_type][0]) && + !node_uses_vert(pc_tree->vertical[cur_region_type][1])) { +#else !node_uses_vert(pc_tree->vertical[0]) && !node_uses_vert(pc_tree->vertical[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4b[VERT] = 1; } if (pc_tree->partitioning == PARTITION_HORZ && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->horizontal[cur_region_type][0]) && + !node_uses_vert(pc_tree->horizontal[cur_region_type][1])) { +#else !node_uses_vert(pc_tree->horizontal[0]) && !node_uses_vert(pc_tree->horizontal[1])) { +#endif // CONFIG_EXTENDED_SDP part_search_state->prune_partition_4b[VERT] = 1; } } if (part_sf->prune_part_4_with_part_3 && !frame_is_intra_only(cm)) { if (pc_tree->partitioning == PARTITION_VERT_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->vertical3[cur_region_type][0]) && + !node_uses_vert(pc_tree->vertical3[cur_region_type][3])) { +#else !node_uses_vert(pc_tree->vertical3[0]) && !node_uses_vert(pc_tree->vertical3[3])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is vertical H, but first and last // subpartitions did not further split in vertical direction. part_search_state->prune_partition_4b[VERT] = 1; } if (pc_tree->partitioning == PARTITION_HORZ_3 && +#if CONFIG_EXTENDED_SDP + !node_uses_vert(pc_tree->horizontal3[cur_region_type][1]) && + !node_uses_vert(pc_tree->horizontal3[cur_region_type][2])) { +#else !node_uses_vert(pc_tree->horizontal3[1]) && !node_uses_vert(pc_tree->horizontal3[2])) { +#endif // CONFIG_EXTENDED_SDP // Prune if best partition is horizontal H, but middle two // subpartitions did not further split in vertical direction. part_search_state->prune_partition_4b[VERT] = 1; @@ -6468,6 +7466,14 @@ const int eighth_step = mi_size_high[bsize] / 8; sum_rdc.rate = search_state->partition_cost[PARTITION_HORZ_4A]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_HORZ_4A)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -6480,7 +7486,22 @@ const BLOCK_SIZE subblock_sizes[4] = { sml_subsize, med_subsize, big_subsize, sml_subsize }; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->horizontal4a[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->horizontal4a[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->horizontal4a[cur_region_type][idx] = NULL; + } + const int this_mi_row = mi_row + eighth_step * cum_step_multipliers[idx]; + pc_tree->horizontal4a[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, this_mi_row, mi_col, subblock_sizes[idx], pc_tree, + PARTITION_HORZ_4A, idx, idx == 3, ss_x, ss_y); +#else if (pc_tree->horizontal4a[idx]) { av1_free_pc_tree_recursive(pc_tree->horizontal4a[idx], num_planes, 0, 0); pc_tree->horizontal4a[idx] = NULL; @@ -6489,6 +7510,7 @@ pc_tree->horizontal4a[idx] = av1_alloc_pc_tree_node( xd->tree_type, this_mi_row, mi_col, subblock_sizes[idx], pc_tree, PARTITION_HORZ_4A, idx, idx == 3, ss_x, ss_y); +#endif // CONFIG_EXTENDED_SDP } bool skippable = true; @@ -6497,14 +7519,19 @@ if (i > 0 && this_mi_row >= cm->mi_params.mi_rows) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->horizontal4a[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - this_mi_row, - mi_col, - subblock_sizes[i], - PARTITION_HORZ_4A }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4a[cur_region_type][i], +#else + pc_tree->horizontal4a[i], +#endif + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + this_mi_row, + mi_col, + subblock_sizes[i], + PARTITION_HORZ_4A + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -6551,6 +7578,10 @@ const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; const BLOCK_SIZE bsize = blk_params->bsize; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif + if (is_part_pruned_by_forced_partition(part_search_state, PARTITION_HORZ_4B) || !part_search_state->partition_4b_allowed[HORZ] || @@ -6575,6 +7606,14 @@ const int eighth_step = mi_size_high[bsize] / 8; sum_rdc.rate = search_state->partition_cost[PARTITION_HORZ_4B]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_HORZ_4A)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -6588,6 +7627,17 @@ sml_subsize }; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->horizontal4b[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->horizontal4b[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->horizontal4b[cur_region_type][idx] = NULL; + } + const int this_mi_row = mi_row + eighth_step * cum_step_multipliers[idx]; + pc_tree->horizontal4b[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, this_mi_row, mi_col, subblock_sizes[idx], pc_tree, + PARTITION_HORZ_4B, idx, idx == 3, ss_x, ss_y); +#else if (pc_tree->horizontal4b[idx]) { av1_free_pc_tree_recursive(pc_tree->horizontal4b[idx], num_planes, 0, 0); pc_tree->horizontal4b[idx] = NULL; @@ -6596,6 +7646,7 @@ pc_tree->horizontal4b[idx] = av1_alloc_pc_tree_node( xd->tree_type, this_mi_row, mi_col, subblock_sizes[idx], pc_tree, PARTITION_HORZ_4B, idx, idx == 3, ss_x, ss_y); +#endif // CONFIG_EXTENDED_SDP } bool skippable = true; @@ -6604,14 +7655,19 @@ if (i > 0 && this_mi_row >= cm->mi_params.mi_rows) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->horizontal4b[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - this_mi_row, - mi_col, - subblock_sizes[i], - PARTITION_HORZ_4B }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal4b[cur_region_type][i], +#else + pc_tree->horizontal4b[i], +#endif // CONFIG_EXTENDED_SDP + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + this_mi_row, + mi_col, + subblock_sizes[i], + PARTITION_HORZ_4B + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -6658,6 +7714,10 @@ const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; const BLOCK_SIZE bsize = blk_params->bsize; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + if (is_part_pruned_by_forced_partition(part_search_state, PARTITION_VERT_4A) || !part_search_state->partition_4a_allowed[VERT] || @@ -6682,6 +7742,14 @@ const int eighth_step = mi_size_wide[bsize] / 8; sum_rdc.rate = search_state->partition_cost[PARTITION_VERT_4A]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_VERT_4A)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -6695,6 +7763,17 @@ sml_subsize }; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->vertical4a[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->vertical4a[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->vertical4a[cur_region_type][idx] = NULL; + } + const int this_mi_col = mi_col + eighth_step * cum_step_multipliers[idx]; + pc_tree->vertical4a[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, mi_row, this_mi_col, subblock_sizes[idx], pc_tree, + PARTITION_VERT_4A, idx, idx == 3, ss_x, ss_y); +#else if (pc_tree->vertical4a[idx]) { av1_free_pc_tree_recursive(pc_tree->vertical4a[idx], num_planes, 0, 0); pc_tree->vertical4a[idx] = NULL; @@ -6703,6 +7782,7 @@ pc_tree->vertical4a[idx] = av1_alloc_pc_tree_node( xd->tree_type, mi_row, this_mi_col, subblock_sizes[idx], pc_tree, PARTITION_VERT_4A, idx, idx == 3, ss_x, ss_y); +#endif // CONFIG_EXTENDED_SDP } bool skippable = true; @@ -6711,14 +7791,19 @@ if (i > 0 && this_mi_col >= cm->mi_params.mi_cols) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->vertical4a[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - mi_row, - this_mi_col, - subblock_sizes[i], - PARTITION_VERT_4A }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4a[cur_region_type][i], +#else + pc_tree->vertical4a[i], +#endif // CONFIG_EXTENDED_SDP + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + mi_row, + this_mi_col, + subblock_sizes[i], + PARTITION_VERT_4A + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -6765,6 +7850,10 @@ const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; const BLOCK_SIZE bsize = blk_params->bsize; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + if (is_part_pruned_by_forced_partition(part_search_state, PARTITION_VERT_4B) || !part_search_state->partition_4b_allowed[VERT] || @@ -6789,6 +7878,14 @@ const int eighth_step = mi_size_wide[bsize] / 8; sum_rdc.rate = search_state->partition_cost[PARTITION_VERT_4B]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_VERT_4A)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -6802,6 +7899,17 @@ sml_subsize }; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->vertical4b[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->vertical4b[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->vertical4b[cur_region_type][idx] = NULL; + } + const int this_mi_col = mi_col + eighth_step * cum_step_multipliers[idx]; + pc_tree->vertical4b[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, mi_row, this_mi_col, subblock_sizes[idx], pc_tree, + PARTITION_VERT_4B, idx, idx == 3, ss_x, ss_y); +#else if (pc_tree->vertical4b[idx]) { av1_free_pc_tree_recursive(pc_tree->vertical4b[idx], num_planes, 0, 0); pc_tree->vertical4b[idx] = NULL; @@ -6810,6 +7918,7 @@ pc_tree->vertical4b[idx] = av1_alloc_pc_tree_node( xd->tree_type, mi_row, this_mi_col, subblock_sizes[idx], pc_tree, PARTITION_VERT_4B, idx, idx == 3, ss_x, ss_y); +#endif // CONFIG_EXTENDED_SDP } bool skippable = true; @@ -6818,14 +7927,19 @@ if (i > 0 && this_mi_col >= cm->mi_params.mi_cols) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->vertical4b[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - mi_row, - this_mi_col, - subblock_sizes[i], - PARTITION_VERT_4B }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->vertical4b[cur_region_type][i], +#else + pc_tree->vertical4b[i], +#endif // CONFIG_EXTENDED_SDP + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + mi_row, + this_mi_col, + subblock_sizes[i], + PARTITION_VERT_4B + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -6873,6 +7987,10 @@ const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; const BLOCK_SIZE bsize = blk_params->bsize; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + if (is_part_pruned_by_forced_partition(part_search_state, PARTITION_HORZ_3) || !part_search_state->partition_3_allowed[HORZ] || part_search_state->prune_partition_3[HORZ]) { @@ -6899,6 +8017,14 @@ const int quarter_step = mi_size_high[bsize] / 4; sum_rdc.rate = search_state->partition_cost[PARTITION_HORZ_3]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_HORZ_3)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -6911,6 +8037,18 @@ const int offset_mc[4] = { 0, 0, mi_size_wide[bsize] / 2, 0 }; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->horizontal3[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->horizontal3[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->horizontal3[cur_region_type][idx] = NULL; + } + + pc_tree->horizontal3[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, mi_row + offset_mr[idx], mi_col + offset_mc[idx], + subblock_sizes[idx], pc_tree, PARTITION_HORZ_3, idx, idx == 3, ss_x, + ss_y); +#else if (pc_tree->horizontal3[idx]) { av1_free_pc_tree_recursive(pc_tree->horizontal3[idx], num_planes, 0, 0); pc_tree->horizontal3[idx] = NULL; @@ -6920,6 +8058,7 @@ xd->tree_type, mi_row + offset_mr[idx], mi_col + offset_mc[idx], subblock_sizes[idx], pc_tree, PARTITION_HORZ_3, idx, idx == 3, ss_x, ss_y); +#endif } bool skippable = true; @@ -6929,14 +8068,19 @@ if (i > 0 && this_mi_row >= cm->mi_params.mi_rows) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->horizontal3[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - this_mi_row, - this_mi_col, - subblock_sizes[i], - PARTITION_HORZ_3 }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->horizontal3[cur_region_type][i], +#else + pc_tree->horizontal3[i], +#endif // CONFIG_EXTENDED_SDP + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + this_mi_row, + this_mi_col, + subblock_sizes[i], + PARTITION_HORZ_3 + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -6984,6 +8128,10 @@ const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col; const BLOCK_SIZE bsize = blk_params->bsize; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP + if (is_part_pruned_by_forced_partition(part_search_state, PARTITION_VERT_3) || !part_search_state->partition_3_allowed[VERT] || part_search_state->prune_partition_3[VERT]) { @@ -7011,6 +8159,14 @@ const int quarter_step = mi_size_wide[bsize] / 4; sum_rdc.rate = search_state->partition_cost[PARTITION_VERT_3]; +#if CONFIG_EXTENDED_SDP + if (pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + is_inter_sdp_allowed(pc_tree->parent->block_size, + pc_tree->parent->partitioning) && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_VERT_3)) + sum_rdc.rate += + part_search_state->region_type_cost[MIXED_INTER_INTRA_REGION]; +#endif // CONFIG_EXTENDED_SDP sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); const BLOCK_SIZE sml_subsize = @@ -7023,6 +8179,18 @@ const int offset_mc[4] = { 0, quarter_step, quarter_step, 3 * quarter_step }; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + if (pc_tree->vertical3[cur_region_type][idx]) { + av1_free_pc_tree_recursive(pc_tree->vertical3[cur_region_type][idx], + num_planes, 0, 0); + pc_tree->vertical3[cur_region_type][idx] = NULL; + } + + pc_tree->vertical3[cur_region_type][idx] = av1_alloc_pc_tree_node( + xd->tree_type, mi_row + offset_mr[idx], mi_col + offset_mc[idx], + subblock_sizes[idx], pc_tree, PARTITION_VERT_3, idx, idx == 3, ss_x, + ss_y); +#else if (pc_tree->vertical3[idx]) { av1_free_pc_tree_recursive(pc_tree->vertical3[idx], num_planes, 0, 0); pc_tree->vertical3[idx] = NULL; @@ -7032,6 +8200,7 @@ xd->tree_type, mi_row + offset_mr[idx], mi_col + offset_mc[idx], subblock_sizes[idx], pc_tree, PARTITION_VERT_3, idx, idx == 3, ss_x, ss_y); +#endif } bool skippable = true; @@ -7041,14 +8210,19 @@ if (i > 0 && this_mi_col >= cm->mi_params.mi_cols) break; - SUBBLOCK_RDO_DATA rdo_data = { pc_tree->vertical3[i], - get_partition_subtree_const(ptree_luma, i), - get_partition_subtree_const(template_tree, - i), - this_mi_row, - this_mi_col, - subblock_sizes[i], - PARTITION_VERT_3 }; + SUBBLOCK_RDO_DATA rdo_data = { +#if CONFIG_EXTENDED_SDP + pc_tree->vertical3[cur_region_type][i], +#else + pc_tree->vertical3[i], +#endif // CONFIG_EXTENDED_SDP + get_partition_subtree_const(ptree_luma, i), + get_partition_subtree_const(template_tree, i), + this_mi_row, + this_mi_col, + subblock_sizes[i], + PARTITION_VERT_3 + }; if (!rd_try_subblock_new(cpi, td, tile_data, tp, &rdo_data, *best_rdc, &sum_rdc, multi_pass_mode, &skippable, max_recursion_depth)) { @@ -7079,69 +8253,134 @@ int curr_depth) { const PARTITION_TYPE partition = pc_tree->partitioning; int max_depth = curr_depth; +#if CONFIG_EXTENDED_SDP + int cur_region_type = pc_tree->region_type; +#endif // CONFIG_EXTENDED_SDP switch (partition) { case PARTITION_NONE: break; case PARTITION_SPLIT: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, get_partition_depth(pc_tree->split[cur_region_type][idx], + curr_depth + 2)); +#else max_depth = AOMMAX(max_depth, get_partition_depth(pc_tree->split[idx], curr_depth + 2)); +#endif // CONFIG_EXTENDED_SDP } break; #if CONFIG_EXT_RECUR_PARTITIONS case PARTITION_HORZ: for (int idx = 0; idx < 2; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->horizontal[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->horizontal[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_VERT: for (int idx = 0; idx < 2; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = + AOMMAX(max_depth, + get_partition_depth(pc_tree->vertical[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX(max_depth, get_partition_depth(pc_tree->vertical[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_HORZ_3: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->horizontal3[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->horizontal3[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_VERT_3: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = + AOMMAX(max_depth, + get_partition_depth(pc_tree->vertical3[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->vertical3[idx], curr_depth + 1)); +#endif } break; case PARTITION_HORZ_4A: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->horizontal4a[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->horizontal4a[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_HORZ_4B: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->horizontal4b[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->horizontal4b[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_VERT_4A: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->vertical4a[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->vertical4a[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; case PARTITION_VERT_4B: for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + max_depth = AOMMAX( + max_depth, + get_partition_depth(pc_tree->vertical4b[cur_region_type][idx], + curr_depth + 1)); +#else max_depth = AOMMAX( max_depth, get_partition_depth(pc_tree->vertical4b[idx], curr_depth + 1)); +#endif // CONFIG_EXTENDED_SDP } break; default: assert(0); break; @@ -7241,13 +8480,25 @@ PC_TREE *const *tree = NULL; int num_sub_parts = 0; if (cur_best_partition == PARTITION_SPLIT) { +#if CONFIG_EXTENDED_SDP + tree = pc_tree->split[pc_tree->region_type]; +#else tree = pc_tree->split; +#endif // CONFIG_EXTENDED_SDP num_sub_parts = SUB_PARTITIONS_SPLIT; } else if (cur_best_partition == PARTITION_HORZ) { +#if CONFIG_EXTENDED_SDP + tree = pc_tree->horizontal[pc_tree->region_type]; +#else tree = pc_tree->horizontal; +#endif // CONFIG_EXTENDED_SDP num_sub_parts = NUM_RECT_PARTS; } else if (cur_best_partition == PARTITION_VERT) { +#if CONFIG_EXTENDED_SDP + tree = pc_tree->vertical[pc_tree->region_type]; +#else tree = pc_tree->vertical; +#endif // CONFIG_EXTENDED_SDP num_sub_parts = NUM_RECT_PARTS; } else { assert(0 && @@ -7284,6 +8535,7 @@ * \param[in] mi_col Column coordinate of the block in a step size of MI_SIZE * \param[in] bsize Current block size +* \param[in] parent_partition Partition of the parent block * \param[in] rd_cost Pointer to the final rd cost of the block * \param[in] best_rdc Upper bound of rd cost of a valid partition * \param[in] pc_tree Pointer to the PC_TREE node storing the @@ -7357,8 +8609,12 @@ bool av1_rd_pick_partition(AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data, TokenExtra **tp, int mi_row, - int mi_col, BLOCK_SIZE bsize, RD_STATS *rd_cost, - RD_STATS best_rdc, PC_TREE *pc_tree, + int mi_col, BLOCK_SIZE bsize, +#if CONFIG_EXTENDED_SDP + PARTITION_TYPE parent_partition, +#endif // CONFIG_EXTENDED_SDP + RD_STATS *rd_cost, RD_STATS best_rdc, + PC_TREE *pc_tree, #if CONFIG_EXT_RECUR_PARTITIONS const PARTITION_TREE *ptree_luma, const PARTITION_TREE *template_tree, @@ -7380,6 +8636,13 @@ RD_SEARCH_MACROBLOCK_CONTEXT x_ctx; const TokenExtra *const tp_orig = *tp; PartitionSearchState part_search_state; + +#if CONFIG_EXTENDED_SDP + if (frame_is_intra_only(cm) && pc_tree) { + pc_tree->region_type = INTRA_REGION; + } +#endif // CONFIG_EXTENDED_SDP + // Initialization of state variables used in partition search. init_partition_search_state_params(x, cpi, &part_search_state, #if CONFIG_EXT_RECUR_PARTITIONS @@ -7402,6 +8665,7 @@ // different partition path. If yes directly copy the RDO decision made for // the counterpart. PC_TREE *counterpart_block = av1_look_for_counterpart_block(pc_tree); + assert(pc_tree != NULL); if (counterpart_block #if CONFIG_CB1TO4_SPLIT && @@ -7412,6 +8676,10 @@ ? counterpart_block->parent->block_size : BLOCK_INVALID)) #endif // CONFIG_CB1TO4_SPLIT +#if CONFIG_EXTENDED_SDP + && (pc_tree->region_type == counterpart_block->region_type && + (pc_tree->region_type != INTRA_REGION || frame_is_intra_only(cm))) +#endif // CONFIG_EXTENDED_SDP ) { if (counterpart_block->rd_cost.rate != INT_MAX) { av1_copy_pc_tree_recursive(xd, cm, pc_tree, counterpart_block, @@ -7568,7 +8836,11 @@ #if CONFIG_CB1TO4_SPLIT blk_params.parent_bsize, #endif // CONFIG_CB1TO4_SPLIT - ptree_luma, template_tree, &pc_tree->chroma_ref_info); + ptree_luma, template_tree, +#if CONFIG_EXTENDED_SDP + pc_tree->region_type, +#endif // CONFIG_EXTENDED_SDP + &pc_tree->chroma_ref_info); } #endif // CONFIG_EXT_RECUR_PARTITIONS @@ -7683,7 +8955,19 @@ #endif // CONFIG_ML_PART_SPLIT // PARTITION_NONE search stage. int64_t part_none_rd = INT64_MAX; +#if CONFIG_EXTENDED_SDP + int partition_none_allowed = 1; + if (pc_tree->parent && pc_tree->region_type == INTRA_REGION && + pc_tree->parent->region_type == MIXED_INTER_INTRA_REGION && + xd->tree_type != CHROMA_PART) + partition_none_allowed = 0; + if (!frame_is_intra_only(cm) && pc_tree->region_type == INTRA_REGION) + search_none_after_rect &= (xd->tree_type != CHROMA_PART); + if (!search_none_after_rect && !search_none_after_split && + partition_none_allowed) { +#else if (!search_none_after_rect && !search_none_after_split) { +#endif // CONFIG_EXTENDED_SDP none_partition_search(cpi, td, tile_data, x, pc_tree, sms_tree, &x_ctx, &part_search_state, &best_rdc, &pb_source_variance, none_rd, &part_none_rd @@ -7693,6 +8977,14 @@ #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK ); } +#if CONFIG_EXTENDED_SDP + if (pc_tree->parent && pc_tree->region_type == INTRA_REGION && + pc_tree->parent->region_type == MIXED_INTER_INTRA_REGION && + xd->tree_type == CHROMA_PART) { + *rd_cost = best_rdc; + return part_search_state.found_best_partition; + } +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS if (cpi->sf.part_sf.end_part_search_after_consec_failures && x->is_whole_sb && @@ -7743,17 +9035,35 @@ // after rect assert(pc_tree->partitioning == PARTITION_SPLIT); for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + const int depth = + get_partition_depth(pc_tree->split[pc_tree->region_type][idx], 0); +#else const int depth = get_partition_depth(pc_tree->split[idx], 0); +#endif // CONFIG_EXTENDED_SDP search_none_after_split &= depth == 0; } } if (cpi->sf.part_sf.prune_rect_with_split_depth && !frame_is_intra_only(cm) && part_search_state.forced_partition == PARTITION_INVALID && +#if CONFIG_EXTENDED_SDP + pc_tree->split[pc_tree->region_type][0] && + pc_tree->split[pc_tree->region_type][1] && + pc_tree->split[pc_tree->region_type][2] && + pc_tree->split[pc_tree->region_type][3] +#else pc_tree->split[0] && pc_tree->split[1] && pc_tree->split[2] && - pc_tree->split[3]) { + pc_tree->split[3] +#endif // CONFIG_EXTENDED_SDP + ) { int min_depth = INT_MAX, max_depth = 0; for (int idx = 0; idx < 4; idx++) { +#if CONFIG_EXTENDED_SDP + const int depth = + get_partition_depth(pc_tree->split[pc_tree->region_type][idx], 0); +#else const int depth = get_partition_depth(pc_tree->split[idx], 0); +#endif // CONFIG_EXTENDED_SDP min_depth = AOMMIN(min_depth, depth); max_depth = AOMMAX(max_depth, depth); } @@ -7765,6 +9075,9 @@ } if (part_search_state.forced_partition == PARTITION_INVALID && +#if CONFIG_EXTENDED_SDP + partition_none_allowed && +#endif // CONFIG_EXTENDED_SDP search_none_after_split) { none_partition_search(cpi, td, tile_data, x, pc_tree, sms_tree, &x_ctx, &part_search_state, &best_rdc, &pb_source_variance, @@ -7787,6 +9100,9 @@ #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK &level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK +#if CONFIG_EXTENDED_SDP + parent_partition, +#endif // CONFIG_INTER_SDP part_none_rd #if CONFIG_ML_PART_SPLIT , @@ -7803,7 +9119,12 @@ assert(IMPLIES(!cpi->oxcf.part_cfg.enable_rect_partitions, !part_search_state.do_rectangular_split)); #if CONFIG_EXT_RECUR_PARTITIONS +#if CONFIG_EXTENDED_SDP + if (search_none_after_rect && !search_none_after_split && + partition_none_allowed) { +#else if (search_none_after_rect && !search_none_after_split) { +#endif // CONFIG_EXTENDED_SDP prune_none_with_rect_results(&part_search_state, pc_tree); none_partition_search(cpi, td, tile_data, x, pc_tree, sms_tree, &x_ctx, &part_search_state, &best_rdc, &pb_source_variance, @@ -7918,51 +9239,63 @@ #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK multi_pass_mode, ext_recur_depth); - prune_ext_partitions_4way(cpi, pc_tree, &part_search_state, - partition_boundaries); +#if CONFIG_EXTENDED_SDP + if ((pc_tree->region_type != INTRA_REGION || frame_is_intra_only(cm))) { +#endif // CONFIG_EXTENDED_SDP + prune_ext_partitions_4way(cpi, pc_tree, &part_search_state, + partition_boundaries); - // PARTITION_HORZ_4A - search_partition_horz_4a(&part_search_state, cpi, td, tile_data, tp, - &best_rdc, pc_tree, - track_ptree_luma ? ptree_luma : NULL, template_tree, - &x_ctx, &part_search_state, + // PARTITION_HORZ_4A + search_partition_horz_4a(&part_search_state, cpi, td, tile_data, tp, + &best_rdc, pc_tree, + track_ptree_luma ? ptree_luma : NULL, + template_tree, &x_ctx, &part_search_state, #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - &level_banks, + &level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - multi_pass_mode, ext_recur_depth); + multi_pass_mode, ext_recur_depth); - // PARTITION_HORZ_4B - search_partition_horz_4b(&part_search_state, cpi, td, tile_data, tp, - &best_rdc, pc_tree, - track_ptree_luma ? ptree_luma : NULL, template_tree, - &x_ctx, &part_search_state, + // PARTITION_HORZ_4B + search_partition_horz_4b(&part_search_state, cpi, td, tile_data, tp, + &best_rdc, pc_tree, + track_ptree_luma ? ptree_luma : NULL, + template_tree, &x_ctx, &part_search_state, #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - &level_banks, + &level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - multi_pass_mode, ext_recur_depth); + multi_pass_mode, ext_recur_depth); - // PARTITION_VERT_4A - search_partition_vert_4a(&part_search_state, cpi, td, tile_data, tp, - &best_rdc, pc_tree, - track_ptree_luma ? ptree_luma : NULL, template_tree, - &x_ctx, &part_search_state, + // PARTITION_VERT_4A + search_partition_vert_4a(&part_search_state, cpi, td, tile_data, tp, + &best_rdc, pc_tree, + track_ptree_luma ? ptree_luma : NULL, + template_tree, &x_ctx, &part_search_state, #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - &level_banks, + &level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - multi_pass_mode, ext_recur_depth); + multi_pass_mode, ext_recur_depth); - // PARTITION_VERT_4B - search_partition_vert_4b(&part_search_state, cpi, td, tile_data, tp, - &best_rdc, pc_tree, - track_ptree_luma ? ptree_luma : NULL, template_tree, - &x_ctx, &part_search_state, + // PARTITION_VERT_4B + search_partition_vert_4b(&part_search_state, cpi, td, tile_data, tp, + &best_rdc, pc_tree, + track_ptree_luma ? ptree_luma : NULL, + template_tree, &x_ctx, &part_search_state, #if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - &level_banks, + &level_banks, #endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK - multi_pass_mode, ext_recur_depth); + multi_pass_mode, ext_recur_depth); +#if CONFIG_EXTENDED_SDP + } +#endif // CONFIG_EXTENDED_SDP #endif // CONFIG_EXT_RECUR_PARTITIONS - if (bsize == cm->sb_size && !part_search_state.found_best_partition) { + if (bsize == cm->sb_size && !part_search_state.found_best_partition +#if CONFIG_EXTENDED_SDP + && ((!frame_is_intra_only(cm) && + pc_tree->region_type == MIXED_INTER_INTRA_REGION) || + ((frame_is_intra_only(cm) && pc_tree->region_type == INTRA_REGION))) +#endif // CONFIG_EXTENDED_SDP + ) { if (x->must_find_valid_partition) { aom_internal_error( &cpi->common.error, AOM_CODEC_ERROR, @@ -7991,6 +9324,23 @@ } #endif // CONFIG_EXT_RECUR_PARTITIONS && !defined(NDEBUG) +#if CONFIG_EXTENDED_SDP + if (frame_is_intra_only(cm)) pc_tree->inter_sdp_allowed_flag = 0; + if (!frame_is_intra_only(cm) && + pc_tree->region_type == MIXED_INTER_INTRA_REGION && pc_tree->parent && + pc_tree->inter_sdp_allowed_flag == 1 && + is_bsize_allowed_for_inter_sdp(bsize, PARTITION_HORZ)) { + search_intra_region_partitioning( + &part_search_state, cpi, td, tile_data, tp, &best_rdc, pc_tree, + track_ptree_luma ? ptree_luma : NULL, template_tree, &x_ctx, + &part_search_state, +#if CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + &level_banks, +#endif // CONFIG_MVP_IMPROVEMENT || WARP_CU_BANK + multi_pass_mode, ext_recur_depth, parent_partition); + } +#endif // CONFIG_EXTENDED_SDP + // Store the final rd cost *rd_cost = best_rdc; #if CONFIG_MVP_IMPROVEMENT
diff --git a/av1/encoder/partition_search.h b/av1/encoder/partition_search.h index fec481c..f11aa1c 100644 --- a/av1/encoder/partition_search.h +++ b/av1/encoder/partition_search.h
@@ -34,8 +34,12 @@ PC_TREE *pc_tree); bool av1_rd_pick_partition(AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data, TokenExtra **tp, int mi_row, - int mi_col, BLOCK_SIZE bsize, RD_STATS *rd_cost, - RD_STATS best_rdc, PC_TREE *pc_tree, + int mi_col, BLOCK_SIZE bsize, +#if CONFIG_EXTENDED_SDP + PARTITION_TYPE parent_partition, +#endif // CONFIG_EXTENDED_SDP + RD_STATS *rd_cost, RD_STATS best_rdc, + PC_TREE *pc_tree, #if CONFIG_EXT_RECUR_PARTITIONS const PARTITION_TREE *ptree_luma, const PARTITION_TREE *template_tree,
diff --git a/av1/encoder/partition_strategy.c b/av1/encoder/partition_strategy.c index 853f06e..3c19b0e 100644 --- a/av1/encoder/partition_strategy.c +++ b/av1/encoder/partition_strategy.c
@@ -1467,6 +1467,18 @@ : (rect_part == PARTITION_HORZ) ? rect_part_win_info->rect_part_win[HORZ] : rect_part_win_info->rect_part_win[VERT]; num_win += (sub_part_win) ? 1 : 0; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; + if (pc_tree->split[cur_region_type][split_idx1]) { + num_win += (pc_tree->split[cur_region_type][split_idx1]->partitioning == + PARTITION_NONE); + } else { + num_win += 1; + } + if (pc_tree->split[cur_region_type][split_idx2]) { + num_win += (pc_tree->split[cur_region_type][split_idx2]->partitioning == + PARTITION_NONE); +#else if (pc_tree->split[split_idx1]) { num_win += (pc_tree->split[split_idx1]->partitioning == PARTITION_NONE) ? 1 : 0; @@ -1476,6 +1488,7 @@ if (pc_tree->split[split_idx2]) { num_win += (pc_tree->split[split_idx2]->partitioning == PARTITION_NONE) ? 1 : 0; +#endif // CONFIG_EXTENDED_SDP } else { num_win += 1; } @@ -2030,10 +2043,20 @@ // Whether we are in the middle of a PARTITION_3 subblock const PC_TREE *parent = pc_tree->parent; +#if CONFIG_EXTENDED_SDP + REGION_TYPE cur_region_type = pc_tree->region_type; + ml_features[num_features++] = + parent && (parent->horizontal3[cur_region_type][1] == pc_tree || + parent->horizontal3[cur_region_type][2] == pc_tree); + ml_features[num_features++] = + parent && (parent->vertical3[cur_region_type][1] == pc_tree || + parent->vertical3[cur_region_type][2] == pc_tree); +#else ml_features[num_features++] = parent && (parent->horizontal3[1] == pc_tree || parent->horizontal3[2] == pc_tree); ml_features[num_features++] = parent && (parent->vertical3[1] == pc_tree || parent->vertical3[2] == pc_tree); +#endif // CONFIG_EXTENDED_SDP assert(num_features == 19); }
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c index d32653b..0e71e22 100644 --- a/av1/encoder/rd.c +++ b/av1/encoder/rd.c
@@ -99,6 +99,12 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, const MACROBLOCKD *xd, ModeCosts *mode_costs, FRAME_CONTEXT *fc) { int i, j; +#if CONFIG_EXTENDED_SDP + for (i = 0; i < INTER_SDP_BSIZE_GROUP; ++i) { + av1_cost_tokens_from_cdf(mode_costs->region_type_cost[i], + fc->region_type_cdf[i], NULL); + } +#endif // CONFIG_EXTENDED_SDP #if CONFIG_EXT_RECUR_PARTITIONS for (int plane_index = (xd->tree_type == CHROMA_PART); plane_index < PARTITION_STRUCTURE_NUM; plane_index++) {
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index f2a7745..d96450b 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -6595,7 +6595,7 @@ int64_t best_rd) { const AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; - if (!av1_allow_intrabc(cm) || (xd->tree_type == CHROMA_PART) || + if (!av1_allow_intrabc(cm, xd) || (xd->tree_type == CHROMA_PART) || !cpi->oxcf.kf_cfg.enable_intrabc) return INT64_MAX; const int num_planes = av1_num_planes(cm); @@ -10584,7 +10584,7 @@ if (search_state.best_skip2 == 0) { const int try_intrabc = cpi->oxcf.kf_cfg.enable_intrabc && cpi->oxcf.kf_cfg.enable_intrabc_ext && - av1_allow_intrabc(cm) && + av1_allow_intrabc(cm, xd) && (xd->tree_type != CHROMA_PART); if (try_intrabc) { this_rd_cost.rdcost = INT64_MAX;
diff --git a/av1/encoder/reconinter_enc.c b/av1/encoder/reconinter_enc.c index eb0b368..17c6029 100644 --- a/av1/encoder/reconinter_enc.c +++ b/av1/encoder/reconinter_enc.c
@@ -358,7 +358,7 @@ #if CONFIG_MORPH_PRED if (mbmi->morph_pred) { - assert(av1_allow_intrabc(cm)); + assert(av1_allow_intrabc(cm, xd)); assert(is_intrabc_block(mbmi, xd->tree_type)); av1_build_morph_pred(cm, xd, bsize, mi_row, mi_col); }
diff --git a/av1/encoder/segmentation.c b/av1/encoder/segmentation.c index b8adb49..31d1ffc 100644 --- a/av1/encoder/segmentation.c +++ b/av1/encoder/segmentation.c
@@ -63,7 +63,11 @@ no_pred_segcounts[segment_id]++; // Temporal prediction not allowed on key frames - if (cm->current_frame.frame_type != KEY_FRAME) { + if (cm->current_frame.frame_type != KEY_FRAME +#if CONFIG_EXTENDED_SDP + && xd->mi[0]->region_type != INTRA_REGION +#endif // CONFIG_EXTENDED_SDP + ) { const BLOCK_SIZE bsize = xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART]; // Test to see if the segment id matches the predicted value. const int pred_segment_id =
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake index 6625c9b..8ced654 100644 --- a/build/cmake/aom_config_defaults.cmake +++ b/build/cmake/aom_config_defaults.cmake
@@ -197,6 +197,8 @@ "AV2 experiment flag to enable modified context derivation : CWG-B065.") set_aom_config_var(CONFIG_EXTENDED_WARP_PREDICTION 1 "AV2 experiment flag to add new local warp modes") +set_aom_config_var(CONFIG_EXTENDED_SDP 1 + "Enable SDP for intra blocks in inter frame") # Begin: CWG-C016 set_aom_config_var( CONFIG_LR_IMPROVEMENTS
diff --git a/tools/aom_entropy_optimizer.c b/tools/aom_entropy_optimizer.c index f88324a..d53937e 100644 --- a/tools/aom_entropy_optimizer.c +++ b/tools/aom_entropy_optimizer.c
@@ -620,6 +620,15 @@ "[CCTX_CONTEXTS][CDF_SIZE(CCTX_TYPES)]", 0, &total_count, 0, mem_wanted, "Transforms"); +#if CONFIG_INTER_SDP + cts_each_dim[0] = INTER_SDP_BSIZE_GROUP; + cts_each_dim[1] = REGION_TYPES; + optimize_cdf_table(&fc.region_type[0][0], probsfile, 2, cts_each_dim, + "static aom_cdf_prob default_region_type_cdf" + "[INTER_SDP_BSIZE_GROUP][CDF_SIZE(2)]", + 0, &total_count, 0, mem_wanted, "Partitions"); +#endif // CONFIG_INTER_SDP + #if CONFIG_EXT_RECUR_PARTITIONS cts_each_dim[0] = PARTITION_STRUCTURE_NUM; cts_each_dim[1] = PARTITION_CONTEXTS;