Merge "Migrating old experiments into new playground branch and speedup" into playground

This commit is contained in:
Yue Chen
2014-06-26 15:36:44 -07:00
committed by Gerrit Code Review
27 changed files with 3881 additions and 6 deletions

5
configure vendored
View File

@@ -273,6 +273,11 @@ EXPERIMENT_LIST="
multiple_arf
spatial_svc
denoising
masked_interinter
interintra
masked_interintra
filterintra
ext_tx
"
CONFIG_LIST="
external_build

View File

@@ -118,11 +118,75 @@ static INLINE int mi_width_log2(BLOCK_SIZE sb_type) {
return mi_width_log2_lookup[sb_type];
}
#if CONFIG_MASKED_INTERINTER
#define MASK_BITS_SML 3
#define MASK_BITS_MED 4
#define MASK_BITS_BIG 5
#define MASK_NONE -1
static inline int get_mask_bits(BLOCK_SIZE sb_type) {
if (sb_type < BLOCK_8X8)
return 0;
if (sb_type <= BLOCK_8X8)
return MASK_BITS_SML;
else if (sb_type <= BLOCK_32X32)
return MASK_BITS_MED;
else
return MASK_BITS_BIG;
}
#endif
#if CONFIG_INTERINTRA
static INLINE TX_SIZE intra_size_log2_for_interintra(int bs) {
switch (bs) {
case 4:
return TX_4X4;
break;
case 8:
return TX_8X8;
break;
case 16:
return TX_16X16;
break;
case 32:
return TX_32X32;
break;
default:
return TX_32X32;
break;
}
}
static INLINE int is_interintra_allowed(BLOCK_SIZE sb_type) {
return ((sb_type >= BLOCK_8X8) && (sb_type < BLOCK_64X64));
}
#if CONFIG_MASKED_INTERINTRA
#define MASK_BITS_SML_INTERINTRA 3
#define MASK_BITS_MED_INTERINTRA 4
#define MASK_BITS_BIG_INTERINTRA 5
#define MASK_NONE_INTERINTRA -1
static INLINE int get_mask_bits_interintra(BLOCK_SIZE sb_type) {
if (sb_type == BLOCK_4X4)
return 0;
if (sb_type <= BLOCK_8X8)
return MASK_BITS_SML_INTERINTRA;
else if (sb_type <= BLOCK_32X32)
return MASK_BITS_MED_INTERINTRA;
else
return MASK_BITS_BIG_INTERINTRA;
}
#endif
#endif
// This structure now relates to 8x8 block regions.
typedef struct {
// Common for both INTER and INTRA blocks
BLOCK_SIZE sb_type;
PREDICTION_MODE mode;
#if CONFIG_FILTERINTRA
int filterbit, uv_filterbit;
#endif
TX_SIZE tx_size;
uint8_t skip;
uint8_t segment_id;
@@ -137,10 +201,30 @@ typedef struct {
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
uint8_t mode_context[MAX_REF_FRAMES];
INTERP_FILTER interp_filter;
#if CONFIG_EXT_TX
EXT_TX_TYPE ext_txfrm;
#endif
#if CONFIG_MASKED_INTERINTER
int use_masked_interinter;
int mask_index;
#endif
#if CONFIG_INTERINTRA
PREDICTION_MODE interintra_mode, interintra_uv_mode;
#if CONFIG_MASKED_INTERINTRA
int interintra_mask_index;
int interintra_uv_mask_index;
int use_masked_interintra;
#endif
#endif
} MB_MODE_INFO;
typedef struct {
MB_MODE_INFO mbmi;
#if CONFIG_FILTERINTRA
int b_filter_info[4];
#endif
b_mode_info bmi[4];
} MODE_INFO;
@@ -149,6 +233,16 @@ static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) {
: mi->mbmi.mode;
}
#if CONFIG_FILTERINTRA
static INLINE int is_filter_allowed(PREDICTION_MODE mode) {
return 1;
}
static INLINE int is_filter_enabled(TX_SIZE txsize) {
return (txsize <= TX_32X32);
}
#endif
static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
return mbmi->ref_frame[0] > INTRA_FRAME;
}
@@ -253,8 +347,20 @@ static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type,
const MACROBLOCKD *xd) {
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
#if !CONFIG_EXT_TX
if (plane_type != PLANE_TYPE_Y || is_inter_block(mbmi))
return DCT_DCT;
#else
if (plane_type != PLANE_TYPE_Y)
return DCT_DCT;
if (is_inter_block(mbmi)) {
if (mbmi->ext_txfrm == NORM || mbmi->tx_size >= TX_32X32)
return DCT_DCT;
else
return ADST_ADST;
}
#endif
return intra_mode_to_tx_type_lookup[mbmi->mode];
}
@@ -262,8 +368,20 @@ static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
const MACROBLOCKD *xd, int ib) {
const MODE_INFO *const mi = xd->mi[0];
#if !CONFIG_EXT_TX
if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(&mi->mbmi))
return DCT_DCT;
#else
if (plane_type != PLANE_TYPE_Y || xd->lossless)
return DCT_DCT;
if (is_inter_block(&mi->mbmi)) {
if (mi->mbmi.ext_txfrm == NORM)
return DCT_DCT;
else
return ADST_ADST;
}
#endif
return intra_mode_to_tx_type_lookup[get_y_mode(mi, ib)];
}

View File

@@ -13,6 +13,37 @@
#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_seg_common.h"
#if CONFIG_MASKED_INTERINTER
static const vp9_prob default_masked_interinter_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#endif
#if CONFIG_INTERINTRA
static const vp9_prob default_interintra_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#if CONFIG_MASKED_INTERINTRA
static const vp9_prob default_masked_interintra_prob[BLOCK_SIZES] = {
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
};
#endif
#endif
#if CONFIG_FILTERINTRA
const vp9_prob default_filterintra_prob[TX_SIZES][INTRA_MODES] = {
// DC V H D45 D135 D117 D153 D207 D63 TM
{153, 171, 147, 150, 129, 101, 100, 153, 132, 111},
{171, 173, 185, 131, 70, 53, 70, 148, 127, 114},
{175, 203, 213, 86, 45, 71, 41, 150, 125, 154},
{235, 230, 154, 202, 154, 205, 37, 128, 0, 202}
};
#endif
#if CONFIG_EXT_TX
const vp9_prob default_ext_tx_prob = 178; // 0.6 = 153, 0.7 = 178, 0.8 = 204
#endif
const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
{ // above = dc
{ 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
@@ -326,6 +357,21 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
fc->tx_probs = default_tx_probs;
vp9_copy(fc->skip_probs, default_skip_probs);
vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_MASKED_INTERINTER
vp9_copy(fc->masked_interinter_prob, default_masked_interinter_prob);
#endif
#if CONFIG_INTERINTRA
vp9_copy(fc->interintra_prob, default_interintra_prob);
#if CONFIG_MASKED_INTERINTRA
vp9_copy(fc->masked_interintra_prob, default_masked_interintra_prob);
#endif
#endif
#if CONFIG_FILTERINTRA
vp9_copy(fc->filterintra_prob, default_filterintra_prob);
#endif
#if CONFIG_EXT_TX
fc->ext_tx_prob = default_ext_tx_prob;
#endif
}
const vp9_tree_index vp9_switchable_interp_tree
@@ -416,6 +462,48 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
for (i = 0; i < SKIP_CONTEXTS; ++i)
fc->skip_probs[i] = adapt_prob(pre_fc->skip_probs[i], counts->skip[i]);
#if CONFIG_MASKED_INTERINTER
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (get_mask_bits(i))
fc->masked_interinter_prob[i] = adapt_prob
(pre_fc->masked_interinter_prob[i],
counts->masked_interinter[i]);
}
}
#endif
#if CONFIG_INTERINTRA
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (is_interintra_allowed(i))
fc->interintra_prob[i] = adapt_prob(pre_fc->interintra_prob[i],
counts->interintra[i]);
}
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; ++i) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
fc->masked_interintra_prob[i] = adapt_prob(
pre_fc->masked_interintra_prob[i],
counts->masked_interintra[i]);
}
}
#endif
}
#endif
#if CONFIG_FILTERINTRA
for (i = 0; i < TX_SIZES; ++i)
for (j = 0; j < INTRA_MODES; ++j)
fc->filterintra_prob[i][j] = adapt_prob(pre_fc->filterintra_prob[i][j],
counts->filterintra[i][j]);
#endif
#if CONFIG_EXT_TX
fc->ext_tx_prob = adapt_prob(pre_fc->ext_tx_prob, counts->ext_tx);
#endif
}
static void set_default_lf_deltas(struct loopfilter *lf) {

View File

@@ -52,6 +52,21 @@ typedef struct frame_contexts {
struct tx_probs tx_probs;
vp9_prob skip_probs[SKIP_CONTEXTS];
nmv_context nmvc;
#if CONFIG_MASKED_INTERINTER
vp9_prob masked_interinter_prob[BLOCK_SIZES];
#endif
#if CONFIG_INTERINTRA
vp9_prob interintra_prob[BLOCK_SIZES];
#if CONFIG_MASKED_INTERINTRA
vp9_prob masked_interintra_prob[BLOCK_SIZES];
#endif
#endif
#if CONFIG_FILTERINTRA
vp9_prob filterintra_prob[TX_SIZES][INTRA_MODES];
#endif
#if CONFIG_EXT_TX
vp9_prob ext_tx_prob;
#endif
} FRAME_CONTEXT;
typedef struct {
@@ -71,6 +86,21 @@ typedef struct {
struct tx_counts tx;
unsigned int skip[SKIP_CONTEXTS][2];
nmv_context_counts mv;
#if CONFIG_MASKED_INTERINTER
unsigned int masked_interinter[BLOCK_SIZES][2];
#endif
#if CONFIG_INTERINTRA
unsigned int interintra[BLOCK_SIZES][2];
#if CONFIG_MASKED_INTERINTRA
unsigned int masked_interintra[BLOCK_SIZES][2];
#endif
#endif
#if CONFIG_FILTERINTRA
unsigned int filterintra[TX_SIZES][INTRA_MODES][2];
#endif
#if CONFIG_EXT_TX
unsigned int ext_tx[2];
#endif
} FRAME_COUNTS;
extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];

View File

@@ -100,6 +100,14 @@ typedef enum {
TX_TYPES = 4
} TX_TYPE;
#if CONFIG_EXT_TX
typedef enum {
NORM = 0,
ALT = 1,
EXT_TX_TYPES = 2
} EXT_TX_TYPE;
#endif
typedef enum {
UNKNOWN = 0,
BT_601 = 1, // YUV

View File

@@ -212,6 +212,16 @@ typedef struct VP9Common {
PARTITION_CONTEXT *above_seg_context;
ENTROPY_CONTEXT *above_context;
#if CONFIG_MASKED_INTERINTER
int use_masked_interinter;
#endif
#if CONFIG_INTERINTRA
int use_interintra;
#if CONFIG_MASKED_INTERINTRA
int use_masked_interintra;
#endif
#endif
} VP9_COMMON;
static INLINE YV12_BUFFER_CONFIG *get_frame_new_buffer(VP9_COMMON *cm) {

View File

@@ -139,6 +139,302 @@ MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd, const MV *src_mv,
return clamped_mv;
}
#if CONFIG_MASKED_INTERINTER
#define MASK_WEIGHT_BITS 6
static int get_masked_weight(int m) {
#define SMOOTHER_LEN 32
static const uint8_t smoothfn[2 * SMOOTHER_LEN + 1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 2, 2, 3, 4, 5, 6,
8, 9, 12, 14, 17, 21, 24, 28,
32,
36, 40, 43, 47, 50, 52, 55, 56,
58, 59, 60, 61, 62, 62, 63, 63,
63, 63, 63, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
};
if (m < -SMOOTHER_LEN)
return 0;
else if (m > SMOOTHER_LEN)
return (1 << MASK_WEIGHT_BITS);
else
return smoothfn[m + SMOOTHER_LEN];
}
static int get_hard_mask(int m) {
return m > 0;
}
// Equation of line: f(x, y) = a[0]*(x - a[2]*w/4) + a[1]*(y - a[3]*h/4) = 0
// The soft mask is obtained by computing f(x, y) and then calling
// get_masked_weight(f(x, y)).
static const int mask_params_sml[1 << MASK_BITS_SML][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
};
static const int mask_params_med_hgtw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
};
static const int mask_params_med_hltw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
};
static const int mask_params_med_heqw[1 << MASK_BITS_MED][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_hgtw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
};
static const int mask_params_big_hltw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_heqw[1 << MASK_BITS_BIG][4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int *get_mask_params(int mask_index,
BLOCK_SIZE sb_type,
int h, int w) {
const int *a;
const int mask_bits = get_mask_bits(sb_type);
if (mask_index == MASK_NONE)
return NULL;
if (mask_bits == MASK_BITS_SML) {
a = mask_params_sml[mask_index];
} else if (mask_bits == MASK_BITS_MED) {
if (h > w)
a = mask_params_med_hgtw[mask_index];
else if (h < w)
a = mask_params_med_hltw[mask_index];
else
a = mask_params_med_heqw[mask_index];
} else if (mask_bits == MASK_BITS_BIG) {
if (h > w)
a = mask_params_big_hgtw[mask_index];
else if (h < w)
a = mask_params_big_hltw[mask_index];
else
a = mask_params_big_heqw[mask_index];
} else {
assert(0);
}
return a;
}
void vp9_generate_masked_weight(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_masked_weight(m);
}
}
void vp9_generate_hard_mask(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_hard_mask(m);
}
}
static void build_masked_compound(uint8_t *dst, int dst_stride,
uint8_t *dst2, int dst2_stride,
int mask_index, BLOCK_SIZE sb_type,
int h, int w) {
int i, j;
uint8_t mask[4096];
vp9_generate_masked_weight(mask_index, sb_type, h, w, mask, 64);
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int m = mask[i * 64 + j];
dst[i * dst_stride + j] = (dst[i * dst_stride + j] * m +
dst2[i * dst2_stride + j] *
((1 << MASK_WEIGHT_BITS) - m) +
(1 << (MASK_WEIGHT_BITS - 1))) >>
MASK_WEIGHT_BITS;
}
}
#endif
static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int bw, int bh,
int x, int y, int w, int h,
@@ -193,8 +489,21 @@ static void build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride
+ (scaled_mv.col >> SUBPEL_BITS);
#if CONFIG_MASKED_INTERINTER
if (ref && get_mask_bits(mi->mbmi.sb_type)
&& mi->mbmi.use_masked_interinter) {
uint8_t tmp_dst[4096];
inter_predictor(pre, pre_buf->stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
build_masked_compound(dst, dst_buf->stride, tmp_dst, 64,
mi->mbmi.mask_index, mi->mbmi.sb_type, h, w);
} else {
#endif
inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
subpel_x, subpel_y, sf, w, h, ref, kernel, xs, ys);
#if CONFIG_MASKED_INTERINTER
}
#endif
}
}
@@ -229,16 +538,39 @@ static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0);
#if CONFIG_INTERINTRA
if (xd->mi[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi[0]->mbmi.sb_type))
vp9_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
xd->plane[0].dst.stride, bsize);
#endif
}
void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1,
MAX_MB_PLANE - 1);
#if CONFIG_INTERINTRA
if (xd->mi[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi[0]->mbmi.sb_type))
vp9_build_interintra_predictors_sbuv(xd, xd->plane[1].dst.buf,
xd->plane[2].dst.buf,
xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
#endif
}
void vp9_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
MAX_MB_PLANE - 1);
#if CONFIG_INTERINTRA
if (xd->mi[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi[0]->mbmi.sb_type))
vp9_build_interintra_predictors(xd, xd->plane[0].dst.buf,
xd->plane[1].dst.buf, xd->plane[2].dst.buf,
xd->plane[0].dst.stride,
xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
#endif
}
// TODO(jingning): This function serves as a placeholder for decoder prediction
@@ -377,8 +709,21 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
}
}
#if CONFIG_MASKED_INTERINTER
if (ref && get_mask_bits(mi->mbmi.sb_type)
&& mi->mbmi.use_masked_interinter) {
uint8_t tmp_dst[4096];
inter_predictor(buf_ptr, buf_stride, tmp_dst, 64,
subpel_x, subpel_y, sf, w, h, 0, kernel, xs, ys);
build_masked_compound(dst, dst_buf->stride, tmp_dst, 64,
mi->mbmi.mask_index, mi->mbmi.sb_type, h, w);
} else {
#endif
inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
subpel_y, sf, w, h, ref, kernel, xs, ys);
#if CONFIG_MASKED_INTERINTER
}
#endif
}
}
@@ -407,6 +752,15 @@ void vp9_dec_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
0, 0, bw, bh, mi_x, mi_y);
}
}
#if CONFIG_INTERINTRA
if (xd->mi[0]->mbmi.ref_frame[1] == INTRA_FRAME &&
is_interintra_allowed(xd->mi[0]->mbmi.sb_type))
vp9_build_interintra_predictors(xd, xd->plane[0].dst.buf,
xd->plane[1].dst.buf, xd->plane[2].dst.buf,
xd->plane[0].dst.stride,
xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
#endif
}
void vp9_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],

