update libaom to rev 76574b6c09515d6687ebfa9760319e521f5abeb3 (without moz.build and aom_ports/aom_once.h)

This commit is contained in:
Roy Tam 2019-04-19 13:08:28 +08:00
commit ef35212f8b
128 changed files with 9426 additions and 4984 deletions

View file

@ -28,9 +28,9 @@ static const SEG_LVL_FEATURES seg_lvl_lf_lut[MAX_MB_PLANE][2] = {
{ SEG_LVL_ALT_LF_V, SEG_LVL_ALT_LF_V }
};
static const int delta_lf_id_lut[MAX_MB_PLANE][2] = {
{ 0, 1 }, { 2, 2 }, { 3, 3 }
};
static const int delta_lf_id_lut[MAX_MB_PLANE][2] = { { 0, 1 },
{ 2, 2 },
{ 3, 3 } };
enum { VERT_EDGE = 0, HORZ_EDGE = 1, NUM_EDGE_DIRS } UENUM1BYTE(EDGE_DIR);
@ -2044,6 +2044,7 @@ static TX_SIZE set_lpf_parameters(
const BLOCK_SIZE bsize =
get_plane_block_size(mbmi->sb_type, plane_ptr->subsampling_x,
plane_ptr->subsampling_y);
assert(bsize < BLOCK_SIZES_ALL);
const int prediction_masks = edge_dir == VERT_EDGE
? block_size_wide[bsize] - 1
: block_size_high[bsize] - 1;

View file

@ -111,9 +111,8 @@ specialize qw/av1_highbd_convolve8_vert/, "$sse2_x86_64";
#inv txfm
add_proto qw/void av1_inv_txfm_add/, "const tran_low_t *dqcoeff, uint8_t *dst, int stride, const TxfmParam *txfm_param";
# TODO(http://crbug.com/aomedia/2350): avx2 is disabled due to test vector
# mismatches.
specialize qw/av1_inv_txfm_add ssse3 neon/;
# TODO(yunqing): Disable NEON version due to test vector mismatch.
specialize qw/av1_inv_txfm_add ssse3 avx2/; # neon/;
add_proto qw/void av1_highbd_inv_txfm_add/, "const tran_low_t *dqcoeff, uint8_t *dst, int stride, const TxfmParam *txfm_param";
# TODO(http://crbug.com/aomedia/2350): avx2 is disabled due to test vector
@ -164,9 +163,7 @@ add_proto qw/void av1_inv_txfm2d_add_32x8/, "const int32_t *input, uint16_t *out
add_proto qw/void av1_highbd_dr_prediction_z1/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_above, int dx, int dy, int bd";
specialize qw/av1_highbd_dr_prediction_z1 avx2/;
add_proto qw/void av1_highbd_dr_prediction_z2/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_above, int upsample_left, int dx, int dy, int bd";
# TODO(niva213@gmail.com): Re-enable avx2 after fixing valgrind issue
# https://crbug.com/aomedia/2316
# specialize qw/av1_highbd_dr_prediction_z2 avx2/;
specialize qw/av1_highbd_dr_prediction_z2 avx2/;
add_proto qw/void av1_highbd_dr_prediction_z3/, "uint16_t *dst, ptrdiff_t stride, int bw, int bh, const uint16_t *above, const uint16_t *left, int upsample_left, int dx, int dy, int bd";
specialize qw/av1_highbd_dr_prediction_z3 avx2/;

View file

@ -61,6 +61,8 @@ void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col,
int i;
int nplanes;
int chroma_ref;
assert(bsize < BLOCK_SIZES_ALL);
chroma_ref =
is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y);

View file

