diff options
Diffstat (limited to 'third_party/aom/av1/common/blockd.h')
-rw-r--r-- | third_party/aom/av1/common/blockd.h | 1538 |
1 files changed, 477 insertions, 1061 deletions
diff --git a/third_party/aom/av1/common/blockd.h b/third_party/aom/av1/common/blockd.h index 01a449a1c..3e8d1d6c6 100644 --- a/third_party/aom/av1/common/blockd.h +++ b/third_party/aom/av1/common/blockd.h @@ -12,7 +12,7 @@ #ifndef AV1_COMMON_BLOCKD_H_ #define AV1_COMMON_BLOCKD_H_ -#include "./aom_config.h" +#include "config/aom_config.h" #include "aom_dsp/aom_dsp_common.h" #include "aom_ports/mem.h" @@ -26,104 +26,40 @@ #include "av1/common/scale.h" #include "av1/common/seg_common.h" #include "av1/common/tile_common.h" -#if CONFIG_PVQ -#include "av1/common/pvq.h" -#include "av1/common/pvq_state.h" -#include "av1/decoder/decint.h" -#endif + #ifdef __cplusplus extern "C" { #endif -#if (CONFIG_CHROMA_SUB8X8 || CONFIG_CHROMA_2X2) -#define SUB8X8_COMP_REF 0 -#else -#define SUB8X8_COMP_REF 1 -#endif +#define USE_B_QUANT_NO_TRELLIS 1 #define MAX_MB_PLANE 3 -#if CONFIG_COMPOUND_SEGMENT -// Set COMPOUND_SEGMENT_TYPE to one of the three -// 0: Uniform -// 1: Difference weighted -#define COMPOUND_SEGMENT_TYPE 1 -#define MAX_SEG_MASK_BITS 1 +#define MAX_DIFFWTD_MASK_BITS 1 -// SEG_MASK_TYPES should not surpass 1 << MAX_SEG_MASK_BITS +// DIFFWTD_MASK_TYPES should not surpass 1 << MAX_DIFFWTD_MASK_BITS typedef enum { -#if COMPOUND_SEGMENT_TYPE == 0 - UNIFORM_45 = 0, - UNIFORM_45_INV, -#elif COMPOUND_SEGMENT_TYPE == 1 DIFFWTD_38 = 0, DIFFWTD_38_INV, -#endif // COMPOUND_SEGMENT_TYPE - SEG_MASK_TYPES, -} SEG_MASK_TYPE; - -#endif // CONFIG_COMPOUND_SEGMENT + DIFFWTD_MASK_TYPES, +} DIFFWTD_MASK_TYPE; typedef enum { KEY_FRAME = 0, INTER_FRAME = 1, -#if CONFIG_OBU INTRA_ONLY_FRAME = 2, // replaces intra-only S_FRAME = 3, -#endif FRAME_TYPES, } FRAME_TYPE; static INLINE int is_comp_ref_allowed(BLOCK_SIZE bsize) { - (void)bsize; -#if SUB8X8_COMP_REF - return 1; -#else return AOMMIN(block_size_wide[bsize], block_size_high[bsize]) >= 8; -#endif // SUB8X8_COMP_REF } static INLINE int is_inter_mode(PREDICTION_MODE mode) { return mode >= NEARESTMV && mode <= NEW_NEWMV; } -#if CONFIG_PVQ -typedef struct PVQ_INFO { - int theta[PVQ_MAX_PARTITIONS]; - int qg[PVQ_MAX_PARTITIONS]; - int k[PVQ_MAX_PARTITIONS]; - od_coeff y[OD_TXSIZE_MAX * OD_TXSIZE_MAX]; - int nb_bands; - int off[PVQ_MAX_PARTITIONS]; - int size[PVQ_MAX_PARTITIONS]; - int skip_rest; - int skip_dir; - int bs; // log of the block size minus two, - // i.e. equivalent to aom's TX_SIZE - // Block skip info, indicating whether DC/AC, is coded. - PVQ_SKIP_TYPE ac_dc_coded; // bit0: DC coded, bit1 : AC coded (1 means coded) - tran_low_t dq_dc_residue; -} PVQ_INFO; - -typedef struct PVQ_QUEUE { - PVQ_INFO *buf; // buffer for pvq info, stored in encoding order - int curr_pos; // curr position to write PVQ_INFO - int buf_len; // allocated buffer length - int last_pos; // last written position of PVQ_INFO in a tile -} PVQ_QUEUE; -#endif - -#if CONFIG_NCOBMC_ADAPT_WEIGHT -typedef struct superblock_mi_boundaries { - int mi_row_begin; - int mi_col_begin; - int mi_row_end; - int mi_col_end; -} SB_MI_BD; - -typedef struct { int16_t KERNEL[4][MAX_SB_SIZE][MAX_SB_SIZE]; } NCOBMC_KERNELS; -#endif - typedef struct { uint8_t *plane[MAX_MB_PLANE]; int stride[MAX_MB_PLANE]; @@ -135,14 +71,6 @@ static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) { static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) { return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV; } -#if CONFIG_COMPOUND_SINGLEREF -static INLINE int is_inter_singleref_comp_mode(PREDICTION_MODE mode) { - return mode >= SR_NEAREST_NEARMV && mode <= SR_NEW_NEWMV; -} -static INLINE int is_inter_anyref_comp_mode(PREDICTION_MODE mode) { - return is_inter_compound_mode(mode) || is_inter_singleref_comp_mode(mode); -} -#endif // CONFIG_COMPOUND_SINGLEREF static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) { static PREDICTION_MODE lut[] = { @@ -151,42 +79,29 @@ static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) { MB_MODE_COUNT, // H_PRED MB_MODE_COUNT, // D45_PRED MB_MODE_COUNT, // D135_PRED - MB_MODE_COUNT, // D117_PRED - MB_MODE_COUNT, // D153_PRED - MB_MODE_COUNT, // D207_PRED - MB_MODE_COUNT, // D63_PRED + MB_MODE_COUNT, // D113_PRED + MB_MODE_COUNT, // D157_PRED + MB_MODE_COUNT, // D203_PRED + MB_MODE_COUNT, // D67_PRED MB_MODE_COUNT, // SMOOTH_PRED -#if CONFIG_SMOOTH_HV MB_MODE_COUNT, // SMOOTH_V_PRED MB_MODE_COUNT, // SMOOTH_H_PRED -#endif // CONFIG_SMOOTH_HV - MB_MODE_COUNT, // TM_PRED + MB_MODE_COUNT, // PAETH_PRED MB_MODE_COUNT, // NEARESTMV MB_MODE_COUNT, // NEARMV - MB_MODE_COUNT, // ZEROMV + MB_MODE_COUNT, // GLOBALMV MB_MODE_COUNT, // NEWMV -#if CONFIG_COMPOUND_SINGLEREF - NEARESTMV, // SR_NEAREST_NEARMV - // NEARESTMV, // SR_NEAREST_NEWMV - NEARMV, // SR_NEAR_NEWMV - ZEROMV, // SR_ZERO_NEWMV - NEWMV, // SR_NEW_NEWMV -#endif // CONFIG_COMPOUND_SINGLEREF - NEARESTMV, // NEAREST_NEARESTMV - NEARMV, // NEAR_NEARMV - NEARESTMV, // NEAREST_NEWMV - NEWMV, // NEW_NEARESTMV - NEARMV, // NEAR_NEWMV - NEWMV, // NEW_NEARMV - ZEROMV, // ZERO_ZEROMV - NEWMV, // NEW_NEWMV + NEARESTMV, // NEAREST_NEARESTMV + NEARMV, // NEAR_NEARMV + NEARESTMV, // NEAREST_NEWMV + NEWMV, // NEW_NEARESTMV + NEARMV, // NEAR_NEWMV + NEWMV, // NEW_NEARMV + GLOBALMV, // GLOBAL_GLOBALMV + NEWMV, // NEW_NEWMV }; assert(NELEMENTS(lut) == MB_MODE_COUNT); -#if CONFIG_COMPOUND_SINGLEREF - assert(is_inter_anyref_comp_mode(mode)); -#else // !CONFIG_COMPOUND_SINGLEREF assert(is_inter_compound_mode(mode)); -#endif // CONFIG_COMPOUND_SINGLEREF return lut[mode]; } @@ -197,94 +112,54 @@ static INLINE PREDICTION_MODE compound_ref1_mode(PREDICTION_MODE mode) { MB_MODE_COUNT, // H_PRED MB_MODE_COUNT, // D45_PRED MB_MODE_COUNT, // D135_PRED - MB_MODE_COUNT, // D117_PRED - MB_MODE_COUNT, // D153_PRED - MB_MODE_COUNT, // D207_PRED - MB_MODE_COUNT, // D63_PRED + MB_MODE_COUNT, // D113_PRED + MB_MODE_COUNT, // D157_PRED + MB_MODE_COUNT, // D203_PRED + MB_MODE_COUNT, // D67_PRED MB_MODE_COUNT, // SMOOTH_PRED -#if CONFIG_SMOOTH_HV MB_MODE_COUNT, // SMOOTH_V_PRED MB_MODE_COUNT, // SMOOTH_H_PRED -#endif // CONFIG_SMOOTH_HV - MB_MODE_COUNT, // TM_PRED + MB_MODE_COUNT, // PAETH_PRED MB_MODE_COUNT, // NEARESTMV MB_MODE_COUNT, // NEARMV - MB_MODE_COUNT, // ZEROMV + MB_MODE_COUNT, // GLOBALMV MB_MODE_COUNT, // NEWMV -#if CONFIG_COMPOUND_SINGLEREF - NEARMV, // SR_NEAREST_NEARMV - // NEWMV, // SR_NEAREST_NEWMV - NEWMV, // SR_NEAR_NEWMV - NEWMV, // SR_ZERO_NEWMV - NEWMV, // SR_NEW_NEWMV -#endif // CONFIG_COMPOUND_SINGLEREF - NEARESTMV, // NEAREST_NEARESTMV - NEARMV, // NEAR_NEARMV - NEWMV, // NEAREST_NEWMV - NEARESTMV, // NEW_NEARESTMV - NEWMV, // NEAR_NEWMV - NEARMV, // NEW_NEARMV - ZEROMV, // ZERO_ZEROMV - NEWMV, // NEW_NEWMV + NEARESTMV, // NEAREST_NEARESTMV + NEARMV, // NEAR_NEARMV + NEWMV, // NEAREST_NEWMV + NEARESTMV, // NEW_NEARESTMV + NEWMV, // NEAR_NEWMV + NEARMV, // NEW_NEARMV + GLOBALMV, // GLOBAL_GLOBALMV + NEWMV, // NEW_NEWMV }; assert(NELEMENTS(lut) == MB_MODE_COUNT); -#if CONFIG_COMPOUND_SINGLEREF - assert(is_inter_anyref_comp_mode(mode)); -#else // !CONFIG_COMPOUND_SINGLEREF assert(is_inter_compound_mode(mode)); -#endif // CONFIG_COMPOUND_SINGLEREF return lut[mode]; } static INLINE int have_nearmv_in_inter_mode(PREDICTION_MODE mode) { return (mode == NEARMV || mode == NEAR_NEARMV || mode == NEAR_NEWMV || -#if CONFIG_COMPOUND_SINGLEREF - mode == SR_NEAREST_NEARMV || mode == SR_NEAR_NEWMV || -#endif // CONFIG_COMPOUND_SINGLEREF mode == NEW_NEARMV); } static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) { return (mode == NEWMV || mode == NEW_NEWMV || mode == NEAREST_NEWMV || -#if CONFIG_COMPOUND_SINGLEREF - /* mode == SR_NEAREST_NEWMV || */ mode == SR_NEAR_NEWMV || - mode == SR_ZERO_NEWMV || mode == SR_NEW_NEWMV || -#endif // CONFIG_COMPOUND_SINGLEREF mode == NEW_NEARESTMV || mode == NEAR_NEWMV || mode == NEW_NEARMV); } static INLINE int use_masked_motion_search(COMPOUND_TYPE type) { -#if CONFIG_WEDGE return (type == COMPOUND_WEDGE); -#else - (void)type; - return 0; -#endif } static INLINE int is_masked_compound_type(COMPOUND_TYPE type) { -#if CONFIG_COMPOUND_SEGMENT && CONFIG_WEDGE - return (type == COMPOUND_WEDGE || type == COMPOUND_SEG); -#elif !CONFIG_COMPOUND_SEGMENT && CONFIG_WEDGE - return (type == COMPOUND_WEDGE); -#elif CONFIG_COMPOUND_SEGMENT && !CONFIG_WEDGE - return (type == COMPOUND_SEG); -#endif // CONFIG_COMPOUND_SEGMENT - (void)type; - return 0; + return (type == COMPOUND_WEDGE || type == COMPOUND_DIFFWTD); } /* For keyframes, intra block modes are predicted by the (already decoded) modes for the Y blocks to the left and above us; for interframes, there is a single probability table. */ -typedef struct { - PREDICTION_MODE as_mode; - int_mv as_mv[2]; // first, second inter predictor motion vectors - int_mv pred_mv[2]; - int_mv ref_mv[2]; -} b_mode_info; - typedef int8_t MV_REFERENCE_FRAME; typedef struct { @@ -294,19 +169,17 @@ typedef struct { uint16_t palette_colors[3 * PALETTE_MAX_SIZE]; } PALETTE_MODE_INFO; -#if CONFIG_FILTER_INTRA -#define USE_3TAP_INTRA_FILTER 1 // 0: 4-tap; 1: 3-tap typedef struct { - // 1: an ext intra mode is used; 0: otherwise. - uint8_t use_filter_intra_mode[PLANE_TYPES]; - FILTER_INTRA_MODE filter_intra_mode[PLANE_TYPES]; + uint8_t use_filter_intra; + FILTER_INTRA_MODE filter_intra_mode; } FILTER_INTRA_MODE_INFO; -#endif // CONFIG_FILTER_INTRA -#if CONFIG_VAR_TX +static const PREDICTION_MODE fimode_to_intradir[FILTER_INTRA_MODES] = { + DC_PRED, V_PRED, H_PRED, D157_PRED, DC_PRED +}; + #if CONFIG_RD_DEBUG -#define TXB_COEFF_COST_MAP_SIZE (2 * MAX_MIB_SIZE) -#endif +#define TXB_COEFF_COST_MAP_SIZE (MAX_MIB_SIZE) #endif typedef struct RD_STATS { @@ -325,213 +198,122 @@ typedef struct RD_STATS { uint8_t invalid_rate; #if CONFIG_RD_DEBUG int txb_coeff_cost[MAX_MB_PLANE]; -#if CONFIG_VAR_TX int txb_coeff_cost_map[MAX_MB_PLANE][TXB_COEFF_COST_MAP_SIZE] [TXB_COEFF_COST_MAP_SIZE]; -#endif // CONFIG_VAR_TX #endif // CONFIG_RD_DEBUG } RD_STATS; // This struct is used to group function args that are commonly // sent together in functions related to interinter compound modes typedef struct { -#if CONFIG_WEDGE int wedge_index; int wedge_sign; -#endif // CONFIG_WEDGE -#if CONFIG_COMPOUND_SEGMENT - SEG_MASK_TYPE mask_type; + DIFFWTD_MASK_TYPE mask_type; uint8_t *seg_mask; -#endif // CONFIG_COMPOUND_SEGMENT - COMPOUND_TYPE interinter_compound_type; + COMPOUND_TYPE type; } INTERINTER_COMPOUND_DATA; -// This structure now relates to 8x8 block regions. +#define INTER_TX_SIZE_BUF_LEN 16 +#define TXK_TYPE_BUF_LEN 64 +// This structure now relates to 4x4 block regions. typedef struct MB_MODE_INFO { // Common for both INTER and INTRA blocks BLOCK_SIZE sb_type; PREDICTION_MODE mode; TX_SIZE tx_size; -#if CONFIG_VAR_TX - // TODO(jingning): This effectively assigned a separate entry for each - // 8x8 block. Apparently it takes much more space than needed. - TX_SIZE inter_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE]; - TX_SIZE min_tx_size; -#endif + uint8_t inter_tx_size[INTER_TX_SIZE_BUF_LEN]; int8_t skip; + int8_t skip_mode; int8_t segment_id; -#if CONFIG_SUPERTX - // Minimum of all segment IDs under the current supertx block. - int8_t segment_id_supertx; -#endif // CONFIG_SUPERTX int8_t seg_id_predicted; // valid only when temporal_update is enabled -#if CONFIG_MRC_TX - int valid_mrc_mask; -#endif // CONFIG_MRC_TX - // Only for INTRA blocks UV_PREDICTION_MODE uv_mode; PALETTE_MODE_INFO palette_mode_info; -#if CONFIG_INTRABC uint8_t use_intrabc; -#endif // CONFIG_INTRABC // Only for INTER blocks InterpFilters interp_filters; MV_REFERENCE_FRAME ref_frame[2]; - TX_TYPE tx_type; -#if CONFIG_TXK_SEL - TX_TYPE txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)]; -#endif -#if CONFIG_LGT_FROM_PRED - int use_lgt; -#endif -#if CONFIG_FILTER_INTRA + TX_TYPE txk_type[TXK_TYPE_BUF_LEN]; + FILTER_INTRA_MODE_INFO filter_intra_mode_info; -#endif // CONFIG_FILTER_INTRA -#if CONFIG_EXT_INTRA + // The actual prediction angle is the base angle + (angle_delta * step). - int8_t angle_delta[2]; -#if CONFIG_INTRA_INTERP - // To-Do (huisu): this may be replaced by interp_filter - INTRA_FILTER intra_filter; -#endif // CONFIG_INTRA_INTERP -#endif // CONFIG_EXT_INTRA - -#if CONFIG_INTERINTRA + int8_t angle_delta[PLANE_TYPES]; + // interintra members INTERINTRA_MODE interintra_mode; -#endif // TODO(debargha): Consolidate these flags int use_wedge_interintra; int interintra_wedge_index; int interintra_wedge_sign; // interinter members - COMPOUND_TYPE interinter_compound_type; -#if CONFIG_WEDGE - int wedge_index; - int wedge_sign; -#endif // CONFIG_WEDGE -#if CONFIG_COMPOUND_SEGMENT - SEG_MASK_TYPE mask_type; -#endif // CONFIG_COMPOUND_SEGMENT + INTERINTER_COMPOUND_DATA interinter_comp; MOTION_MODE motion_mode; -#if CONFIG_MOTION_VAR int overlappable_neighbors[2]; -#if CONFIG_NCOBMC_ADAPT_WEIGHT - // Applying different weighting kernels in ncobmc - // In current implementation, interpolation modes only defined for squared - // blocks. A rectangular block is divided into two squared blocks and each - // squared block has an interpolation mode. - NCOBMC_MODE ncobmc_mode[2]; -#endif // CONFIG_NCOBMC_ADAPT_WEIGHT -#endif // CONFIG_MOTION_VAR int_mv mv[2]; - int_mv pred_mv[2]; uint8_t ref_mv_idx; -#if CONFIG_EXT_PARTITION_TYPES PARTITION_TYPE partition; -#endif -#if CONFIG_NEW_QUANT - int dq_off_index; - int send_dq_bit; -#endif // CONFIG_NEW_QUANT /* deringing gain *per-superblock* */ int8_t cdef_strength; - int current_q_index; -#if CONFIG_EXT_DELTA_Q - int current_delta_lf_from_base; -#if CONFIG_LOOPFILTER_LEVEL - int curr_delta_lf[FRAME_LF_COUNT]; -#endif // CONFIG_LOOPFILTER_LEVEL -#endif + int current_qindex; + int delta_lf_from_base; + int delta_lf[FRAME_LF_COUNT]; #if CONFIG_RD_DEBUG RD_STATS rd_stats; int mi_row; int mi_col; #endif -#if CONFIG_WARPED_MOTION int num_proj_ref[2]; WarpedMotionParams wm_params[2]; -#endif // CONFIG_WARPED_MOTION -#if CONFIG_CFL // Index of the alpha Cb and alpha Cr combination int cfl_alpha_idx; // Joint sign of alpha Cb and alpha Cr int cfl_alpha_signs; -#endif - BOUNDARY_TYPE boundary_info; -#if CONFIG_LPF_SB - uint8_t filt_lvl; - int reuse_sb_lvl; - int sign; - int delta; -#endif + int compound_idx; + int comp_group_idx; } MB_MODE_INFO; -typedef struct MODE_INFO { - MB_MODE_INFO mbmi; - b_mode_info bmi[4]; -} MODE_INFO; - -#if CONFIG_INTRABC static INLINE int is_intrabc_block(const MB_MODE_INFO *mbmi) { return mbmi->use_intrabc; } -#endif - -static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) { -#if CONFIG_CB4X4 - (void)block; - return mi->mbmi.mode; -#else - return mi->mbmi.sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode : mi->mbmi.mode; -#endif -} -#if CONFIG_CFL static INLINE PREDICTION_MODE get_uv_mode(UV_PREDICTION_MODE mode) { - static const PREDICTION_MODE uv2y[UV_INTRA_MODES] = { - DC_PRED, // UV_DC_PRED - V_PRED, // UV_V_PRED - H_PRED, // UV_H_PRED - D45_PRED, // UV_D45_PRED - D135_PRED, // UV_D135_PRED - D117_PRED, // UV_D117_PRED - D153_PRED, // UV_D153_PRED - D207_PRED, // UV_D207_PRED - D63_PRED, // UV_D63_PRED - SMOOTH_PRED, // UV_SMOOTH_PRED -#if CONFIG_SMOOTH_HV + assert(mode < UV_INTRA_MODES); + static const PREDICTION_MODE uv2y[] = { + DC_PRED, // UV_DC_PRED + V_PRED, // UV_V_PRED + H_PRED, // UV_H_PRED + D45_PRED, // UV_D45_PRED + D135_PRED, // UV_D135_PRED + D113_PRED, // UV_D113_PRED + D157_PRED, // UV_D157_PRED + D203_PRED, // UV_D203_PRED + D67_PRED, // UV_D67_PRED + SMOOTH_PRED, // UV_SMOOTH_PRED SMOOTH_V_PRED, // UV_SMOOTH_V_PRED SMOOTH_H_PRED, // UV_SMOOTH_H_PRED -#endif // CONFIG_SMOOTH_HV - TM_PRED, // UV_TM_PRED - DC_PRED, // CFL_PRED + PAETH_PRED, // UV_PAETH_PRED + DC_PRED, // UV_CFL_PRED + INTRA_INVALID, // UV_INTRA_MODES + INTRA_INVALID, // UV_MODE_INVALID }; return uv2y[mode]; } -#else -static INLINE PREDICTION_MODE get_uv_mode(PREDICTION_MODE mode) { return mode; } -#endif // CONFIG_CFL static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) { -#if CONFIG_INTRABC - if (is_intrabc_block(mbmi)) return 1; -#endif - return mbmi->ref_frame[0] > INTRA_FRAME; + return is_intrabc_block(mbmi) || mbmi->ref_frame[0] > INTRA_FRAME; } static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) { return mbmi->ref_frame[1] > INTRA_FRAME; } -#if CONFIG_EXT_COMP_REFS static INLINE int has_uni_comp_refs(const MB_MODE_INFO *mbmi) { return has_second_ref(mbmi) && (!((mbmi->ref_frame[0] >= BWDREF_FRAME) ^ (mbmi->ref_frame[1] >= BWDREF_FRAME))); @@ -539,48 +321,60 @@ static INLINE int has_uni_comp_refs(const MB_MODE_INFO *mbmi) { static INLINE MV_REFERENCE_FRAME comp_ref0(int ref_idx) { static const MV_REFERENCE_FRAME lut[] = { - LAST_FRAME, // LAST_LAST2_FRAMES, - LAST_FRAME, // LAST_LAST3_FRAMES, - LAST_FRAME, // LAST_GOLDEN_FRAMES, - BWDREF_FRAME, // BWDREF_ALTREF_FRAMES, + LAST_FRAME, // LAST_LAST2_FRAMES, + LAST_FRAME, // LAST_LAST3_FRAMES, + LAST_FRAME, // LAST_GOLDEN_FRAMES, + BWDREF_FRAME, // BWDREF_ALTREF_FRAMES, + LAST2_FRAME, // LAST2_LAST3_FRAMES + LAST2_FRAME, // LAST2_GOLDEN_FRAMES, + LAST3_FRAME, // LAST3_GOLDEN_FRAMES, + BWDREF_FRAME, // BWDREF_ALTREF2_FRAMES, + ALTREF2_FRAME, // ALTREF2_ALTREF_FRAMES, }; - assert(NELEMENTS(lut) == UNIDIR_COMP_REFS); + assert(NELEMENTS(lut) == TOTAL_UNIDIR_COMP_REFS); return lut[ref_idx]; } static INLINE MV_REFERENCE_FRAME comp_ref1(int ref_idx) { static const MV_REFERENCE_FRAME lut[] = { - LAST2_FRAME, // LAST_LAST2_FRAMES, - LAST3_FRAME, // LAST_LAST3_FRAMES, - GOLDEN_FRAME, // LAST_GOLDEN_FRAMES, - ALTREF_FRAME, // BWDREF_ALTREF_FRAMES, + LAST2_FRAME, // LAST_LAST2_FRAMES, + LAST3_FRAME, // LAST_LAST3_FRAMES, + GOLDEN_FRAME, // LAST_GOLDEN_FRAMES, + ALTREF_FRAME, // BWDREF_ALTREF_FRAMES, + LAST3_FRAME, // LAST2_LAST3_FRAMES + GOLDEN_FRAME, // LAST2_GOLDEN_FRAMES, + GOLDEN_FRAME, // LAST3_GOLDEN_FRAMES, + ALTREF2_FRAME, // BWDREF_ALTREF2_FRAMES, + ALTREF_FRAME, // ALTREF2_ALTREF_FRAMES, }; - assert(NELEMENTS(lut) == UNIDIR_COMP_REFS); + assert(NELEMENTS(lut) == TOTAL_UNIDIR_COMP_REFS); return lut[ref_idx]; } -#endif // CONFIG_EXT_COMP_REFS -PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *left_mi, int b); +PREDICTION_MODE av1_left_block_mode(const MB_MODE_INFO *left_mi); -PREDICTION_MODE av1_above_block_mode(const MODE_INFO *cur_mi, - const MODE_INFO *above_mi, int b); +PREDICTION_MODE av1_above_block_mode(const MB_MODE_INFO *above_mi); -#if CONFIG_GLOBAL_MOTION -static INLINE int is_global_mv_block(const MODE_INFO *mi, int block, +static INLINE int is_global_mv_block(const MB_MODE_INFO *const mbmi, TransformationType type) { - PREDICTION_MODE mode = get_y_mode(mi, block); -#if GLOBAL_SUB8X8_USED - const int block_size_allowed = 1; -#else - const BLOCK_SIZE bsize = mi->mbmi.sb_type; + const PREDICTION_MODE mode = mbmi->mode; + const BLOCK_SIZE bsize = mbmi->sb_type; const int block_size_allowed = AOMMIN(block_size_wide[bsize], block_size_high[bsize]) >= 8; -#endif // GLOBAL_SUB8X8_USED - return (mode == ZEROMV || mode == ZERO_ZEROMV) && type > TRANSLATION && + return (mode == GLOBALMV || mode == GLOBAL_GLOBALMV) && type > TRANSLATION && block_size_allowed; } -#endif // CONFIG_GLOBAL_MOTION + +#if CONFIG_MISMATCH_DEBUG +static INLINE void mi_to_pixel_loc(int *pixel_c, int *pixel_r, int mi_col, + int mi_row, int tx_blk_col, int tx_blk_row, + int subsampling_x, int subsampling_y) { + *pixel_c = ((mi_col >> subsampling_x) << MI_SIZE_LOG2) + + (tx_blk_col << tx_size_wide_log2[0]); + *pixel_r = ((mi_row >> subsampling_y) << MI_SIZE_LOG2) + + (tx_blk_row << tx_size_high_log2[0]); +} +#endif enum mv_precision { MV_PRECISION_Q3, MV_PRECISION_Q4 }; @@ -592,8 +386,22 @@ struct buf_2d { int stride; }; +typedef struct eob_info { + uint16_t eob; + uint16_t max_scan_line; +} eob_info; + +typedef struct { + DECLARE_ALIGNED(32, tran_low_t, dqcoeff[MAX_MB_PLANE][MAX_SB_SQUARE]); + eob_info eob_data[MAX_MB_PLANE] + [MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)]; + DECLARE_ALIGNED(16, uint8_t, color_index_map[2][MAX_SB_SQUARE]); +} CB_BUFFER; + typedef struct macroblockd_plane { tran_low_t *dqcoeff; + tran_low_t *dqcoeff_block; + eob_info *eob_data; PLANE_TYPE plane_type; int subsampling_x; int subsampling_y; @@ -601,56 +409,36 @@ typedef struct macroblockd_plane { struct buf_2d pre[2]; ENTROPY_CONTEXT *above_context; ENTROPY_CONTEXT *left_context; - int16_t seg_dequant[MAX_SEGMENTS][2]; -#if CONFIG_NEW_QUANT - dequant_val_type_nuq seg_dequant_nuq[MAX_SEGMENTS][QUANT_PROFILES] - [COEF_BANDS]; -#endif + + // The dequantizers below are true dequntizers used only in the + // dequantization process. They have the same coefficient + // shift/scale as TX. + int16_t seg_dequant_QTX[MAX_SEGMENTS][2]; uint8_t *color_index_map; - // number of 4x4s in current block - uint16_t n4_w, n4_h; - // log2 of n4_w, n4_h - uint8_t n4_wl, n4_hl; // block size in pixels uint8_t width, height; -#if CONFIG_AOM_QM - qm_val_t *seg_iqmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL]; - qm_val_t *seg_qmatrix[MAX_SEGMENTS][2][TX_SIZES_ALL]; -#endif - // encoder - const int16_t *dequant; -#if CONFIG_NEW_QUANT - const dequant_val_type_nuq *dequant_val_nuq[QUANT_PROFILES]; -#endif // CONFIG_NEW_QUANT - -#if CONFIG_PVQ || CONFIG_DIST_8X8 - DECLARE_ALIGNED(16, int16_t, pred[MAX_SB_SQUARE]); -#endif -#if CONFIG_PVQ - // PVQ: forward transformed predicted image, a reference for PVQ. - tran_low_t *pvq_ref_coeff; -#endif + qm_val_t *seg_iqmatrix[MAX_SEGMENTS][TX_SIZES_ALL]; + qm_val_t *seg_qmatrix[MAX_SEGMENTS][TX_SIZES_ALL]; + + // the 'dequantizers' below are not literal dequantizer values. + // They're used by encoder RDO to generate ad-hoc lambda values. + // They use a hardwired Q3 coeff shift and do not necessarily match + // the TX scale in use. + const int16_t *dequant_Q3; } MACROBLOCKD_PLANE; #define BLOCK_OFFSET(x, i) \ ((x) + (i) * (1 << (tx_size_wide_log2[0] + tx_size_high_log2[0]))) typedef struct RefBuffer { - int idx; + int idx; // frame buf idx + int map_idx; // frame map idx YV12_BUFFER_CONFIG *buf; struct scale_factors sf; -#if CONFIG_VAR_REFS - int is_valid; -#endif // CONFIG_VAR_REFS } RefBuffer; -#if CONFIG_ADAPT_SCAN -typedef int16_t EobThresholdMD[TX_TYPES][EOB_THRESHOLD_NUM]; -#endif - -#if CONFIG_LOOP_RESTORATION typedef struct { DECLARE_ALIGNED(16, InterpKernel, vfilter); DECLARE_ALIGNED(16, InterpKernel, hfilter); @@ -660,77 +448,75 @@ typedef struct { int ep; int xqd[2]; } SgrprojInfo; -#endif // CONFIG_LOOP_RESTORATION -#if CONFIG_CFL -#if CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG +#if CONFIG_DEBUG #define CFL_SUB8X8_VAL_MI_SIZE (4) #define CFL_SUB8X8_VAL_MI_SQUARE \ (CFL_SUB8X8_VAL_MI_SIZE * CFL_SUB8X8_VAL_MI_SIZE) -#endif // CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG +#endif // CONFIG_DEBUG +#define CFL_MAX_BLOCK_SIZE (BLOCK_32X32) +#define CFL_BUF_LINE (32) +#define CFL_BUF_LINE_I128 (CFL_BUF_LINE >> 3) +#define CFL_BUF_LINE_I256 (CFL_BUF_LINE >> 4) +#define CFL_BUF_SQUARE (CFL_BUF_LINE * CFL_BUF_LINE) typedef struct cfl_ctx { - // The CfL prediction buffer is used in two steps: - // 1. Stores Q3 reconstructed luma pixels - // (only Q2 is required, but Q3 is used to avoid shifts) - // 2. Stores Q3 AC contributions (step1 - tx block avg) - int16_t pred_buf_q3[MAX_SB_SQUARE]; + // Q3 reconstructed luma pixels (only Q2 is required, but Q3 is used to avoid + // shifts) + uint16_t recon_buf_q3[CFL_BUF_SQUARE]; + // Q3 AC contributions (reconstructed luma pixels - tx block avg) + int16_t ac_buf_q3[CFL_BUF_SQUARE]; + + // Cache the DC_PRED when performing RDO, so it does not have to be recomputed + // for every scaling parameter + int dc_pred_is_cached[CFL_PRED_PLANES]; + // The DC_PRED cache is disable when decoding + int use_dc_pred_cache; + // Only cache the first row of the DC_PRED + int16_t dc_pred_cache[CFL_PRED_PLANES][CFL_BUF_LINE]; // Height and width currently used in the CfL prediction buffer. int buf_height, buf_width; - // Height and width of the chroma prediction block currently associated with - // this context - int uv_height, uv_width; - int are_parameters_computed; // Chroma subsampling int subsampling_x, subsampling_y; - // Block level DC_PRED for each chromatic plane - int dc_pred[CFL_PRED_PLANES]; - int mi_row, mi_col; // Whether the reconstructed luma pixels need to be stored int store_y; -#if CONFIG_CB4X4 +#if CONFIG_DEBUG + int rate; +#endif // CONFIG_DEBUG + int is_chroma_reference; -#if CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG - // The prediction used for sub8x8 blocks originates from multiple luma blocks, - // this array is used to validate that cfl_store() is called only once for - // each luma block - uint8_t sub8x8_val[CFL_SUB8X8_VAL_MI_SQUARE]; -#endif // CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG -#endif // CONFIG_CB4X4 } CFL_CTX; -#endif // CONFIG_CFL + +typedef struct jnt_comp_params { + int use_jnt_comp_avg; + int fwd_offset; + int bck_offset; +} JNT_COMP_PARAMS; typedef struct macroblockd { struct macroblockd_plane plane[MAX_MB_PLANE]; - uint8_t bmode_blocks_wl; - uint8_t bmode_blocks_hl; - FRAME_COUNTS *counts; TileInfo tile; int mi_stride; - MODE_INFO **mi; - MODE_INFO *left_mi; - MODE_INFO *above_mi; + MB_MODE_INFO **mi; MB_MODE_INFO *left_mbmi; MB_MODE_INFO *above_mbmi; + MB_MODE_INFO *chroma_left_mbmi; + MB_MODE_INFO *chroma_above_mbmi; int up_available; int left_available; -#if CONFIG_CHROMA_SUB8X8 int chroma_up_available; int chroma_left_available; -#endif - - const aom_prob (*partition_probs)[PARTITION_TYPES - 1]; /* Distance of MB away from frame edges in subpixels (1/8th pixel) */ int mb_to_left_edge; @@ -738,40 +524,24 @@ typedef struct macroblockd { int mb_to_top_edge; int mb_to_bottom_edge; - FRAME_CONTEXT *fc; - /* pointers to reference frames */ const RefBuffer *block_refs[2]; /* pointer to current frame */ const YV12_BUFFER_CONFIG *cur_buf; -#if CONFIG_INTRABC - /* Scale of the current frame with respect to itself */ - struct scale_factors sf_identity; -#endif - ENTROPY_CONTEXT *above_context[MAX_MB_PLANE]; - ENTROPY_CONTEXT left_context[MAX_MB_PLANE][2 * MAX_MIB_SIZE]; + ENTROPY_CONTEXT left_context[MAX_MB_PLANE][MAX_MIB_SIZE]; PARTITION_CONTEXT *above_seg_context; PARTITION_CONTEXT left_seg_context[MAX_MIB_SIZE]; -#if CONFIG_VAR_TX TXFM_CONTEXT *above_txfm_context; TXFM_CONTEXT *left_txfm_context; - TXFM_CONTEXT left_txfm_context_buffer[2 * MAX_MIB_SIZE]; - - TX_SIZE max_tx_size; -#if CONFIG_SUPERTX - TX_SIZE supertx_size; -#endif -#endif + TXFM_CONTEXT left_txfm_context_buffer[MAX_MIB_SIZE]; -#if CONFIG_LOOP_RESTORATION WienerInfo wiener_info[MAX_MB_PLANE]; SgrprojInfo sgrproj_info[MAX_MB_PLANE]; -#endif // CONFIG_LOOP_RESTORATION // block dimension in the unit of mode_info. uint8_t n8_w, n8_h; @@ -780,9 +550,10 @@ typedef struct macroblockd { CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE]; uint8_t is_sec_rect; -#if CONFIG_PVQ - daala_dec_ctx daala_dec; -#endif + // Counts of each reference frame in the above and left neighboring blocks. + // NOTE: Take into account both single and comp references. + uint8_t neighbors_ref_counts[REF_FRAMES]; + FRAME_CONTEXT *tile_ctx; /* Bit depth: 8, 10, 12 */ int bd; @@ -790,27 +561,19 @@ typedef struct macroblockd { int qindex[MAX_SEGMENTS]; int lossless[MAX_SEGMENTS]; int corrupted; -#if CONFIG_AMVR - int cur_frame_mv_precision_level; -// same with that in AV1_COMMON -#endif + int cur_frame_force_integer_mv; + // same with that in AV1_COMMON struct aom_internal_error_info *error_info; -#if CONFIG_GLOBAL_MOTION - WarpedMotionParams *global_motion; -#endif // CONFIG_GLOBAL_MOTION - int prev_qindex; + const WarpedMotionParams *global_motion; int delta_qindex; int current_qindex; -#if CONFIG_EXT_DELTA_Q // Since actual frame level loop filtering level value is not available // at the beginning of the tile (only available during actual filtering) // at encoder side.we record the delta_lf (against the frame level loop // filtering level) and code the delta between previous superblock's delta // lf and current delta lf. It is equivalent to the delta between previous // superblock's actual lf and current lf. - int prev_delta_lf_from_base; - int current_delta_lf_from_base; -#if CONFIG_LOOPFILTER_LEVEL + int delta_lf_from_base; // For this experiment, we have four frame filter levels for different plane // and direction. So, to support the per superblock update, we need to add // a few more params as below. @@ -824,420 +587,151 @@ typedef struct macroblockd { // SEG_LVL_ALT_LF_Y_H = 2; // SEG_LVL_ALT_LF_U = 3; // SEG_LVL_ALT_LF_V = 4; - int prev_delta_lf[FRAME_LF_COUNT]; - int curr_delta_lf[FRAME_LF_COUNT]; -#endif // CONFIG_LOOPFILTER_LEVEL -#endif -#if CONFIG_ADAPT_SCAN - const EobThresholdMD *eob_threshold_md; -#endif + int delta_lf[FRAME_LF_COUNT]; + int cdef_preset[4]; -#if CONFIG_COMPOUND_SEGMENT DECLARE_ALIGNED(16, uint8_t, seg_mask[2 * MAX_SB_SQUARE]); -#endif // CONFIG_COMPOUND_SEGMENT + uint8_t *mc_buf[2]; + CFL_CTX cfl; -#if CONFIG_MRC_TX - uint8_t *mrc_mask; -#endif // CONFIG_MRC_TX + JNT_COMP_PARAMS jcp_param; -#if CONFIG_CFL - CFL_CTX *cfl; -#endif - -#if CONFIG_NCOBMC_ADAPT_WEIGHT - uint8_t *ncobmc_pred_buf[MAX_MB_PLANE]; - int ncobmc_pred_buf_stride[MAX_MB_PLANE]; - SB_MI_BD sb_mi_bd; -#endif + uint16_t cb_offset[MAX_MB_PLANE]; + uint16_t txb_offset[MAX_MB_PLANE]; + uint16_t color_index_map_offset[2]; } MACROBLOCKD; static INLINE int get_bitdepth_data_path_index(const MACROBLOCKD *xd) { return xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? 1 : 0; } -static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, - PARTITION_TYPE partition) { - if (partition == PARTITION_INVALID) - return BLOCK_INVALID; - else - return subsize_lookup[partition][bsize]; -} - -static const TX_TYPE intra_mode_to_tx_type_context[INTRA_MODES] = { - DCT_DCT, // DC - ADST_DCT, // V - DCT_ADST, // H - DCT_DCT, // D45 - ADST_ADST, // D135 - ADST_DCT, // D117 - DCT_ADST, // D153 - DCT_ADST, // D207 - ADST_DCT, // D63 - ADST_ADST, // SMOOTH -#if CONFIG_SMOOTH_HV - ADST_DCT, // SMOOTH_V - DCT_ADST, // SMOOTH_H -#endif // CONFIG_SMOOTH_HV - ADST_ADST, // TM -}; +static INLINE int get_sqr_bsize_idx(BLOCK_SIZE bsize) { + switch (bsize) { + case BLOCK_4X4: return 0; + case BLOCK_8X8: return 1; + case BLOCK_16X16: return 2; + case BLOCK_32X32: return 3; + case BLOCK_64X64: return 4; + case BLOCK_128X128: return 5; + default: return SQR_BLOCK_SIZES; + } +} -#if CONFIG_SUPERTX -static INLINE int supertx_enabled(const MB_MODE_INFO *mbmi) { - TX_SIZE max_tx_size = txsize_sqr_map[mbmi->tx_size]; - return tx_size_wide[max_tx_size] > - AOMMIN(block_size_wide[mbmi->sb_type], block_size_high[mbmi->sb_type]); +// Note: the input block size should be square. +// Otherwise it's considered invalid. +static INLINE BLOCK_SIZE get_partition_subsize(BLOCK_SIZE bsize, + PARTITION_TYPE partition) { + if (partition == PARTITION_INVALID) { + return BLOCK_INVALID; + } else { + const int sqr_bsize_idx = get_sqr_bsize_idx(bsize); + return sqr_bsize_idx >= SQR_BLOCK_SIZES + ? BLOCK_INVALID + : subsize_lookup[partition][sqr_bsize_idx]; + } } -#endif // CONFIG_SUPERTX -#define USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4 1 +static TX_TYPE intra_mode_to_tx_type(const MB_MODE_INFO *mbmi, + PLANE_TYPE plane_type) { + static const TX_TYPE _intra_mode_to_tx_type[INTRA_MODES] = { + DCT_DCT, // DC + ADST_DCT, // V + DCT_ADST, // H + DCT_DCT, // D45 + ADST_ADST, // D135 + ADST_DCT, // D117 + DCT_ADST, // D153 + DCT_ADST, // D207 + ADST_DCT, // D63 + ADST_ADST, // SMOOTH + ADST_DCT, // SMOOTH_V + DCT_ADST, // SMOOTH_H + ADST_ADST, // PAETH + }; + const PREDICTION_MODE mode = + (plane_type == PLANE_TYPE_Y) ? mbmi->mode : get_uv_mode(mbmi->uv_mode); + assert(mode < INTRA_MODES); + return _intra_mode_to_tx_type[mode]; +} -#if CONFIG_RECT_TX static INLINE int is_rect_tx(TX_SIZE tx_size) { return tx_size >= TX_SIZES; } -#endif // CONFIG_RECT_TX static INLINE int block_signals_txsize(BLOCK_SIZE bsize) { -#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX return bsize > BLOCK_4X4; -#else - return bsize >= BLOCK_8X8; -#endif } -#if CONFIG_MRC_TX -#define USE_MRC_INTRA 0 -#define USE_MRC_INTER 1 -#define SIGNAL_MRC_MASK_INTRA (USE_MRC_INTRA && 0) -#define SIGNAL_MRC_MASK_INTER (USE_MRC_INTER && 1) -#define SIGNAL_ANY_MRC_MASK (SIGNAL_MRC_MASK_INTRA || SIGNAL_MRC_MASK_INTER) -#endif // CONFIG_MRC_TX - -#if CONFIG_EXT_TX -#define ALLOW_INTRA_EXT_TX 1 - // Number of transform types in each set type static const int av1_num_ext_tx_set[EXT_TX_SET_TYPES] = { - 1, 2, -#if CONFIG_MRC_TX - 2, 3, -#endif // CONFIG_MRC_TX - 5, 7, 12, 16, -}; - -static const int av1_ext_tx_set_idx_to_type[2][AOMMAX(EXT_TX_SETS_INTRA, - EXT_TX_SETS_INTER)] = { - { - // Intra - EXT_TX_SET_DCTONLY, EXT_TX_SET_DTT4_IDTX_1DDCT, EXT_TX_SET_DTT4_IDTX, -#if CONFIG_MRC_TX - EXT_TX_SET_MRC_DCT, -#endif // CONFIG_MRC_TX - }, - { - // Inter - EXT_TX_SET_DCTONLY, EXT_TX_SET_ALL16, EXT_TX_SET_DTT9_IDTX_1DDCT, - EXT_TX_SET_DCT_IDTX, -#if CONFIG_MRC_TX - EXT_TX_SET_MRC_DCT_IDTX, -#endif // CONFIG_MRC_TX - } + 1, 2, 5, 7, 12, 16, }; -#if CONFIG_MRC_TX static const int av1_ext_tx_used[EXT_TX_SET_TYPES][TX_TYPES] = { - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, - }, - { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, }; -#else // CONFIG_MRC_TX -static const int av1_ext_tx_used[EXT_TX_SET_TYPES][TX_TYPES] = { - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, - }, - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }, -}; -#endif // CONFIG_MRC_TX -static INLINE TxSetType get_ext_tx_set_type(TX_SIZE tx_size, BLOCK_SIZE bs, - int is_inter, int use_reduced_set) { +static INLINE TxSetType av1_get_ext_tx_set_type(TX_SIZE tx_size, int is_inter, + int use_reduced_set) { const TX_SIZE tx_size_sqr_up = txsize_sqr_up_map[tx_size]; - const TX_SIZE tx_size_sqr = txsize_sqr_map[tx_size]; -#if CONFIG_CB4X4 && USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4 - (void)bs; if (tx_size_sqr_up > TX_32X32) return EXT_TX_SET_DCTONLY; -#else - if (tx_size_sqr_up > TX_32X32 || bs < BLOCK_8X8) return EXT_TX_SET_DCTONLY; -#endif - if (use_reduced_set) - return is_inter ? EXT_TX_SET_DCT_IDTX : EXT_TX_SET_DTT4_IDTX; -#if CONFIG_MRC_TX - if (tx_size == TX_32X32) { - if (is_inter && USE_MRC_INTER) - return EXT_TX_SET_MRC_DCT_IDTX; - else if (!is_inter && USE_MRC_INTRA) - return EXT_TX_SET_MRC_DCT; - } -#endif // CONFIG_MRC_TX if (tx_size_sqr_up == TX_32X32) return is_inter ? EXT_TX_SET_DCT_IDTX : EXT_TX_SET_DCTONLY; - if (is_inter) + if (use_reduced_set) + return is_inter ? EXT_TX_SET_DCT_IDTX : EXT_TX_SET_DTT4_IDTX; + const TX_SIZE tx_size_sqr = txsize_sqr_map[tx_size]; + if (is_inter) { return (tx_size_sqr == TX_16X16 ? EXT_TX_SET_DTT9_IDTX_1DDCT : EXT_TX_SET_ALL16); - else + } else { return (tx_size_sqr == TX_16X16 ? EXT_TX_SET_DTT4_IDTX : EXT_TX_SET_DTT4_IDTX_1DDCT); + } } // Maps tx set types to the indices. static const int ext_tx_set_index[2][EXT_TX_SET_TYPES] = { - { - // Intra - 0, -1, -#if CONFIG_MRC_TX - 3, -1, -#endif // CONFIG_MRC_TX - 2, 1, -1, -1, - }, - { - // Inter - 0, 3, -#if CONFIG_MRC_TX - -1, 4, -#endif // CONFIG_MRC_TX - -1, -1, 2, 1, - }, + { // Intra + 0, -1, 2, 1, -1, -1 }, + { // Inter + 0, 3, -1, -1, 2, 1 }, }; -static INLINE int get_ext_tx_set(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter, +static INLINE int get_ext_tx_set(TX_SIZE tx_size, int is_inter, int use_reduced_set) { const TxSetType set_type = - get_ext_tx_set_type(tx_size, bs, is_inter, use_reduced_set); + av1_get_ext_tx_set_type(tx_size, is_inter, use_reduced_set); return ext_tx_set_index[is_inter][set_type]; } -static INLINE int get_ext_tx_types(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter, +static INLINE int get_ext_tx_types(TX_SIZE tx_size, int is_inter, int use_reduced_set) { const int set_type = - get_ext_tx_set_type(tx_size, bs, is_inter, use_reduced_set); + av1_get_ext_tx_set_type(tx_size, is_inter, use_reduced_set); return av1_num_ext_tx_set[set_type]; } -#if CONFIG_LGT_FROM_PRED -static INLINE int is_lgt_allowed(PREDICTION_MODE mode, TX_SIZE tx_size) { - if (!LGT_FROM_PRED_INTRA && !is_inter_mode(mode)) return 0; - if (!LGT_FROM_PRED_INTER && is_inter_mode(mode)) return 0; - - switch (mode) { - case D45_PRED: - case D63_PRED: - case D117_PRED: - case V_PRED: -#if CONFIG_SMOOTH_HV - case SMOOTH_V_PRED: -#endif - return tx_size_wide[tx_size] <= 8; - case D135_PRED: - case D153_PRED: - case D207_PRED: - case H_PRED: -#if CONFIG_SMOOTH_HV - case SMOOTH_H_PRED: -#endif - return tx_size_high[tx_size] <= 8; - case DC_PRED: - case SMOOTH_PRED: return 0; - case TM_PRED: - default: return tx_size_wide[tx_size] <= 8 || tx_size_high[tx_size] <= 8; - } -} -#endif // CONFIG_LGT_FROM_PRED - -#if CONFIG_RECT_TX -static INLINE int is_rect_tx_allowed_bsize(BLOCK_SIZE bsize) { - static const char LUT[BLOCK_SIZES_ALL] = { -#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8 - 0, // BLOCK_2X2 - 0, // BLOCK_2X4 - 0, // BLOCK_4X2 -#endif - 0, // BLOCK_4X4 - 1, // BLOCK_4X8 - 1, // BLOCK_8X4 - 0, // BLOCK_8X8 - 1, // BLOCK_8X16 - 1, // BLOCK_16X8 - 0, // BLOCK_16X16 - 1, // BLOCK_16X32 - 1, // BLOCK_32X16 - 0, // BLOCK_32X32 - 1, // BLOCK_32X64 - 1, // BLOCK_64X32 - 0, // BLOCK_64X64 -#if CONFIG_EXT_PARTITION - 0, // BLOCK_64X128 - 0, // BLOCK_128X64 - 0, // BLOCK_128X128 -#endif // CONFIG_EXT_PARTITION - 0, // BLOCK_4X16 - 0, // BLOCK_16X4 - 0, // BLOCK_8X32 - 0, // BLOCK_32X8 - 0, // BLOCK_16X64 - 0, // BLOCK_64X16 -#if CONFIG_EXT_PARTITION - 0, // BLOCK_32X128 - 0, // BLOCK_128X32 -#endif // CONFIG_EXT_PARTITION - }; - - return LUT[bsize]; -} +#define TXSIZEMAX(t1, t2) (tx_size_2d[(t1)] >= tx_size_2d[(t2)] ? (t1) : (t2)) +#define TXSIZEMIN(t1, t2) (tx_size_2d[(t1)] <= tx_size_2d[(t2)] ? (t1) : (t2)) -static INLINE int is_rect_tx_allowed(const MACROBLOCKD *xd, - const MB_MODE_INFO *mbmi) { - return is_rect_tx_allowed_bsize(mbmi->sb_type) && - !xd->lossless[mbmi->segment_id]; -} -#endif // CONFIG_RECT_TX -#endif // CONFIG_EXT_TX - -#if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX) -static INLINE int is_quarter_tx_allowed_bsize(BLOCK_SIZE bsize) { - static const char LUT_QTTX[BLOCK_SIZES_ALL] = { -#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8 - 0, // BLOCK_2X2 - 0, // BLOCK_2X4 - 0, // BLOCK_4X2 -#endif - 0, // BLOCK_4X4 - 0, // BLOCK_4X8 - 0, // BLOCK_8X4 - 0, // BLOCK_8X8 - 1, // BLOCK_8X16 - 1, // BLOCK_16X8 - 0, // BLOCK_16X16 - 0, // BLOCK_16X32 - 0, // BLOCK_32X16 - 0, // BLOCK_32X32 - 0, // BLOCK_32X64 - 0, // BLOCK_64X32 - 0, // BLOCK_64X64 -#if CONFIG_EXT_PARTITION - 0, // BLOCK_64X128 - 0, // BLOCK_128X64 - 0, // BLOCK_128X128 -#endif // CONFIG_EXT_PARTITION - 0, // BLOCK_4X16 - 0, // BLOCK_16X4 - 0, // BLOCK_8X32 - 0, // BLOCK_32X8 - 0, // BLOCK_16X64 - 0, // BLOCK_64X16 -#if CONFIG_EXT_PARTITION - 0, // BLOCK_32X128 - 0, // BLOCK_128X32 -#endif // CONFIG_EXT_PARTITION - }; - - return LUT_QTTX[bsize]; -} - -static INLINE int is_quarter_tx_allowed(const MACROBLOCKD *xd, - const MB_MODE_INFO *mbmi, - int is_inter) { - return is_quarter_tx_allowed_bsize(mbmi->sb_type) && is_inter && - !xd->lossless[mbmi->segment_id]; -} -#endif - -static INLINE TX_SIZE tx_size_from_tx_mode(BLOCK_SIZE bsize, TX_MODE tx_mode, - int is_inter) { +static INLINE TX_SIZE tx_size_from_tx_mode(BLOCK_SIZE bsize, TX_MODE tx_mode) { const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[tx_mode]; -#if (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX const TX_SIZE max_rect_tx_size = max_txsize_rect_lookup[bsize]; -#else - const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; -#endif // (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX - (void)is_inter; -#if CONFIG_VAR_TX && CONFIG_RECT_TX -#if CONFIG_CB4X4 if (bsize == BLOCK_4X4) return AOMMIN(max_txsize_lookup[bsize], largest_tx_size); -#else - if (bsize < BLOCK_8X8) - return AOMMIN(max_txsize_lookup[bsize], largest_tx_size); -#endif if (txsize_sqr_map[max_rect_tx_size] <= largest_tx_size) return max_rect_tx_size; else return largest_tx_size; -#elif CONFIG_EXT_TX && CONFIG_RECT_TX - if (txsize_sqr_up_map[max_rect_tx_size] <= largest_tx_size) { - return max_rect_tx_size; - } else { - return largest_tx_size; - } -#else - return AOMMIN(max_tx_size, largest_tx_size); -#endif // CONFIG_VAR_TX && CONFIG_RECT_TX } -#if CONFIG_EXT_INTRA -#define MAX_ANGLE_DELTA 3 -#define ANGLE_STEP 3 extern const int16_t dr_intra_derivative[90]; static const uint8_t mode_to_angle_map[] = { - 0, 90, 180, 45, 135, 111, 157, 203, 67, 0, 0, -#if CONFIG_SMOOTH_HV - 0, 0, -#endif // CONFIG_SMOOTH_HV + 0, 90, 180, 45, 135, 113, 157, 203, 67, 0, 0, 0, 0, }; -#if CONFIG_INTRA_INTERP -// Returns whether filter selection is needed for a given -// intra prediction angle. -int av1_is_intra_filter_switchable(int angle); -#endif // CONFIG_INTRA_INTERP -#endif // CONFIG_EXT_INTRA - -#if CONFIG_DCT_ONLY -#define FIXED_TX_TYPE 1 -#else -#define FIXED_TX_TYPE 0 -#endif // Converts block_index for given transform size to index of the block in raster // order. @@ -1261,168 +755,182 @@ static INLINE int av1_raster_order_to_block_index(TX_SIZE tx_size, } static INLINE TX_TYPE get_default_tx_type(PLANE_TYPE plane_type, - const MACROBLOCKD *xd, int block_idx, + const MACROBLOCKD *xd, TX_SIZE tx_size) { - const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; + const MB_MODE_INFO *const mbmi = xd->mi[0]; - if (CONFIG_DCT_ONLY || is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y || + if (is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y || xd->lossless[mbmi->segment_id] || tx_size >= TX_32X32) return DCT_DCT; - return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y - ? get_y_mode(xd->mi[0], block_idx) - : get_uv_mode(mbmi->uv_mode)]; + return intra_mode_to_tx_type(mbmi, plane_type); +} + +static INLINE BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize, + int subsampling_x, + int subsampling_y) { + if (bsize == BLOCK_INVALID) return BLOCK_INVALID; + return ss_size_lookup[bsize][subsampling_x][subsampling_y]; +} + +static INLINE int av1_get_txb_size_index(BLOCK_SIZE bsize, int blk_row, + int blk_col) { + TX_SIZE txs = max_txsize_rect_lookup[bsize]; + for (int level = 0; level < MAX_VARTX_DEPTH - 1; ++level) + txs = sub_tx_size_map[txs]; + const int tx_w_log2 = tx_size_wide_log2[txs] - MI_SIZE_LOG2; + const int tx_h_log2 = tx_size_high_log2[txs] - MI_SIZE_LOG2; + const int bw_log2 = mi_size_wide_log2[bsize]; + const int stride_log2 = bw_log2 - tx_w_log2; + const int index = + ((blk_row >> tx_h_log2) << stride_log2) + (blk_col >> tx_w_log2); + assert(index < INTER_TX_SIZE_BUF_LEN); + return index; +} + +static INLINE int av1_get_txk_type_index(BLOCK_SIZE bsize, int blk_row, + int blk_col) { + TX_SIZE txs = max_txsize_rect_lookup[bsize]; + for (int level = 0; level < MAX_VARTX_DEPTH; ++level) + txs = sub_tx_size_map[txs]; + const int tx_w_log2 = tx_size_wide_log2[txs] - MI_SIZE_LOG2; + const int tx_h_log2 = tx_size_high_log2[txs] - MI_SIZE_LOG2; + const int bw_uint_log2 = mi_size_wide_log2[bsize]; + const int stride_log2 = bw_uint_log2 - tx_w_log2; + const int index = + ((blk_row >> tx_h_log2) << stride_log2) + (blk_col >> tx_w_log2); + assert(index < TXK_TYPE_BUF_LEN); + return index; +} + +static INLINE void update_txk_array(TX_TYPE *txk_type, BLOCK_SIZE bsize, + int blk_row, int blk_col, TX_SIZE tx_size, + TX_TYPE tx_type) { + const int txk_type_idx = av1_get_txk_type_index(bsize, blk_row, blk_col); + txk_type[txk_type_idx] = tx_type; + + const int txw = tx_size_wide_unit[tx_size]; + const int txh = tx_size_high_unit[tx_size]; + // The 16x16 unit is due to the constraint from tx_64x64 which sets the + // maximum tx size for chroma as 32x32. Coupled with 4x1 transform block + // size, the constraint takes effect in 32x16 / 16x32 size too. To solve + // the intricacy, cover all the 16x16 units inside a 64 level transform. + if (txw == tx_size_wide_unit[TX_64X64] || + txh == tx_size_high_unit[TX_64X64]) { + const int tx_unit = tx_size_wide_unit[TX_16X16]; + for (int idy = 0; idy < txh; idy += tx_unit) { + for (int idx = 0; idx < txw; idx += tx_unit) { + const int this_index = + av1_get_txk_type_index(bsize, blk_row + idy, blk_col + idx); + txk_type[this_index] = tx_type; + } + } + } } static INLINE TX_TYPE av1_get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd, int blk_row, - int blk_col, int block, TX_SIZE tx_size) { - const MODE_INFO *const mi = xd->mi[0]; - const MB_MODE_INFO *const mbmi = &mi->mbmi; - (void)blk_row; - (void)blk_col; -#if CONFIG_INTRABC && (!CONFIG_EXT_TX || CONFIG_TXK_SEL) - // TODO(aconverse@google.com): Handle INTRABC + EXT_TX + TXK_SEL - if (is_intrabc_block(mbmi)) return DCT_DCT; -#endif // CONFIG_INTRABC && (!CONFIG_EXT_TX || CONFIG_TXK_SEL) - -#if CONFIG_TXK_SEL + int blk_col, TX_SIZE tx_size, + int reduced_tx_set) { + const MB_MODE_INFO *const mbmi = xd->mi[0]; + const struct macroblockd_plane *const pd = &xd->plane[plane_type]; + const TxSetType tx_set_type = + av1_get_ext_tx_set_type(tx_size, is_inter_block(mbmi), reduced_tx_set); + TX_TYPE tx_type; - if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] >= TX_32X32) { + if (xd->lossless[mbmi->segment_id] || txsize_sqr_up_map[tx_size] > TX_32X32) { tx_type = DCT_DCT; } else { - if (plane_type == PLANE_TYPE_Y) - tx_type = mbmi->txk_type[(blk_row << 4) + blk_col]; - else if (is_inter_block(mbmi)) - tx_type = mbmi->txk_type[(blk_row << 5) + (blk_col << 1)]; - else - tx_type = intra_mode_to_tx_type_context[mbmi->uv_mode]; - } - assert(tx_type >= DCT_DCT && tx_type < TX_TYPES); - return tx_type; -#endif // CONFIG_TXK_SEL - -#if FIXED_TX_TYPE - const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block); - return get_default_tx_type(plane_type, xd, block_raster_idx, tx_size); -#endif // FIXED_TX_TYPE - -#if CONFIG_EXT_TX -#if CONFIG_MRC_TX - if (mbmi->tx_type == MRC_DCT) { - assert(((is_inter_block(mbmi) && USE_MRC_INTER) || - (!is_inter_block(mbmi) && USE_MRC_INTRA)) && - "INVALID BLOCK TYPE FOR MRC_DCT"); if (plane_type == PLANE_TYPE_Y) { - assert(tx_size == TX_32X32); - return mbmi->tx_type; + const int txk_type_idx = + av1_get_txk_type_index(mbmi->sb_type, blk_row, blk_col); + tx_type = mbmi->txk_type[txk_type_idx]; + } else if (is_inter_block(mbmi)) { + // scale back to y plane's coordinate + blk_row <<= pd->subsampling_y; + blk_col <<= pd->subsampling_x; + const int txk_type_idx = + av1_get_txk_type_index(mbmi->sb_type, blk_row, blk_col); + tx_type = mbmi->txk_type[txk_type_idx]; + } else { + // In intra mode, uv planes don't share the same prediction mode as y + // plane, so the tx_type should not be shared + tx_type = intra_mode_to_tx_type(mbmi, PLANE_TYPE_UV); } - return DCT_DCT; } -#endif // CONFIG_MRC_TX - if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] > TX_32X32 || - (txsize_sqr_map[tx_size] >= TX_32X32 && !is_inter_block(mbmi))) - return DCT_DCT; - if (mbmi->sb_type >= BLOCK_8X8 || CONFIG_CB4X4) { - if (plane_type == PLANE_TYPE_Y) { -#if !ALLOW_INTRA_EXT_TX - if (is_inter_block(mbmi)) -#endif // ALLOW_INTRA_EXT_TX - return mbmi->tx_type; - } + assert(tx_type < TX_TYPES); + if (!av1_ext_tx_used[tx_set_type][tx_type]) return DCT_DCT; + return tx_type; +} - if (is_inter_block(mbmi)) { -// UV Inter only -#if CONFIG_CHROMA_2X2 - if (tx_size < TX_4X4) return DCT_DCT; -#endif - return (mbmi->tx_type == IDTX && txsize_sqr_map[tx_size] >= TX_32X32) - ? DCT_DCT - : mbmi->tx_type; - } - } +void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y, + const int num_planes); -#if CONFIG_CB4X4 - (void)block; -#if CONFIG_CHROMA_2X2 - if (tx_size < TX_4X4) - return DCT_DCT; - else -#endif // CONFIG_CHROMA_2X2 - return intra_mode_to_tx_type_context[get_uv_mode(mbmi->uv_mode)]; -#else // CONFIG_CB4X4 - // Sub8x8-Inter/Intra OR UV-Intra - if (is_inter_block(mbmi)) { // Sub8x8-Inter - return DCT_DCT; - } else { // Sub8x8 Intra OR UV-Intra - const int block_raster_idx = - av1_block_index_to_raster_order(tx_size, block); - return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y - ? get_y_mode(mi, block_raster_idx) - : get_uv_mode(mbmi->uv_mode)]; - } -#endif // CONFIG_CB4X4 -#else // CONFIG_EXT_TX - (void)block; -#if CONFIG_MRC_TX - if (mbmi->tx_type == MRC_DCT) { - if (plane_type == PLANE_TYPE_Y && !xd->lossless[mbmi->segment_id]) { - assert(tx_size == TX_32X32); - return mbmi->tx_type; - } - return DCT_DCT; +static INLINE int bsize_to_max_depth(BLOCK_SIZE bsize) { + TX_SIZE tx_size = max_txsize_rect_lookup[bsize]; + int depth = 0; + while (depth < MAX_TX_DEPTH && tx_size != TX_4X4) { + depth++; + tx_size = sub_tx_size_map[tx_size]; } -#endif // CONFIG_MRC_TX - if (plane_type != PLANE_TYPE_Y || xd->lossless[mbmi->segment_id] || - txsize_sqr_map[tx_size] >= TX_32X32) - return DCT_DCT; - return mbmi->tx_type; -#endif // CONFIG_EXT_TX + return depth; } -void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y); - -static INLINE int tx_size_to_depth(TX_SIZE tx_size) { - return (int)(tx_size - TX_SIZE_LUMA_MIN); +static INLINE int bsize_to_tx_size_cat(BLOCK_SIZE bsize) { + TX_SIZE tx_size = max_txsize_rect_lookup[bsize]; + assert(tx_size != TX_4X4); + int depth = 0; + while (tx_size != TX_4X4) { + depth++; + tx_size = sub_tx_size_map[tx_size]; + assert(depth < 10); + } + assert(depth <= MAX_TX_CATS); + return depth - 1; } -static INLINE TX_SIZE depth_to_tx_size(int depth) { - return (TX_SIZE)(depth + TX_SIZE_LUMA_MIN); +static INLINE TX_SIZE depth_to_tx_size(int depth, BLOCK_SIZE bsize) { + TX_SIZE max_tx_size = max_txsize_rect_lookup[bsize]; + TX_SIZE tx_size = max_tx_size; + for (int d = 0; d < depth; ++d) tx_size = sub_tx_size_map[tx_size]; + return tx_size; } -static INLINE TX_SIZE av1_get_uv_tx_size(const MB_MODE_INFO *mbmi, - const struct macroblockd_plane *pd) { -#if CONFIG_CHROMA_2X2 - assert(mbmi->tx_size > TX_2X2); -#endif // CONFIG_CHROMA_2X2 - -#if CONFIG_SUPERTX - if (supertx_enabled(mbmi)) - return uvsupertx_size_lookup[txsize_sqr_map[mbmi->tx_size]] - [pd->subsampling_x][pd->subsampling_y]; -#endif // CONFIG_SUPERTX +static INLINE TX_SIZE av1_get_adjusted_tx_size(TX_SIZE tx_size) { + switch (tx_size) { + case TX_64X64: + case TX_64X32: + case TX_32X64: return TX_32X32; + case TX_64X16: return TX_32X16; + case TX_16X64: return TX_16X32; + default: return tx_size; + } +} - const TX_SIZE uv_txsize = - uv_txsize_lookup[mbmi->sb_type][mbmi->tx_size][pd->subsampling_x] - [pd->subsampling_y]; - assert(uv_txsize != TX_INVALID); - return uv_txsize; +static INLINE TX_SIZE av1_get_max_uv_txsize(BLOCK_SIZE bsize, int subsampling_x, + int subsampling_y) { + const BLOCK_SIZE plane_bsize = + get_plane_block_size(bsize, subsampling_x, subsampling_y); + assert(plane_bsize < BLOCK_SIZES_ALL); + const TX_SIZE uv_tx = max_txsize_rect_lookup[plane_bsize]; + return av1_get_adjusted_tx_size(uv_tx); } static INLINE TX_SIZE av1_get_tx_size(int plane, const MACROBLOCKD *xd) { - const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; + const MB_MODE_INFO *mbmi = xd->mi[0]; + if (xd->lossless[mbmi->segment_id]) return TX_4X4; if (plane == 0) return mbmi->tx_size; const MACROBLOCKD_PLANE *pd = &xd->plane[plane]; - return av1_get_uv_tx_size(mbmi, pd); -} - -static INLINE BLOCK_SIZE -get_plane_block_size(BLOCK_SIZE bsize, const struct macroblockd_plane *pd) { - return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y]; + return av1_get_max_uv_txsize(mbmi->sb_type, pd->subsampling_x, + pd->subsampling_y); } void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, - BLOCK_SIZE bsize); + BLOCK_SIZE bsize, const int num_planes); + +void av1_reset_loop_filter_delta(MACROBLOCKD *xd, int num_planes); + +void av1_reset_loop_restoration(MACROBLOCKD *xd, const int num_planes); typedef void (*foreach_transformed_block_visitor)(int plane, int block, int blk_row, int blk_col, @@ -1433,54 +941,31 @@ void av1_foreach_transformed_block_in_plane( const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, foreach_transformed_block_visitor visit, void *arg); -#if CONFIG_LV_MAP void av1_foreach_transformed_block(const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int mi_row, int mi_col, foreach_transformed_block_visitor visit, - void *arg); -#endif - -#if CONFIG_COEF_INTERLEAVE -static INLINE int get_max_4x4_size(int num_4x4, int mb_to_edge, - int subsampling) { - return num_4x4 + (mb_to_edge >= 0 ? 0 : mb_to_edge >> (5 + subsampling)); -} - -void av1_foreach_transformed_block_interleave( - const MACROBLOCKD *const xd, BLOCK_SIZE bsize, - foreach_transformed_block_visitor visit, void *arg); -#endif + void *arg, const int num_planes); void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, - int plane, TX_SIZE tx_size, int has_eob, int aoff, - int loff); + int plane, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, + int has_eob, int aoff, int loff); + +#define MAX_INTERINTRA_SB_SQUARE 32 * 32 +static INLINE int is_interintra_mode(const MB_MODE_INFO *mbmi) { + return (mbmi->ref_frame[0] > INTRA_FRAME && + mbmi->ref_frame[1] == INTRA_FRAME); +} static INLINE int is_interintra_allowed_bsize(const BLOCK_SIZE bsize) { -#if CONFIG_INTERINTRA - // TODO(debargha): Should this be bsize < BLOCK_LARGEST? - return (bsize >= BLOCK_8X8) && (bsize < BLOCK_64X64); -#else - (void)bsize; - return 0; -#endif // CONFIG_INTERINTRA + return (bsize >= BLOCK_8X8) && (bsize <= BLOCK_32X32); } static INLINE int is_interintra_allowed_mode(const PREDICTION_MODE mode) { -#if CONFIG_INTERINTRA return (mode >= NEARESTMV) && (mode <= NEWMV); -#else - (void)mode; - return 0; -#endif // CONFIG_INTERINTRA } static INLINE int is_interintra_allowed_ref(const MV_REFERENCE_FRAME rf[2]) { -#if CONFIG_INTERINTRA return (rf[0] > INTRA_FRAME) && (rf[1] <= INTRA_FRAME); -#else - (void)rf; - return 0; -#endif // CONFIG_INTERINTRA } static INLINE int is_interintra_allowed(const MB_MODE_INFO *mbmi) { @@ -1501,54 +986,30 @@ static INLINE int is_interintra_allowed_bsize_group(int group) { } static INLINE int is_interintra_pred(const MB_MODE_INFO *mbmi) { - return (mbmi->ref_frame[1] == INTRA_FRAME) && is_interintra_allowed(mbmi); -} - -#if CONFIG_VAR_TX -static INLINE int get_vartx_max_txsize(const MB_MODE_INFO *const mbmi, - BLOCK_SIZE bsize, int subsampled) { -#if CONFIG_CB4X4 - (void)mbmi; - TX_SIZE max_txsize = max_txsize_rect_lookup[bsize]; -#else - TX_SIZE max_txsize = mbmi->sb_type < BLOCK_8X8 - ? max_txsize_rect_lookup[mbmi->sb_type] - : max_txsize_rect_lookup[bsize]; -#endif // CONFIG_C4X4 - -#if CONFIG_EXT_PARTITION && CONFIG_TX64X64 - // The decoder is designed so that it can process 64x64 luma pixels at a - // time. If this is a chroma plane with subsampling and bsize corresponds to - // a subsampled BLOCK_128X128 then the lookup above will give TX_64X64. That - // mustn't be used for the subsampled plane (because it would be bigger than - // a 64x64 luma block) so we round down to TX_32X32. - if (subsampled && max_txsize == TX_64X64) max_txsize = TX_32X32; -#else - (void)subsampled; -#endif + return mbmi->ref_frame[0] > INTRA_FRAME && + mbmi->ref_frame[1] == INTRA_FRAME && is_interintra_allowed(mbmi); +} - return max_txsize; +static INLINE int get_vartx_max_txsize(const MACROBLOCKD *xd, BLOCK_SIZE bsize, + int plane) { + if (xd->lossless[xd->mi[0]->segment_id]) return TX_4X4; + const TX_SIZE max_txsize = max_txsize_rect_lookup[bsize]; + if (plane == 0) return max_txsize; // luma + return av1_get_adjusted_tx_size(max_txsize); // chroma } -#endif // CONFIG_VAR_TX -#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION static INLINE int is_motion_variation_allowed_bsize(BLOCK_SIZE bsize) { return AOMMIN(block_size_wide[bsize], block_size_high[bsize]) >= 8; } static INLINE int is_motion_variation_allowed_compound( const MB_MODE_INFO *mbmi) { -#if CONFIG_COMPOUND_SINGLEREF - if (!has_second_ref(mbmi) && !is_inter_singleref_comp_mode(mbmi->mode)) -#else if (!has_second_ref(mbmi)) -#endif // CONFIG_COMPOUND_SINGLEREF return 1; else return 0; } -#if CONFIG_MOTION_VAR // input: log2 of length, 0(4), 1(8), ... static const int max_neighbor_obmc[6] = { 0, 1, 2, 3, 4, 4 }; @@ -1556,102 +1017,53 @@ static INLINE int check_num_overlappable_neighbors(const MB_MODE_INFO *mbmi) { return !(mbmi->overlappable_neighbors[0] == 0 && mbmi->overlappable_neighbors[1] == 0); } -#if CONFIG_NCOBMC_ADAPT_WEIGHT -static INLINE NCOBMC_MODE ncobmc_mode_allowed_bsize(BLOCK_SIZE bsize) { - if (bsize < BLOCK_8X8 || bsize >= BLOCK_64X64) - return NO_OVERLAP; - else - return MAX_NCOBMC_MODES; -} -#endif // CONFIG_NCOBMC_ADAPT_WEIGHT -#endif // CONFIG_MOTION_VAR -static INLINE MOTION_MODE motion_mode_allowed( -#if CONFIG_GLOBAL_MOTION - int block, const WarpedMotionParams *gm_params, -#endif // CONFIG_GLOBAL_MOTION -#if CONFIG_WARPED_MOTION - const MACROBLOCKD *xd, -#endif - const MODE_INFO *mi) { - const MB_MODE_INFO *mbmi = &mi->mbmi; -#if CONFIG_AMVR - if (xd->cur_frame_mv_precision_level == 0) { -#endif -#if CONFIG_GLOBAL_MOTION +static INLINE MOTION_MODE +motion_mode_allowed(const WarpedMotionParams *gm_params, const MACROBLOCKD *xd, + const MB_MODE_INFO *mbmi, int allow_warped_motion) { + if (xd->cur_frame_force_integer_mv == 0) { const TransformationType gm_type = gm_params[mbmi->ref_frame[0]].wmtype; - if (is_global_mv_block(mi, block, gm_type)) return SIMPLE_TRANSLATION; -#endif // CONFIG_GLOBAL_MOTION -#if CONFIG_AMVR + if (is_global_mv_block(mbmi, gm_type)) return SIMPLE_TRANSLATION; } -#endif if (is_motion_variation_allowed_bsize(mbmi->sb_type) && is_inter_mode(mbmi->mode) && mbmi->ref_frame[1] != INTRA_FRAME && is_motion_variation_allowed_compound(mbmi)) { -#if CONFIG_MOTION_VAR if (!check_num_overlappable_neighbors(mbmi)) return SIMPLE_TRANSLATION; -#endif -#if CONFIG_WARPED_MOTION - if (!has_second_ref(mbmi) && mbmi->num_proj_ref[0] >= 1 && - !av1_is_scaled(&(xd->block_refs[0]->sf))) { -#if CONFIG_AMVR - if (xd->cur_frame_mv_precision_level) { + assert(!has_second_ref(mbmi)); + if (mbmi->num_proj_ref[0] >= 1 && + (allow_warped_motion && !av1_is_scaled(&(xd->block_refs[0]->sf)))) { + if (xd->cur_frame_force_integer_mv) { return OBMC_CAUSAL; } -#endif return WARPED_CAUSAL; } - -#endif // CONFIG_WARPED_MOTION -#if CONFIG_MOTION_VAR -#if CONFIG_NCOBMC_ADAPT_WEIGHT - if (ncobmc_mode_allowed_bsize(mbmi->sb_type) < NO_OVERLAP) - return NCOBMC_ADAPT_WEIGHT; - else -#endif - return OBMC_CAUSAL; -#else - return SIMPLE_TRANSLATION; -#endif // CONFIG_MOTION_VAR + return OBMC_CAUSAL; } else { return SIMPLE_TRANSLATION; } } static INLINE void assert_motion_mode_valid(MOTION_MODE mode, -#if CONFIG_GLOBAL_MOTION - int block, const WarpedMotionParams *gm_params, -#endif // CONFIG_GLOBAL_MOTION -#if CONFIG_WARPED_MOTION const MACROBLOCKD *xd, -#endif - const MODE_INFO *mi) { - const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed( -#if CONFIG_GLOBAL_MOTION - block, gm_params, -#endif // CONFIG_GLOBAL_MOTION -#if CONFIG_WARPED_MOTION - xd, -#endif - mi); + const MB_MODE_INFO *mbmi, + int allow_warped_motion) { + const MOTION_MODE last_motion_mode_allowed = + motion_mode_allowed(gm_params, xd, mbmi, allow_warped_motion); // Check that the input mode is not illegal if (last_motion_mode_allowed < mode) assert(0 && "Illegal motion mode selected"); } -#if CONFIG_MOTION_VAR static INLINE int is_neighbor_overlappable(const MB_MODE_INFO *mbmi) { return (is_inter_block(mbmi)); } -#endif // CONFIG_MOTION_VAR -#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION static INLINE int av1_allow_palette(int allow_screen_content_tools, BLOCK_SIZE sb_type) { - return allow_screen_content_tools && sb_type >= BLOCK_8X8 && - sb_type <= BLOCK_LARGEST; + return allow_screen_content_tools && block_size_wide[sb_type] <= 64 && + block_size_high[sb_type] <= 64 && sb_type >= BLOCK_8X8; } // Returns sub-sampled dimensions of the given block. @@ -1677,10 +1089,21 @@ static INLINE void av1_get_block_dimensions(BLOCK_SIZE bsize, int plane, assert(IMPLIES(plane == PLANE_TYPE_Y, pd->subsampling_y == 0)); assert(block_width >= block_cols); assert(block_height >= block_rows); - if (width) *width = block_width >> pd->subsampling_x; - if (height) *height = block_height >> pd->subsampling_y; - if (rows_within_bounds) *rows_within_bounds = block_rows >> pd->subsampling_y; - if (cols_within_bounds) *cols_within_bounds = block_cols >> pd->subsampling_x; + const int plane_block_width = block_width >> pd->subsampling_x; + const int plane_block_height = block_height >> pd->subsampling_y; + // Special handling for chroma sub8x8. + const int is_chroma_sub8_x = plane > 0 && plane_block_width < 4; + const int is_chroma_sub8_y = plane > 0 && plane_block_height < 4; + if (width) *width = plane_block_width + 2 * is_chroma_sub8_x; + if (height) *height = plane_block_height + 2 * is_chroma_sub8_y; + if (rows_within_bounds) { + *rows_within_bounds = + (block_rows >> pd->subsampling_y) + 2 * is_chroma_sub8_y; + } + if (cols_within_bounds) { + *cols_within_bounds = + (block_cols >> pd->subsampling_x) + 2 * is_chroma_sub8_x; + } } /* clang-format off */ @@ -1701,39 +1124,22 @@ typedef struct { ColorCost color_cost; } Av1ColorMapParam; -#if CONFIG_GLOBAL_MOTION -static INLINE int is_nontrans_global_motion(const MACROBLOCKD *xd) { - const MODE_INFO *mi = xd->mi[0]; - const MB_MODE_INFO *const mbmi = &mi->mbmi; +static INLINE int is_nontrans_global_motion(const MACROBLOCKD *xd, + const MB_MODE_INFO *mbmi) { int ref; -#if CONFIG_CB4X4 - const int unify_bsize = 1; -#else - const int unify_bsize = 0; -#endif - // First check if all modes are ZEROMV - if (mbmi->sb_type >= BLOCK_8X8 || unify_bsize) { - if (mbmi->mode != ZEROMV && mbmi->mode != ZERO_ZEROMV) return 0; - } else { - if ((mi->bmi[0].as_mode != ZEROMV && mi->bmi[0].as_mode != ZERO_ZEROMV) || - (mi->bmi[1].as_mode != ZEROMV && mi->bmi[1].as_mode != ZERO_ZEROMV) || - (mi->bmi[2].as_mode != ZEROMV && mi->bmi[2].as_mode != ZERO_ZEROMV) || - (mi->bmi[3].as_mode != ZEROMV && mi->bmi[3].as_mode != ZERO_ZEROMV)) - return 0; - } + // First check if all modes are GLOBALMV + if (mbmi->mode != GLOBALMV && mbmi->mode != GLOBAL_GLOBALMV) return 0; -#if !GLOBAL_SUB8X8_USED - if (mbmi->sb_type < BLOCK_8X8) return 0; -#endif + if (AOMMIN(mi_size_wide[mbmi->sb_type], mi_size_high[mbmi->sb_type]) < 2) + return 0; // Now check if all global motion is non translational for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) { - if (xd->global_motion[mbmi->ref_frame[ref]].wmtype <= TRANSLATION) return 0; + if (xd->global_motion[mbmi->ref_frame[ref]].wmtype == TRANSLATION) return 0; } return 1; } -#endif // CONFIG_GLOBAL_MOTION static INLINE PLANE_TYPE get_plane_type(int plane) { return (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV; @@ -1771,6 +1177,16 @@ static INLINE void transpose_int32(int32_t *dst, int dst_stride, for (c = 0; c < w; ++c) dst[c * dst_stride + r] = src[r * src_stride + c]; } +static INLINE int av1_get_max_eob(TX_SIZE tx_size) { + if (tx_size == TX_64X64 || tx_size == TX_64X32 || tx_size == TX_32X64) { + return 1024; + } + if (tx_size == TX_16X64 || tx_size == TX_64X16) { + return 512; + } + return tx_size_2d[tx_size]; +} + #ifdef __cplusplus } // extern "C" #endif |