View File

@@ -65,6 +65,13 @@ void vp9_setup_pre_planes(MACROBLOCKD *xd, int idx,
const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
const struct scale_factors *sf);
#if CONFIG_MASKED_INTERINTER
void vp9_generate_masked_weight(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride);
void vp9_generate_hard_mask(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride);
#endif
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -444,8 +444,227 @@ static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
}
}
#if CONFIG_FILTERINTRA
static void filter_intra_predictors_4tap(uint8_t *ypred_ptr, int y_stride,
int bs,
const uint8_t *yabove_row,
const uint8_t *yleft_col,
int mode) {
static const int prec_bits = 10;
static const int round_val = 511;
int k, r, c;
int pred[33][33];
int mean, ipred;
int taps4_4[10][4] = {
{735, 881, -537, -54},
{1005, 519, -488, -11},
{383, 990, -343, -6},
{442, 805, -542, 319},
{658, 616, -133, -116},
{875, 442, -141, -151},
{386, 741, -23, -80},
{390, 1027, -446, 51},
{679, 606, -523, 262},
{903, 922, -778, -23}
};
int taps4_8[10][4] = {
{648, 803, -444, 16},
{972, 620, -576, 7},
{561, 967, -499, -5},
{585, 762, -468, 144},
{596, 619, -182, -9},
{895, 459, -176, -153},
{557, 722, -126, -129},
{601, 839, -523, 105},
{562, 709, -499, 251},
{803, 872, -695, 43}
};
int taps4_16[10][4] = {
{423, 728, -347, 111},
{963, 685, -665, 23},
{281, 1024, -480, 216},
{640, 596, -437, 78},
{429, 669, -259, 99},
{740, 646, -415, 23},
{568, 771, -346, 40},
{404, 833, -486, 209},
{398, 712, -423, 307},
{939, 935, -887, 17}
};
int taps4_32[10][4] = {
{477, 737, -393, 150},
{881, 630, -546, 67},
{506, 984, -443, -20},
{114, 459, -270, 528},
{433, 528, 14, 3},
{837, 470, -301, -30},
{181, 777, 89, -107},
{-29, 716, -232, 259},
{589, 646, -495, 255},
{740, 884, -728, 77}
};
const int c1 = (bs >= 32) ? taps4_32[mode][0] : ((bs >= 16) ?
taps4_16[mode][0] : ((bs >= 8) ? taps4_8[mode][0] : taps4_4[mode][0]));
const int c2 = (bs >= 32) ? taps4_32[mode][1] : ((bs >= 16) ?
taps4_16[mode][1] : ((bs >= 8) ? taps4_8[mode][1] : taps4_4[mode][1]));
const int c3 = (bs >= 32) ? taps4_32[mode][2] : ((bs >= 16) ?
taps4_16[mode][2] : ((bs >= 8) ? taps4_8[mode][2] : taps4_4[mode][2]));
const int c4 = (bs >= 32) ? taps4_32[mode][3] : ((bs >= 16) ?
taps4_16[mode][3] : ((bs >= 8) ? taps4_8[mode][3] : taps4_4[mode][3]));
k = 0;
mean = 0;
while (k < bs) {
mean = mean + (int)yleft_col[k];
mean = mean + (int)yabove_row[k];
k++;
}
mean = (mean + bs) / (2 * bs);
for (r = 0; r < bs; r++)
pred[r + 1][0] = (int)yleft_col[r] - mean;
for (c = 0; c < 2 * bs + 1; c++)
pred[0][c] = (int)yabove_row[c - 1] - mean;
for (r = 1; r < bs + 1; r++)
for (c = 1; c < 2 * bs + 1 - r; c++) {
ipred = c1 * pred[r - 1][c] + c2 * pred[r][c - 1]
+ c3 * pred[r - 1][c - 1] + c4 * pred[r - 1][c + 1];
pred[r][c] = ipred < 0 ? -((-ipred + round_val) >> prec_bits) :
((ipred + round_val) >> prec_bits);
}
for (r = 0; r < bs; r++) {
for (c = 0; c < bs; c++) {
ipred = pred[r + 1][c + 1] + mean;
ypred_ptr[c] = clip_pixel(ipred);
}
ypred_ptr += y_stride;
}
}
static void build_filter_intra_predictors(const MACROBLOCKD *xd,
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
PREDICTION_MODE mode, TX_SIZE tx_size,
int up_available, int left_available,
int right_available, int x, int y,
int plane) {
int i;
DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
uint8_t *above_row = above_data + 16;
const uint8_t *const_above_row = above_row;
const int bs = 4 << tx_size;
int frame_width, frame_height;
int x0, y0;
const struct macroblockd_plane *const pd = &xd->plane[plane];
// Get current frame pointer, width and height.
if (plane == 0) {
frame_width = xd->cur_buf->y_width;
frame_height = xd->cur_buf->y_height;
} else {
frame_width = xd->cur_buf->uv_width;
frame_height = xd->cur_buf->uv_height;
}
// Get block position in current frame.
x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
vpx_memset(left_col, 129, 64);
// left
if (left_available) {
if (xd->mb_to_bottom_edge < 0) {
/* slower path if the block needs border extension */
if (y0 + bs <= frame_height) {
for (i = 0; i < bs; ++i)
left_col[i] = ref[i * ref_stride - 1];
} else {
const int extend_bottom = frame_height - y0;
for (i = 0; i < extend_bottom; ++i)
left_col[i] = ref[i * ref_stride - 1];
for (; i < bs; ++i)
left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
}
} else {
/* faster path if the block does not need extension */
for (i = 0; i < bs; ++i)
left_col[i] = ref[i * ref_stride - 1];
}
}
// TODO(hkuang) do not extend 2*bs pixels for all modes.
// above
if (up_available) {
const uint8_t *above_ref = ref - ref_stride;
if (xd->mb_to_right_edge < 0) {
/* slower path if the block needs border extension */
if (x0 + 2 * bs <= frame_width) {
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, 2 * bs);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 + bs <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
}
}
above_row[-1] = left_available ? above_ref[-1] : 129;
} else {
/* faster path if the block does not need extension */
if (bs == 4 && right_available && left_available) {
const_above_row = above_ref;
} else {
vpx_memcpy(above_row, above_ref, bs);
if (bs == 4 && right_available)
vpx_memcpy(above_row + bs, above_ref + bs, bs);
else
vpx_memset(above_row + bs, above_row[bs - 1], bs);
above_row[-1] = left_available ? above_ref[-1] : 129;
}
}
} else {
vpx_memset(above_row, 127, bs * 2);
above_row[-1] = 127;
}
// predict
filter_intra_predictors_4tap(dst, dst_stride, bs, const_above_row, left_col,
mode);
}
#endif
void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
TX_SIZE tx_size, PREDICTION_MODE mode,
#if CONFIG_FILTERINTRA
int filterbit,
#endif
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
int aoff, int loff, int plane) {
@@ -456,8 +675,708 @@ void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
const int have_right = ((block_idx & wmask) != wmask);
const int x = aoff * 4;
const int y = loff * 4;
#if CONFIG_FILTERINTRA
const int filterflag = is_filter_allowed(mode) && is_filter_enabled(tx_size)
&& filterbit;
#endif
assert(bwl >= 0);
#if CONFIG_FILTERINTRA
if (!filterflag) {
#endif
build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
have_top, have_left, have_right, x, y, plane);
#if CONFIG_FILTERINTRA
} else {
build_filter_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode,
tx_size, have_top, have_left, have_right, x, y, plane);
}
#endif
}
#if CONFIG_INTERINTRA
#if CONFIG_MASKED_INTERINTRA
#define MASK_WEIGHT_BITS_INTERINTRA 6
static int get_masked_weight_interintra(int m) {
#define SMOOTHER_LEN_INTERINTRA 32
static const uint8_t smoothfn[2 * SMOOTHER_LEN_INTERINTRA + 1] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 2, 2, 3, 4, 5, 6,
8, 9, 12, 14, 17, 21, 24, 28,
32,
36, 40, 43, 47, 50, 52, 55, 56,
58, 59, 60, 61, 62, 62, 63, 63,
63, 63, 63, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
};
if (m < -SMOOTHER_LEN_INTERINTRA)
return 0;
else if (m > SMOOTHER_LEN_INTERINTRA)
return (1 << MASK_WEIGHT_BITS_INTERINTRA);
else
return smoothfn[m + SMOOTHER_LEN_INTERINTRA];
}
static int get_hard_mask_interintra(int m) {
return m > 0;
}
// Equation of line: f(x, y) = a[0]*(x - a[2]*w/4) + a[1]*(y - a[3]*h/4) = 0
// The soft mask is obtained by computing f(x, y) and then calling
// get_masked_weight(f(x, y)).
static const int mask_params_sml_interintra[1 << MASK_BITS_SML_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
};
static const int mask_params_med_hgtw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
};
static const int mask_params_med_hltw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
};
static const int mask_params_med_heqw_interintra[1 << MASK_BITS_MED_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_hgtw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
};
static const int mask_params_big_hltw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 2},
{ 0, -2, 0, 2},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 2, 0},
{-2, 0, 2, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int mask_params_big_heqw_interintra[1 << MASK_BITS_BIG_INTERINTRA]
[4] = {
{-1, 2, 2, 2},
{ 1, -2, 2, 2},
{-2, 1, 2, 2},
{ 2, -1, 2, 2},
{ 2, 1, 2, 2},
{-2, -1, 2, 2},
{ 1, 2, 2, 2},
{-1, -2, 2, 2},
{-1, 2, 2, 1},
{ 1, -2, 2, 1},
{-1, 2, 2, 3},
{ 1, -2, 2, 3},
{ 1, 2, 2, 1},
{-1, -2, 2, 1},
{ 1, 2, 2, 3},
{-1, -2, 2, 3},
{-2, 1, 1, 2},
{ 2, -1, 1, 2},
{-2, 1, 3, 2},
{ 2, -1, 3, 2},
{ 2, 1, 1, 2},
{-2, -1, 1, 2},
{ 2, 1, 3, 2},
{-2, -1, 3, 2},
{ 0, 2, 0, 1},
{ 0, -2, 0, 1},
{ 0, 2, 0, 3},
{ 0, -2, 0, 3},
{ 2, 0, 1, 0},
{-2, 0, 1, 0},
{ 2, 0, 3, 0},
{-2, 0, 3, 0},
};
static const int *get_mask_params_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w) {
const int *a;
const int mask_bits = get_mask_bits_interintra(sb_type);
if (mask_index == MASK_NONE_INTERINTRA)
return NULL;
if (mask_bits == MASK_BITS_SML_INTERINTRA) {
a = mask_params_sml_interintra[mask_index];
} else if (mask_bits == MASK_BITS_MED_INTERINTRA) {
if (h > w)
a = mask_params_med_hgtw_interintra[mask_index];
else if (h < w)
a = mask_params_med_hltw_interintra[mask_index];
else
a = mask_params_med_heqw_interintra[mask_index];
} else if (mask_bits == MASK_BITS_BIG_INTERINTRA) {
if (h > w)
a = mask_params_big_hgtw_interintra[mask_index];
else if (h < w)
a = mask_params_big_hltw_interintra[mask_index];
else
a = mask_params_big_heqw_interintra[mask_index];
} else {
assert(0);
}
return a;
}
void vp9_generate_masked_weight_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params_interintra(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_masked_weight_interintra(m);
}
}
void vp9_generate_hard_mask_interintra(int mask_index, BLOCK_SIZE sb_type,
int h, int w, uint8_t *mask, int stride) {
int i, j;
const int *a = get_mask_params_interintra(mask_index, sb_type, h, w);
if (!a) return;
for (i = 0; i < h; ++i)
for (j = 0; j < w; ++j) {
int x = (j - (a[2] * w) / 4);
int y = (i - (a[3] * h) / 4);
int m = a[0] * x + a[1] * y;
mask[i * stride + j] = get_hard_mask_interintra(m);
}
}
#endif
static void combine_interintra(PREDICTION_MODE mode,
#if CONFIG_MASKED_INTERINTRA
int use_masked_interintra,
int mask_index,
BLOCK_SIZE bsize,
#endif
uint8_t *comppred,
int compstride,
uint8_t *interpred,
int interstride,
uint8_t *intrapred,
int intrastride,
int bw, int bh) {
static const int scale_bits = 8;
static const int scale_max = 256;
static const int scale_round = 127;
static const int weights1d[64] = {
128, 125, 122, 119, 116, 114, 111, 109,
107, 105, 103, 101, 99, 97, 96, 94,
93, 91, 90, 89, 88, 86, 85, 84,
83, 82, 81, 81, 80, 79, 78, 78,
77, 76, 76, 75, 75, 74, 74, 73,
73, 72, 72, 71, 71, 71, 70, 70,
70, 70, 69, 69, 69, 69, 68, 68,
68, 68, 68, 67, 67, 67, 67, 67,
};
int size = MAX(bw, bh);
int size_scale = (size >= 64 ? 1 :
size == 32 ? 2 :
size == 16 ? 4 :
size == 8 ? 8 : 16);
int i, j;
#if CONFIG_MASKED_INTERINTRA
if (use_masked_interintra && get_mask_bits_interintra(bsize)) {
uint8_t mask[4096];
vp9_generate_masked_weight_interintra(mask_index, bsize, bh, bw, mask, bw);
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int m = mask[i * bw + j];
comppred[i * compstride + j] =
(intrapred[i * intrastride + j] * m +
interpred[i * interstride + j] *
((1 << MASK_WEIGHT_BITS_INTERINTRA) - m) +
(1 << (MASK_WEIGHT_BITS_INTERINTRA - 1))) >>
MASK_WEIGHT_BITS_INTERINTRA;
}
}
return;
}
#endif
switch (mode) {
case V_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = weights1d[i * size_scale];
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case H_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = weights1d[j * size_scale];
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D63_PRED:
case D117_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = (weights1d[i * size_scale] * 3 +
weights1d[j * size_scale]) >> 2;
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D207_PRED:
case D153_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = (weights1d[j * size_scale] * 3 +
weights1d[i * size_scale]) >> 2;
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D135_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = weights1d[(i < j ? i : j) * size_scale];
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case D45_PRED:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
int scale = (weights1d[i * size_scale] +
weights1d[j * size_scale]) >> 1;
comppred[i * compstride + j] =
((scale_max - scale) * interpred[i * interstride + j] +
scale * intrapred[i * intrastride + j] + scale_round)
>> scale_bits;
}
}
break;
case TM_PRED:
case DC_PRED:
default:
for (i = 0; i < bh; ++i) {
for (j = 0; j < bw; ++j) {
comppred[i * compstride + j] = (interpred[i * interstride + j] +
intrapred[i * intrastride + j]) >> 1;
}
}
break;
}
}
static void build_intra_predictors_for_2nd_block_interintra
(const MACROBLOCKD *xd, const uint8_t *ref,
int ref_stride, uint8_t *dst, int dst_stride,
PREDICTION_MODE mode, TX_SIZE tx_size,
int up_available, int left_available,
int right_available, int bwltbh,
int x, int y, int plane) {
int i;
DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
uint8_t *above_row = above_data + 16;
const uint8_t *const_above_row = above_row;
const int bs = 4 << tx_size;
int frame_width, frame_height;
int x0, y0;
const struct macroblockd_plane *const pd = &xd->plane[plane];
const uint8_t *ref_fi;
int ref_stride_fi;
// 127 127 127 .. 127 127 127 127 127 127
// 129 A B .. Y Z
// 129 C D .. W X
// 129 E F .. U V
// 129 G H .. S T T T T T
// ..
once(init_intra_pred_fn_ptrs);
// Get current frame pointer, width and height.
if (plane == 0) {
frame_width = xd->cur_buf->y_width;
frame_height = xd->cur_buf->y_height;
} else {
frame_width = xd->cur_buf->uv_width;
frame_height = xd->cur_buf->uv_height;
}
// Get block position in current frame.
x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
vpx_memset(left_col, 129, 64);
// left
if (left_available) {
if (bwltbh) {
ref_fi = ref;
ref_stride_fi = ref_stride;
} else {
ref_fi = dst;
ref_stride_fi = dst_stride;
}
if (xd->mb_to_bottom_edge < 0) {
/* slower path if the block needs border extension */
if (y0 + bs <= frame_height) {
for (i = 0; i < bs; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
} else {
const int extend_bottom = frame_height - y0;
assert(extend_bottom >= 0);
for (i = 0; i < extend_bottom; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
for (; i < bs; ++i)
left_col[i] = ref_fi[(extend_bottom - 1) * ref_stride_fi - 1];
}
} else {
/* faster path if the block does not need extension */
for (i = 0; i < bs; ++i)
left_col[i] = ref_fi[i * ref_stride_fi - 1];
}
}
// TODO(hkuang) do not extend 2*bs pixels for all modes.
// above
if (up_available) {
const uint8_t *above_ref;
if (bwltbh) {
ref_fi = dst;
ref_stride_fi = dst_stride;
above_row[-1] = left_available ? ref[-ref_stride-1] : 129;
} else {
ref_fi = ref;
ref_stride_fi = ref_stride;
above_row[-1] = ref[-ref_stride-1];
}
above_ref = ref_fi - ref_stride_fi;
if (xd->mb_to_right_edge < 0) {
/* slower path if the block needs border extension */
if (x0 + 2 * bs <= frame_width) {
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, 2 * bs);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 + bs <= frame_width) {
const int r = frame_width - x0;
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, bs);
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
} else if (x0 <= frame_width) {
const int r = frame_width - x0;
assert(r >= 0);
if (right_available && bs == 4) {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
} else {
vpx_memcpy(above_row, above_ref, r);
vpx_memset(above_row + r, above_row[r - 1],
x0 + 2 * bs - frame_width);
}
}
} else {
/* faster path if the block does not need extension */
if (bs == 4 && right_available && left_available) {
const_above_row = above_ref;
} else {
vpx_memcpy(above_row, above_ref, bs);
if (bs == 4 && right_available)
vpx_memcpy(above_row + bs, above_ref + bs, bs);
else
vpx_memset(above_row + bs, above_row[bs - 1], bs);
}
}
} else {
vpx_memset(above_row, 127, bs * 2);
above_row[-1] = 127;
}
// predict
if (mode == DC_PRED) {
dc_pred[left_available][up_available][tx_size](dst, dst_stride,
const_above_row, left_col);
} else {
pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
}
}
// Break down rectangular intra prediction for joint spatio-temporal prediction
// into two square intra predictions.
static void build_intra_predictors_for_interintra(MACROBLOCKD *xd,
uint8_t *src, int src_stride,
uint8_t *pred_ptr, int stride,
PREDICTION_MODE mode,
int bw, int bh,
int up_available, int left_available,
int right_available, int plane) {
if (bw == bh) {
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, right_available,
0, 0, plane);
} else if (bw < bh) {
uint8_t *src_bottom = src + bw * src_stride;
uint8_t *pred_ptr_bottom = pred_ptr + bw * stride;
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, right_available,
0, 0, plane);
build_intra_predictors_for_2nd_block_interintra(xd, src_bottom, src_stride,
pred_ptr_bottom, stride,
mode, intra_size_log2_for_interintra(bw),
up_available, left_available, 0, 1,
0, bw, plane);
} else {
uint8_t *src_right = src + bh;
uint8_t *pred_ptr_right = pred_ptr + bh;
build_intra_predictors(xd, src, src_stride, pred_ptr, stride,
mode, intra_size_log2_for_interintra(bh),
up_available, left_available, 1,
0, 0, plane);
build_intra_predictors_for_2nd_block_interintra(xd, src_right, src_stride,
pred_ptr_right, stride,
mode, intra_size_log2_for_interintra(bh),
up_available, left_available, right_available, 0,
bh, 0, plane);
}
}
void vp9_build_interintra_predictors_sby(MACROBLOCKD *xd,
uint8_t *ypred,
int ystride,
BLOCK_SIZE bsize) {
int bw = 4 << b_width_log2(bsize);
int bh = 4 << b_height_log2(bsize);
uint8_t intrapredictor[4096];
build_intra_predictors_for_interintra(
xd, xd->plane[0].dst.buf, xd->plane[0].dst.stride,
intrapredictor, bw,
xd->mi[0]->mbmi.interintra_mode, bw, bh,
xd->up_available, xd->left_available, 0, 0);
combine_interintra(xd->mi[0]->mbmi.interintra_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi[0]->mbmi.use_masked_interintra,
xd->mi[0]->mbmi.interintra_mask_index,
bsize,
#endif
xd->plane[0].dst.buf, xd->plane[0].dst.stride,
ypred, ystride, intrapredictor, bw, bw, bh);
}
void vp9_build_interintra_predictors_sbuv(MACROBLOCKD *xd,
uint8_t *upred,
uint8_t *vpred,
int ustride, int vstride,
BLOCK_SIZE bsize) {
int bwl = b_width_log2(bsize), bw = 2 << bwl;
int bhl = b_height_log2(bsize), bh = 2 << bhl;
uint8_t uintrapredictor[1024];
uint8_t vintrapredictor[1024];
build_intra_predictors_for_interintra(
xd, xd->plane[1].dst.buf, xd->plane[1].dst.stride,
uintrapredictor, bw,
xd->mi[0]->mbmi.interintra_uv_mode, bw, bh,
xd->up_available, xd->left_available, 0, 1);
build_intra_predictors_for_interintra(
xd, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
vintrapredictor, bw,
xd->mi[0]->mbmi.interintra_uv_mode, bw, bh,
xd->up_available, xd->left_available, 0, 2);
combine_interintra(xd->mi[0]->mbmi.interintra_uv_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi[0]->mbmi.use_masked_interintra,
xd->mi[0]->mbmi.interintra_uv_mask_index,
bsize,
#endif
xd->plane[1].dst.buf, xd->plane[1].dst.stride,
upred, ustride, uintrapredictor, bw, bw, bh);
combine_interintra(xd->mi[0]->mbmi.interintra_uv_mode,
#if CONFIG_MASKED_INTERINTRA
xd->mi[0]->mbmi.use_masked_interintra,
xd->mi[0]->mbmi.interintra_uv_mask_index,
bsize,
#endif
xd->plane[2].dst.buf, xd->plane[2].dst.stride,
vpred, vstride, vintrapredictor, bw, bw, bh);
}
void vp9_build_interintra_predictors(MACROBLOCKD *xd,
uint8_t *ypred,
uint8_t *upred,
uint8_t *vpred,
int ystride, int ustride, int vstride,
BLOCK_SIZE bsize) {
vp9_build_interintra_predictors_sby(xd, ypred, ystride, bsize);
vp9_build_interintra_predictors_sbuv(xd, upred, vpred,
ustride, vstride, bsize);
}
#endif

