Allow blocks to directly copy motion information from neighbors
A new set of prediction modes, called copy modes, is implemented to allow blocks to directly copy motion information from a neighbor. The motivation is to create regions of arbitrary shapes in which blocks share same motion parameters and hence to save bits spent on duplicated side information. Compression gain: derf: 0.894%; stdhd: 1.513%. Change-Id: I5e026b12c902bc6985c199ec38f1b3b67ac7d930
This commit is contained in:
1
configure
vendored
1
configure
vendored
@@ -279,6 +279,7 @@ EXPERIMENT_LIST="
|
|||||||
filterintra
|
filterintra
|
||||||
ext_tx
|
ext_tx
|
||||||
supertx
|
supertx
|
||||||
|
copy_coding
|
||||||
"
|
"
|
||||||
CONFIG_LIST="
|
CONFIG_LIST="
|
||||||
external_build
|
external_build
|
||||||
|
@@ -32,6 +32,9 @@ extern "C" {
|
|||||||
#define BLOCK_SIZE_GROUPS 4
|
#define BLOCK_SIZE_GROUPS 4
|
||||||
#define SKIP_CONTEXTS 3
|
#define SKIP_CONTEXTS 3
|
||||||
#define INTER_MODE_CONTEXTS 7
|
#define INTER_MODE_CONTEXTS 7
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
#define COPY_MODE_CONTEXTS 5
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Segment Feature Masks */
|
/* Segment Feature Masks */
|
||||||
#define MAX_MV_REF_CANDIDATES 2
|
#define MAX_MV_REF_CANDIDATES 2
|
||||||
@@ -79,6 +82,16 @@ typedef enum {
|
|||||||
MB_MODE_COUNT
|
MB_MODE_COUNT
|
||||||
} PREDICTION_MODE;
|
} PREDICTION_MODE;
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
typedef enum {
|
||||||
|
NOREF,
|
||||||
|
REF0,
|
||||||
|
REF1,
|
||||||
|
REF2,
|
||||||
|
COPY_MODE_COUNT
|
||||||
|
} COPY_MODE;
|
||||||
|
#endif
|
||||||
|
|
||||||
static INLINE int is_inter_mode(PREDICTION_MODE mode) {
|
static INLINE int is_inter_mode(PREDICTION_MODE mode) {
|
||||||
return mode >= NEARESTMV && mode <= NEWMV;
|
return mode >= NEARESTMV && mode <= NEWMV;
|
||||||
}
|
}
|
||||||
@@ -218,6 +231,10 @@ typedef struct {
|
|||||||
int use_masked_interintra;
|
int use_masked_interintra;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
COPY_MODE copy_mode;
|
||||||
|
int inter_ref_count;
|
||||||
|
#endif
|
||||||
} MB_MODE_INFO;
|
} MB_MODE_INFO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -54,6 +54,43 @@ static const vp9_prob default_supertxsplit_prob[TX_SIZES] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
static const vp9_prob default_copy_noref_prob[COPY_MODE_CONTEXTS]
|
||||||
|
[BLOCK_SIZES] = {
|
||||||
|
{255, 255, 255, 82, 148, 182, 65, 193, 158, 70, 138, 101, 23},
|
||||||
|
{255, 255, 255, 118, 153, 161, 123, 169, 157, 82, 101, 123, 88},
|
||||||
|
{255, 255, 255, 130, 178, 226, 194, 196, 174, 173, 135, 144, 141},
|
||||||
|
{255, 255, 255, 178, 218, 225, 197, 230, 222, 215, 220, 220, 220},
|
||||||
|
{255, 255, 255, 243, 248, 241, 233, 249, 249, 249, 249, 249, 249}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vp9_prob default_copy_mode_probs_l2[COPY_MODE_CONTEXTS][1] = {
|
||||||
|
{207},
|
||||||
|
{135},
|
||||||
|
{141},
|
||||||
|
{189},
|
||||||
|
{209}
|
||||||
|
};
|
||||||
|
|
||||||
|
const vp9_tree_index vp9_copy_mode_tree_l2[TREE_SIZE(2)] = {
|
||||||
|
-(REF0 - REF0), -(REF1 - REF0)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const vp9_prob default_copy_mode_probs[COPY_MODE_CONTEXTS]
|
||||||
|
[COPY_MODE_COUNT - 2] = {
|
||||||
|
{130, 159},
|
||||||
|
{126, 176},
|
||||||
|
{120, 150},
|
||||||
|
{158, 183},
|
||||||
|
{149, 125}
|
||||||
|
};
|
||||||
|
|
||||||
|
const vp9_tree_index vp9_copy_mode_tree[TREE_SIZE(COPY_MODE_COUNT - 1)] = {
|
||||||
|
-(REF0 - REF0), 2,
|
||||||
|
-(REF1 - REF0), -(REF2 - REF0)
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
|
const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
|
||||||
{ // above = dc
|
{ // above = dc
|
||||||
{ 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
{ 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
|
||||||
@@ -286,7 +323,11 @@ const vp9_tree_index vp9_partition_tree[TREE_SIZE(PARTITION_TYPES)] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const vp9_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = {
|
static const vp9_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = {
|
||||||
|
#if !CONFIG_COPY_CODING
|
||||||
9, 102, 187, 225
|
9, 102, 187, 225
|
||||||
|
#else
|
||||||
|
35, 112, 187, 225
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
|
static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
|
||||||
@@ -386,6 +427,11 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
|
|||||||
vp9_copy(fc->supertx_prob, default_supertx_prob);
|
vp9_copy(fc->supertx_prob, default_supertx_prob);
|
||||||
vp9_copy(fc->supertxsplit_prob, default_supertxsplit_prob);
|
vp9_copy(fc->supertxsplit_prob, default_supertxsplit_prob);
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
vp9_copy(fc->copy_noref_prob, default_copy_noref_prob);
|
||||||
|
vp9_copy(fc->copy_mode_probs_l2, default_copy_mode_probs_l2);
|
||||||
|
vp9_copy(fc->copy_mode_probs, default_copy_mode_probs);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const vp9_tree_index vp9_switchable_interp_tree
|
const vp9_tree_index vp9_switchable_interp_tree
|
||||||
@@ -523,17 +569,25 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
|
|||||||
for (i = 1; i < TX_SIZES; ++i) {
|
for (i = 1; i < TX_SIZES; ++i) {
|
||||||
fc->supertx_prob[i] = adapt_prob(pre_fc->supertx_prob[i],
|
fc->supertx_prob[i] = adapt_prob(pre_fc->supertx_prob[i],
|
||||||
counts->supertx[i]);
|
counts->supertx[i]);
|
||||||
/* fprintf(stderr, "%d(%d %d) ", fc->supertx_prob[i],
|
|
||||||
counts->supertx[i][0], counts->supertx[i][1]);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < TX_SIZES; ++i) {
|
for (i = 1; i < TX_SIZES; ++i) {
|
||||||
fc->supertxsplit_prob[i] = adapt_prob(pre_fc->supertxsplit_prob[i],
|
fc->supertxsplit_prob[i] = adapt_prob(pre_fc->supertxsplit_prob[i],
|
||||||
counts->supertxsplit[i]);
|
counts->supertxsplit[i]);
|
||||||
/* fprintf(stderr, "%d(%d %d) ", fc->supertxsplit_prob[i],
|
|
||||||
counts->supertxsplit[i][0], counts->supertxsplit[i][1]);*/
|
|
||||||
}
|
}
|
||||||
/* fprintf(stderr, "\n");*/
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
for (i = 0; i < COPY_MODE_CONTEXTS; i++) {
|
||||||
|
for (j = BLOCK_8X8; j < BLOCK_SIZES; j++) {
|
||||||
|
fc->copy_noref_prob[i][j] =
|
||||||
|
adapt_prob(pre_fc->copy_noref_prob[i][j], counts->copy_noref[i][j]);
|
||||||
|
}
|
||||||
|
adapt_probs(vp9_copy_mode_tree_l2, pre_fc->copy_mode_probs_l2[i],
|
||||||
|
counts->copy_mode_l2[i], fc->copy_mode_probs_l2[i]);
|
||||||
|
adapt_probs(vp9_copy_mode_tree, pre_fc->copy_mode_probs[i],
|
||||||
|
counts->copy_mode[i], fc->copy_mode_probs[i]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,6 +71,11 @@ typedef struct frame_contexts {
|
|||||||
vp9_prob supertx_prob[TX_SIZES];
|
vp9_prob supertx_prob[TX_SIZES];
|
||||||
vp9_prob supertxsplit_prob[TX_SIZES];
|
vp9_prob supertxsplit_prob[TX_SIZES];
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
vp9_prob copy_noref_prob[COPY_MODE_CONTEXTS][BLOCK_SIZES];
|
||||||
|
vp9_prob copy_mode_probs_l2[COPY_MODE_CONTEXTS][1];
|
||||||
|
vp9_prob copy_mode_probs[COPY_MODE_CONTEXTS][COPY_MODE_COUNT - 2];
|
||||||
|
#endif
|
||||||
} FRAME_CONTEXT;
|
} FRAME_CONTEXT;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -110,6 +115,11 @@ typedef struct {
|
|||||||
unsigned int supertxsplit[TX_SIZES][2];
|
unsigned int supertxsplit[TX_SIZES][2];
|
||||||
unsigned int supertx_size[BLOCK_SIZES];
|
unsigned int supertx_size[BLOCK_SIZES];
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
unsigned int copy_noref[COPY_MODE_CONTEXTS][BLOCK_SIZES][2];
|
||||||
|
unsigned int copy_mode_l2[COPY_MODE_CONTEXTS][2];
|
||||||
|
unsigned int copy_mode[COPY_MODE_CONTEXTS][COPY_MODE_COUNT - 1];
|
||||||
|
#endif
|
||||||
} FRAME_COUNTS;
|
} FRAME_COUNTS;
|
||||||
|
|
||||||
extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
|
extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
|
||||||
@@ -122,6 +132,10 @@ extern const vp9_tree_index vp9_inter_mode_tree[TREE_SIZE(INTER_MODES)];
|
|||||||
extern const vp9_tree_index vp9_partition_tree[TREE_SIZE(PARTITION_TYPES)];
|
extern const vp9_tree_index vp9_partition_tree[TREE_SIZE(PARTITION_TYPES)];
|
||||||
extern const vp9_tree_index vp9_switchable_interp_tree
|
extern const vp9_tree_index vp9_switchable_interp_tree
|
||||||
[TREE_SIZE(SWITCHABLE_FILTERS)];
|
[TREE_SIZE(SWITCHABLE_FILTERS)];
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
extern const vp9_tree_index vp9_copy_mode_tree_l2[TREE_SIZE(2)];
|
||||||
|
extern const vp9_tree_index vp9_copy_mode_tree[TREE_SIZE(COPY_MODE_COUNT - 1)];
|
||||||
|
#endif
|
||||||
|
|
||||||
void vp9_setup_past_independence(struct VP9Common *cm);
|
void vp9_setup_past_independence(struct VP9Common *cm);
|
||||||
|
|
||||||
|
@@ -188,3 +188,176 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
|
|||||||
assert("Invalid block index.");
|
assert("Invalid block index.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
static int compare_interinfo(MB_MODE_INFO *mbmi, MB_MODE_INFO *ref_mbmi) {
|
||||||
|
if (mbmi == ref_mbmi) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
int is_same;
|
||||||
|
#if CONFIG_INTERINTRA
|
||||||
|
MV_REFERENCE_FRAME mbmi_ref1_backup = mbmi->ref_frame[1];
|
||||||
|
MV_REFERENCE_FRAME refmbmi_ref1_backup = ref_mbmi->ref_frame[1];
|
||||||
|
|
||||||
|
if (mbmi->ref_frame[1] == INTRA_FRAME)
|
||||||
|
mbmi->ref_frame[1] = NONE;
|
||||||
|
if (ref_mbmi->ref_frame[1] == INTRA_FRAME)
|
||||||
|
ref_mbmi->ref_frame[1] = NONE;
|
||||||
|
#endif
|
||||||
|
if (mbmi->ref_frame[0] == ref_mbmi->ref_frame[0] &&
|
||||||
|
mbmi->ref_frame[1] == ref_mbmi->ref_frame[1]) {
|
||||||
|
if (mbmi->ref_frame[1] > INTRA_FRAME)
|
||||||
|
is_same = mbmi->mv[0].as_int == ref_mbmi->mv[0].as_int &&
|
||||||
|
mbmi->mv[1].as_int == ref_mbmi->mv[1].as_int &&
|
||||||
|
mbmi->interp_filter == ref_mbmi->interp_filter;
|
||||||
|
else
|
||||||
|
is_same = mbmi->mv[0].as_int == ref_mbmi->mv[0].as_int &&
|
||||||
|
mbmi->interp_filter == ref_mbmi->interp_filter;
|
||||||
|
} else {
|
||||||
|
is_same = 0;
|
||||||
|
}
|
||||||
|
#if CONFIG_INTERINTRA
|
||||||
|
mbmi->ref_frame[1] = mbmi_ref1_backup;
|
||||||
|
ref_mbmi->ref_frame[1] = refmbmi_ref1_backup;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return is_same;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_inside(VP9_COMMON *cm, int mi_row, int mi_col) {
|
||||||
|
return mi_row >= 0 && mi_col >= 0 &&
|
||||||
|
mi_row < cm->mi_rows && mi_col < cm->mi_cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_right_available(BLOCK_SIZE bsize, int mi_row, int mi_col) {
|
||||||
|
int depth, max_depth = 4 - MIN(b_width_log2(bsize), b_height_log2(bsize));
|
||||||
|
int block[4] = {0};
|
||||||
|
|
||||||
|
if (bsize == BLOCK_64X64)
|
||||||
|
return 1;
|
||||||
|
mi_row = mi_row % 8;
|
||||||
|
mi_col = mi_col % 8;
|
||||||
|
for (depth = 1; depth <= max_depth; depth++) {
|
||||||
|
block[depth] = (mi_row >> (3 - depth)) * 2 + (mi_col >> (3 - depth));
|
||||||
|
mi_row = mi_row % (8 >> depth);
|
||||||
|
mi_col = mi_col % (8 >> depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b_width_log2(bsize) < b_height_log2(bsize)) {
|
||||||
|
if (block[max_depth] == 0)
|
||||||
|
return 1;
|
||||||
|
} else if (b_width_log2(bsize) > b_height_log2(bsize)) {
|
||||||
|
if (block[max_depth] > 0)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (block[max_depth] == 0 || block[max_depth] == 2)
|
||||||
|
return 1;
|
||||||
|
else if (block[max_depth] == 3)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (depth = max_depth - 1; depth > 0; depth--) {
|
||||||
|
if (block[depth] == 0 || block[depth] == 2)
|
||||||
|
return 1;
|
||||||
|
else if (block[depth] == 3)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_second_rec(int mi_row, int mi_col, BLOCK_SIZE bsize) {
|
||||||
|
int bw = 4 << b_width_log2(bsize);
|
||||||
|
int bh = 4 << b_height_log2(bsize);
|
||||||
|
|
||||||
|
if (bw < bh)
|
||||||
|
return (mi_col << 3) % (bw << 1) == 0 ? 0 : 1;
|
||||||
|
else if (bh < bw)
|
||||||
|
return (mi_row << 3) % (bh << 1) == 0 ? 0 : 2;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vp9_construct_ref_inter_list(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||||
|
BLOCK_SIZE bsize, int mi_row, int mi_col,
|
||||||
|
MB_MODE_INFO *ref_list[18]) {
|
||||||
|
int bw = 4 << b_width_log2(bsize);
|
||||||
|
int bh = 4 << b_height_log2(bsize);
|
||||||
|
int row_offset, col_offset;
|
||||||
|
int mi_offset;
|
||||||
|
MB_MODE_INFO *ref_mbmi;
|
||||||
|
int ref_index, ref_num = 0;
|
||||||
|
int row_offset_cand[18], col_offset_cand[18];
|
||||||
|
int offset_num = 0, i, switchflag;
|
||||||
|
int is_sec_rec = is_second_rec(mi_row, mi_col, bsize);
|
||||||
|
|
||||||
|
if (is_sec_rec != 2) {
|
||||||
|
row_offset_cand[offset_num] = -1; col_offset_cand[offset_num] = 0;
|
||||||
|
offset_num++;
|
||||||
|
}
|
||||||
|
if (is_sec_rec != 1) {
|
||||||
|
row_offset_cand[offset_num] = bh / 16; col_offset_cand[offset_num] = -1;
|
||||||
|
offset_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
row_offset = bh / 8 - 1;
|
||||||
|
col_offset = 1;
|
||||||
|
if (is_sec_rec < 2)
|
||||||
|
switchflag = 1;
|
||||||
|
else
|
||||||
|
switchflag = 0;
|
||||||
|
while ((is_sec_rec == 0 && ((row_offset >=0) || col_offset < (bw / 8 + 1))) ||
|
||||||
|
(is_sec_rec == 1 && col_offset < (bw / 8 + 1)) ||
|
||||||
|
(is_sec_rec == 2 && row_offset >=0)) {
|
||||||
|
switch (switchflag) {
|
||||||
|
case 0:
|
||||||
|
if (row_offset >= 0) {
|
||||||
|
if (row_offset != bh / 16) {
|
||||||
|
row_offset_cand[offset_num] = row_offset;
|
||||||
|
col_offset_cand[offset_num] = -1;
|
||||||
|
offset_num++;
|
||||||
|
}
|
||||||
|
row_offset--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (col_offset < (bw / 8 + 1)) {
|
||||||
|
row_offset_cand[offset_num] = -1;
|
||||||
|
col_offset_cand[offset_num] = col_offset;
|
||||||
|
offset_num++;
|
||||||
|
col_offset++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
if (is_sec_rec == 0)
|
||||||
|
switchflag = 1 - switchflag;
|
||||||
|
}
|
||||||
|
row_offset_cand[offset_num] = -1;
|
||||||
|
col_offset_cand[offset_num] = -1;
|
||||||
|
offset_num++;
|
||||||
|
|
||||||
|
for (i = 0; i < offset_num; i++) {
|
||||||
|
row_offset = row_offset_cand[i];
|
||||||
|
col_offset = col_offset_cand[i];
|
||||||
|
if ((col_offset < (bw / 8) ||
|
||||||
|
(col_offset == (bw / 8) && is_right_available(bsize, mi_row, mi_col)))
|
||||||
|
&& check_inside(cm, mi_row + row_offset, mi_col + col_offset)) {
|
||||||
|
mi_offset = row_offset * cm->mi_stride + col_offset;
|
||||||
|
ref_mbmi = &xd->mi[mi_offset]->mbmi;
|
||||||
|
if (is_inter_block(ref_mbmi)) {
|
||||||
|
for (ref_index = 0; ref_index < ref_num; ref_index++) {
|
||||||
|
if (compare_interinfo(ref_mbmi, ref_list[ref_index]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ref_index == ref_num) {
|
||||||
|
ref_list[ref_num] = ref_mbmi;
|
||||||
|
ref_num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ref_num;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -220,6 +220,12 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
|
|||||||
int block, int ref, int mi_row, int mi_col,
|
int block, int ref, int mi_row, int mi_col,
|
||||||
int_mv *nearest, int_mv *near);
|
int_mv *nearest, int_mv *near);
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int vp9_construct_ref_inter_list(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||||
|
BLOCK_SIZE bsize, int mi_row, int mi_col,
|
||||||
|
MB_MODE_INFO *ref_list[18]);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -383,3 +383,47 @@ int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids,
|
|||||||
assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
|
assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
|
||||||
return segment_id;
|
return segment_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int vp9_get_copy_mode_context(const MACROBLOCKD *xd) {
|
||||||
|
const MB_MODE_INFO *const above_mbmi = get_mbmi(get_above_mi(xd));
|
||||||
|
const MB_MODE_INFO *const left_mbmi = get_mbmi(get_left_mi(xd));
|
||||||
|
const int has_above = above_mbmi != NULL;
|
||||||
|
const int has_left = left_mbmi != NULL;
|
||||||
|
|
||||||
|
if (has_above && has_left) {
|
||||||
|
const int above_intra = !is_inter_block(above_mbmi);
|
||||||
|
const int left_intra = !is_inter_block(left_mbmi);
|
||||||
|
|
||||||
|
if (above_intra && left_intra) {
|
||||||
|
return 4;
|
||||||
|
} else if (above_intra || left_intra) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
const int above_predict = above_mbmi->copy_mode != NOREF;
|
||||||
|
const int left_predict = left_mbmi->copy_mode != NOREF;
|
||||||
|
if (above_predict && left_predict)
|
||||||
|
return 0;
|
||||||
|
else if (above_predict || left_predict)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
} else if (has_above || has_left) {
|
||||||
|
const MB_MODE_INFO *const ref_mbmi = has_above ? above_mbmi : left_mbmi;
|
||||||
|
const int ref_intra = !is_inter_block(ref_mbmi);
|
||||||
|
|
||||||
|
if (ref_intra) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
const int ref_predict = ref_mbmi != NOREF;
|
||||||
|
if (ref_predict)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -134,6 +134,10 @@ static INLINE unsigned int *get_tx_counts(TX_SIZE max_tx_size, int ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int vp9_get_copy_mode_context(const MACROBLOCKD *xd);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1742,6 +1742,15 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
for (j = 0; j < COPY_MODE_CONTEXTS; j++) {
|
||||||
|
for (i = 0; i < 1; i++)
|
||||||
|
vp9_diff_update_prob(&r, &fc->copy_mode_probs_l2[j][i]);
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
vp9_diff_update_prob(&r, &fc->copy_mode_probs[j][i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return vp9_reader_has_error(&r);
|
return vp9_reader_has_error(&r);
|
||||||
|
@@ -54,6 +54,36 @@ static PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r, int ctx) {
|
|||||||
return NEARESTMV + mode;
|
return NEARESTMV + mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
static COPY_MODE read_copy_mode(VP9_COMMON *cm, vp9_reader *r,
|
||||||
|
int num_candidate, int ctx) {
|
||||||
|
COPY_MODE mode;
|
||||||
|
|
||||||
|
switch (num_candidate) {
|
||||||
|
case 0:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mode = REF0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mode = REF0 + vp9_read_tree(r, vp9_copy_mode_tree_l2,
|
||||||
|
cm->fc.copy_mode_probs_l2[ctx]);
|
||||||
|
if (!cm->frame_parallel_decoding_mode)
|
||||||
|
++cm->counts.copy_mode_l2[ctx][mode - REF0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = REF0 + vp9_read_tree(r, vp9_copy_mode_tree,
|
||||||
|
cm->fc.copy_mode_probs[ctx]);
|
||||||
|
if (!cm->frame_parallel_decoding_mode)
|
||||||
|
++cm->counts.copy_mode[ctx][mode - REF0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
|
static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
|
||||||
return vp9_read_tree(r, vp9_segment_tree, seg->tree_probs);
|
return vp9_read_tree(r, vp9_segment_tree, seg->tree_probs);
|
||||||
}
|
}
|
||||||
@@ -568,22 +598,6 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
|
|||||||
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
|
read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
|
||||||
is_compound = has_second_ref(mbmi);
|
is_compound = has_second_ref(mbmi);
|
||||||
|
|
||||||
#if CONFIG_EXT_TX
|
|
||||||
if (mbmi->tx_size <= TX_16X16 &&
|
|
||||||
bsize >= BLOCK_8X8 &&
|
|
||||||
#if CONFIG_SUPERTX
|
|
||||||
!supertx_enabled &&
|
|
||||||
#endif
|
|
||||||
!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) {
|
for (ref = 0; ref < 1 + is_compound; ++ref) {
|
||||||
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
|
const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
|
||||||
vp9_find_mv_refs(cm, xd, tile, mi, frame, mbmi->ref_mvs[frame],
|
vp9_find_mv_refs(cm, xd, tile, mi, frame, mbmi->ref_mvs[frame],
|
||||||
@@ -717,27 +731,108 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
|
|||||||
MODE_INFO *const mi = xd->mi[0];
|
MODE_INFO *const mi = xd->mi[0];
|
||||||
MB_MODE_INFO *const mbmi = &mi->mbmi;
|
MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||||
int inter_block;
|
int inter_block;
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int num_candidate = 0;
|
||||||
|
MB_MODE_INFO *inter_ref_list[18] = {NULL};
|
||||||
|
#endif
|
||||||
|
|
||||||
mbmi->mv[0].as_int = 0;
|
mbmi->mv[0].as_int = 0;
|
||||||
mbmi->mv[1].as_int = 0;
|
mbmi->mv[1].as_int = 0;
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (mbmi->sb_type >= BLOCK_8X8)
|
||||||
|
num_candidate = vp9_construct_ref_inter_list(cm, xd, mbmi->sb_type,
|
||||||
|
mi_row, mi_col, inter_ref_list);
|
||||||
|
if (mbmi->sb_type >= BLOCK_8X8 && num_candidate > 0) {
|
||||||
|
int ctx = vp9_get_copy_mode_context(xd);
|
||||||
|
int is_copy = vp9_read(r, cm->fc.copy_noref_prob[ctx][mbmi->sb_type]);
|
||||||
|
|
||||||
|
++cm->counts.copy_noref[ctx][mbmi->sb_type][is_copy];
|
||||||
|
if (!is_copy) {
|
||||||
|
mbmi->copy_mode = NOREF;
|
||||||
|
} else {
|
||||||
|
mbmi->copy_mode = read_copy_mode(cm, r, num_candidate, ctx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mbmi->copy_mode = NOREF;
|
||||||
|
}
|
||||||
|
if (mbmi->copy_mode != NOREF) {
|
||||||
|
BLOCK_SIZE bsize_backup = mbmi->sb_type;
|
||||||
|
int skip_backup = mbmi->skip;
|
||||||
|
COPY_MODE copy_mode_backup = mbmi->copy_mode;
|
||||||
|
#if CONFIG_SUPERTX
|
||||||
|
TX_SIZE tx_size_backup = mbmi->tx_size;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
EXT_TX_TYPE ext_txfrm_backup = mbmi->ext_txfrm;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inter_block = 1;
|
||||||
|
*mbmi = *inter_ref_list[mbmi->copy_mode - REF0];
|
||||||
|
#if CONFIG_MASKED_INTERINTER
|
||||||
|
mbmi->use_masked_interinter = 0;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_INTERINTRA
|
||||||
|
if (mbmi->ref_frame[1] == INTRA_FRAME)
|
||||||
|
mbmi->ref_frame[1] = NONE;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_SUPERTX
|
||||||
|
mbmi->tx_size = tx_size_backup;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
mbmi->ext_txfrm = ext_txfrm_backup;
|
||||||
|
#endif
|
||||||
|
mbmi->sb_type = bsize_backup;
|
||||||
|
mbmi->mode = NEARESTMV;
|
||||||
|
mbmi->skip = skip_backup;
|
||||||
|
mbmi->copy_mode = copy_mode_backup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SUPERTX
|
#if CONFIG_SUPERTX
|
||||||
if (!supertx_enabled) {
|
if (!supertx_enabled) {
|
||||||
#endif
|
#endif
|
||||||
mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
|
mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
|
||||||
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
|
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (mbmi->copy_mode == NOREF)
|
||||||
|
#endif
|
||||||
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
|
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
|
||||||
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
|
mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
|
||||||
!mbmi->skip || !inter_block, r);
|
!mbmi->skip || !inter_block, r);
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
if (inter_block &&
|
||||||
|
mbmi->tx_size <= TX_16X16 &&
|
||||||
|
mbmi->sb_type >= BLOCK_8X8 &&
|
||||||
|
#if CONFIG_SUPERTX
|
||||||
|
!supertx_enabled &&
|
||||||
|
#endif
|
||||||
|
!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
|
||||||
#if CONFIG_SUPERTX
|
#if CONFIG_SUPERTX
|
||||||
} else {
|
} else {
|
||||||
const int ctx = vp9_get_intra_inter_context(xd);
|
const int ctx = vp9_get_intra_inter_context(xd);
|
||||||
mbmi->segment_id = 0;
|
mbmi->segment_id = 0;
|
||||||
inter_block = 1;
|
inter_block = 1;
|
||||||
if (!cm->frame_parallel_decoding_mode)
|
if (!cm->frame_parallel_decoding_mode)
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (mbmi->copy_mode == NOREF)
|
||||||
|
#endif
|
||||||
++cm->counts.intra_inter[ctx][1];
|
++cm->counts.intra_inter[ctx][1];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (mbmi->copy_mode == NOREF) {
|
||||||
|
#endif
|
||||||
if (inter_block)
|
if (inter_block)
|
||||||
read_inter_block_mode_info(cm, xd, tile, mi,
|
read_inter_block_mode_info(cm, xd, tile, mi,
|
||||||
#if CONFIG_SUPERTX && CONFIG_EXT_TX
|
#if CONFIG_SUPERTX && CONFIG_EXT_TX
|
||||||
@@ -746,6 +841,9 @@ static void read_inter_frame_mode_info(VP9_COMMON *const cm,
|
|||||||
mi_row, mi_col, r);
|
mi_row, mi_col, r);
|
||||||
else
|
else
|
||||||
read_intra_block_mode_info(cm, mi, r);
|
read_intra_block_mode_info(cm, mi, r);
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
|
void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||||
|
@@ -38,6 +38,10 @@ static struct vp9_token intra_mode_encodings[INTRA_MODES];
|
|||||||
static struct vp9_token switchable_interp_encodings[SWITCHABLE_FILTERS];
|
static struct vp9_token switchable_interp_encodings[SWITCHABLE_FILTERS];
|
||||||
static struct vp9_token partition_encodings[PARTITION_TYPES];
|
static struct vp9_token partition_encodings[PARTITION_TYPES];
|
||||||
static struct vp9_token inter_mode_encodings[INTER_MODES];
|
static struct vp9_token inter_mode_encodings[INTER_MODES];
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
static struct vp9_token copy_mode_encodings_l2[2];
|
||||||
|
static struct vp9_token copy_mode_encodings[COPY_MODE_COUNT - 1];
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SUPERTX
|
#if CONFIG_SUPERTX
|
||||||
static int vp9_check_supertx(VP9_COMMON *cm, int mi_row, int mi_col,
|
static int vp9_check_supertx(VP9_COMMON *cm, int mi_row, int mi_col,
|
||||||
@@ -56,6 +60,10 @@ void vp9_entropy_mode_init() {
|
|||||||
vp9_tokens_from_tree(switchable_interp_encodings, vp9_switchable_interp_tree);
|
vp9_tokens_from_tree(switchable_interp_encodings, vp9_switchable_interp_tree);
|
||||||
vp9_tokens_from_tree(partition_encodings, vp9_partition_tree);
|
vp9_tokens_from_tree(partition_encodings, vp9_partition_tree);
|
||||||
vp9_tokens_from_tree(inter_mode_encodings, vp9_inter_mode_tree);
|
vp9_tokens_from_tree(inter_mode_encodings, vp9_inter_mode_tree);
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
vp9_tokens_from_tree(copy_mode_encodings_l2, vp9_copy_mode_tree_l2);
|
||||||
|
vp9_tokens_from_tree(copy_mode_encodings, vp9_copy_mode_tree);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
|
static void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
|
||||||
@@ -70,6 +78,21 @@ static void write_inter_mode(vp9_writer *w, PREDICTION_MODE mode,
|
|||||||
&inter_mode_encodings[INTER_OFFSET(mode)]);
|
&inter_mode_encodings[INTER_OFFSET(mode)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
static void write_copy_mode(VP9_COMMON *cm, vp9_writer *w, COPY_MODE mode,
|
||||||
|
int inter_ref_count, int copy_mode_context) {
|
||||||
|
if (inter_ref_count == 2) {
|
||||||
|
vp9_write_token(w, vp9_copy_mode_tree_l2,
|
||||||
|
cm->fc.copy_mode_probs_l2[copy_mode_context],
|
||||||
|
©_mode_encodings_l2[mode - REF0]);
|
||||||
|
} else if (inter_ref_count > 2) {
|
||||||
|
vp9_write_token(w, vp9_copy_mode_tree,
|
||||||
|
cm->fc.copy_mode_probs[copy_mode_context],
|
||||||
|
©_mode_encodings[mode - REF0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void encode_unsigned_max(struct vp9_write_bit_buffer *wb,
|
static void encode_unsigned_max(struct vp9_write_bit_buffer *wb,
|
||||||
int data, int max) {
|
int data, int max) {
|
||||||
vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
|
vp9_wb_write_literal(wb, data, get_unsigned_bits(max));
|
||||||
@@ -254,7 +277,19 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
|||||||
const int is_inter = is_inter_block(mbmi);
|
const int is_inter = is_inter_block(mbmi);
|
||||||
const int is_compound = has_second_ref(mbmi);
|
const int is_compound = has_second_ref(mbmi);
|
||||||
int skip, ref;
|
int skip, ref;
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int copy_mode_context = vp9_get_copy_mode_context(xd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (bsize >= BLOCK_8X8 && mbmi->inter_ref_count > 0) {
|
||||||
|
vp9_write(w, mbmi->copy_mode != NOREF,
|
||||||
|
cm->fc.copy_noref_prob[copy_mode_context][bsize]);
|
||||||
|
if (mbmi->copy_mode != NOREF)
|
||||||
|
write_copy_mode(cm, w, mbmi->copy_mode, mbmi->inter_ref_count,
|
||||||
|
copy_mode_context);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (seg->update_map) {
|
if (seg->update_map) {
|
||||||
if (seg->temporal_update) {
|
if (seg->temporal_update) {
|
||||||
const int pred_flag = mbmi->seg_id_predicted;
|
const int pred_flag = mbmi->seg_id_predicted;
|
||||||
@@ -278,6 +313,9 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
|||||||
|
|
||||||
#if CONFIG_SUPERTX
|
#if CONFIG_SUPERTX
|
||||||
if (!supertx_enabled) {
|
if (!supertx_enabled) {
|
||||||
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (mbmi->copy_mode == NOREF)
|
||||||
#endif
|
#endif
|
||||||
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
|
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
|
||||||
vp9_write(w, is_inter, vp9_get_intra_inter_prob(cm, xd));
|
vp9_write(w, is_inter, vp9_get_intra_inter_prob(cm, xd));
|
||||||
@@ -293,6 +331,18 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
|||||||
(skip || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
|
(skip || vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)))) {
|
||||||
write_selected_tx_size(cpi, mbmi->tx_size, bsize, w);
|
write_selected_tx_size(cpi, mbmi->tx_size, bsize, w);
|
||||||
}
|
}
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
if (is_inter &&
|
||||||
|
mbmi->tx_size <= TX_16X16 &&
|
||||||
|
bsize >= BLOCK_8X8 &&
|
||||||
|
#if CONFIG_SUPERTX
|
||||||
|
!supertx_enabled &&
|
||||||
|
#endif
|
||||||
|
!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 (!is_inter) {
|
if (!is_inter) {
|
||||||
if (bsize >= BLOCK_8X8) {
|
if (bsize >= BLOCK_8X8) {
|
||||||
@@ -328,23 +378,15 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
|||||||
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
|
cm->fc.filterintra_prob[get_uv_tx_size(mbmi)][mbmi->uv_mode]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if !CONFIG_COPY_CODING
|
||||||
} else {
|
} else {
|
||||||
|
#else
|
||||||
|
} else if (mbmi->copy_mode == NOREF) {
|
||||||
|
#endif
|
||||||
const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
|
const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
|
||||||
const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx];
|
const vp9_prob *const inter_probs = cm->fc.inter_mode_probs[mode_ctx];
|
||||||
write_ref_frames(cpi, w);
|
write_ref_frames(cpi, w);
|
||||||
|
|
||||||
#if CONFIG_EXT_TX
|
|
||||||
if (mbmi->tx_size <= TX_16X16 &&
|
|
||||||
bsize >= BLOCK_8X8 &&
|
|
||||||
#if CONFIG_SUPERTX
|
|
||||||
!supertx_enabled &&
|
|
||||||
#endif
|
|
||||||
!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 segment skip is not enabled code the mode.
|
||||||
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
|
if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
|
||||||
if (bsize >= BLOCK_8X8) {
|
if (bsize >= BLOCK_8X8) {
|
||||||
@@ -1470,6 +1512,15 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
for (i = 0; i < COPY_MODE_CONTEXTS; i++) {
|
||||||
|
prob_diff_update(vp9_copy_mode_tree_l2, cm->fc.copy_mode_probs_l2[i],
|
||||||
|
cm->counts.copy_mode_l2[i], 2, &header_bc);
|
||||||
|
prob_diff_update(vp9_copy_mode_tree, cm->fc.copy_mode_probs[i],
|
||||||
|
cm->counts.copy_mode[i], 3, &header_bc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vp9_stop_encode(&header_bc);
|
vp9_stop_encode(&header_bc);
|
||||||
|
@@ -736,7 +736,25 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!frame_is_intra_only(cm)) {
|
if (!frame_is_intra_only(cm)) {
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
COPY_MODE copy_mode = mbmi->copy_mode;
|
||||||
|
if (mbmi->sb_type >= BLOCK_8X8) {
|
||||||
|
int copy_mode_context = vp9_get_copy_mode_context(xd);
|
||||||
|
if (mbmi->inter_ref_count > 0) {
|
||||||
|
++cm->counts.copy_noref[copy_mode_context][mbmi->sb_type]
|
||||||
|
[copy_mode != NOREF];
|
||||||
|
if (copy_mode != NOREF) {
|
||||||
|
if (mbmi->inter_ref_count == 2)
|
||||||
|
++cm->counts.copy_mode_l2[copy_mode_context][copy_mode - REF0];
|
||||||
|
else if (mbmi->inter_ref_count > 2)
|
||||||
|
++cm->counts.copy_mode[copy_mode_context][copy_mode - REF0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_inter_block(mbmi) && copy_mode == NOREF) {
|
||||||
|
#else
|
||||||
if (is_inter_block(mbmi)) {
|
if (is_inter_block(mbmi)) {
|
||||||
|
#endif
|
||||||
vp9_update_mv_count(cm, xd);
|
vp9_update_mv_count(cm, xd);
|
||||||
|
|
||||||
if (cm->interp_filter == SWITCHABLE) {
|
if (cm->interp_filter == SWITCHABLE) {
|
||||||
@@ -842,7 +860,25 @@ static void update_state_supertx(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!frame_is_intra_only(cm)) {
|
if (!frame_is_intra_only(cm)) {
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
COPY_MODE copy_mode = mbmi->copy_mode;
|
||||||
|
if (mbmi->sb_type >= BLOCK_8X8) {
|
||||||
|
int copy_mode_context = vp9_get_copy_mode_context(xd);
|
||||||
|
if (mbmi->inter_ref_count > 0) {
|
||||||
|
++cm->counts.copy_noref[copy_mode_context][mbmi->sb_type]
|
||||||
|
[copy_mode != NOREF];
|
||||||
|
if (copy_mode != NOREF) {
|
||||||
|
if (mbmi->inter_ref_count == 2)
|
||||||
|
++cm->counts.copy_mode_l2[copy_mode_context][copy_mode - REF0];
|
||||||
|
else if (mbmi->inter_ref_count > 2)
|
||||||
|
++cm->counts.copy_mode[copy_mode_context][copy_mode - REF0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_inter_block(mbmi) && copy_mode == NOREF) {
|
||||||
|
#else
|
||||||
if (is_inter_block(mbmi)) {
|
if (is_inter_block(mbmi)) {
|
||||||
|
#endif
|
||||||
vp9_update_mv_count(cm, xd);
|
vp9_update_mv_count(cm, xd);
|
||||||
|
|
||||||
if (cm->interp_filter == SWITCHABLE) {
|
if (cm->interp_filter == SWITCHABLE) {
|
||||||
@@ -1259,7 +1295,11 @@ static void update_stats(VP9_COMP *cpi) {
|
|||||||
const MODE_INFO *const mi = xd->mi[0];
|
const MODE_INFO *const mi = xd->mi[0];
|
||||||
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||||
|
|
||||||
|
#if !CONFIG_COPY_CODING
|
||||||
if (!frame_is_intra_only(cm)) {
|
if (!frame_is_intra_only(cm)) {
|
||||||
|
#else
|
||||||
|
if (!frame_is_intra_only(cm) && mbmi->copy_mode == NOREF) {
|
||||||
|
#endif
|
||||||
const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
|
const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
|
||||||
SEG_LVL_REF_FRAME);
|
SEG_LVL_REF_FRAME);
|
||||||
if (!seg_ref_active) {
|
if (!seg_ref_active) {
|
||||||
|
@@ -409,6 +409,10 @@ typedef struct VP9_COMP {
|
|||||||
int intra_uv_mode_cost[FRAME_TYPES][INTRA_MODES];
|
int intra_uv_mode_cost[FRAME_TYPES][INTRA_MODES];
|
||||||
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
|
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
|
||||||
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
|
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
int copy_mode_cost_l2[COPY_MODE_CONTEXTS][2];
|
||||||
|
int copy_mode_cost[COPY_MODE_CONTEXTS][COPY_MODE_COUNT - 1];
|
||||||
|
#endif
|
||||||
|
|
||||||
PICK_MODE_CONTEXT *leaf_tree;
|
PICK_MODE_CONTEXT *leaf_tree;
|
||||||
PC_TREE *pc_tree;
|
PC_TREE *pc_tree;
|
||||||
|
@@ -356,6 +356,15 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) {
|
|||||||
cm->fc.inter_mode_probs[i], vp9_inter_mode_tree);
|
cm->fc.inter_mode_probs[i], vp9_inter_mode_tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
for (i = 0; i < COPY_MODE_CONTEXTS; ++i) {
|
||||||
|
vp9_cost_tokens((int *)cpi->copy_mode_cost_l2[i],
|
||||||
|
cm->fc.copy_mode_probs_l2[i], vp9_copy_mode_tree_l2);
|
||||||
|
vp9_cost_tokens((int *)cpi->copy_mode_cost[i],
|
||||||
|
cm->fc.copy_mode_probs[i], vp9_copy_mode_tree);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int MAX_XSQ_Q10 = 245727;
|
static const int MAX_XSQ_Q10 = 245727;
|
||||||
@@ -3793,12 +3802,23 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
int is_best_interintra = 0;
|
int is_best_interintra = 0;
|
||||||
int start_skip = 0;
|
int start_skip = 0;
|
||||||
int mode_skip_mask_interintra = 0;
|
int mode_skip_mask_interintra = 0;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
COPY_MODE copy_mode;
|
||||||
|
int inter_ref_count;
|
||||||
|
MB_MODE_INFO *inter_ref_list[18];
|
||||||
|
int copy_mode_context = vp9_get_copy_mode_context(xd);
|
||||||
#endif
|
#endif
|
||||||
vp9_zero(best_mbmode);
|
vp9_zero(best_mbmode);
|
||||||
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
||||||
|
|
||||||
estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
|
estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
|
||||||
&comp_mode_p);
|
&comp_mode_p);
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
inter_ref_count =
|
||||||
|
vp9_construct_ref_inter_list(cm, xd, bsize, mi_row, mi_col, inter_ref_list);
|
||||||
|
mbmi->inter_ref_count = inter_ref_count;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < REFERENCE_MODES; ++i)
|
for (i = 0; i < REFERENCE_MODES; ++i)
|
||||||
best_pred_rd[i] = INT64_MAX;
|
best_pred_rd[i] = INT64_MAX;
|
||||||
@@ -4064,6 +4084,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
// them for this frame.
|
// them for this frame.
|
||||||
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
|
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
|
||||||
: cm->interp_filter;
|
: cm->interp_filter;
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
mbmi->copy_mode = NOREF;
|
||||||
|
#endif
|
||||||
x->skip = 0;
|
x->skip = 0;
|
||||||
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
|
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
|
||||||
|
|
||||||
@@ -4217,6 +4240,12 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
rate2 += ref_costs_single[ref_frame];
|
rate2 += ref_costs_single[ref_frame];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (inter_ref_count > 0)
|
||||||
|
rate2 += vp9_cost_bit(cm->fc.copy_noref_prob[copy_mode_context][bsize],
|
||||||
|
0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!disable_skip) {
|
if (!disable_skip) {
|
||||||
if (skippable) {
|
if (skippable) {
|
||||||
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
|
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
|
||||||
@@ -4423,10 +4452,15 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
++cpi->interintra_select_count[is_best_interintra];
|
++cpi->interintra_select_count[is_best_interintra];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !CONFIG_COPY_CODING
|
||||||
if (best_mode_index < 0 || best_rd >= best_rd_so_far)
|
if (best_mode_index < 0 || best_rd >= best_rd_so_far)
|
||||||
return INT64_MAX;
|
return INT64_MAX;
|
||||||
|
#endif
|
||||||
|
|
||||||
// If we used an estimate for the uv intra rd in the loop above...
|
// If we used an estimate for the uv intra rd in the loop above...
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
if (!(best_mode_index < 0 || best_rd >= best_rd_so_far)) {
|
||||||
|
#endif
|
||||||
if (cpi->sf.use_uv_intra_rd_estimate) {
|
if (cpi->sf.use_uv_intra_rd_estimate) {
|
||||||
// Do Intra UV best rd mode selection if best mode choice above was intra.
|
// Do Intra UV best rd mode selection if best mode choice above was intra.
|
||||||
if (vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
|
if (vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
|
||||||
@@ -4482,6 +4516,188 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
||||||
store_coding_context(x, ctx, best_mode_index,
|
store_coding_context(x, ctx, best_mode_index,
|
||||||
best_pred_diff, best_tx_diff, best_filter_diff);
|
best_pred_diff, best_tx_diff, best_filter_diff);
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
}
|
||||||
|
|
||||||
|
for (copy_mode = REF0;
|
||||||
|
copy_mode < MIN(REF0 + inter_ref_count, COPY_MODE_COUNT); copy_mode++) {
|
||||||
|
int64_t this_rd = INT64_MAX;
|
||||||
|
int rate2 = 0, rate_y = 0, rate_uv = 0;
|
||||||
|
int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
|
||||||
|
int this_skip2 = 0, skippable = 0, skippable_y = 0, skippable_uv = 0;
|
||||||
|
int64_t ssey, sseuv, total_sse = INT64_MAX;
|
||||||
|
int64_t tx_cache[TX_MODES];
|
||||||
|
int i;
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
int tx_type, rate2_tx, this_skip2_tx, best_tx_size, best_tx_type;
|
||||||
|
int64_t distortion2_tx, bestrd_tx = INT64_MAX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*mbmi = *inter_ref_list[copy_mode - REF0];
|
||||||
|
#if CONFIG_MASKED_INTERINTER
|
||||||
|
mbmi->use_masked_interinter = 0;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_INTERINTRA
|
||||||
|
if (mbmi->ref_frame[1] == INTRA_FRAME)
|
||||||
|
mbmi->ref_frame[1] = NONE;
|
||||||
|
#endif
|
||||||
|
mbmi->sb_type = bsize;
|
||||||
|
mbmi->inter_ref_count = inter_ref_count;
|
||||||
|
mbmi->copy_mode = copy_mode;
|
||||||
|
mbmi->mode = NEARESTMV;
|
||||||
|
x->skip = 0;
|
||||||
|
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
||||||
|
for (i = 0; i < MAX_MB_PLANE; i++) {
|
||||||
|
xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
|
||||||
|
if (mbmi->ref_frame[1] > INTRA_FRAME)
|
||||||
|
xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
|
||||||
|
}
|
||||||
|
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
|
||||||
|
|
||||||
|
for (i = 0; i < TX_MODES; ++i)
|
||||||
|
tx_cache[i] = INT64_MAX;
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
for (tx_type = 0; tx_type < 2; tx_type++) {
|
||||||
|
mbmi->ext_txfrm = tx_type;
|
||||||
|
#endif
|
||||||
|
inter_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable_y, &ssey,
|
||||||
|
bsize, tx_cache, INT64_MAX);
|
||||||
|
super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &skippable_uv, &sseuv,
|
||||||
|
bsize, INT64_MAX);
|
||||||
|
|
||||||
|
rate2 = rate_y + rate_uv;
|
||||||
|
distortion2 = distortion_y + distortion_uv;
|
||||||
|
skippable = skippable_y && skippable_uv;
|
||||||
|
total_sse = ssey + sseuv;
|
||||||
|
|
||||||
|
if (skippable) {
|
||||||
|
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
|
||||||
|
|
||||||
|
rate2 -= (rate_y + rate_uv);
|
||||||
|
rate_y = 0;
|
||||||
|
rate_uv = 0;
|
||||||
|
if (skip_prob) {
|
||||||
|
int prob_skip_cost = vp9_cost_bit(skip_prob, 1);
|
||||||
|
rate2 += prob_skip_cost;
|
||||||
|
}
|
||||||
|
} else if (!xd->lossless) {
|
||||||
|
if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
|
||||||
|
RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
|
||||||
|
rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
|
||||||
|
} else {
|
||||||
|
rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
|
||||||
|
distortion2 = total_sse;
|
||||||
|
assert(total_sse >= 0);
|
||||||
|
rate2 -= (rate_y + rate_uv);
|
||||||
|
rate_y = 0;
|
||||||
|
rate_uv = 0;
|
||||||
|
this_skip2 = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
|
||||||
|
}
|
||||||
|
#if CONFIG_EXT_TX
|
||||||
|
if (mbmi->tx_size <= TX_16X16 && !this_skip2)
|
||||||
|
rate2 += vp9_cost_bit(cm->fc.ext_tx_prob, tx_type);
|
||||||
|
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
|
||||||
|
if (tx_type == 0 || this_rd < (bestrd_tx * 0.97)) {
|
||||||
|
bestrd_tx = this_rd;
|
||||||
|
best_tx_type = tx_type;
|
||||||
|
best_tx_size = mbmi->tx_size;
|
||||||
|
rate2_tx = rate2;
|
||||||
|
distortion2_tx = distortion2;
|
||||||
|
this_skip2_tx = this_skip2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_tx_size <= TX_16X16)
|
||||||
|
mbmi->ext_txfrm = best_tx_type;
|
||||||
|
else
|
||||||
|
mbmi->ext_txfrm = 0;
|
||||||
|
|
||||||
|
inter_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable_y, &ssey,
|
||||||
|
bsize, tx_cache, INT64_MAX);
|
||||||
|
super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &skippable_uv, &sseuv,
|
||||||
|
bsize, INT64_MAX);
|
||||||
|
|
||||||
|
rate2 = rate2_tx;
|
||||||
|
distortion2 = distortion2_tx;
|
||||||
|
this_skip2 = this_skip2_tx;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rate2 += vp9_cost_bit(cm->fc.copy_noref_prob[copy_mode_context][bsize], 1);
|
||||||
|
switch (inter_ref_count) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rate2 += cpi->copy_mode_cost_l2[copy_mode_context][copy_mode - REF0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rate2 += cpi->copy_mode_cost[copy_mode_context][copy_mode - REF0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
|
||||||
|
|
||||||
|
if (this_rd < best_rd) {
|
||||||
|
int max_plane = MAX_MB_PLANE;
|
||||||
|
|
||||||
|
*returnrate = rate2;
|
||||||
|
*returndistortion = distortion2;
|
||||||
|
#if CONFIG_SUPERTX
|
||||||
|
*returnrate_nocoef =
|
||||||
|
vp9_cost_bit(cm->fc.copy_noref_prob[copy_mode_context][bsize], 1);
|
||||||
|
if (inter_ref_count == 2)
|
||||||
|
*returnrate_nocoef +=
|
||||||
|
cpi->copy_mode_cost_l2[copy_mode_context][copy_mode - REF0];
|
||||||
|
else if (inter_ref_count > 2)
|
||||||
|
*returnrate_nocoef +=
|
||||||
|
cpi->copy_mode_cost[copy_mode_context][copy_mode - REF0];
|
||||||
|
#endif
|
||||||
|
best_rd = this_rd;
|
||||||
|
best_mbmode = *mbmi;
|
||||||
|
best_skip2 = this_skip2;
|
||||||
|
if (!x->select_tx_size)
|
||||||
|
swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
|
||||||
|
vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
|
||||||
|
sizeof(uint8_t) * ctx->num_4x4_blk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bsize < BLOCK_32X32) {
|
||||||
|
if (bsize < BLOCK_16X16)
|
||||||
|
tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
|
||||||
|
tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
|
||||||
|
}
|
||||||
|
if (this_rd != INT64_MAX) {
|
||||||
|
for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
|
||||||
|
int64_t adj_rd = INT64_MAX;
|
||||||
|
adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
|
||||||
|
|
||||||
|
if (adj_rd < best_tx_rd[i])
|
||||||
|
best_tx_rd[i] = adj_rd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((best_mode_index < 0 && best_mbmode.copy_mode == NOREF)
|
||||||
|
|| best_rd >= best_rd_so_far)
|
||||||
|
return INT64_MAX;
|
||||||
|
|
||||||
|
*mbmi = best_mbmode;
|
||||||
|
x->skip |= best_skip2;
|
||||||
|
ctx->skip = x->skip;
|
||||||
|
ctx->mic = *xd->mi[0];
|
||||||
|
|
||||||
|
if (!x->skip) {
|
||||||
|
for (i = 0; i < TX_MODES; i++) {
|
||||||
|
if (best_tx_rd[i] == INT64_MAX)
|
||||||
|
best_tx_diff[i] = 0;
|
||||||
|
else
|
||||||
|
best_tx_diff[i] = best_rd - best_tx_rd[i];
|
||||||
|
}
|
||||||
|
vpx_memcpy(ctx->tx_rd_diff, best_tx_diff, sizeof(ctx->tx_rd_diff));
|
||||||
|
} else {
|
||||||
|
vp9_zero(best_filter_diff);
|
||||||
|
vp9_zero(best_tx_diff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return best_rd;
|
return best_rd;
|
||||||
}
|
}
|
||||||
@@ -4655,6 +4871,9 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
#if CONFIG_EXT_TX
|
#if CONFIG_EXT_TX
|
||||||
mbmi->ext_txfrm = NORM;
|
mbmi->ext_txfrm = NORM;
|
||||||
#endif
|
#endif
|
||||||
|
#if CONFIG_COPY_CODING
|
||||||
|
mbmi->copy_mode = NOREF;
|
||||||
|
#endif
|
||||||
|
|
||||||
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
||||||
vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
|
vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
|
||||||
|
Reference in New Issue
Block a user