@ -187,9 +187,7 @@ typedef struct RD_STATS {
int64_t rdcost;
int64_t sse;
int skip; // sse should equal to dist when skip == 1
int64_t ref_rdcost;
int zero_rate;
uint8_t invalid_rate;
#if CONFIG_RD_DEBUG
int txb_coeff_cost[MAX_MB_PLANE];
int txb_coeff_cost_map[MAX_MB_PLANE][TXB_COEFF_COST_MAP_SIZE]
@ -537,6 +535,7 @@ typedef struct macroblockd {
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
uint16_t weight[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
uint8_t is_sec_rect;
// Counts of each reference frame in the above and left neighboring blocks.
@ -786,6 +785,8 @@ static INLINE BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize,
int subsampling_x,
int subsampling_y) {
if (bsize == BLOCK_INVALID) return BLOCK_INVALID;
assert(subsampling_x >= 0 && subsampling_x < 2);
assert(subsampling_y >= 0 && subsampling_y < 2);
return ss_size_lookup[bsize][subsampling_x][subsampling_y];
}
@ -1006,6 +1007,7 @@ static INLINE int get_vartx_max_txsize(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
}
static INLINE int is_motion_variation_allowed_bsize(BLOCK_SIZE bsize) {
assert(bsize < BLOCK_SIZES_ALL);
return AOMMIN(block_size_wide[bsize], block_size_high[bsize]) >= 8;
}

View file

@ -121,6 +121,7 @@ void av1_convolve_2d_sr_c(const uint8_t *src, int src_stride, uint8_t *dst,
int16_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
assert(w <= MAX_SB_SIZE && h <= MAX_SB_SIZE);
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const int bd = 8;
@ -704,6 +705,7 @@ void av1_highbd_convolve_2d_sr_c(const uint16_t *src, int src_stride,
int16_t im_block[(MAX_SB_SIZE + MAX_FILTER_TAP - 1) * MAX_SB_SIZE];
int im_h = h + filter_params_y->taps - 1;
int im_stride = w;
assert(w <= MAX_SB_SIZE && h <= MAX_SB_SIZE);
const int fo_vert = filter_params_y->taps / 2 - 1;
const int fo_horiz = filter_params_x->taps / 2 - 1;
const int bits =

View file

@ -435,16 +435,16 @@ static const aom_cdf_prob
{ AOM_CDF3(601, 943) }, { AOM_CDF3(14969, 21398) }
};
static const aom_cdf_prob default_newmv_cdf[NEWMV_MODE_CONTEXTS][CDF_SIZE(2)] =
{ { AOM_CDF2(24035) }, { AOM_CDF2(16630) }, { AOM_CDF2(15339) },
{ AOM_CDF2(8386) }, { AOM_CDF2(12222) }, { AOM_CDF2(4676) } };
static const aom_cdf_prob default_newmv_cdf[NEWMV_MODE_CONTEXTS][CDF_SIZE(
2)] = { { AOM_CDF2(24035) }, { AOM_CDF2(16630) }, { AOM_CDF2(15339) },
{ AOM_CDF2(8386) }, { AOM_CDF2(12222) }, { AOM_CDF2(4676) } };
static const aom_cdf_prob default_zeromv_cdf[GLOBALMV_MODE_CONTEXTS][CDF_SIZE(
2)] = { { AOM_CDF2(2175) }, { AOM_CDF2(1054) } };
static const aom_cdf_prob default_refmv_cdf[REFMV_MODE_CONTEXTS][CDF_SIZE(2)] =
{ { AOM_CDF2(23974) }, { AOM_CDF2(24188) }, { AOM_CDF2(17848) },
{ AOM_CDF2(28622) }, { AOM_CDF2(24312) }, { AOM_CDF2(19923) } };
static const aom_cdf_prob default_refmv_cdf[REFMV_MODE_CONTEXTS][CDF_SIZE(
2)] = { { AOM_CDF2(23974) }, { AOM_CDF2(24188) }, { AOM_CDF2(17848) },
{ AOM_CDF2(28622) }, { AOM_CDF2(24312) }, { AOM_CDF2(19923) } };
static const aom_cdf_prob default_drl_cdf[DRL_MODE_CONTEXTS][CDF_SIZE(2)] = {
{ AOM_CDF2(13104) }, { AOM_CDF2(24560) }, { AOM_CDF2(18945) }
@ -470,11 +470,11 @@ static const aom_cdf_prob default_interintra_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(
{ AOM_CDF2(30237) } };
static const aom_cdf_prob
default_interintra_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(INTERINTRA_MODES)] =
{ { AOM_CDF4(8192, 16384, 24576) },
{ AOM_CDF4(1875, 11082, 27332) },
{ AOM_CDF4(2473, 9996, 26388) },
{ AOM_CDF4(4238, 11537, 25926) } };
default_interintra_mode_cdf[BLOCK_SIZE_GROUPS][CDF_SIZE(
INTERINTRA_MODES)] = { { AOM_CDF4(8192, 16384, 24576) },
{ AOM_CDF4(1875, 11082, 27332) },
{ AOM_CDF4(2473, 9996, 26388) },
{ AOM_CDF4(4238, 11537, 25926) } };
static const aom_cdf_prob
default_wedge_interintra_cdf[BLOCK_SIZES_ALL][CDF_SIZE(2)] = {
@ -500,51 +500,51 @@ static const aom_cdf_prob default_compound_type_cdf[BLOCK_SIZES_ALL][CDF_SIZE(
{ AOM_CDF2(16384) }
};
static const aom_cdf_prob default_wedge_idx_cdf[BLOCK_SIZES_ALL][CDF_SIZE(16)] =
{ { AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2438, 4440, 6599, 8663, 11005, 12874, 15751, 18094, 20359,
22362, 24127, 25702, 27752, 29450, 31171) },
{ AOM_CDF16(806, 3266, 6005, 6738, 7218, 7367, 7771, 14588, 16323, 17367,
18452, 19422, 22839, 26127, 29629) },
{ AOM_CDF16(2779, 3738, 4683, 7213, 7775, 8017, 8655, 14357, 17939, 21332,
24520, 27470, 29456, 30529, 31656) },
{ AOM_CDF16(1684, 3625, 5675, 7108, 9302, 11274, 14429, 17144, 19163,
20961, 22884, 24471, 26719, 28714, 30877) },
{ AOM_CDF16(1142, 3491, 6277, 7314, 8089, 8355, 9023, 13624, 15369, 16730,
18114, 19313, 22521, 26012, 29550) },
{ AOM_CDF16(2742, 4195, 5727, 8035, 8980, 9336, 10146, 14124, 17270,
20533, 23434, 25972, 27944, 29570, 31416) },
{ AOM_CDF16(1727, 3948, 6101, 7796, 9841, 12344, 15766, 18944, 20638,
22038, 23963, 25311, 26988, 28766, 31012) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(154, 987, 1925, 2051, 2088, 2111, 2151, 23033, 23703, 24284,
24985, 25684, 27259, 28883, 30911) },
{ AOM_CDF16(1135, 1322, 1493, 2635, 2696, 2737, 2770, 21016, 22935, 25057,
27251, 29173, 30089, 30960, 31933) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432,
20480, 22528, 24576, 26624, 28672, 30720) } };
static const aom_cdf_prob default_wedge_idx_cdf[BLOCK_SIZES_ALL][CDF_SIZE(
16)] = { { AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2438, 4440, 6599, 8663, 11005, 12874, 15751, 18094,
20359, 22362, 24127, 25702, 27752, 29450, 31171) },
{ AOM_CDF16(806, 3266, 6005, 6738, 7218, 7367, 7771, 14588, 16323,
17367, 18452, 19422, 22839, 26127, 29629) },
{ AOM_CDF16(2779, 3738, 4683, 7213, 7775, 8017, 8655, 14357, 17939,
21332, 24520, 27470, 29456, 30529, 31656) },
{ AOM_CDF16(1684, 3625, 5675, 7108, 9302, 11274, 14429, 17144,
19163, 20961, 22884, 24471, 26719, 28714, 30877) },
{ AOM_CDF16(1142, 3491, 6277, 7314, 8089, 8355, 9023, 13624, 15369,
16730, 18114, 19313, 22521, 26012, 29550) },
{ AOM_CDF16(2742, 4195, 5727, 8035, 8980, 9336, 10146, 14124,
17270, 20533, 23434, 25972, 27944, 29570, 31416) },
{ AOM_CDF16(1727, 3948, 6101, 7796, 9841, 12344, 15766, 18944,
20638, 22038, 23963, 25311, 26988, 28766, 31012) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(154, 987, 1925, 2051, 2088, 2111, 2151, 23033, 23703,
24284, 24985, 25684, 27259, 28883, 30911) },
{ AOM_CDF16(1135, 1322, 1493, 2635, 2696, 2737, 2770, 21016, 22935,
25057, 27251, 29173, 30089, 30960, 31933) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) },
{ AOM_CDF16(2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384,
18432, 20480, 22528, 24576, 26624, 28672, 30720) } };
static const aom_cdf_prob default_motion_mode_cdf[BLOCK_SIZES_ALL][CDF_SIZE(
MOTION_MODES)] = { { AOM_CDF3(10923, 21845) }, { AOM_CDF3(10923, 21845) },

View file

@ -526,7 +526,9 @@ enum {
#define DELTA_Q_SMALL 3
#define DELTA_Q_PROBS (DELTA_Q_SMALL)
#define DEFAULT_DELTA_Q_RES 4
#define DEFAULT_DELTA_Q_RES_PERCEPTUAL 4
#define DEFAULT_DELTA_Q_RES_OBJECTIVE 8
#define DELTA_LF_SMALL 3
#define DELTA_LF_PROBS (DELTA_LF_SMALL)
#define DEFAULT_DELTA_LF_RES 2
@ -625,6 +627,25 @@ enum {
RESTORE_TYPES = 4,
} UENUM1BYTE(RestorationType);
// Picture prediction structures (0-12 are predefined) in scalability metadata.
enum {
SCALABILITY_L1T2 = 0,
SCALABILITY_L1T3 = 1,
SCALABILITY_L2T1 = 2,
SCALABILITY_L2T2 = 3,
SCALABILITY_L2T3 = 4,
SCALABILITY_S2T1 = 5,
SCALABILITY_S2T2 = 6,
SCALABILITY_S2T3 = 7,
SCALABILITY_L2T1h = 8,
SCALABILITY_L2T2h = 9,
SCALABILITY_L2T3h = 10,
SCALABILITY_S2T1h = 11,
SCALABILITY_S2T2h = 12,
SCALABILITY_S2T3h = 13,
SCALABILITY_SS = 14
} UENUM1BYTE(SCALABILITY_STRUCTURES);
#define SUPERRES_SCALE_BITS 3
#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)

View file

@ -277,7 +277,6 @@ static INLINE TransformationType get_wmtype(const WarpedMotionParams *gm) {
typedef struct candidate_mv {
int_mv this_mv;
int_mv comp_mv;
int weight;
} CANDIDATE_MV;
static INLINE int is_zero_mv(const MV *mv) {

View file

@ -74,8 +74,9 @@ void av1_copy_frame_mvs(const AV1_COMMON *const cm,
static void add_ref_mv_candidate(
const MB_MODE_INFO *const candidate, const MV_REFERENCE_FRAME rf[2],
uint8_t *refmv_count, uint8_t *ref_match_count, uint8_t *newmv_count,
CANDIDATE_MV *ref_mv_stack, int_mv *gm_mv_candidates,
const WarpedMotionParams *gm_params, int col, int weight) {
CANDIDATE_MV *ref_mv_stack, uint16_t *ref_mv_weight,
int_mv *gm_mv_candidates, const WarpedMotionParams *gm_params, int col,
uint16_t weight) {
if (!is_inter_block(candidate)) return; // for intrabc
int index = 0, ref;
assert(weight % 2 == 0);
@ -93,12 +94,12 @@ static void add_ref_mv_candidate(
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
if (index < *refmv_count) ref_mv_stack[index].weight += weight;
if (index < *refmv_count) ref_mv_weight[index] += weight;
// Add a new item to the list.
if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight;
ref_mv_weight[index] = weight;
++(*refmv_count);
}
if (have_newmv_in_inter_mode(candidate->mode)) ++*newmv_count;
@ -122,13 +123,13 @@ static void add_ref_mv_candidate(
(ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
break;
if (index < *refmv_count) ref_mv_stack[index].weight += weight;
if (index < *refmv_count) ref_mv_weight[index] += weight;
// Add a new item to the list.
if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[index].this_mv = this_refmv[0];
ref_mv_stack[index].comp_mv = this_refmv[1];
ref_mv_stack[index].weight = weight;
ref_mv_weight[index] = weight;
++(*refmv_count);
}
if (have_newmv_in_inter_mode(candidate->mode)) ++*newmv_count;
@ -140,10 +141,10 @@ static void add_ref_mv_candidate(
static void scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int mi_row, int mi_col,
const MV_REFERENCE_FRAME rf[2], int row_offset,
CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count,
uint8_t *ref_match_count, uint8_t *newmv_count,
int_mv *gm_mv_candidates, int max_row_offset,
int *processed_rows) {
CANDIDATE_MV *ref_mv_stack, uint16_t *ref_mv_weight,
uint8_t *refmv_count, uint8_t *ref_match_count,
uint8_t *newmv_count, int_mv *gm_mv_candidates,
int max_row_offset, int *processed_rows) {
int end_mi = AOMMIN(xd->n4_w, cm->mi_cols - mi_col);
end_mi = AOMMIN(end_mi, mi_size_wide[BLOCK_64X64]);
const int n8_w_8 = mi_size_wide[BLOCK_8X8];
@ -169,10 +170,10 @@ static void scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
else if (abs(row_offset) > 1)
len = AOMMAX(len, n8_w_8);
int weight = 2;
uint16_t weight = 2;
if (xd->n4_w >= n8_w_8 && xd->n4_w <= n4_w) {
int inc = AOMMIN(-max_row_offset + row_offset + 1,
mi_size_high[candidate_bsize]);
uint16_t inc = AOMMIN(-max_row_offset + row_offset + 1,
mi_size_high[candidate_bsize]);
// Obtain range used in weight calculation.
weight = AOMMAX(weight, inc);
// Update processed rows.
@ -180,8 +181,9 @@ static void scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
}
add_ref_mv_candidate(candidate, rf, refmv_count, ref_match_count,
newmv_count, ref_mv_stack, gm_mv_candidates,
cm->global_motion, col_offset + i, len * weight);
newmv_count, ref_mv_stack, ref_mv_weight,
gm_mv_candidates, cm->global_motion, col_offset + i,
len * weight);
i += len;
}
@ -190,10 +192,10 @@ static void scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
static void scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int mi_row, int mi_col,
const MV_REFERENCE_FRAME rf[2], int col_offset,
CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count,
uint8_t *ref_match_count, uint8_t *newmv_count,
int_mv *gm_mv_candidates, int max_col_offset,
int *processed_cols) {
CANDIDATE_MV *ref_mv_stack, uint16_t *ref_mv_weight,
uint8_t *refmv_count, uint8_t *ref_match_count,
uint8_t *newmv_count, int_mv *gm_mv_candidates,
int max_col_offset, int *processed_cols) {
int end_mi = AOMMIN(xd->n4_h, cm->mi_rows - mi_row);
end_mi = AOMMIN(end_mi, mi_size_high[BLOCK_64X64]);
const int n8_h_8 = mi_size_high[BLOCK_8X8];
@ -229,8 +231,9 @@ static void scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
}
add_ref_mv_candidate(candidate, rf, refmv_count, ref_match_count,
newmv_count, ref_mv_stack, gm_mv_candidates,
cm->global_motion, col_offset, len * weight);
newmv_count, ref_mv_stack, ref_mv_weight,
gm_mv_candidates, cm->global_motion, col_offset,
len * weight);
i += len;
}
@ -240,8 +243,8 @@ static void scan_blk_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col,
const MV_REFERENCE_FRAME rf[2], int row_offset,
int col_offset, CANDIDATE_MV *ref_mv_stack,
uint8_t *ref_match_count, uint8_t *newmv_count,
int_mv *gm_mv_candidates,
uint16_t *ref_mv_weight, uint8_t *ref_match_count,
uint8_t *newmv_count, int_mv *gm_mv_candidates,
uint8_t refmv_count[MODE_CTX_REF_FRAMES]) {
const TileInfo *const tile = &xd->tile;
POSITION mi_pos;
@ -255,8 +258,9 @@ static void scan_blk_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const int len = mi_size_wide[BLOCK_8X8];
add_ref_mv_candidate(candidate, rf, refmv_count, ref_match_count,
newmv_count, ref_mv_stack, gm_mv_candidates,
cm->global_motion, mi_pos.col, 2 * len);
newmv_count, ref_mv_stack, ref_mv_weight,
gm_mv_candidates, cm->global_motion, mi_pos.col,
2 * len);
} // Analyze a single 8x8 block motion information.
}
@ -328,10 +332,11 @@ static int add_tpl_ref_mv(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int blk_row, int blk_col, int_mv *gm_mv_candidates,
uint8_t refmv_count[MODE_CTX_REF_FRAMES],
CANDIDATE_MV ref_mv_stacks[][MAX_REF_MV_STACK_SIZE],
uint16_t ref_mv_weights[][MAX_REF_MV_STACK_SIZE],
int16_t *mode_context) {
POSITION mi_pos;
int idx;
const int weight_unit = 1; // mi_size_wide[BLOCK_8X8];
const uint16_t weight_unit = 1; // mi_size_wide[BLOCK_8X8];
mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
@ -352,7 +357,7 @@ static int add_tpl_ref_mv(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int cur_offset_0 = get_relative_dist(&cm->seq_params.order_hint_info,
cur_frame_index, frame0_index);
CANDIDATE_MV *ref_mv_stack = ref_mv_stacks[rf[0]];
uint16_t *ref_mv_weight = ref_mv_weights[rf[0]];
if (prev_frame_mvs->mfmv0.as_int != INVALID_MV) {
int_mv this_refmv;
@ -369,12 +374,12 @@ static int add_tpl_ref_mv(const AV1_COMMON *cm, const MACROBLOCKD *xd,
for (idx = 0; idx < refmv_count[rf[0]]; ++idx)
if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int) break;
if (idx < refmv_count[rf[0]]) ref_mv_stack[idx].weight += 2 * weight_unit;
if (idx < refmv_count[rf[0]]) ref_mv_weight[idx] += 2 * weight_unit;
if (idx == refmv_count[rf[0]] &&
refmv_count[rf[0]] < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
ref_mv_stack[idx].weight = 2 * weight_unit;
ref_mv_weight[idx] = 2 * weight_unit;
++(refmv_count[rf[0]]);
}
return 1;
@ -392,7 +397,7 @@ static int add_tpl_ref_mv(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int cur_offset_1 = get_relative_dist(&cm->seq_params.order_hint_info,
cur_frame_index, frame1_index);
CANDIDATE_MV *ref_mv_stack = ref_mv_stacks[ref_frame];
uint16_t *ref_mv_weight = ref_mv_weights[ref_frame];
if (prev_frame_mvs->mfmv0.as_int != INVALID_MV) {
int_mv this_refmv;
int_mv comp_refmv;
@ -418,14 +423,13 @@ static int add_tpl_ref_mv(const AV1_COMMON *cm, const MACROBLOCKD *xd,
comp_refmv.as_int == ref_mv_stack[idx].comp_mv.as_int)
break;
if (idx < refmv_count[ref_frame])
ref_mv_stack[idx].weight += 2 * weight_unit;
if (idx < refmv_count[ref_frame]) ref_mv_weight[idx] += 2 * weight_unit;
if (idx == refmv_count[ref_frame] &&
refmv_count[ref_frame] < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
ref_mv_stack[idx].comp_mv.as_int = comp_refmv.as_int;
ref_mv_stack[idx].weight = 2 * weight_unit;
ref_mv_weight[idx] = 2 * weight_unit;
++(refmv_count[ref_frame]);
}
return 1;
@ -462,7 +466,8 @@ static void process_compound_ref_mv_candidate(
static void process_single_ref_mv_candidate(
const MB_MODE_INFO *const candidate, const AV1_COMMON *const cm,
MV_REFERENCE_FRAME ref_frame, uint8_t refmv_count[MODE_CTX_REF_FRAMES],
CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE]) {
CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE]) {
for (int rf_idx = 0; rf_idx < 2; ++rf_idx) {
if (candidate->ref_frame[rf_idx] > INTRA_FRAME) {
int_mv this_mv = candidate->mv[rf_idx];
@ -482,7 +487,7 @@ static void process_single_ref_mv_candidate(
// TODO(jingning): Set an arbitrary small number here. The weight
// doesn't matter as long as it is properly initialized.
ref_mv_stack[ref_frame][stack_idx].weight = 2;
ref_mv_weight[ref_frame][stack_idx] = 2;
++refmv_count[ref_frame];
}
}
@ -493,6 +498,7 @@ static void setup_ref_mv_list(
const AV1_COMMON *cm, const MACROBLOCKD *xd, MV_REFERENCE_FRAME ref_frame,
uint8_t refmv_count[MODE_CTX_REF_FRAMES],
CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE],
int_mv mv_ref_list[][MAX_MV_REF_CANDIDATES], int_mv *gm_mv_candidates,
int mi_row, int mi_col, int16_t *mode_context) {
const int bs = AOMMAX(xd->n4_w, xd->n4_h);
@ -536,25 +542,28 @@ static void setup_ref_mv_list(
// Scan the first above row mode info. row_offset = -1;
if (abs(max_row_offset) >= 1)
scan_row_mbmi(cm, xd, mi_row, mi_col, rf, -1, ref_mv_stack[ref_frame],
&refmv_count[ref_frame], &row_match_count, &newmv_count,
gm_mv_candidates, max_row_offset, &processed_rows);
ref_mv_weight[ref_frame], &refmv_count[ref_frame],
&row_match_count, &newmv_count, gm_mv_candidates,
max_row_offset, &processed_rows);
// Scan the first left column mode info. col_offset = -1;
if (abs(max_col_offset) >= 1)
scan_col_mbmi(cm, xd, mi_row, mi_col, rf, -1, ref_mv_stack[ref_frame],
&refmv_count[ref_frame], &col_match_count, &newmv_count,
gm_mv_candidates, max_col_offset, &processed_cols);
ref_mv_weight[ref_frame], &refmv_count[ref_frame],
&col_match_count, &newmv_count, gm_mv_candidates,
max_col_offset, &processed_cols);
// Check top-right boundary
if (has_tr)
scan_blk_mbmi(cm, xd, mi_row, mi_col, rf, -1, xd->n4_w,
ref_mv_stack[ref_frame], &row_match_count, &newmv_count,
gm_mv_candidates, &refmv_count[ref_frame]);
ref_mv_stack[ref_frame], ref_mv_weight[ref_frame],
&row_match_count, &newmv_count, gm_mv_candidates,
&refmv_count[ref_frame]);
const uint8_t nearest_match = (row_match_count > 0) + (col_match_count > 0);
const uint8_t nearest_refmv_count = refmv_count[ref_frame];
// TODO(yunqing): for comp_search, do it for all 3 cases.
for (int idx = 0; idx < nearest_refmv_count; ++idx)
ref_mv_stack[ref_frame][idx].weight += REF_CAT_LEVEL;
ref_mv_weight[ref_frame][idx] += REF_CAT_LEVEL;
if (cm->allow_ref_frame_mvs) {
int is_available = 0;
@ -584,7 +593,7 @@ static void setup_ref_mv_list(
for (int blk_col = 0; blk_col < blk_col_end; blk_col += step_w) {
int ret = add_tpl_ref_mv(cm, xd, mi_row, mi_col, ref_frame, blk_row,
blk_col, gm_mv_candidates, refmv_count,
ref_mv_stack, mode_context);
ref_mv_stack, ref_mv_weight, mode_context);
if (blk_row == 0 && blk_col == 0) is_available = ret;
}
}
@ -597,7 +606,8 @@ static void setup_ref_mv_list(
if (!check_sb_border(mi_row, mi_col, blk_row, blk_col)) continue;
add_tpl_ref_mv(cm, xd, mi_row, mi_col, ref_frame, blk_row, blk_col,
gm_mv_candidates, refmv_count, ref_mv_stack, mode_context);
gm_mv_candidates, refmv_count, ref_mv_stack, ref_mv_weight,
mode_context);
}
}
@ -605,8 +615,8 @@ static void setup_ref_mv_list(
// Scan the second outer area.
scan_blk_mbmi(cm, xd, mi_row, mi_col, rf, -1, -1, ref_mv_stack[ref_frame],
&row_match_count, &dummy_newmv_count, gm_mv_candidates,
&refmv_count[ref_frame]);
ref_mv_weight[ref_frame], &row_match_count, &dummy_newmv_count,
gm_mv_candidates, &refmv_count[ref_frame]);
for (int idx = 2; idx <= MVREF_ROW_COLS; ++idx) {
const int row_offset = -(idx << 1) + 1 + row_adj;
@ -615,16 +625,18 @@ static void setup_ref_mv_list(
if (abs(row_offset) <= abs(max_row_offset) &&
abs(row_offset) > processed_rows)
scan_row_mbmi(cm, xd, mi_row, mi_col, rf, row_offset,
ref_mv_stack[ref_frame], &refmv_count[ref_frame],
&row_match_count, &dummy_newmv_count, gm_mv_candidates,
max_row_offset, &processed_rows);
ref_mv_stack[ref_frame], ref_mv_weight[ref_frame],
&refmv_count[ref_frame], &row_match_count,
&dummy_newmv_count, gm_mv_candidates, max_row_offset,
&processed_rows);
if (abs(col_offset) <= abs(max_col_offset) &&
abs(col_offset) > processed_cols)
scan_col_mbmi(cm, xd, mi_row, mi_col, rf, col_offset,
ref_mv_stack[ref_frame], &refmv_count[ref_frame],
&col_match_count, &dummy_newmv_count, gm_mv_candidates,
max_col_offset, &processed_cols);
ref_mv_stack[ref_frame], ref_mv_weight[ref_frame],
&refmv_count[ref_frame], &col_match_count,
&dummy_newmv_count, gm_mv_candidates, max_col_offset,
&processed_cols);
}
const uint8_t ref_match_count = (row_match_count > 0) + (col_match_count > 0);
@ -661,11 +673,13 @@ static void setup_ref_mv_list(
while (len > 0) {
int nr_len = 0;
for (int idx = 1; idx < len; ++idx) {
if (ref_mv_stack[ref_frame][idx - 1].weight <
ref_mv_stack[ref_frame][idx].weight) {
if (ref_mv_weight[ref_frame][idx - 1] < ref_mv_weight[ref_frame][idx]) {
CANDIDATE_MV tmp_mv = ref_mv_stack[ref_frame][idx - 1];
uint16_t tmp_ref_mv_weight = ref_mv_weight[ref_frame][idx - 1];
ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
ref_mv_stack[ref_frame][idx] = tmp_mv;
ref_mv_weight[ref_frame][idx - 1] = ref_mv_weight[ref_frame][idx];
ref_mv_weight[ref_frame][idx] = tmp_ref_mv_weight;
nr_len = idx;
}
}
@ -676,11 +690,13 @@ static void setup_ref_mv_list(
while (len > nearest_refmv_count) {
int nr_len = nearest_refmv_count;
for (int idx = nearest_refmv_count + 1; idx < len; ++idx) {
if (ref_mv_stack[ref_frame][idx - 1].weight <
ref_mv_stack[ref_frame][idx].weight) {
if (ref_mv_weight[ref_frame][idx - 1] < ref_mv_weight[ref_frame][idx]) {
CANDIDATE_MV tmp_mv = ref_mv_stack[ref_frame][idx - 1];
uint16_t tmp_ref_mv_weight = ref_mv_weight[ref_frame][idx - 1];
ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
ref_mv_stack[ref_frame][idx] = tmp_mv;
ref_mv_weight[ref_frame][idx - 1] = ref_mv_weight[ref_frame][idx];
ref_mv_weight[ref_frame][idx] = tmp_ref_mv_weight;
nr_len = idx;
}
}
@ -745,7 +761,7 @@ static void setup_ref_mv_list(
ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv =
comp_list[0][1];
}
ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
ref_mv_weight[ref_frame][refmv_count[ref_frame]] = 2;
++refmv_count[ref_frame];
} else {
for (int idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx) {
@ -753,7 +769,7 @@ static void setup_ref_mv_list(
comp_list[idx][0];
ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv =
comp_list[idx][1];
ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
ref_mv_weight[ref_frame][refmv_count[ref_frame]] = 2;
++refmv_count[ref_frame];
}
}
@ -779,7 +795,7 @@ static void setup_ref_mv_list(
refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
const MB_MODE_INFO *const candidate = xd->mi[-xd->mi_stride + idx];
process_single_ref_mv_candidate(candidate, cm, ref_frame, refmv_count,
ref_mv_stack);
ref_mv_stack, ref_mv_weight);
idx += mi_size_wide[candidate->sb_type];
}
@ -787,7 +803,7 @@ static void setup_ref_mv_list(
refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
const MB_MODE_INFO *const candidate = xd->mi[idx * xd->mi_stride - 1];
process_single_ref_mv_candidate(candidate, cm, ref_frame, refmv_count,
ref_mv_stack);
ref_mv_stack, ref_mv_weight);
idx += mi_size_high[candidate->sb_type];
}
@ -813,6 +829,7 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
MB_MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES],
CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE],
int_mv mv_ref_list[][MAX_MV_REF_CANDIDATES],
int_mv *global_mvs, int mi_row, int mi_col,
int16_t *mode_context) {
@ -848,8 +865,9 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
zeromv[0].as_int = zeromv[1].as_int = 0;
}
setup_ref_mv_list(cm, xd, ref_frame, ref_mv_count, ref_mv_stack, mv_ref_list,
zeromv, mi_row, mi_col, mode_context);
setup_ref_mv_list(cm, xd, ref_frame, ref_mv_count, ref_mv_stack,
ref_mv_weight, mv_ref_list, zeromv, mi_row, mi_col,
mode_context);
}
void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,

View file

@ -189,18 +189,17 @@ static INLINE int16_t av1_mode_context_analyzer(
return comp_ctx;
}
static INLINE uint8_t av1_drl_ctx(const CANDIDATE_MV *ref_mv_stack,
int ref_idx) {
if (ref_mv_stack[ref_idx].weight >= REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight >= REF_CAT_LEVEL)
static INLINE uint8_t av1_drl_ctx(const uint16_t *ref_mv_weight, int ref_idx) {
if (ref_mv_weight[ref_idx] >= REF_CAT_LEVEL &&
ref_mv_weight[ref_idx + 1] >= REF_CAT_LEVEL)
return 0;
if (ref_mv_stack[ref_idx].weight >= REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL)
if (ref_mv_weight[ref_idx] >= REF_CAT_LEVEL &&
ref_mv_weight[ref_idx + 1] < REF_CAT_LEVEL)
return 1;
if (ref_mv_stack[ref_idx].weight < REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL)
if (ref_mv_weight[ref_idx] < REF_CAT_LEVEL &&
ref_mv_weight[ref_idx + 1] < REF_CAT_LEVEL)
return 2;
return 0;
@ -251,6 +250,7 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
MB_MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES],
CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE],
int_mv mv_ref_list[][MAX_MV_REF_CANDIDATES],
int_mv *global_mvs, int mi_row, int mi_col,
int16_t *mode_context);

View file

@ -917,6 +917,7 @@ static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row,
static INLINE int is_chroma_reference(int mi_row, int mi_col, BLOCK_SIZE bsize,
int subsampling_x, int subsampling_y) {
assert(bsize < BLOCK_SIZES_ALL);
const int bw = mi_size_wide[bsize];
const int bh = mi_size_high[bsize];
int ref_pos = ((mi_row & 0x01) || !(bh & 0x01) || !subsampling_y) &&
@ -926,6 +927,8 @@ static INLINE int is_chroma_reference(int mi_row, int mi_col, BLOCK_SIZE bsize,
static INLINE BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
int subsampling_y) {
assert(subsampling_x >= 0 && subsampling_x < 2);
assert(subsampling_y >= 0 && subsampling_y < 2);
BLOCK_SIZE bs = bsize;
switch (bsize) {
case BLOCK_4X4:
@ -1076,6 +1079,7 @@ static INLINE int partition_cdf_length(BLOCK_SIZE bsize) {
static INLINE int max_block_wide(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
int plane) {
assert(bsize < BLOCK_SIZES_ALL);
int max_blocks_wide = block_size_wide[bsize];
const struct macroblockd_plane *const pd = &xd->plane[plane];

View file

@ -182,6 +182,7 @@ int av1_get_palette_cache(const MACROBLOCKD *const xd, int plane,
uint16_t *cache);
static INLINE int av1_get_palette_bsize_ctx(BLOCK_SIZE bsize) {
assert(bsize < BLOCK_SIZES_ALL);
return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8];
}

View file

@ -1140,6 +1140,7 @@ void av1_build_interintra_predictors_sbp(const AV1_COMMON *cm, MACROBLOCKD *xd,
uint8_t *pred, int stride,
const BUFFER_SET *ctx, int plane,
BLOCK_SIZE bsize) {
assert(bsize < BLOCK_SIZES_ALL);
if (is_cur_buf_hbd(xd)) {
DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
av1_build_intra_predictors_for_interintra(

View file

@ -1015,9 +1015,9 @@ static int intra_edge_filter_strength(int bs0, int bs1, int delta, int type) {
void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) {
if (!strength) return;
const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = {
{ 0, 4, 8, 4, 0 }, { 0, 5, 6, 5, 0 }, { 2, 4, 4, 4, 2 }
};
const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
{ 0, 5, 6, 5, 0 },
{ 2, 4, 4, 4, 2 } };
const int filt = strength - 1;
uint8_t edge[129];
@ -1048,9 +1048,9 @@ static void filter_intra_edge_corner(uint8_t *p_above, uint8_t *p_left) {
void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
if (!strength) return;
const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = {
{ 0, 4, 8, 4, 0 }, { 0, 5, 6, 5, 0 }, { 2, 4, 4, 4, 2 }
};
const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
{ 0, 5, 6, 5, 0 },
{ 2, 4, 4, 4, 2 } };
const int filt = strength - 1;
uint16_t edge[129];

View file

@ -431,7 +431,6 @@ static int32_t get_upscale_convolve_x0(int in_length, int out_length,
return (int32_t)((uint32_t)x0 & RS_SCALE_SUBPEL_MASK);
}
#ifndef __clang_analyzer__
static void down2_symeven(const uint8_t *const input, int length,
uint8_t *output) {
// Actual filter len = 2 * filter_len_half.
@ -486,7 +485,6 @@ static void down2_symeven(const uint8_t *const input, int length,
}
}
}
#endif
static void down2_symodd(const uint8_t *const input, int length,
uint8_t *output) {
@ -852,7 +850,6 @@ static void highbd_interpolate(const uint16_t *const input, int in_length,
&interp_filters[0][0], SUBPEL_TAPS);
}
#ifndef __clang_analyzer__
static void highbd_down2_symeven(const uint16_t *const input, int length,
uint16_t *output, int bd) {
// Actual filter len = 2 * filter_len_half.
@ -960,7 +957,6 @@ static void highbd_down2_symodd(const uint16_t *const input, int length,
}
}
}
#endif
static void highbd_resize_multistep(const uint16_t *const input, int length,
uint16_t *output, int olength,

View file

@ -1146,7 +1146,7 @@ void av1_loop_restoration_copy_planes(AV1LrStruct *loop_rest_ctxt,
static const copy_fun copy_funs[3] = { aom_yv12_partial_coloc_copy_y,
aom_yv12_partial_coloc_copy_u,
aom_yv12_partial_coloc_copy_v };
assert(num_planes <= 3);
for (int plane = 0; plane < num_planes; ++plane) {
if (cm->rst_info[plane].frame_restoration_type == RESTORE_NONE) continue;
AV1PixelRect tile_rect = loop_rest_ctxt->ctxt[plane].tile_rect;

View file

@ -122,6 +122,7 @@ extern "C" {
// If WIENER_WIN_CHROMA == WIENER_WIN - 2, that implies 5x5 filters are used for
// chroma. To use 7x7 for chroma set WIENER_WIN_CHROMA to WIENER_WIN.
#define WIENER_WIN_CHROMA (WIENER_WIN - 2)
#define WIENER_WIN_REDUCED (WIENER_WIN - 2)
#define WIENER_WIN2_CHROMA ((WIENER_WIN_CHROMA) * (WIENER_WIN_CHROMA))
#define WIENER_FILT_PREC_BITS 7

View file

@ -45,11 +45,13 @@ void av1_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w,
int other_h, int this_w, int this_h);
static INLINE int av1_is_valid_scale(const struct scale_factors *sf) {
assert(sf != NULL);
return sf->x_scale_fp != REF_INVALID_SCALE &&
sf->y_scale_fp != REF_INVALID_SCALE;
}
static INLINE int av1_is_scaled(const struct scale_factors *sf) {
assert(sf != NULL);
return av1_is_valid_scale(sf) &&
(sf->x_scale_fp != REF_NO_SCALE || sf->y_scale_fp != REF_NO_SCALE);
}

View file

@ -14,9 +14,9 @@
#include "av1/common/common_data.h"
#include "av1/common/scan.h"
DECLARE_ALIGNED(16, static const int16_t, default_scan_4x4[16]) = {
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
};
DECLARE_ALIGNED(16, static const int16_t,
default_scan_4x4[16]) = { 0, 1, 4, 8, 5, 2, 3, 6,
9, 12, 13, 10, 7, 11, 14, 15 };
DECLARE_ALIGNED(16, static const int16_t, mcol_scan_4x4[16]) = {
0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15,
@ -2376,9 +2376,9 @@ DECLARE_ALIGNED(16, static const int16_t,
990, 1021, 991, 1022, 0, 0
};
DECLARE_ALIGNED(16, static const int16_t, av1_default_iscan_4x4[16]) = {
0, 1, 5, 6, 2, 4, 7, 12, 3, 8, 11, 13, 9, 10, 14, 15
};
DECLARE_ALIGNED(16, static const int16_t,
av1_default_iscan_4x4[16]) = { 0, 1, 5, 6, 2, 4, 7, 12,
3, 8, 11, 13, 9, 10, 14, 15 };
DECLARE_ALIGNED(16, static const int16_t, av1_mcol_iscan_4x4[16]) = {
0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15,

File diff suppressed because it is too large Load diff

View file

@ -574,7 +574,6 @@ static int64_t highbd_warp_error(
CONVERT_TO_BYTEPTR(tmp), j, i, warp_w, warp_h,
WARP_ERROR_BLOCK, subsampling_x, subsampling_y, bd,
&conv_params);
gm_sumerr += highbd_frame_error(
tmp, WARP_ERROR_BLOCK, CONVERT_TO_SHORTPTR(dst8) + j + i * p_stride,
warp_w, warp_h, p_stride, bd);

View file

@ -1638,6 +1638,7 @@ static INLINE void lowbd_inv_txfm2d_add_no_identity_avx2(
assert(row_txfm != NULL);
int ud_flip, lr_flip;
get_flip_cfg(tx_type, &ud_flip, &lr_flip);
const __m256i scale0 = _mm256_set1_epi16(1 << (15 + shift[0]));
for (int i = 0; i < buf_size_nonzero_h_div16; i++) {
__m256i buf0[64];
const int32_t *input_row = input + (i << 4) * input_stride;
@ -1652,7 +1653,9 @@ static INLINE void lowbd_inv_txfm2d_add_no_identity_avx2(
round_shift_avx2(buf0, buf0, input_stride); // rect special code
}
row_txfm(buf0, buf0, cos_bit_row);
round_shift_16bit_w16_avx2(buf0, txfm_size_col, shift[0]);
for (int j = 0; j < txfm_size_col; ++j) {
buf0[j] = _mm256_mulhrs_epi16(buf0[j], scale0);
}
__m256i *buf1_cur = buf1 + (i << 4);
if (lr_flip) {
@ -1668,10 +1671,13 @@ static INLINE void lowbd_inv_txfm2d_add_no_identity_avx2(
}
}
}
const __m256i scale1 = _mm256_set1_epi16(1 << (15 + shift[1]));
for (int i = 0; i < buf_size_w_div16; i++) {
__m256i *buf1_cur = buf1 + i * txfm_size_row;
col_txfm(buf1_cur, buf1_cur, cos_bit_col);
round_shift_16bit_w16_avx2(buf1_cur, txfm_size_row, shift[1]);
for (int j = 0; j < txfm_size_row; ++j) {
buf1_cur[j] = _mm256_mulhrs_epi16(buf1_cur[j], scale1);
}
}
for (int i = 0; i < buf_size_w_div16; i++) {
lowbd_write_buffer_16xn_avx2(buf1 + i * txfm_size_row, output + 16 * i,

View file

@ -2820,8 +2820,22 @@ static void lowbd_inv_txfm2d_add_4x16_ssse3(const int32_t *input,
load_buffer_32bit_to_16bit_w4(input_cur, txfm_size_col, buf_cur,
row_one_loop);
transpose_16bit_4x8(buf_cur, buf_cur);
row_txfm(buf_cur, buf_cur, cos_bit_row);
round_shift_16bit_ssse3(buf_cur, row_one_loop, shift[0]);
if (row_txfm == iidentity4_new_ssse3) {
const __m128i scale = pair_set_epi16(NewSqrt2, 3 << (NewSqrt2Bits - 1));
const __m128i ones = _mm_set1_epi16(1);
for (int j = 0; j < 4; ++j) {
const __m128i buf_lo = _mm_unpacklo_epi16(buf_cur[j], ones);
const __m128i buf_hi = _mm_unpackhi_epi16(buf_cur[j], ones);
const __m128i buf_32_lo =
_mm_srai_epi32(_mm_madd_epi16(buf_lo, scale), (NewSqrt2Bits + 1));
const __m128i buf_32_hi =
_mm_srai_epi32(_mm_madd_epi16(buf_hi, scale), (NewSqrt2Bits + 1));
buf_cur[j] = _mm_packs_epi32(buf_32_lo, buf_32_hi);
}
} else {
row_txfm(buf_cur, buf_cur, cos_bit_row);
round_shift_16bit_ssse3(buf_cur, row_one_loop, shift[0]);
}
if (lr_flip) {
__m128i temp[8];
flip_buf_sse2(buf_cur, temp, txfm_size_col);
@ -2867,8 +2881,22 @@ static void lowbd_inv_txfm2d_add_16x4_ssse3(const int32_t *input,
txfm_size_row);
transpose_16bit_8x4(buf_cur, buf_cur);
}
row_txfm(buf, buf, cos_bit_row);
round_shift_16bit_ssse3(buf, txfm_size_col, shift[0]);
if (row_txfm == iidentity16_new_ssse3) {
const __m128i scale = pair_set_epi16(2 * NewSqrt2, 3 << (NewSqrt2Bits - 1));
const __m128i ones = _mm_set1_epi16(1);
for (int j = 0; j < 16; ++j) {
const __m128i buf_lo = _mm_unpacklo_epi16(buf[j], ones);
const __m128i buf_hi = _mm_unpackhi_epi16(buf[j], ones);
const __m128i buf_32_lo =
_mm_srai_epi32(_mm_madd_epi16(buf_lo, scale), (NewSqrt2Bits + 1));
const __m128i buf_32_hi =
_mm_srai_epi32(_mm_madd_epi16(buf_hi, scale), (NewSqrt2Bits + 1));
buf[j] = _mm_packs_epi32(buf_32_lo, buf_32_hi);
}
} else {
row_txfm(buf, buf, cos_bit_row);
round_shift_16bit_ssse3(buf, txfm_size_col, shift[0]);
}
if (lr_flip) {
__m128i temp[16];
flip_buf_sse2(buf, temp, 16);
@ -2916,22 +2944,14 @@ void av1_lowbd_inv_txfm2d_add_ssse3(const int32_t *input, uint8_t *output,
break;
}
}
void av1_inv_txfm_add_ssse3(const tran_low_t *dqcoeff, uint8_t *dst, int stride,
const TxfmParam *txfm_param) {
const TX_TYPE tx_type = txfm_param->tx_type;
if (!txfm_param->lossless) {
switch (txfm_param->tx_size) {
case TX_4X16:
case TX_16X4:
// TODO(http://crbug.com/aomedia/2350): the ssse3 versions cause test
// vector mismatches.
av1_inv_txfm_add_c(dqcoeff, dst, stride, txfm_param);
break;
default:
av1_lowbd_inv_txfm2d_add_ssse3(dqcoeff, dst, stride, tx_type,
txfm_param->tx_size, txfm_param->eob);
break;
}
const TX_TYPE tx_type = txfm_param->tx_type;
av1_lowbd_inv_txfm2d_add_ssse3(dqcoeff, dst, stride, tx_type,
txfm_param->tx_size, txfm_param->eob);
} else {
av1_inv_txfm_add_c(dqcoeff, dst, stride, txfm_param);
}

View file

@ -15,9 +15,9 @@
#include "av1/common/warped_motion.h"
static const uint8_t warp_highbd_arrange_bytes[16] = {
0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
};
static const uint8_t warp_highbd_arrange_bytes[16] = { 0, 2, 4, 6, 8, 10,
12, 14, 1, 3, 5, 7,
9, 11, 13, 15 };
static const uint8_t highbd_shuffle_alpha0_mask0[16] = {
0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
@ -25,12 +25,12 @@ static const uint8_t highbd_shuffle_alpha0_mask0[16] = {
static const uint8_t highbd_shuffle_alpha0_mask1[16] = {
4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7
};
static const uint8_t highbd_shuffle_alpha0_mask2[16] = {
8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11
};
static const uint8_t highbd_shuffle_alpha0_mask3[16] = {
12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15
};
static const uint8_t highbd_shuffle_alpha0_mask2[16] = { 8, 9, 10, 11, 8, 9,
10, 11, 8, 9, 10, 11,
8, 9, 10, 11 };
static const uint8_t highbd_shuffle_alpha0_mask3[16] = { 12, 13, 14, 15, 12, 13,
14, 15, 12, 13, 14, 15,
12, 13, 14, 15 };
static INLINE void highbd_prepare_horizontal_filter_coeff(int alpha, int sx,
__m128i *coeff) {

View file

@ -212,10 +212,10 @@ void av1_upsample_intra_edge_sse4_1(uint8_t *p, int sz) {
{ -1, 9, 9, -1, -1, 9, 9, -1, -1, 9, 9, -1, -1, 9, 9, -1 }
};
DECLARE_ALIGNED(16, static const int8_t, v_const[2][16]) = {
{ 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 },
{ 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 }
};
DECLARE_ALIGNED(
16, static const int8_t,
v_const[2][16]) = { { 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6 },
{ 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10 } };
// Extend first/last samples (upper-left p[-1], last p[sz-1])
// to support 4-tap filter

View file

@ -221,9 +221,9 @@ static const uint8_t shuffle_gamma0_mask1[16] = { 4, 5, 6, 7, 4, 5, 6, 7,
4, 5, 6, 7, 4, 5, 6, 7 };
static const uint8_t shuffle_gamma0_mask2[16] = { 8, 9, 10, 11, 8, 9, 10, 11,
8, 9, 10, 11, 8, 9, 10, 11 };
static const uint8_t shuffle_gamma0_mask3[16] = {
12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15
};
static const uint8_t shuffle_gamma0_mask3[16] = { 12, 13, 14, 15, 12, 13,
14, 15, 12, 13, 14, 15,
12, 13, 14, 15 };
static INLINE void filter_src_pixels(__m128i src, __m128i *tmp, __m128i *coeff,
const int offset_bits_horiz,

View file

@ -17,6 +17,7 @@
#include "av1/common/convolve.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
#include "aom_dsp/x86/convolve_avx2.h"
#include "aom_dsp/x86/synonyms.h"
#include "aom_dsp/x86/synonyms_avx2.h"
@ -25,6 +26,20 @@
// on the left.
// A row of, say, 8-bit pixels with values p0, p1, p2, ..., p30, p31 will be
// loaded and stored as [ p31 ... p17 p16 ][ p15 ... p1 p0 ].
// Exploiting the range of wiener filter coefficients,
// horizontal filtering can be done in 16 bit intermediate precision.
// The details are as follows :
// Consider the horizontal wiener filter coefficients of the following form :
// [C0, C1, C2, 2^(FILTER_BITS) -2 * (C0 + C1 + C2), C2, C1, C0]
// Subtracting 2^(FILTER_BITS) from the centre tap we get the following :
// [C0, C1, C2, -2 * (C0 + C1 + C2), C2, C1, C0]
// The sum of the product "C0 * p0 + C1 * p1 + C2 * p2 -2 * (C0 + C1 + C2) * p3
// + C2 * p4 + C1 * p5 + C0 * p6" would be in the range of signed 16 bit
// precision. Finally, after rounding the above result by round_0, we multiply
// the centre pixel by 2^(FILTER_BITS - round_0) and add it to get the
// horizontal filter output.
void av1_wiener_convolve_add_src_avx2(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x, int x_step_q4,
@ -37,224 +52,190 @@ void av1_wiener_convolve_add_src_avx2(const uint8_t *src, ptrdiff_t src_stride,
(void)x_step_q4;
(void)y_step_q4;
DECLARE_ALIGNED(32, uint16_t,
temp[(MAX_SB_SIZE + SUBPEL_TAPS - 1) * MAX_SB_SIZE]);
int intermediate_height = h + SUBPEL_TAPS - 2;
memset(temp + (intermediate_height * MAX_SB_SIZE), 0, MAX_SB_SIZE);
const int center_tap = ((SUBPEL_TAPS - 1) / 2);
DECLARE_ALIGNED(32, int16_t, im_block[(MAX_SB_SIZE + SUBPEL_TAPS) * 8]);
int im_h = h + SUBPEL_TAPS - 2;
int im_stride = 8;
memset(im_block + (im_h * im_stride), 0, MAX_SB_SIZE);
int i, j;
const int center_tap = (SUBPEL_TAPS - 1) / 2;
const uint8_t *const src_ptr = src - center_tap * src_stride - center_tap;
const __m128i zero_128 = _mm_setzero_si128();
const __m256i zero_256 = _mm256_setzero_si256();
__m256i filt[4], coeffs_h[4], coeffs_v[4], filt_center;
// Add an offset to account for the "add_src" part of the convolve function.
const __m128i offset = _mm_insert_epi16(zero_128, 1 << FILTER_BITS, 3);
assert(conv_params->round_0 > 0);
const __m256i clamp_low = zero_256;
filt[0] = _mm256_load_si256((__m256i const *)filt1_global_avx2);
filt[1] = _mm256_load_si256((__m256i const *)filt2_global_avx2);
filt[2] = _mm256_load_si256((__m256i const *)filt3_global_avx2);
filt[3] = _mm256_load_si256((__m256i const *)filt4_global_avx2);
filt_center = _mm256_load_si256((__m256i const *)filt_center_global_avx2);
const __m128i coeffs_x = _mm_loadu_si128((__m128i *)filter_x);
const __m256i filter_coeffs_x = _mm256_broadcastsi128_si256(coeffs_x);
// coeffs 0 1 0 1 0 1 0 1
coeffs_h[0] =
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0200u));
// coeffs 2 3 2 3 2 3 2 3
coeffs_h[1] =
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0604u));
// coeffs 4 5 4 5 4 5 4 5
coeffs_h[2] =
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0a08u));
// coeffs 6 7 6 7 6 7 6 7
coeffs_h[3] =
_mm256_shuffle_epi8(filter_coeffs_x, _mm256_set1_epi16(0x0e0cu));
const __m256i round_const_h =
_mm256_set1_epi16((1 << (conv_params->round_0 - 1)));
const __m256i round_const_horz =
_mm256_set1_epi16((1 << (bd + FILTER_BITS - conv_params->round_0 - 1)));
const __m256i clamp_low = _mm256_setzero_si256();
const __m256i clamp_high =
_mm256_set1_epi16(WIENER_CLAMP_LIMIT(conv_params->round_0, bd) - 1);
const __m128i round_shift_h = _mm_cvtsi32_si128(conv_params->round_0);
/* Horizontal filter */
{
// coeffs [ f7 f6 f5 f4 f3 f2 f1 f0 ]
const __m128i coeffs_x = _mm_add_epi16(xx_loadu_128(filter_x), offset);
// Add an offset to account for the "add_src" part of the convolve function.
const __m128i zero_128 = _mm_setzero_si128();
const __m128i offset_0 = _mm_insert_epi16(zero_128, 1 << FILTER_BITS, 3);
const __m128i coeffs_y = _mm_add_epi16(xx_loadu_128(filter_y), offset_0);
// coeffs [ f3 f2 f3 f2 f1 f0 f1 f0 ]
const __m128i coeffs_0123 = _mm_unpacklo_epi32(coeffs_x, coeffs_x);
// coeffs [ f7 f6 f7 f6 f5 f4 f5 f4 ]
const __m128i coeffs_4567 = _mm_unpackhi_epi32(coeffs_x, coeffs_x);
const __m256i filter_coeffs_y = _mm256_broadcastsi128_si256(coeffs_y);
// coeffs [ f1 f0 f1 f0 f1 f0 f1 f0 ]
const __m128i coeffs_01_128 = _mm_unpacklo_epi64(coeffs_0123, coeffs_0123);
// coeffs [ f3 f2 f3 f2 f3 f2 f3 f2 ]
const __m128i coeffs_23_128 = _mm_unpackhi_epi64(coeffs_0123, coeffs_0123);
// coeffs [ f5 f4 f5 f4 f5 f4 f5 f4 ]
const __m128i coeffs_45_128 = _mm_unpacklo_epi64(coeffs_4567, coeffs_4567);
// coeffs [ f7 f6 f7 f6 f7 f6 f7 f6 ]
const __m128i coeffs_67_128 = _mm_unpackhi_epi64(coeffs_4567, coeffs_4567);
// coeffs 0 1 0 1 0 1 0 1
coeffs_v[0] = _mm256_shuffle_epi32(filter_coeffs_y, 0x00);
// coeffs 2 3 2 3 2 3 2 3
coeffs_v[1] = _mm256_shuffle_epi32(filter_coeffs_y, 0x55);
// coeffs 4 5 4 5 4 5 4 5
coeffs_v[2] = _mm256_shuffle_epi32(filter_coeffs_y, 0xaa);
// coeffs 6 7 6 7 6 7 6 7
coeffs_v[3] = _mm256_shuffle_epi32(filter_coeffs_y, 0xff);
// coeffs [ f1 f0 f1 f0 f1 f0 f1 f0 ][ f1 f0 f1 f0 f1 f0 f1 f0 ]
const __m256i coeffs_01 = yy_set_m128i(coeffs_01_128, coeffs_01_128);
// coeffs [ f3 f2 f3 f2 f3 f2 f3 f2 ][ f3 f2 f3 f2 f3 f2 f3 f2 ]
const __m256i coeffs_23 = yy_set_m128i(coeffs_23_128, coeffs_23_128);
// coeffs [ f5 f4 f5 f4 f5 f4 f5 f4 ][ f5 f4 f5 f4 f5 f4 f5 f4 ]
const __m256i coeffs_45 = yy_set_m128i(coeffs_45_128, coeffs_45_128);
// coeffs [ f7 f6 f7 f6 f7 f6 f7 f6 ][ f7 f6 f7 f6 f7 f6 f7 f6 ]
const __m256i coeffs_67 = yy_set_m128i(coeffs_67_128, coeffs_67_128);
const __m256i round_const_v =
_mm256_set1_epi32((1 << (conv_params->round_1 - 1)) -
(1 << (bd + conv_params->round_1 - 1)));
const __m128i round_shift_v = _mm_cvtsi32_si128(conv_params->round_1);
const __m256i round_const = _mm256_set1_epi32(
(1 << (conv_params->round_0 - 1)) + (1 << (bd + FILTER_BITS - 1)));
for (j = 0; j < w; j += 8) {
for (i = 0; i < im_h; i += 2) {
__m256i data = _mm256_castsi128_si256(
_mm_loadu_si128((__m128i *)&src_ptr[(i * src_stride) + j]));
for (int i = 0; i < intermediate_height; ++i) {
for (int j = 0; j < w; j += 16) {
const uint8_t *data_ij = src_ptr + i * src_stride + j;
// Load the next line
if (i + 1 < im_h)
data = _mm256_inserti128_si256(
data,
_mm_loadu_si128(
(__m128i *)&src_ptr[(i * src_stride) + j + src_stride]),
1);
// Load 8-bit src data
const __m128i data_0 = xx_loadu_128(data_ij + 0);
const __m128i data_1 = xx_loadu_128(data_ij + 1);
const __m128i data_2 = xx_loadu_128(data_ij + 2);
const __m128i data_3 = xx_loadu_128(data_ij + 3);
const __m128i data_4 = xx_loadu_128(data_ij + 4);
const __m128i data_5 = xx_loadu_128(data_ij + 5);
const __m128i data_6 = xx_loadu_128(data_ij + 6);
const __m128i data_7 = xx_loadu_128(data_ij + 7);
__m256i res = convolve_lowbd_x(data, coeffs_h, filt);
// (Zero-)Extend 8-bit data to 16-bit data
const __m256i src_0 = _mm256_cvtepu8_epi16(data_0);
const __m256i src_1 = _mm256_cvtepu8_epi16(data_1);
const __m256i src_2 = _mm256_cvtepu8_epi16(data_2);
const __m256i src_3 = _mm256_cvtepu8_epi16(data_3);
const __m256i src_4 = _mm256_cvtepu8_epi16(data_4);
const __m256i src_5 = _mm256_cvtepu8_epi16(data_5);
const __m256i src_6 = _mm256_cvtepu8_epi16(data_6);
const __m256i src_7 = _mm256_cvtepu8_epi16(data_7);
res =
_mm256_sra_epi16(_mm256_add_epi16(res, round_const_h), round_shift_h);
// Multiply src data by filter coeffs and sum pairs
const __m256i res_0 = _mm256_madd_epi16(src_0, coeffs_01);
const __m256i res_1 = _mm256_madd_epi16(src_1, coeffs_01);
const __m256i res_2 = _mm256_madd_epi16(src_2, coeffs_23);
const __m256i res_3 = _mm256_madd_epi16(src_3, coeffs_23);
const __m256i res_4 = _mm256_madd_epi16(src_4, coeffs_45);
const __m256i res_5 = _mm256_madd_epi16(src_5, coeffs_45);
const __m256i res_6 = _mm256_madd_epi16(src_6, coeffs_67);
const __m256i res_7 = _mm256_madd_epi16(src_7, coeffs_67);
__m256i data_0 = _mm256_shuffle_epi8(data, filt_center);
// Calculate scalar product for even- and odd-indices separately,
// increasing to 32-bit precision
const __m256i res_even_sum = _mm256_add_epi32(
_mm256_add_epi32(res_0, res_4), _mm256_add_epi32(res_2, res_6));
const __m256i res_odd_sum = _mm256_add_epi32(
_mm256_add_epi32(res_1, res_5), _mm256_add_epi32(res_3, res_7));
const __m256i res_even = _mm256_srai_epi32(
_mm256_add_epi32(res_even_sum, round_const), conv_params->round_0);
const __m256i res_odd = _mm256_srai_epi32(
_mm256_add_epi32(res_odd_sum, round_const), conv_params->round_0);
// Reduce to 16-bit precision and pack even- and odd-index results
// back into one register. The _mm256_packs_epi32 intrinsic returns
// a register with the pixels ordered as follows:
// [ 15 13 11 9 14 12 10 8 ] [ 7 5 3 1 6 4 2 0 ]
const __m256i res = _mm256_packs_epi32(res_even, res_odd);
const __m256i res_clamped =
_mm256_min_epi16(_mm256_max_epi16(res, clamp_low), clamp_high);
// Store in a temporary array
yy_storeu_256(temp + i * MAX_SB_SIZE + j, res_clamped);
}
// multiply the center pixel by 2^(FILTER_BITS - round_0) and add it to
// the result
data_0 = _mm256_slli_epi16(data_0, FILTER_BITS - conv_params->round_0);
res = _mm256_add_epi16(res, data_0);
res = _mm256_add_epi16(res, round_const_horz);
const __m256i res_clamped =
_mm256_min_epi16(_mm256_max_epi16(res, clamp_low), clamp_high);
_mm256_store_si256((__m256i *)&im_block[i * im_stride], res_clamped);
}
}
/* Vertical filter */
{
// coeffs [ g7 g6 g5 g4 g3 g2 g1 g0 ]
const __m128i coeffs_y = _mm_add_epi16(xx_loadu_128(filter_y), offset);
/* Vertical filter */
{
__m256i src_0 = _mm256_loadu_si256((__m256i *)(im_block + 0 * im_stride));
__m256i src_1 = _mm256_loadu_si256((__m256i *)(im_block + 1 * im_stride));
__m256i src_2 = _mm256_loadu_si256((__m256i *)(im_block + 2 * im_stride));
__m256i src_3 = _mm256_loadu_si256((__m256i *)(im_block + 3 * im_stride));
__m256i src_4 = _mm256_loadu_si256((__m256i *)(im_block + 4 * im_stride));
__m256i src_5 = _mm256_loadu_si256((__m256i *)(im_block + 5 * im_stride));
// coeffs [ g3 g2 g3 g2 g1 g0 g1 g0 ]
const __m128i coeffs_0123 = _mm_unpacklo_epi32(coeffs_y, coeffs_y);
// coeffs [ g7 g6 g7 g6 g5 g4 g5 g4 ]
const __m128i coeffs_4567 = _mm_unpackhi_epi32(coeffs_y, coeffs_y);
__m256i s[8];
s[0] = _mm256_unpacklo_epi16(src_0, src_1);
s[1] = _mm256_unpacklo_epi16(src_2, src_3);
s[2] = _mm256_unpacklo_epi16(src_4, src_5);
// coeffs [ g1 g0 g1 g0 g1 g0 g1 g0 ]
const __m128i coeffs_01_128 = _mm_unpacklo_epi64(coeffs_0123, coeffs_0123);
// coeffs [ g3 g2 g3 g2 g3 g2 g3 g2 ]
const __m128i coeffs_23_128 = _mm_unpackhi_epi64(coeffs_0123, coeffs_0123);
// coeffs [ g5 g4 g5 g4 g5 g4 g5 g4 ]
const __m128i coeffs_45_128 = _mm_unpacklo_epi64(coeffs_4567, coeffs_4567);
// coeffs [ g7 g6 g7 g6 g7 g6 g7 g6 ]
const __m128i coeffs_67_128 = _mm_unpackhi_epi64(coeffs_4567, coeffs_4567);
s[4] = _mm256_unpackhi_epi16(src_0, src_1);
s[5] = _mm256_unpackhi_epi16(src_2, src_3);
s[6] = _mm256_unpackhi_epi16(src_4, src_5);
// coeffs [ g1 g0 g1 g0 g1 g0 g1 g0 ][ g1 g0 g1 g0 g1 g0 g1 g0 ]
const __m256i coeffs_01 = yy_set_m128i(coeffs_01_128, coeffs_01_128);
// coeffs [ g3 g2 g3 g2 g3 g2 g3 g2 ][ g3 g2 g3 g2 g3 g2 g3 g2 ]
const __m256i coeffs_23 = yy_set_m128i(coeffs_23_128, coeffs_23_128);
// coeffs [ g5 g4 g5 g4 g5 g4 g5 g4 ][ g5 g4 g5 g4 g5 g4 g5 g4 ]
const __m256i coeffs_45 = yy_set_m128i(coeffs_45_128, coeffs_45_128);
// coeffs [ g7 g6 g7 g6 g7 g6 g7 g6 ][ g7 g6 g7 g6 g7 g6 g7 g6 ]
const __m256i coeffs_67 = yy_set_m128i(coeffs_67_128, coeffs_67_128);
for (i = 0; i < h - 1; i += 2) {
const int16_t *data = &im_block[i * im_stride];
const __m256i round_const =
_mm256_set1_epi32((1 << (conv_params->round_1 - 1)) -
(1 << (bd + conv_params->round_1 - 1)));
const __m256i s6 =
_mm256_loadu_si256((__m256i *)(data + 6 * im_stride));
const __m256i s7 =
_mm256_loadu_si256((__m256i *)(data + 7 * im_stride));
for (int i = 0; i < h; ++i) {
for (int j = 0; j < w; j += 16) {
const uint16_t *data_ij = temp + i * MAX_SB_SIZE + j;
s[3] = _mm256_unpacklo_epi16(s6, s7);
s[7] = _mm256_unpackhi_epi16(s6, s7);
// Load 16-bit data from the output of the horizontal filter in
// which the pixels are ordered as follows:
// [ 15 13 11 9 14 12 10 8 ] [ 7 5 3 1 6 4 2 0 ]
const __m256i data_0 = yy_loadu_256(data_ij + 0 * MAX_SB_SIZE);
const __m256i data_1 = yy_loadu_256(data_ij + 1 * MAX_SB_SIZE);
const __m256i data_2 = yy_loadu_256(data_ij + 2 * MAX_SB_SIZE);
const __m256i data_3 = yy_loadu_256(data_ij + 3 * MAX_SB_SIZE);
const __m256i data_4 = yy_loadu_256(data_ij + 4 * MAX_SB_SIZE);
const __m256i data_5 = yy_loadu_256(data_ij + 5 * MAX_SB_SIZE);
const __m256i data_6 = yy_loadu_256(data_ij + 6 * MAX_SB_SIZE);
const __m256i data_7 = yy_loadu_256(data_ij + 7 * MAX_SB_SIZE);
__m256i res_a = convolve(s, coeffs_v);
__m256i res_b = convolve(s + 4, coeffs_v);
// Filter the even-indices, increasing to 32-bit precision
const __m256i src_0 = _mm256_unpacklo_epi16(data_0, data_1);
const __m256i src_2 = _mm256_unpacklo_epi16(data_2, data_3);
const __m256i src_4 = _mm256_unpacklo_epi16(data_4, data_5);
const __m256i src_6 = _mm256_unpacklo_epi16(data_6, data_7);
const __m256i res_a_round = _mm256_sra_epi32(
_mm256_add_epi32(res_a, round_const_v), round_shift_v);
const __m256i res_b_round = _mm256_sra_epi32(
_mm256_add_epi32(res_b, round_const_v), round_shift_v);
const __m256i res_0 = _mm256_madd_epi16(src_0, coeffs_01);
const __m256i res_2 = _mm256_madd_epi16(src_2, coeffs_23);
const __m256i res_4 = _mm256_madd_epi16(src_4, coeffs_45);
const __m256i res_6 = _mm256_madd_epi16(src_6, coeffs_67);
/* rounding code */
// 16 bit conversion
const __m256i res_16bit = _mm256_packs_epi32(res_a_round, res_b_round);
// 8 bit conversion and saturation to uint8
const __m256i res_8b = _mm256_packus_epi16(res_16bit, res_16bit);
const __m256i res_even = _mm256_add_epi32(
_mm256_add_epi32(res_0, res_2), _mm256_add_epi32(res_4, res_6));
const __m128i res_0 = _mm256_castsi256_si128(res_8b);
const __m128i res_1 = _mm256_extracti128_si256(res_8b, 1);
// Filter the odd-indices, increasing to 32-bit precision
const __m256i src_1 = _mm256_unpackhi_epi16(data_0, data_1);
const __m256i src_3 = _mm256_unpackhi_epi16(data_2, data_3);
const __m256i src_5 = _mm256_unpackhi_epi16(data_4, data_5);
const __m256i src_7 = _mm256_unpackhi_epi16(data_6, data_7);
// Store values into the destination buffer
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
__m128i *const p_1 = (__m128i *)&dst[i * dst_stride + j + dst_stride];
const __m256i res_1 = _mm256_madd_epi16(src_1, coeffs_01);
const __m256i res_3 = _mm256_madd_epi16(src_3, coeffs_23);
const __m256i res_5 = _mm256_madd_epi16(src_5, coeffs_45);
const __m256i res_7 = _mm256_madd_epi16(src_7, coeffs_67);
_mm_storel_epi64(p_0, res_0);
_mm_storel_epi64(p_1, res_1);
const __m256i res_odd = _mm256_add_epi32(
_mm256_add_epi32(res_1, res_3), _mm256_add_epi32(res_5, res_7));
s[0] = s[1];
s[1] = s[2];
s[2] = s[3];
// Pixels are currently in the following order:
// res_even order: [ 14 12 10 8 ] [ 6 4 2 0 ]
// res_odd order: [ 15 13 11 9 ] [ 7 5 3 1 ]
//
// Rearrange the pixels into the following order:
// res_lo order: [ 11 10 9 8 ] [ 3 2 1 0 ]
// res_hi order: [ 15 14 13 12 ] [ 7 6 5 4 ]
const __m256i res_lo = _mm256_unpacklo_epi32(res_even, res_odd);
const __m256i res_hi = _mm256_unpackhi_epi32(res_even, res_odd);
s[4] = s[5];
s[5] = s[6];
s[6] = s[7];
}
if (h - i) {
s[0] = _mm256_permute2x128_si256(s[0], s[4], 0x20);
s[1] = _mm256_permute2x128_si256(s[1], s[5], 0x20);
s[2] = _mm256_permute2x128_si256(s[2], s[6], 0x20);
const __m256i res_lo_round = _mm256_srai_epi32(
_mm256_add_epi32(res_lo, round_const), conv_params->round_1);
const __m256i res_hi_round = _mm256_srai_epi32(
_mm256_add_epi32(res_hi, round_const), conv_params->round_1);
const int16_t *data = &im_block[i * im_stride];
const __m128i s6_ = _mm_loadu_si128((__m128i *)(data + 6 * im_stride));
const __m128i s7_ = _mm_loadu_si128((__m128i *)(data + 7 * im_stride));
// Reduce to 16-bit precision and pack into the correct order:
// [ 15 14 13 12 11 10 9 8 ][ 7 6 5 4 3 2 1 0 ]
const __m256i res_16bit =
_mm256_packs_epi32(res_lo_round, res_hi_round);
__m128i s3 = _mm_unpacklo_epi16(s6_, s7_);
__m128i s7 = _mm_unpackhi_epi16(s6_, s7_);
// Reduce to 8-bit precision. This messes up the order:
// [ - - - - - - - - 15 14 13 12 11 10 9 8 ]
// [ - - - - - - - - 7 6 5 4 3 2 1 0 ]
const __m256i res_8bit =
_mm256_packus_epi16(res_16bit, zero_256 /* don't care value */);
s[3] = _mm256_inserti128_si256(_mm256_castsi128_si256(s3), s7, 1);
__m256i convolveres = convolve(s, coeffs_v);
// Swap the two central 32-bit values to get the order:
// [ - - - - - - - - - - - - - - - - ]
// [ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ]
const __m256i res_8bit2 = _mm256_permute4x64_epi64(res_8bit, 0xd8);
const __m256i res_round = _mm256_sra_epi32(
_mm256_add_epi32(convolveres, round_const_v), round_shift_v);
// Store the lower 128-bit lane in the dst array
xx_storeu_128(dst + i * dst_stride + j,
_mm256_castsi256_si128(res_8bit2));
/* rounding code */
// 16 bit conversion
__m128i reslo = _mm256_castsi256_si128(res_round);
__m128i reshi = _mm256_extracti128_si256(res_round, 1);
const __m128i res_16bit = _mm_packus_epi32(reslo, reshi);
// 8 bit conversion and saturation to uint8
const __m128i res_8b = _mm_packus_epi16(res_16bit, res_16bit);
__m128i *const p_0 = (__m128i *)&dst[i * dst_stride + j];
_mm_storel_epi64(p_0, res_8b);
}
}
}