View File

@@ -20,9 +20,37 @@ extern "C" {
void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
TX_SIZE tx_size, PREDICTION_MODE mode,
#if CONFIG_FILTERINTRA
int filterbit,
#endif
const uint8_t *ref, int ref_stride,
uint8_t *dst, int dst_stride,
int aoff, int loff, int plane);
#if CONFIG_INTERINTRA
void vp9_build_interintra_predictors(MACROBLOCKD *xd,
uint8_t *ypred,
uint8_t *upred,
uint8_t *vpred,
int ystride,
int ustride,
int vstride,
BLOCK_SIZE bsize);
void vp9_build_interintra_predictors_sby(MACROBLOCKD *xd,
uint8_t *ypred,
int ystride,
BLOCK_SIZE bsize);
void vp9_build_interintra_predictors_sbuv(MACROBLOCKD *xd,
uint8_t *upred,
uint8_t *vpred,
int ustride, int vstride,
BLOCK_SIZE bsize);
#if CONFIG_MASKED_INTERINTRA
void vp9_generate_masked_weight_interintra(int mask_index,
BLOCK_SIZE sb_type,
int h, int w,
uint8_t *mask, int stride);
#endif
#endif
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -506,6 +506,125 @@ specialize qw/vp9_sub_pixel_variance8x8/, "$sse2_x86inc", "$ssse3_x86inc";
add_proto qw/unsigned int vp9_sub_pixel_avg_variance8x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, const uint8_t *second_pred";
specialize qw/vp9_sub_pixel_avg_variance8x8/, "$sse2_x86inc", "$ssse3_x86inc";
if ((vpx_config("CONFIG_MASKED_INTERINTER") eq "yes") || ((vpx_config("CONFIG_INTERINTRA") eq "yes") && (vpx_config("CONFIG_MASKED_INTERINTRA") eq "yes"))) {
add_proto qw/unsigned int vp9_masked_variance32x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance32x16/;
add_proto qw/unsigned int vp9_masked_variance16x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masdctked_variance16x32/;
add_proto qw/unsigned int vp9_masked_variance64x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance64x32/;
add_proto qw/unsigned int vp9_masked_variance32x64/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance32x64/;
add_proto qw/unsigned int vp9_masked_variance32x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance32x32/;
add_proto qw/unsigned int vp9_masked_variance64x64/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance64x64/;
add_proto qw/unsigned int vp9_masked_variance16x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance16x16/;
add_proto qw/unsigned int vp9_masked_variance16x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance16x8/;
add_proto qw/unsigned int vp9_masked_variance8x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance8x16/;
add_proto qw/unsigned int vp9_masked_variance8x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance8x8/;
add_proto qw/unsigned int vp9_masked_variance8x4/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance8x4/;
add_proto qw/unsigned int vp9_masked_variance4x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance4x8/;
add_proto qw/unsigned int vp9_masked_variance4x4/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_variance4x4/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance64x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance64x64/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance32x64/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance32x64/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance64x32/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance64x32/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance32x16/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance32x16/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance16x32/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance16x32/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance32x32/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance32x32/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance16x16/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance16x16/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance8x16/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance8x16/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance16x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance16x8/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance8x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance8x8/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance8x4/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance8x4/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance4x8/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance4x8/;
add_proto qw/unsigned int vp9_masked_sub_pixel_variance4x4/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride, unsigned int *sse";
specialize qw/vp9_masked_sub_pixel_variance4x4/;
add_proto qw/unsigned int vp9_masked_sad64x64/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad64x64/;
add_proto qw/unsigned int vp9_masked_sad32x64/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad32x64/;
add_proto qw/unsigned int vp9_masked_sad64x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad64x32/;
add_proto qw/unsigned int vp9_masked_sad32x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad32x16/;
add_proto qw/unsigned int vp9_masked_sad16x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad16x32/;
add_proto qw/unsigned int vp9_masked_sad32x32/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad32x32/;
add_proto qw/unsigned int vp9_masked_sad16x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad16x16/;
add_proto qw/unsigned int vp9_masked_sad16x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad16x8/;
add_proto qw/unsigned int vp9_masked_sad8x16/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad8x16/;
add_proto qw/unsigned int vp9_masked_sad8x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad8x8/;
add_proto qw/unsigned int vp9_masked_sad8x4/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad8x4/;
add_proto qw/unsigned int vp9_masked_sad4x8/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad4x8/;
add_proto qw/unsigned int vp9_masked_sad4x4/, "const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *mask, int mask_stride";
specialize qw/vp9_masked_sad4x4/;
}
# TODO(jingning): need to convert 8x4/4x8 functions into mmx/sse form
add_proto qw/unsigned int vp9_sub_pixel_variance8x4/, "const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse";
specialize qw/vp9_sub_pixel_variance8x4/, "$sse2_x86inc", "$ssse3_x86inc";

View File

@@ -254,11 +254,24 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
: mi->mbmi.uv_mode;
int x, y;
uint8_t *dst;
#if CONFIG_FILTERINTRA
int fbit;
if (plane == 0)
if (mi->mbmi.sb_type < BLOCK_8X8)
fbit = mi->b_filter_info[block];
else
fbit = is_filter_enabled(tx_size) ? mi->mbmi.filterbit : 0;
else
fbit = is_filter_enabled(tx_size) ? mi->mbmi.uv_filterbit : 0;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
dst = &pd->dst.buf[4 * y * pd->dst.stride + 4 * x];
vp9_predict_intra_block(xd, block >> (tx_size << 1),
b_width_log2(plane_bsize), tx_size, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
dst, pd->dst.stride, dst, pd->dst.stride,
x, y, plane);
@@ -1246,6 +1259,53 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
vp9_diff_update_prob(&r, &fc->partition_prob[j][i]);
read_mv_probs(nmvc, cm->allow_high_precision_mv, &r);
#if CONFIG_EXT_TX
vp9_diff_update_prob(&r, &fc->ext_tx_prob);
#endif
#if CONFIG_MASKED_INTERINTER
if (cm->reference_mode != SINGLE_REFERENCE) {
cm->use_masked_interinter = vp9_read_bit(&r);
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (get_mask_bits(i))
vp9_diff_update_prob(&r, &fc->masked_interinter_prob[i]);
}
}
} else {
cm->use_masked_interinter = 0;
}
#endif
#if CONFIG_INTERINTRA
if (cm->reference_mode != COMPOUND_REFERENCE) {
cm->use_interintra = vp9_read_bit(&r);
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i)) {
vp9_diff_update_prob(&r, &fc->interintra_prob[i]);
}
}
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = vp9_read_bit(&r);
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
vp9_diff_update_prob(&r, &fc->masked_interintra_prob[i]);
}
}
} else {
cm->use_masked_interintra = 0;
#endif
}
} else {
cm->use_interintra = 0;
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = 0;
#endif
}
#endif
}
return vp9_reader_has_error(&r);
@@ -1297,6 +1357,10 @@ static void debug_check_frame_counts(const VP9_COMMON *const cm) {
assert(!memcmp(&cm->counts.tx, &zero_counts.tx, sizeof(cm->counts.tx)));
assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip)));
assert(!memcmp(&cm->counts.mv, &zero_counts.mv, sizeof(cm->counts.mv)));
#if CONFIG_EXT_TX
assert(!memcmp(cm->counts.ext_tx, zero_counts.ext_tx,
sizeof(cm->counts.ext_tx)));
#endif
}
#endif // NDEBUG

View File

@@ -175,29 +175,85 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
switch (bsize) {
case BLOCK_4X4:
#if !CONFIG_FILTERINTRA
for (i = 0; i < 4; ++i)
#else
for (i = 0; i < 4; ++i) {
#endif
mi->bmi[i].as_mode =
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[i].as_mode))
mi->b_filter_info[i] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[i].as_mode]);
else
mi->b_filter_info[i] = 0;
}
mbmi->filterbit = mi->b_filter_info[3];
#endif
mbmi->mode = mi->bmi[3].as_mode;
break;
case BLOCK_4X8:
mi->bmi[0].as_mode = mi->bmi[2].as_mode =
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[0].as_mode))
mi->b_filter_info[0] = mi->b_filter_info[2] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[0].as_mode]);
else
mi->b_filter_info[0] = mi->b_filter_info[2] = 0;
#endif
mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[1].as_mode))
mi->b_filter_info[1] = mi->b_filter_info[3] = mbmi->filterbit =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[1].as_mode]);
else
mi->b_filter_info[1] = mi->b_filter_info[3] = mbmi->filterbit = 0;
#endif
break;
case BLOCK_8X4:
mi->bmi[0].as_mode = mi->bmi[1].as_mode =
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[0].as_mode))
mi->b_filter_info[0] = mi->b_filter_info[1] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[0].as_mode]);
else
mi->b_filter_info[0] = mi->b_filter_info[1] = 0;
#endif
mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[2].as_mode))
mi->b_filter_info[2] = mi->b_filter_info[3] = mbmi->filterbit =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[2].as_mode]);
else
mi->b_filter_info[2] = mi->b_filter_info[3] = mbmi->filterbit = 0;
#endif
break;
default:
mbmi->mode = read_intra_mode(r,
get_y_mode_probs(mi, above_mi, left_mi, 0));
#if CONFIG_FILTERINTRA
if (is_filter_enabled(mbmi->tx_size) && is_filter_allowed(mbmi->mode))
mbmi->filterbit = vp9_read(r,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
else
mbmi->filterbit = 0;
#endif
}
mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
#if CONFIG_FILTERINTRA
if (is_filter_enabled(get_uv_tx_size(mbmi)) &&
is_filter_allowed(mbmi->uv_mode))
mbmi->uv_filterbit = vp9_read(r,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
else
mbmi->uv_filterbit = 0;
#endif
}
static int read_mv_component(vp9_reader *r,
@@ -335,25 +391,97 @@ static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
switch (bsize) {
case BLOCK_4X4:
#if !CONFIG_FILTERINTRA
for (i = 0; i < 4; ++i)
#else
for (i = 0; i < 4; ++i) {
#endif
mi->bmi[i].as_mode = read_intra_mode_y(cm, r, 0);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[i].as_mode)) {
mi->b_filter_info[i] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[i].as_mode]);
cm->counts.filterintra[0][mi->bmi[i].as_mode]
[mi->b_filter_info[i]]++;
} else {
mi->b_filter_info[i] = 0;
}
}
mbmi->filterbit = mi->b_filter_info[3];
#endif
mbmi->mode = mi->bmi[3].as_mode;
break;
case BLOCK_4X8:
mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, r, 0);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[0].as_mode)) {
mi->b_filter_info[0] = mi->b_filter_info[2] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[0].as_mode]);
cm->counts.filterintra[0][mi->bmi[0].as_mode][mi->b_filter_info[0]]++;
} else {
mi->b_filter_info[0] = mi->b_filter_info[2] = 0;
}
#endif
mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
read_intra_mode_y(cm, r, 0);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[1].as_mode)) {
mi->b_filter_info[1] = mi->b_filter_info[3] = mbmi->filterbit =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[1].as_mode]);
cm->counts.filterintra[0][mi->bmi[1].as_mode][mi->b_filter_info[1]]++;
} else {
mi->b_filter_info[1] = mi->b_filter_info[3] = mbmi->filterbit = 0;
}
#endif
break;
case BLOCK_8X4:
mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, r, 0);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[0].as_mode)) {
mi->b_filter_info[0] = mi->b_filter_info[1] =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[0].as_mode]);
cm->counts.filterintra[0][mi->bmi[0].as_mode][mi->b_filter_info[0]]++;
} else {
mi->b_filter_info[0] = mi->b_filter_info[1] = 0;
}
#endif
mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
read_intra_mode_y(cm, r, 0);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[2].as_mode)) {
mi->b_filter_info[2] = mi->b_filter_info[3] = mbmi->filterbit =
vp9_read(r, cm->fc.filterintra_prob[0][mi->bmi[2].as_mode]);
cm->counts.filterintra[0][mi->bmi[2].as_mode][mi->b_filter_info[2]]++;
} else {
mi->b_filter_info[2] = mi->b_filter_info[3] = mbmi->filterbit = 0;
}
#endif
break;
default:
mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size)) {
mbmi->filterbit = vp9_read(r,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
cm->counts.filterintra[mbmi->tx_size][mbmi->mode][mbmi->filterbit]++;
} else {
mbmi->filterbit = 0;
}
#endif
}
mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi))) {
mbmi->uv_filterbit = vp9_read(r,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
cm->counts.filterintra[get_uv_tx_size(mbmi)]
[mbmi->uv_mode][mbmi->uv_filterbit]++;
} else {
mbmi->uv_filterbit = 0;
}
#endif
}
static INLINE int is_mv_valid(const MV *mv) {
@@ -433,6 +561,19 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
is_compound = has_second_ref(mbmi);
#if CONFIG_EXT_TX
if (mbmi->tx_size <= TX_16X16 &&
bsize >= BLOCK_8X8 &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
!mbmi->skip) {
mbmi->ext_txfrm = vp9_read(r, cm->fc.ext_tx_prob);
if (!cm->frame_parallel_decoding_mode)
++cm->counts.ext_tx[mbmi->ext_txfrm];
} else {
mbmi->ext_txfrm = NORM;
}
#endif
for (ref = 0; ref < 1 + is_compound; ++ref) {
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
vp9_find_mv_refs(cm, xd, tile, mi, frame, mbmi->ref_mvs[frame],
@@ -464,6 +605,37 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
? read_switchable_interp_filter(cm, xd, r)
: cm->interp_filter;
#if CONFIG_INTERINTRA
if ((cm->use_interintra) &&
is_interintra_allowed(bsize) &&
is_inter_mode(mbmi->mode) &&
(mbmi->ref_frame[1] <= INTRA_FRAME)) {
mbmi->ref_frame[1] = vp9_read(r, cm->fc.interintra_prob[bsize]) ?
INTRA_FRAME : NONE;
cm->counts.interintra[bsize][mbmi->ref_frame[1] == INTRA_FRAME]++;
#if CONFIG_MASKED_INTERINTRA
mbmi->use_masked_interintra = 0;
#endif
if (mbmi->ref_frame[1] == INTRA_FRAME) {
mbmi->interintra_mode =
read_intra_mode_y(cm, r, size_group_lookup[bsize]);
mbmi->interintra_uv_mode = mbmi->interintra_mode;
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra && get_mask_bits_interintra(bsize)) {
mbmi->use_masked_interintra = vp9_read(r,
cm->fc.masked_interintra_prob[bsize]);
cm->counts.masked_interintra[bsize][mbmi->use_masked_interintra]++;
if (mbmi->use_masked_interintra) {
mbmi->interintra_mask_index = vp9_read_literal(r,
get_mask_bits_interintra(bsize));
mbmi->interintra_uv_mask_index = mbmi->interintra_mask_index;
}
}
#endif
}
}
#endif
if (bsize < BLOCK_8X8) {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; // 1 or 2
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; // 1 or 2
@@ -508,6 +680,21 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv, nearestmv,
nearestmv, nearmv, is_compound, allow_hp, r);
}
#if CONFIG_MASKED_INTERINTER
mbmi->use_masked_interinter = 0;
if (cm->use_masked_interinter &&
cm->reference_mode != SINGLE_REFERENCE &&
is_inter_mode(mbmi->mode) &&
get_mask_bits(bsize) &&
mbmi->ref_frame[1] > INTRA_FRAME) {
mbmi->use_masked_interinter =
vp9_read(r, cm->fc.masked_interinter_prob[bsize]);
cm->counts.masked_interinter[bsize][mbmi->use_masked_interinter]++;
if (mbmi->use_masked_interinter) {
mbmi->mask_index = vp9_read_literal(r, get_mask_bits(bsize));
}
}
#endif
}
static void read_inter_frame_mode_info(VP9_COMMON *const cm,

View File

@@ -266,6 +266,12 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
if (!is_inter) {
if (bsize >= BLOCK_8X8) {
write_intra_mode(w, mode, cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mode) && is_filter_enabled(mbmi->tx_size)) {
vp9_write(w, mbmi->filterbit,
cm->fc.filterintra_prob[mbmi->tx_size][mode]);
}
#endif
} else {
int idx, idy;
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
@@ -274,15 +280,37 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
for (idx = 0; idx < 2; idx += num_4x4_w) {
const PREDICTION_MODE b_mode = mi->bmi[idy * 2 + idx].as_mode;
write_intra_mode(w, b_mode, cm->fc.y_mode_prob[0]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(b_mode)) {
vp9_write(w, mi->b_filter_info[idy * 2 + idx],
cm->fc.filterintra_prob[0][b_mode]);
}
#endif
}
}
}
write_intra_mode(w, mbmi->uv_mode, cm->fc.uv_mode_prob[mode]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi))) {
vp9_write(w, mbmi->uv_filterbit,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
}
#endif
} else {
const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx];
write_ref_frames(cpi, w);
#if CONFIG_EXT_TX
if (mbmi->tx_size <= TX_16X16 &&
bsize >= BLOCK_8X8 &&
!mbmi->skip &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
vp9_write(w, mbmi->ext_txfrm, cm->fc.ext_tx_prob);
}
#endif
// If segment skip is not enabled code the mode.
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
if (bsize >= BLOCK_8X8) {
@@ -300,6 +328,32 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
assert(mbmi->interp_filter == cm->interp_filter);
}
#if CONFIG_INTERINTRA
if ((cm->use_interintra) &&
cpi->common.reference_mode != COMPOUND_REFERENCE &&
is_interintra_allowed(bsize) &&
is_inter_mode(mode) &&
(mbmi->ref_frame[1] <= INTRA_FRAME)) {
vp9_write(w, mbmi->ref_frame[1] == INTRA_FRAME,
cm->fc.interintra_prob[bsize]);
if (mbmi->ref_frame[1] == INTRA_FRAME) {
write_intra_mode(w, mbmi->interintra_mode,
cm->fc.y_mode_prob[size_group_lookup[bsize]]);
#if CONFIG_MASKED_INTERINTRA
if (get_mask_bits_interintra(bsize) &&
cm->use_masked_interintra) {
vp9_write(w, mbmi->use_masked_interintra,
cm->fc.masked_interintra_prob[bsize]);
if (mbmi->use_masked_interintra) {
vp9_write_literal(w, mbmi->interintra_mask_index,
get_mask_bits_interintra(bsize));
}
}
#endif
}
}
#endif
if (bsize < BLOCK_8X8) {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -326,6 +380,18 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
allow_hp);
}
}
#if CONFIG_MASKED_INTERINTER
if (cm->use_masked_interinter &&
cm->reference_mode != SINGLE_REFERENCE &&
is_inter_mode(mode) &&
get_mask_bits(mbmi->sb_type) &&
mbmi->ref_frame[1] > INTRA_FRAME) {
vp9_write(w, mbmi->use_masked_interinter,
cm->fc.masked_interinter_prob[bsize]);
if (mbmi->use_masked_interinter)
vp9_write_literal(w, mbmi->mask_index, get_mask_bits(mbmi->sb_type));
}
#endif
}
}
@@ -350,6 +416,11 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8,
if (bsize >= BLOCK_8X8) {
write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->mode) && is_filter_enabled(mbmi->tx_size))
vp9_write(w, mbmi->filterbit,
cm->fc.filterintra_prob[mbmi->tx_size][mbmi->mode]);
#endif
} else {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -360,11 +431,22 @@ static void write_mb_modes_kf(const VP9_COMP *cpi, MODE_INFO **mi_8x8,
const int block = idy * 2 + idx;
write_intra_mode(w, mi->bmi[block].as_mode,
get_y_mode_probs(mi, above_mi, left_mi, block));
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[block].as_mode))
vp9_write(w, mi->b_filter_info[block],
cm->fc.filterintra_prob[0][mi->bmi[block].as_mode]);
#endif
}
}
}
write_intra_mode(w, mbmi->uv_mode, vp9_kf_uv_mode_prob[mbmi->mode]);
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mbmi->uv_mode) &&
is_filter_enabled(get_uv_tx_size(mbmi)))
vp9_write(w, mbmi->uv_filterbit,
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
#endif
}
static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
@@ -1176,6 +1258,95 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
cm->counts.partition[i], PARTITION_TYPES, &header_bc);
vp9_write_nmv_probs(cm, cm->allow_high_precision_mv, &header_bc);
#if CONFIG_EXT_TX
vp9_cond_prob_diff_update(&header_bc, &fc->ext_tx_prob, cm->counts.ext_tx);
#endif
#if CONFIG_MASKED_INTERINTER
if (cm->reference_mode != SINGLE_REFERENCE) {
if (!cpi->dummy_packing && cm->use_masked_interinter) {
cm->use_masked_interinter = 0;
for (i = 0; i < BLOCK_SIZES; i++)
if (get_mask_bits(i) && (cm->counts.masked_interinter[i][1] > 0)) {
cm->use_masked_interinter = 1;
break;
}
}
vp9_write_bit(&header_bc, cm->use_masked_interinter);
if (cm->use_masked_interinter) {
for (i = 0; i < BLOCK_SIZES; i++)
if (get_mask_bits(i))
vp9_cond_prob_diff_update(&header_bc,
&fc->masked_interinter_prob[i],
cm->counts.masked_interinter[i]);
} else {
vp9_zero(cm->counts.masked_interinter);
}
} else {
if (!cpi->dummy_packing)
cm->use_masked_interinter = 0;
vp9_zero(cm->counts.masked_interinter);
}
#endif
#if CONFIG_INTERINTRA
if (cm->reference_mode != COMPOUND_REFERENCE) {
if (!cpi->dummy_packing && cm->use_interintra) {
cm->use_interintra = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && (cm->counts.interintra[i][1] > 0)) {
cm->use_interintra = 1;
break;
}
}
}
vp9_write_bit(&header_bc, cm->use_interintra);
if (cm->use_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i)) {
vp9_cond_prob_diff_update(&header_bc,
&fc->interintra_prob[i],
cm->counts.interintra[i]);
}
}
#if CONFIG_MASKED_INTERINTRA
if (!cpi->dummy_packing && cm->use_masked_interintra) {
cm->use_masked_interintra = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i) &&
(cm->counts.masked_interintra[i][1] > 0)) {
cm->use_masked_interintra = 1;
break;
}
}
}
vp9_write_bit(&header_bc, cm->use_masked_interintra);
if (cm->use_masked_interintra) {
for (i = 0; i < BLOCK_SIZES; i++) {
if (is_interintra_allowed(i) && get_mask_bits_interintra(i))
vp9_cond_prob_diff_update(&header_bc,
&fc->masked_interintra_prob[i],
cm->counts.masked_interintra[i]);
}
} else {
vp9_zero(cm->counts.masked_interintra);
}
#endif
} else {
vp9_zero(cm->counts.interintra);
}
} else {
if (!cpi->dummy_packing)
cm->use_interintra = 0;
vp9_zero(cm->counts.interintra);
#if CONFIG_MASKED_INTERINTRA
if (!cpi->dummy_packing)
cm->use_masked_interintra = 0;
vp9_zero(cm->counts.masked_interintra);
#endif
}
#endif
}
vp9_stop_encode(&header_bc);

View File

@@ -410,6 +410,9 @@ static void choose_partitioning(VP9_COMP *cpi,
vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf);
xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
#if CONFIG_INTERINTRA
xd->mi[0]->mbmi.ref_frame[1] = NONE;
#endif
xd->mi[0]->mbmi.sb_type = BLOCK_64X64;
vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
xd->mi[0]->mbmi.ref_mvs[LAST_FRAME],
@@ -630,6 +633,31 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
const int ctx = vp9_get_pred_context_switchable_interp(xd);
++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
}
#if CONFIG_MASKED_INTERINTER
if (cm->use_masked_interinter &&
cm->reference_mode != SINGLE_REFERENCE &&
get_mask_bits(bsize) &&
mbmi->ref_frame[1] > INTRA_FRAME)
++cm->counts.masked_interinter[bsize][mbmi->use_masked_interinter];
#endif
#if CONFIG_INTERINTRA
if (cm->use_interintra &&
is_interintra_allowed(bsize) &&
is_inter_mode(mbmi->mode) &&
(mbmi->ref_frame[1] <= INTRA_FRAME)) {
if (mbmi->ref_frame[1] == INTRA_FRAME) {
++cm->counts.y_mode[size_group_lookup[bsize]][mbmi->interintra_mode];
++cm->counts.interintra[bsize][1];
#if CONFIG_MASKED_INTERINTRA
if (cm->use_masked_interintra && get_mask_bits_interintra(bsize))
++cm->counts.masked_interintra[bsize][mbmi->use_masked_interintra];
#endif
} else {
++cm->counts.interintra[bsize][0];
}
}
#endif
}
rd_opt->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
@@ -2337,6 +2365,16 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
2 * aligned_mi_cols * MAX_MB_PLANE);
vpx_memset(xd->above_seg_context, 0,
sizeof(*xd->above_seg_context) * aligned_mi_cols);
#if CONFIG_MASKED_INTERINTER
vp9_zero(cpi->masked_interinter_select_counts);
#endif
#if CONFIG_INTERINTRA
vp9_zero(cpi->interintra_select_count);
#if CONFIG_MASKED_INTERINTRA
vp9_zero(cpi->masked_interintra_select_count);
#endif
#endif
}
static int check_dual_ref_flags(VP9_COMP *cpi) {
@@ -3232,6 +3270,10 @@ static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
const PREDICTION_MODE y_mode = mi->mbmi.mode;
const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
const BLOCK_SIZE bsize = mi->mbmi.sb_type;
#if CONFIG_FILTERINTRA
const int uv_fbit = mi->mbmi.uv_filterbit;
int fbit = mi->mbmi.filterbit;
#endif
if (bsize < BLOCK_8X8) {
int idx, idy;
@@ -3239,12 +3281,31 @@ static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
for (idy = 0; idy < 2; idy += num_4x4_h)
for (idx = 0; idx < 2; idx += num_4x4_w)
#if CONFIG_FILTERINTRA
{
#endif
++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(mi->bmi[idy * 2 + idx].as_mode)) {
fbit = mi->b_filter_info[idy * 2 + idx];
++counts->filterintra[0][mi->bmi[idy * 2 + idx].as_mode][fbit];
}
}
#endif
} else {
++counts->y_mode[size_group_lookup[bsize]][y_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(y_mode) && is_filter_enabled(mi->mbmi.tx_size))
++counts->filterintra[mi->mbmi.tx_size][y_mode][fbit];
#endif
}
++counts->uv_mode[y_mode][uv_mode];
#if CONFIG_FILTERINTRA
if (is_filter_allowed(uv_mode) &&
is_filter_enabled(get_uv_tx_size(&(mi->mbmi))))
++counts->filterintra[get_uv_tx_size(&(mi->mbmi))][uv_mode][uv_fbit];
#endif
}
static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
@@ -3360,5 +3421,15 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;
}
#if CONFIG_EXT_TX
if (mbmi->tx_size <= TX_16X16 &&
is_inter_block(mbmi) &&
bsize >= BLOCK_8X8 &&
!mbmi->skip &&
!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
++cm->counts.ext_tx[mbmi->ext_txfrm];
}
#endif
}
}

View File

@@ -360,6 +360,9 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
int i, j;
const int16_t *src_diff;
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
@@ -372,21 +375,45 @@ void vp9_xform_quant(MACROBLOCK *x, int plane, int block,
scan_order->iscan);
break;
case TX_16X16:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
vp9_fdct16x16(src_diff, coeff, diff_stride);
#if CONFIG_EXT_TX
} else {
vp9_fht16x16(src_diff, coeff, diff_stride, ADST_ADST);
}
#endif
vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_8X8:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
vp9_fdct8x8(src_diff, coeff, diff_stride);
#if CONFIG_EXT_TX
} else {
vp9_fht8x8(src_diff, coeff, diff_stride, ADST_ADST);
}
#endif
vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
scan_order->scan, scan_order->iscan);
break;
case TX_4X4:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
x->fwd_txm4x4(src_diff, coeff, diff_stride);
#if CONFIG_EXT_TX
} else {
vp9_fht4x4(src_diff, coeff, diff_stride, ADST_ADST);
}
#endif
vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
p->quant, p->quant_shift, qcoeff, dqcoeff,
pd->dequant, p->zbin_extra, eob,
@@ -409,6 +436,9 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
int i, j;
uint8_t *dst;
ENTROPY_CONTEXT *a, *l;
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
a = &ctx->ta[plane][i];
@@ -454,16 +484,43 @@ static void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
break;
case TX_16X16:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
#if CONFIG_EXT_TX
} else {
vp9_iht16x16_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
}
#endif
break;
case TX_8X8:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
#if CONFIG_EXT_TX
} else {
vp9_iht8x8_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
}
#endif
break;
case TX_4X4:
#if CONFIG_EXT_TX
if (plane != 0 || mbmi->ext_txfrm == NORM) {
#endif
// this is like vp9_short_idct4x4 but has a special case around eob<=1
// which is significant (not just an optimization) for the lossless
// case.
x->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
#if CONFIG_EXT_TX
} else {
vp9_iht4x4_add(ADST_ADST, dqcoeff, dst, pd->dst.stride,
p->eobs[block]);
}
#endif
break;
default:
assert(0 && "Invalid transform size");
@@ -479,6 +536,10 @@ static void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
int i, j;
uint8_t *dst;
#if CONFIG_EXT_TX
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
mbmi->ext_txfrm = NORM;
#endif
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
@@ -531,6 +592,9 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
const scan_order *scan_order;
TX_TYPE tx_type;
PREDICTION_MODE mode;
#if CONFIG_FILTERINTRA
int fbit = 0;
#endif
const int bwl = b_width_log2(plane_bsize);
const int diff_stride = 4 * (1 << bwl);
uint8_t *src, *dst;
@@ -544,11 +608,20 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
src = &p->src.buf[4 * (j * src_stride + i)];
src_diff = &p->src_diff[4 * (j * diff_stride + i)];
#if CONFIG_FILTERINTRA
if (mbmi->sb_type < BLOCK_8X8 && plane == 0)
fbit = xd->mi[0]->b_filter_info[block];
else
fbit = plane == 0 ? mbmi->filterbit : mbmi->uv_filterbit;
#endif
switch (tx_size) {
case TX_32X32:
scan_order = &vp9_default_scan_orders[TX_32X32];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 6, bwl, TX_32X32, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
@@ -569,6 +642,9 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
scan_order = &vp9_scan_orders[TX_16X16][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 4, bwl, TX_16X16, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
@@ -589,6 +665,9 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
scan_order = &vp9_scan_orders[TX_8X8][tx_type];
mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
vp9_predict_intra_block(xd, block >> 2, bwl, TX_8X8, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);
@@ -609,6 +688,9 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
scan_order = &vp9_scan_orders[TX_4X4][tx_type];
mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mbmi->uv_mode;
vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
#if CONFIG_FILTERINTRA
fbit,
#endif
x->skip_encode ? src : dst,
x->skip_encode ? src_stride : dst_stride,
dst, dst_stride, i, j, plane);

View File

@@ -985,6 +985,41 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
vp9_sub_pixel_avg_variance4x4,
vp9_sad4x4x3, vp9_sad4x4x8, vp9_sad4x4x4d)
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
#define MBFP(BT, MSDF, MVF, MSVF) \
cpi->fn_ptr[BT].msdf = MSDF; \
cpi->fn_ptr[BT].mvf = MVF; \
cpi->fn_ptr[BT].msvf = MSVF;
MBFP(BLOCK_64X64, vp9_masked_sad64x64, vp9_masked_variance64x64,
vp9_masked_sub_pixel_variance64x64)
MBFP(BLOCK_64X32, vp9_masked_sad64x32, vp9_masked_variance64x32,
vp9_masked_sub_pixel_variance64x32)
MBFP(BLOCK_32X64, vp9_masked_sad32x64, vp9_masked_variance32x64,
vp9_masked_sub_pixel_variance32x64)
MBFP(BLOCK_32X32, vp9_masked_sad32x32, vp9_masked_variance32x32,
vp9_masked_sub_pixel_variance32x32)
MBFP(BLOCK_32X16, vp9_masked_sad32x16, vp9_masked_variance32x16,
vp9_masked_sub_pixel_variance32x16)
MBFP(BLOCK_16X32, vp9_masked_sad16x32, vp9_masked_variance16x32,
vp9_masked_sub_pixel_variance16x32)
MBFP(BLOCK_16X16, vp9_masked_sad16x16, vp9_masked_variance16x16,
vp9_masked_sub_pixel_variance16x16)
MBFP(BLOCK_16X8, vp9_masked_sad16x8, vp9_masked_variance16x8,
vp9_masked_sub_pixel_variance16x8)
MBFP(BLOCK_8X16, vp9_masked_sad8x16, vp9_masked_variance8x16,
vp9_masked_sub_pixel_variance8x16)
MBFP(BLOCK_8X8, vp9_masked_sad8x8, vp9_masked_variance8x8,
vp9_masked_sub_pixel_variance8x8)
MBFP(BLOCK_4X8, vp9_masked_sad4x8, vp9_masked_variance4x8,
vp9_masked_sub_pixel_variance4x8)
MBFP(BLOCK_8X4, vp9_masked_sad8x4, vp9_masked_variance8x4,
vp9_masked_sub_pixel_variance8x4)
MBFP(BLOCK_4X4, vp9_masked_sad4x4, vp9_masked_variance4x4,
vp9_masked_sub_pixel_variance4x4)
#endif
cpi->full_search_sad = vp9_full_search_sad;
cpi->diamond_search_sad = vp9_diamond_search_sad;
cpi->refining_search_sad = vp9_refining_search_sad;
@@ -1967,6 +2002,45 @@ YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm,
}
}
#if CONFIG_MASKED_INTERINTER
static void select_masked_interinter_mode(VP9_COMP *cpi) {
static const double threshold = 1/128.0;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->masked_interinter_select_counts[1] +
cpi->masked_interinter_select_counts[0];
if (sum) {
double fraction = (double) cpi->masked_interinter_select_counts[1] / sum;
cm->use_masked_interinter = (fraction > threshold);
}
}
#endif
#if CONFIG_INTERINTRA
static void select_interintra_mode(VP9_COMP *cpi) {
static const double threshold = 0.007;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->interintra_select_count[1] + cpi->interintra_select_count[0];
if (sum) {
double fraction = (double)cpi->interintra_select_count[1] / (double)sum;
cm->use_interintra = (fraction > threshold);
}
}
#if CONFIG_MASKED_INTERINTRA
static void select_masked_interintra_mode(VP9_COMP *cpi) {
static const double threshold = 1/100.0;
VP9_COMMON *cm = &cpi->common;
int sum = cpi->masked_interintra_select_count[1] +
cpi->masked_interintra_select_count[0];
if (sum) {
double fraction = (double)cpi->masked_interintra_select_count[1] /
(double)sum;
cm->use_masked_interintra = (fraction > threshold);
}
}
#endif
#endif
static void encode_frame_to_data_rate(VP9_COMP *cpi,
size_t *size,
uint8_t *dest,
@@ -2120,6 +2194,20 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
}
#if CONFIG_MASKED_INTERINTER
if (cm->current_video_frame == 0)
cm->use_masked_interinter = 0;
#endif
#if CONFIG_INTERINTRA
if (cm->current_video_frame == 0) {
cm->use_interintra = 1;
#if CONFIG_MASKED_INTERINTRA
cm->use_masked_interintra = 1;
#endif
}
#endif
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
encode_without_recode_loop(cpi, q);
} else {
@@ -2181,6 +2269,18 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_adapt_mode_probs(cm);
vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv);
}
#if CONFIG_MASKED_INTERINTER
select_masked_interinter_mode(cpi);
#endif
#if CONFIG_INTERINTRA
select_interintra_mode(cpi);
#if CONFIG_MASKED_INTERINTRA
if (cpi->common.use_interintra)
select_masked_interintra_mode(cpi);
else
cpi->common.use_masked_interintra = 0;
#endif
#endif
}
if (cpi->refresh_golden_frame == 1)

View File

@@ -64,7 +64,6 @@ typedef struct {
FRAME_CONTEXT fc;
} CODING_CONTEXT;
typedef enum {
// encode_breakout is disabled.
ENCODE_BREAKOUT_DISABLED = 0,
@@ -422,6 +421,16 @@ typedef struct VP9_COMP {
#if CONFIG_DENOISING
VP9_DENOISER denoiser;
#endif
#if CONFIG_MASKED_INTERINTER
unsigned int masked_interinter_select_counts[2];
#endif
#if CONFIG_INTERINTRA
unsigned int interintra_select_count[2];
#if CONFIG_MASKED_INTERINTRA
unsigned int masked_interintra_select_count[2];
#endif
#endif
} VP9_COMP;
void vp9_initialize_enc();

View File

@@ -64,6 +64,9 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi,
xd->mi[0]->mbmi.mode = NEWMV;
xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv;
#if CONFIG_INTERINTRA
xd->mi[0]->mbmi.ref_frame[1] = NONE;
#endif
vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16);
/* restore UMV window */
@@ -141,6 +144,9 @@ static int find_best_16x16_intra(VP9_COMP *cpi, PREDICTION_MODE *pbest_mode) {
xd->mi[0]->mbmi.mode = mode;
vp9_predict_intra_block(xd, 0, 2, TX_16X16, mode,
#if CONFIG_FILTERINTRA
0,
#endif
x->plane[0].src.buf, x->plane[0].src.stride,
xd->plane[0].dst.buf, xd->plane[0].dst.stride,
0, 0, 0);

View File

@@ -1640,3 +1640,354 @@ int vp9_full_pixel_search(VP9_COMP *cpi, MACROBLOCK *x,
return var;
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
/* returns subpixel variance error function */
#define DIST(r, c) \
vfp->msvf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \
src_stride, mask, mask_stride, &sse)
/* checks if (r, c) has better score than previous best */
#define MVC(r, c) \
(mvcost ? \
((mvjcost[((r) != rr) * 2 + ((c) != rc)] + \
mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \
error_per_bit + 4096) >> 13 : 0)
#define CHECK_BETTER(v, r, c) \
if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \
thismse = (DIST(r, c)); \
if ((v = MVC(r, c) + thismse) < besterr) { \
besterr = v; \
br = r; \
bc = c; \
*distortion = thismse; \
*sse1 = sse; \
} \
} else { \
v = INT_MAX; \
}
int vp9_find_best_masked_sub_pixel_tree(const MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1, int is_second) {
const uint8_t *const z = x->plane[0].src.buf;
const int src_stride = x->plane[0].src.stride;
const MACROBLOCKD *xd = &x->e_mbd;
unsigned int besterr = INT_MAX;
unsigned int sse;
unsigned int whichdir;
int thismse;
unsigned int halfiters = iters_per_step;
unsigned int quarteriters = iters_per_step;
unsigned int eighthiters = iters_per_step;
const int y_stride = xd->plane[0].pre[is_second].stride;
const int offset = bestmv->row * y_stride + bestmv->col;
const uint8_t *const y = xd->plane[0].pre[is_second].buf;
int rr = ref_mv->row;
int rc = ref_mv->col;
int br = bestmv->row * 8;
int bc = bestmv->col * 8;
int hstep = 4;
const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX);
const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX);
const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX);
const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX);
int tr = br;
int tc = bc;
// central mv
bestmv->row *= 8;
bestmv->col *= 8;
// calculate central point error
besterr = vfp->mvf(y + offset, y_stride, z, src_stride, mask, mask_stride,
sse1);
*distortion = besterr;
besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit);
// 1/2 pel
FIRST_LEVEL_CHECKS;
if (halfiters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
// Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
if (forced_stop != 2) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (quarteriters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
}
if (allow_hp && vp9_use_mv_hp(ref_mv) && forced_stop == 0) {
hstep >>= 1;
FIRST_LEVEL_CHECKS;
if (eighthiters > 1) {
SECOND_LEVEL_CHECKS;
}
tr = br;
tc = bc;
}
// These lines insure static analysis doesn't warn that
// tr and tc aren't used after the above point.
(void) tr;
(void) tc;
bestmv->row = br;
bestmv->col = bc;
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
return INT_MAX;
return besterr;
}
#undef DIST
#undef MVC
#undef CHECK_BETTER
int vp9_get_masked_mvpred_var(const MACROBLOCK *x,
uint8_t *mask, int mask_stride,
const MV *best_mv, const MV *center_mv,
const vp9_variance_fn_ptr_t *vfp,
int use_mvcost, int is_second) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
const MV mv = {best_mv->row * 8, best_mv->col * 8};
unsigned int unused;
return vfp->mvf(what->buf, what->stride,
get_buf_from_mv(in_what, best_mv), in_what->stride,
mask, mask_stride, &unused) +
(use_mvcost ? mv_err_cost(&mv, center_mv, x->nmvjointcost,
x->mvcost, x->errorperbit) : 0);
}
int vp9_masked_refining_search_sad_c(const MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *ref_mv, int error_per_bit,
int search_range,
const vp9_variance_fn_ptr_t *fn_ptr,
const MV *center_mv, int is_second) {
const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
unsigned int best_sad = fn_ptr->msdf(what->buf, what->stride,
get_buf_from_mv(in_what, ref_mv),
in_what->stride, mask, mask_stride) +
mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit);
int i, j;
for (i = 0; i < search_range; i++) {
int best_site = -1;
for (j = 0; j < 4; j++) {
const MV mv = {ref_mv->row + neighbors[j].row,
ref_mv->col + neighbors[j].col};
if (is_mv_in(x, &mv)) {
unsigned int sad = fn_ptr->msdf(what->buf, what->stride,
get_buf_from_mv(in_what, &mv), in_what->stride, mask, mask_stride);
if (sad < best_sad) {
sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_site = j;
}
}
}
}
if (best_site == -1) {
break;
} else {
ref_mv->row += neighbors[best_site].row;
ref_mv->col += neighbors[best_site].col;
}
}
return best_sad;
}
int vp9_masked_diamond_search_sad_c(const MACROBLOCK *x,
const search_site_config *cfg,
uint8_t *mask, int mask_stride,
MV *ref_mv, MV *best_mv,
int search_param, int sad_per_bit, int *num00,
const vp9_variance_fn_ptr_t *fn_ptr,
const MV *center_mv, int is_second) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
// search_param determines the length of the initial step and hence the number
// of iterations
// 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 =
// (MAX_FIRST_STEP/4) pel... etc.
const search_site *const ss = &cfg->ss[search_param * cfg->searches_per_step];
const int tot_steps = (cfg->ss_count / cfg->searches_per_step) - search_param;
const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
const uint8_t *best_address, *in_what_ref;
int best_sad = INT_MAX;
int best_site = 0;
int last_site = 0;
int i, j, step;
clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
in_what_ref = get_buf_from_mv(in_what, ref_mv);
best_address = in_what_ref;
*num00 = 0;
*best_mv = *ref_mv;
// Check the starting position
best_sad = fn_ptr->msdf(what->buf, what->stride,
best_address, in_what->stride,
mask, mask_stride) +
mvsad_err_cost(x, best_mv, &fcenter_mv, sad_per_bit);
i = 1;
for (step = 0; step < tot_steps; step++) {
for (j = 0; j < cfg->searches_per_step; j++) {
const MV mv = {best_mv->row + ss[i].mv.row,
best_mv->col + ss[i].mv.col};
if (is_mv_in(x, &mv)) {
int sad = fn_ptr->msdf(what->buf, what->stride,
best_address + ss[i].offset, in_what->stride,
mask, mask_stride);
if (sad < best_sad) {
sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_site = i;
}
}
}
i++;
}
if (best_site != last_site) {
best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
last_site = best_site;
#if defined(NEW_DIAMOND_SEARCH)
while (1) {
const MV this_mv = {best_mv->row + ss[best_site].mv.row,
best_mv->col + ss[best_site].mv.col};
if (is_mv_in(x, &this_mv)) {
int sad = fn_ptr->msdf(what->buf, what->stride,
best_address + ss[best_site].offset,
in_what->stride, mask, mask_stride);
if (sad < best_sad) {
sad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
continue;
}
}
}
break;
}
#endif
} else if (best_address == in_what_ref) {
(*num00)++;
}
}
return best_sad;
}
int vp9_masked_full_pixel_diamond(const VP9_COMP *cpi, MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *mvp_full, int step_param,
int sadpb, int further_steps, int do_refine,
const vp9_variance_fn_ptr_t *fn_ptr,
const MV *ref_mv, MV *dst_mv,
int is_second) {
MV temp_mv;
int thissme, n, num00 = 0;
int bestsme = vp9_masked_diamond_search_sad_c(x, &cpi->ss_cfg,
mask, mask_stride,
mvp_full, &temp_mv,
step_param, sadpb, &n,
fn_ptr, ref_mv, is_second);
if (bestsme < INT_MAX)
bestsme = vp9_get_masked_mvpred_var(x, mask, mask_stride, &temp_mv, ref_mv,
fn_ptr, 1, is_second);
*dst_mv = temp_mv;
// If there won't be more n-step search, check to see if refining search is
// needed.
if (n > further_steps)
do_refine = 0;
while (n < further_steps) {
++n;
if (num00) {
num00--;
} else {
thissme = vp9_masked_diamond_search_sad_c(x, &cpi->ss_cfg,
mask, mask_stride,
mvp_full, &temp_mv,
step_param + n, sadpb, &num00,
fn_ptr, ref_mv, is_second);
if (thissme < INT_MAX)
thissme = vp9_get_masked_mvpred_var(x, mask, mask_stride,
&temp_mv, ref_mv, fn_ptr, 1,
is_second);
// check to see if refining search is needed.
if (num00 > further_steps - n)
do_refine = 0;
if (thissme < bestsme) {
bestsme = thissme;
*dst_mv = temp_mv;
}
}
}
// final 1-away diamond refining search
if (do_refine) {
const int search_range = 8;
MV best_mv = *dst_mv;
thissme = vp9_masked_refining_search_sad_c(x, mask, mask_stride,
&best_mv, sadpb, search_range,
fn_ptr, ref_mv, is_second);
if (thissme < INT_MAX)
thissme = vp9_get_masked_mvpred_var(x, mask, mask_stride,
&best_mv, ref_mv, fn_ptr, 1,
is_second);
if (thissme < bestsme) {
bestsme = thissme;
*dst_mv = best_mv;
}
}
return bestsme;
}
#endif

View File

@@ -153,6 +153,29 @@ int vp9_full_pixel_search(struct VP9_COMP *cpi, MACROBLOCK *x,
int step_param, int error_per_bit,
const MV *ref_mv, MV *tmp_mv,
int var_max, int rd);
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
int vp9_find_best_masked_sub_pixel_tree(const MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *bestmv, const MV *ref_mv,
int allow_hp,
int error_per_bit,
const vp9_variance_fn_ptr_t *vfp,
int forced_stop,
int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion,
unsigned int *sse1, int is_second);
int vp9_masked_full_pixel_diamond(const struct VP9_COMP *cpi, MACROBLOCK *x,
uint8_t *mask, int mask_stride,
MV *mvp_full, int step_param,
int sadpb, int further_steps, int do_refine,
const vp9_variance_fn_ptr_t *fn_ptr,
const MV *ref_mv, MV *dst_mv,
int is_second);
#endif
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -689,6 +689,9 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < width; i += step) {
vp9_predict_intra_block(xd, block_idx, b_width_log2(bsize),
mbmi->tx_size, this_mode,
#if CONFIG_FILTERINTRA
0,
#endif
&p->src.buf[4 * (j * dst_stride + i)],
src_stride,
&pd->dst.buf[4 * (j * dst_stride + i)],
@@ -699,7 +702,6 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
++block_idx;
}
}
rate = rate2;
dist = dist2;

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,11 @@ extern "C" {
#define INVALID_MV 0x80008000
#if !CONFIG_INTERINTRA
#define MAX_MODES 30
#else
#define MAX_MODES 42
#endif
#define MAX_REFS 6
// This enumerator type needs to be kept aligned with the mode order in
@@ -76,6 +80,23 @@ typedef enum {
THR_D63_PRED,
THR_D117_PRED,
THR_D45_PRED,
#if CONFIG_INTERINTRA
THR_COMP_INTERINTRA_ZEROL,
THR_COMP_INTERINTRA_NEARESTL,
THR_COMP_INTERINTRA_NEARL,
THR_COMP_INTERINTRA_NEWL,
THR_COMP_INTERINTRA_ZEROG,
THR_COMP_INTERINTRA_NEARESTG,
THR_COMP_INTERINTRA_NEARG,
THR_COMP_INTERINTRA_NEWG,
THR_COMP_INTERINTRA_ZEROA,
THR_COMP_INTERINTRA_NEARESTA,
THR_COMP_INTERINTRA_NEARA,
THR_COMP_INTERINTRA_NEWA,
#endif
} THR_MODES;
typedef enum {

View File

@@ -131,3 +131,47 @@ sadMxN(4, 4)
sadMxNxK(4, 4, 3)
sadMxNxK(4, 4, 8)
sadMxNx4D(4, 4)
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
static INLINE unsigned int masked_sad(const uint8_t *a, int a_stride,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride,
int width, int height) {
int y, x;
unsigned int sad = 0;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
sad += m[x] * abs(a[x] - b[x]);
a += a_stride;
b += b_stride;
m += m_stride;
}
sad = (sad + 31) >> 6;
return sad;
}
#define MASKSADMxN(m, n) \
unsigned int vp9_masked_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
const uint8_t *ref, int ref_stride, \
const uint8_t *msk, int msk_stride) { \
return masked_sad(src, src_stride, ref, ref_stride, msk, msk_stride, m, n); \
}
MASKSADMxN(64, 64)
MASKSADMxN(64, 32)
MASKSADMxN(32, 64)
MASKSADMxN(32, 32)
MASKSADMxN(32, 16)
MASKSADMxN(16, 32)
MASKSADMxN(16, 16)
MASKSADMxN(16, 8)
MASKSADMxN(8, 16)
MASKSADMxN(8, 8)
MASKSADMxN(8, 4)
MASKSADMxN(4, 8)
MASKSADMxN(4, 4)
#endif

View File

@@ -266,3 +266,98 @@ void vp9_comp_avg_pred(uint8_t *comp_pred, const uint8_t *pred, int width,
ref += ref_stride;
}
}
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
void masked_variance(const uint8_t *a, int a_stride,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride,
int w, int h, unsigned int *sse, int *sum) {
int i, j;
*sum = 0;
*sse = 0;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
const int diff = (a[j] - b[j]) * (m[j]);
*sum += diff;
*sse += diff * diff;
}
a += a_stride;
b += b_stride;
m += m_stride;
}
*sum = (*sum >= 0) ? ((*sum + 31) >> 6) : -((-*sum + 31) >> 6);
*sse = (*sse + 2047) >> 12;
}
#define MASK_VAR(W, H) \
unsigned int vp9_masked_variance##W##x##H##_c(const uint8_t *a, int a_stride, \
const uint8_t *b, int b_stride, \
const uint8_t *m, int m_stride, \
unsigned int *sse) { \
int sum; \
masked_variance(a, a_stride, b, b_stride, m, m_stride, W, H, sse, &sum); \
return *sse - (((int64_t)sum * sum) / (W * H)); \
}
#define MASK_SUBPIX_VAR(W, H) \
unsigned int vp9_masked_sub_pixel_variance##W##x##H##_c( \
const uint8_t *src, int src_stride, \
int xoffset, int yoffset, \
const uint8_t *dst, int dst_stride, \
const uint8_t *msk, int msk_stride, \
unsigned int *sse) { \
uint16_t fdata3[(H + 1) * W]; \
uint8_t temp2[H * W]; \
\
var_filter_block2d_bil_first_pass(src, fdata3, src_stride, 1, H + 1, W, \
BILINEAR_FILTERS_2TAP(xoffset)); \
var_filter_block2d_bil_second_pass(fdata3, temp2, W, W, H, W, \
BILINEAR_FILTERS_2TAP(yoffset)); \
\
return vp9_masked_variance##W##x##H##_c(temp2, W, dst, dst_stride, \
msk, msk_stride, sse); \
}
MASK_VAR(4, 4)
MASK_SUBPIX_VAR(4, 4)
MASK_VAR(4, 8)
MASK_SUBPIX_VAR(4, 8)
MASK_VAR(8, 4)
MASK_SUBPIX_VAR(8, 4)
MASK_VAR(8, 8)
MASK_SUBPIX_VAR(8, 8)
MASK_VAR(8, 16)
MASK_SUBPIX_VAR(8, 16)
MASK_VAR(16, 8)
MASK_SUBPIX_VAR(16, 8)
MASK_VAR(16, 16)
MASK_SUBPIX_VAR(16, 16)
MASK_VAR(16, 32)
MASK_SUBPIX_VAR(16, 32)
MASK_VAR(32, 16)
MASK_SUBPIX_VAR(32, 16)
MASK_VAR(32, 32)
MASK_SUBPIX_VAR(32, 32)
MASK_VAR(32, 64)
MASK_SUBPIX_VAR(32, 64)
MASK_VAR(64, 32)
MASK_SUBPIX_VAR(64, 32)
MASK_VAR(64, 64)
MASK_SUBPIX_VAR(64, 64)
#endif

View File

@@ -67,6 +67,32 @@ typedef unsigned int (*vp9_subp_avg_variance_fn_t)(const uint8_t *src_ptr,
unsigned int *sse,
const uint8_t *second_pred);
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
typedef unsigned int(*vp9_masked_sad_fn_t)(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride);
typedef unsigned int (*vp9_masked_variance_fn_t)(const uint8_t *src_ptr,
int source_stride,
const uint8_t *ref_ptr,
int ref_stride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse);
typedef unsigned int (*vp9_masked_subpixvariance_fn_t)(const uint8_t *src_ptr,
int source_stride,
int xoffset,
int yoffset,
const uint8_t *ref_ptr,
int Refstride,
const uint8_t *msk_ptr,
int msk_stride,
unsigned int *sse);
#endif
typedef struct vp9_variance_vtable {
vp9_sad_fn_t sdf;
vp9_sad_avg_fn_t sdaf;
@@ -76,6 +102,12 @@ typedef struct vp9_variance_vtable {
vp9_sad_multi_fn_t sdx3f;
vp9_sad_multi_fn_t sdx8f;
vp9_sad_multi_d_fn_t sdx4df;
#if ((CONFIG_MASKED_INTERINTRA && CONFIG_INTERINTRA) || \
CONFIG_MASKED_INTERINTER)
vp9_masked_sad_fn_t msdf;
vp9_masked_variance_fn_t mvf;
vp9_masked_subpixvariance_fn_t msvf;
#endif
} vp9_variance_fn_ptr_t;
void vp9_comp_avg_pred(uint8_t *comp_pred, const uint8_t *pred, int width,