Added one more reference frame LAST2_FRAME
Under the experiment CONFIG_MULTI_REF. Current version shows LAST2 vs base in nextgen on the testset of derflr: (1) 8-bit: Average PSNR +0.53% (worst: students_cif: -0.247%; best: mobile_cif: 1.902%) (2) 12-bit HBD: Average PSNR +0.63% (worst: pamphlet_cif: -0.213%, best: mobile_cif: 2.101%) More tuning on the reference frame context design and default probs are being conducted. This version does not guarantee to work with other experiments in nextgen. A separate CL will address the working with all other experiments. Change-Id: I7f40d2522517afc26ca389c995bad56989587f65
This commit is contained in:
parent
2de18d1fd2
commit
897192be43
1
configure
vendored
1
configure
vendored
@ -306,6 +306,7 @@ EXPERIMENT_LIST="
|
||||
qctx_tprobs
|
||||
dst1
|
||||
sr_mode
|
||||
multi_ref
|
||||
"
|
||||
CONFIG_LIST="
|
||||
external_build
|
||||
|
@ -206,9 +206,15 @@ typedef enum {
|
||||
NONE = -1,
|
||||
INTRA_FRAME = 0,
|
||||
LAST_FRAME = 1,
|
||||
#if CONFIG_MULTI_REF
|
||||
LAST2_FRAME = 2,
|
||||
GOLDEN_FRAME = 3,
|
||||
ALTREF_FRAME = 4,
|
||||
#else
|
||||
GOLDEN_FRAME = 2,
|
||||
ALTREF_FRAME = 3,
|
||||
MAX_REF_FRAMES = 4
|
||||
#endif // CONFIG_MULTI_REF
|
||||
MAX_REF_FRAMES
|
||||
} MV_REFERENCE_FRAME;
|
||||
|
||||
// This structure now relates to 8x8 block regions.
|
||||
|
@ -415,6 +415,24 @@ static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
|
||||
239, 183, 119, 96, 41
|
||||
};
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
// TODO(zoeliu): To adjust the initial prob values.
|
||||
static const vp9_prob default_comp_ref_p[REF_CONTEXTS][2] = {
|
||||
{ 33, 16 },
|
||||
{ 77, 74 },
|
||||
{ 142, 142 },
|
||||
{ 172, 170 },
|
||||
{ 238, 247 }
|
||||
};
|
||||
|
||||
static const vp9_prob default_single_ref_p[REF_CONTEXTS][3] = {
|
||||
{ 33, 16, 16 },
|
||||
{ 77, 74, 74 },
|
||||
{ 142, 142, 142 },
|
||||
{ 172, 170, 170 },
|
||||
{ 238, 247, 247 }
|
||||
};
|
||||
#else
|
||||
static const vp9_prob default_comp_ref_p[REF_CONTEXTS] = {
|
||||
50, 126, 123, 221, 226
|
||||
};
|
||||
@ -426,6 +444,7 @@ static const vp9_prob default_single_ref_p[REF_CONTEXTS][2] = {
|
||||
{ 172, 170 },
|
||||
{ 238, 247 }
|
||||
};
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
static const struct tx_probs default_tx_probs = {
|
||||
#if CONFIG_TX64X64
|
||||
@ -1064,13 +1083,26 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
|
||||
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
|
||||
fc->comp_inter_prob[i] = adapt_prob(pre_fc->comp_inter_prob[i],
|
||||
counts->comp_inter[i]);
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
for (i = 0; i < REF_CONTEXTS; i++) {
|
||||
#if CONFIG_MULTI_REF
|
||||
for (j = 0; j < 2; j++)
|
||||
fc->comp_ref_prob[i][j] = adapt_prob(pre_fc->comp_ref_prob[i][j],
|
||||
counts->comp_ref[i][j]);
|
||||
#else
|
||||
fc->comp_ref_prob[i] = adapt_prob(pre_fc->comp_ref_prob[i],
|
||||
counts->comp_ref[i]);
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
|
||||
for (i = 0; i < REF_CONTEXTS; i++) {
|
||||
#if CONFIG_MULTI_REF
|
||||
for (j = 0; j < 3; j++)
|
||||
#else
|
||||
for (j = 0; j < 2; j++)
|
||||
#endif // CONFIG_MULTI_REF
|
||||
fc->single_ref_prob[i][j] = adapt_prob(pre_fc->single_ref_prob[i][j],
|
||||
counts->single_ref[i][j]);
|
||||
}
|
||||
|
||||
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
|
||||
adapt_probs(vp9_inter_mode_tree, pre_fc->inter_mode_probs[i],
|
||||
@ -1258,6 +1290,9 @@ static void set_default_lf_deltas(struct loopfilter *lf) {
|
||||
|
||||
lf->ref_deltas[INTRA_FRAME] = 1;
|
||||
lf->ref_deltas[LAST_FRAME] = 0;
|
||||
#if CONFIG_MULTI_REF
|
||||
lf->ref_deltas[LAST2_FRAME] = lf->ref_deltas[LAST_FRAME];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
lf->ref_deltas[GOLDEN_FRAME] = -1;
|
||||
lf->ref_deltas[ALTREF_FRAME] = -1;
|
||||
|
||||
|
@ -74,8 +74,13 @@ typedef struct frame_contexts {
|
||||
#endif // CONFIG_NEW_INTER
|
||||
vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
|
||||
vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_prob single_ref_prob[REF_CONTEXTS][3];
|
||||
vp9_prob comp_ref_prob[REF_CONTEXTS][2];
|
||||
#else
|
||||
vp9_prob single_ref_prob[REF_CONTEXTS][2];
|
||||
vp9_prob comp_ref_prob[REF_CONTEXTS];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
struct tx_probs tx_probs;
|
||||
vp9_prob skip_probs[SKIP_CONTEXTS];
|
||||
nmv_context nmvc;
|
||||
@ -154,8 +159,13 @@ typedef struct {
|
||||
#endif // CONFIG_NEW_INTER
|
||||
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
|
||||
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
|
||||
#if CONFIG_MULTI_REF
|
||||
unsigned int single_ref[REF_CONTEXTS][3][2];
|
||||
unsigned int comp_ref[REF_CONTEXTS][2][2];
|
||||
#else
|
||||
unsigned int single_ref[REF_CONTEXTS][2][2];
|
||||
unsigned int comp_ref[REF_CONTEXTS][2];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
struct tx_counts tx;
|
||||
unsigned int skip[SKIP_CONTEXTS][2];
|
||||
nmv_context_counts mv;
|
||||
|
@ -182,8 +182,14 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
VP9_LAST_FLAG = 1 << 0,
|
||||
#if CONFIG_MULTI_REF
|
||||
VP9_LAST2_FLAG = 1 << 1,
|
||||
VP9_GOLD_FLAG = 1 << 2,
|
||||
VP9_ALT_FLAG = 1 << 3,
|
||||
#else
|
||||
VP9_GOLD_FLAG = 1 << 1,
|
||||
VP9_ALT_FLAG = 1 << 2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} VP9_REFFRAME;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -26,7 +26,12 @@ extern "C" {
|
||||
|
||||
#define SIMD_WIDTH 16
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
#define MAX_REF_LF_DELTAS 5
|
||||
#else
|
||||
#define MAX_REF_LF_DELTAS 4
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#define MAX_MODE_LF_DELTAS 2
|
||||
|
||||
struct VP9Common;
|
||||
@ -103,7 +108,7 @@ struct loopfilter {
|
||||
uint8_t mode_ref_delta_enabled;
|
||||
uint8_t mode_ref_delta_update;
|
||||
|
||||
// 0 = Intra, Last, GF, ARF
|
||||
// 0 = Intra, Last, Last2(CONFIG_MULTI_REF), GF, ARF
|
||||
signed char ref_deltas[MAX_REF_LF_DELTAS];
|
||||
signed char last_ref_deltas[MAX_REF_LF_DELTAS];
|
||||
|
||||
|
@ -30,7 +30,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
#define REFS_PER_FRAME 4
|
||||
#else
|
||||
#define REFS_PER_FRAME 3
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#define REF_FRAMES_LOG2 3
|
||||
#define REF_FRAMES (1 << REF_FRAMES_LOG2)
|
||||
@ -185,7 +189,11 @@ typedef struct VP9Common {
|
||||
// Context probabilities for reference frame prediction
|
||||
int allow_comp_inter_inter;
|
||||
MV_REFERENCE_FRAME comp_fixed_ref;
|
||||
#if CONFIG_MULTI_REF
|
||||
MV_REFERENCE_FRAME comp_var_ref[3];
|
||||
#else
|
||||
MV_REFERENCE_FRAME comp_var_ref[2];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
REFERENCE_MODE reference_mode;
|
||||
|
||||
FRAME_CONTEXT fc; /* this frame entropy */
|
||||
|
@ -109,6 +109,196 @@ int vp9_get_reference_mode_context(const VP9_COMMON *cm,
|
||||
return ctx;
|
||||
}
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
|
||||
#define CHECK_LAST_OR_LAST2(ref_frame) \
|
||||
((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME))
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// Signal the first reference frame for a compound mode is GOLDEN.
|
||||
int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
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 above_in_image = above_mbmi != NULL;
|
||||
const int left_in_image = left_mbmi != NULL;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
|
||||
const int var_ref_idx = !fix_ref_idx;
|
||||
|
||||
if (above_in_image && left_in_image) { // both edges available
|
||||
const int above_intra = !is_inter_block(above_mbmi);
|
||||
const int left_intra = !is_inter_block(left_mbmi);
|
||||
|
||||
if (above_intra && left_intra) { // intra/intra (2)
|
||||
pred_context = 2;
|
||||
} else if (above_intra || left_intra) { // intra/inter
|
||||
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
|
||||
|
||||
if (!has_second_ref(edge_mbmi)) // single pred (1/3)
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
|
||||
else // comp pred (1/3)
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
|
||||
!= GOLDEN_FRAME);
|
||||
} else { // inter/inter
|
||||
const int l_sg = !has_second_ref(left_mbmi);
|
||||
const int a_sg = !has_second_ref(above_mbmi);
|
||||
const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
|
||||
: above_mbmi->ref_frame[var_ref_idx];
|
||||
const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
|
||||
: left_mbmi->ref_frame[var_ref_idx];
|
||||
|
||||
if (vrfa == vrfl && vrfa == GOLDEN_FRAME) {
|
||||
pred_context = 0;
|
||||
} else if (l_sg && a_sg) { // single/single
|
||||
if ((vrfa == ALTREF_FRAME && CHECK_LAST_OR_LAST2(vrfl)) ||
|
||||
(vrfl == ALTREF_FRAME && CHECK_LAST_OR_LAST2(vrfa))) {
|
||||
pred_context = 4;
|
||||
} else if (vrfa == vrfl || (CHECK_LAST_OR_LAST2(vrfa) &&
|
||||
CHECK_LAST_OR_LAST2(vrfl))) {
|
||||
pred_context = 3;
|
||||
} else { // either vrfa or vrfl == GOLDEN_FRAME
|
||||
// NOTE(zoeliu): Following assert may be removed once confirmed.
|
||||
assert(vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME);
|
||||
pred_context = 1;
|
||||
}
|
||||
} else if (l_sg || a_sg) { // single/comp
|
||||
const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
|
||||
const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
|
||||
|
||||
if (vrfc == GOLDEN_FRAME && rfs != GOLDEN_FRAME)
|
||||
pred_context = 1;
|
||||
else if (rfs == GOLDEN_FRAME && vrfc != GOLDEN_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 4;
|
||||
} else { // comp/comp
|
||||
if ((CHECK_LAST_OR_LAST2(vrfa) && CHECK_LAST_OR_LAST2(vrfl))) {
|
||||
pred_context = 4;
|
||||
} else {
|
||||
// NOTE(zoeliu): Following assert may be removed once confirmed.
|
||||
assert(vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME);
|
||||
pred_context = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (above_in_image || left_in_image) { // one edge available
|
||||
const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
|
||||
|
||||
if (!is_inter_block(edge_mbmi)) {
|
||||
pred_context = 2;
|
||||
} else {
|
||||
if (has_second_ref(edge_mbmi))
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] != GOLDEN_FRAME);
|
||||
else
|
||||
pred_context = 3 * (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
|
||||
}
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// Signal the first reference frame for a compound mode is LAST,
|
||||
// conditioning on that it is known not GOLDEN.
|
||||
int vp9_get_pred_context_comp_ref_p1(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
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 above_in_image = above_mbmi != NULL;
|
||||
const int left_in_image = left_mbmi != NULL;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
|
||||
const int var_ref_idx = !fix_ref_idx;
|
||||
|
||||
if (above_in_image && left_in_image) { // both edges available
|
||||
const int above_intra = !is_inter_block(above_mbmi);
|
||||
const int left_intra = !is_inter_block(left_mbmi);
|
||||
|
||||
if (above_intra && left_intra) { // intra/intra (2)
|
||||
pred_context = 2;
|
||||
} else if (above_intra || left_intra) { // intra/inter
|
||||
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
|
||||
|
||||
if (!has_second_ref(edge_mbmi)) // single pred (1/3)
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != LAST_FRAME);
|
||||
else // comp pred (1/3)
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
|
||||
!= LAST_FRAME);
|
||||
} else { // inter/inter
|
||||
const int l_sg = !has_second_ref(left_mbmi);
|
||||
const int a_sg = !has_second_ref(above_mbmi);
|
||||
const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
|
||||
: above_mbmi->ref_frame[var_ref_idx];
|
||||
const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
|
||||
: left_mbmi->ref_frame[var_ref_idx];
|
||||
|
||||
if (vrfa == vrfl && vrfa == LAST_FRAME)
|
||||
pred_context = 0;
|
||||
else if (l_sg && a_sg) { // single/single
|
||||
if (vrfa == LAST_FRAME || vrfl == LAST_FRAME)
|
||||
pred_context = 1;
|
||||
else if (vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME)
|
||||
pred_context = 2 + (vrfa != vrfl);
|
||||
else if (vrfa == vrfl)
|
||||
pred_context = 3;
|
||||
else
|
||||
pred_context = 4;
|
||||
} else if (l_sg || a_sg) { // single/comp
|
||||
const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
|
||||
const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
|
||||
|
||||
if (vrfc == LAST_FRAME && rfs != LAST_FRAME)
|
||||
pred_context = 1;
|
||||
else if (rfs == LAST_FRAME && vrfc != LAST_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 + (vrfc == LAST2_FRAME || rfs != GOLDEN_FRAME);
|
||||
} else { // comp/comp
|
||||
if (vrfa == LAST_FRAME || vrfl == LAST_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 + (vrfa != GOLDEN_FRAME || vrfl != GOLDEN_FRAME);
|
||||
}
|
||||
}
|
||||
} else if (above_in_image || left_in_image) { // one edge available
|
||||
const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
|
||||
|
||||
if (!is_inter_block(edge_mbmi)) {
|
||||
pred_context = 2;
|
||||
} else {
|
||||
if (has_second_ref(edge_mbmi)) {
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] != LAST_FRAME);
|
||||
} else {
|
||||
if (edge_mbmi->ref_frame[0] == LAST_FRAME)
|
||||
pred_context = 0;
|
||||
else
|
||||
pred_context = 2 + (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
|
||||
}
|
||||
}
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#else // CONFIG_MULTI_REF
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
@ -192,6 +382,269 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
|
||||
// For the bit to signal whether the single reference is a LAST_FRAME/
|
||||
// LAST2_FRAME, or not.
|
||||
int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
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;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
if (has_above && has_left) { // both edges available
|
||||
const int above_intra = !is_inter_block(above_mbmi);
|
||||
const int left_intra = !is_inter_block(left_mbmi);
|
||||
|
||||
if (above_intra && left_intra) { // intra/intra
|
||||
pred_context = 2;
|
||||
} else if (above_intra || left_intra) { // intra/inter or inter/intra
|
||||
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
|
||||
if (!has_second_ref(edge_mbmi))
|
||||
pred_context = 4 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
|
||||
else
|
||||
pred_context = 1 + (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
|
||||
CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
|
||||
} else { // inter/inter
|
||||
const int above_has_second = has_second_ref(above_mbmi);
|
||||
const int left_has_second = has_second_ref(left_mbmi);
|
||||
const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
|
||||
const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
|
||||
|
||||
if (above_has_second && left_has_second) {
|
||||
pred_context = 1 + (CHECK_LAST_OR_LAST2(above0) ||
|
||||
CHECK_LAST_OR_LAST2(above1) ||
|
||||
CHECK_LAST_OR_LAST2(left0) ||
|
||||
CHECK_LAST_OR_LAST2(left1));
|
||||
} else if (above_has_second || left_has_second) {
|
||||
const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
|
||||
|
||||
if (CHECK_LAST_OR_LAST2(rfs))
|
||||
pred_context = 3 + (CHECK_LAST_OR_LAST2(crf1) ||
|
||||
CHECK_LAST_OR_LAST2(crf2));
|
||||
else
|
||||
pred_context = CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2);
|
||||
} else {
|
||||
pred_context = 2 * CHECK_LAST_OR_LAST2(above0) +
|
||||
2 * CHECK_LAST_OR_LAST2(left0);
|
||||
}
|
||||
}
|
||||
} else if (has_above || has_left) { // one edge available
|
||||
const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
|
||||
if (!is_inter_block(edge_mbmi)) { // intra
|
||||
pred_context = 2;
|
||||
} else { // inter
|
||||
if (!has_second_ref(edge_mbmi))
|
||||
pred_context = 4 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
|
||||
else
|
||||
pred_context = 1 + (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
|
||||
CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
|
||||
}
|
||||
} else { // no edges available
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
// For the bit to signal whether the single reference is a LAST_FRAME or a
|
||||
// LAST2_FRAME, knowing that it shall be either of these 2 choices.
|
||||
int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
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;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
if (has_above && has_left) { // both edges available
|
||||
const int above_intra = !is_inter_block(above_mbmi);
|
||||
const int left_intra = !is_inter_block(left_mbmi);
|
||||
|
||||
if (above_intra && left_intra) { // intra/intra
|
||||
pred_context = 2;
|
||||
} else if (above_intra || left_intra) { // intra/inter or inter/intra
|
||||
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
|
||||
if (!has_second_ref(edge_mbmi)) {
|
||||
if (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]))
|
||||
pred_context = 3;
|
||||
else
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
|
||||
} else {
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
|
||||
}
|
||||
} else { // inter/inter
|
||||
const int above_has_second = has_second_ref(above_mbmi);
|
||||
const int left_has_second = has_second_ref(left_mbmi);
|
||||
const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
|
||||
const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
|
||||
|
||||
if (above_has_second && left_has_second) {
|
||||
if (above0 == left0 && above1 == left1)
|
||||
pred_context = 3 * (above0 == GOLDEN_FRAME ||
|
||||
above1 == GOLDEN_FRAME ||
|
||||
left0 == GOLDEN_FRAME ||
|
||||
left1 == GOLDEN_FRAME);
|
||||
else
|
||||
pred_context = 2;
|
||||
} else if (above_has_second || left_has_second) {
|
||||
const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
|
||||
|
||||
if (rfs == GOLDEN_FRAME)
|
||||
pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
|
||||
else if (rfs == ALTREF_FRAME)
|
||||
pred_context = (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
|
||||
else
|
||||
pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
|
||||
} else {
|
||||
if (CHECK_LAST_OR_LAST2(above0) && CHECK_LAST_OR_LAST2(left0)) {
|
||||
pred_context = 2 + (above0 == left0);
|
||||
} else if (CHECK_LAST_OR_LAST2(above0) || CHECK_LAST_OR_LAST2(left0)) {
|
||||
const MV_REFERENCE_FRAME edge0 = CHECK_LAST_OR_LAST2(above0) ? left0
|
||||
: above0;
|
||||
pred_context = 4 * (edge0 == GOLDEN_FRAME);
|
||||
} else {
|
||||
pred_context = 2 * (above0 == GOLDEN_FRAME) +
|
||||
2 * (left0 == GOLDEN_FRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (has_above || has_left) { // one edge available
|
||||
const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
|
||||
|
||||
if (!is_inter_block(edge_mbmi) ||
|
||||
(CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) &&
|
||||
!has_second_ref(edge_mbmi)))
|
||||
pred_context = 2;
|
||||
else if (!has_second_ref(edge_mbmi))
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
|
||||
else
|
||||
pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#define CHECK_GOLDEN_OR_ALTREF(ref_frame) \
|
||||
((ref_frame == GOLDEN_FRAME) || (ref_frame == ALTREF_FRAME))
|
||||
|
||||
// For the bit to signal whether the single reference is a GOLDEN_FRAME or an
|
||||
// ALTREF_FRAME, knowing that it shall be either of these 2 choices.
|
||||
int vp9_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
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;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialised to 0.
|
||||
if (has_above && has_left) { // both edges available
|
||||
const int above_intra = !is_inter_block(above_mbmi);
|
||||
const int left_intra = !is_inter_block(left_mbmi);
|
||||
|
||||
if (above_intra && left_intra) { // intra/intra
|
||||
pred_context = 2;
|
||||
} else if (above_intra || left_intra) { // intra/inter or inter/intra
|
||||
const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
|
||||
if (!has_second_ref(edge_mbmi)) {
|
||||
if (CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]))
|
||||
pred_context = 3;
|
||||
else
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
|
||||
} else {
|
||||
pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == LAST_FRAME);
|
||||
}
|
||||
} else { // inter/inter
|
||||
const int above_has_second = has_second_ref(above_mbmi);
|
||||
const int left_has_second = has_second_ref(left_mbmi);
|
||||
const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
|
||||
const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
|
||||
const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
|
||||
|
||||
if (above_has_second && left_has_second) {
|
||||
if (above0 == left0 && above1 == left1)
|
||||
pred_context = 3 * (above0 == LAST_FRAME ||
|
||||
above1 == LAST_FRAME ||
|
||||
left0 == LAST_FRAME ||
|
||||
left1 == LAST_FRAME);
|
||||
else
|
||||
pred_context = 2;
|
||||
} else if (above_has_second || left_has_second) {
|
||||
const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
|
||||
const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
|
||||
|
||||
if (rfs == LAST_FRAME)
|
||||
pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
|
||||
else if (rfs == LAST2_FRAME)
|
||||
pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
|
||||
else
|
||||
pred_context = 1 + 2 * (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
|
||||
} else {
|
||||
if (CHECK_GOLDEN_OR_ALTREF(above0) && CHECK_GOLDEN_OR_ALTREF(left0)) {
|
||||
pred_context = 2 + (above0 == left0);
|
||||
} else if (CHECK_GOLDEN_OR_ALTREF(above0) ||
|
||||
CHECK_GOLDEN_OR_ALTREF(left0)) {
|
||||
const MV_REFERENCE_FRAME edge0 =
|
||||
CHECK_GOLDEN_OR_ALTREF(above0) ? left0 : above0;
|
||||
pred_context = 4 * (edge0 == LAST_FRAME);
|
||||
} else {
|
||||
pred_context = 2 * (above0 == LAST_FRAME) +
|
||||
2 * (left0 == LAST_FRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (has_above || has_left) { // one edge available
|
||||
const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
|
||||
|
||||
if (!is_inter_block(edge_mbmi) ||
|
||||
(CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) &&
|
||||
!has_second_ref(edge_mbmi)))
|
||||
pred_context = 2;
|
||||
else if (!has_second_ref(edge_mbmi))
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
|
||||
else
|
||||
pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == LAST_FRAME);
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#else // CONFIG_MULTI_REF
|
||||
|
||||
int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = get_mbmi(get_above_mi(xd));
|
||||
@ -343,6 +796,9 @@ int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries corresponding to real blocks.
|
||||
|
@ -127,9 +127,24 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
|
||||
static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd);
|
||||
#if CONFIG_MULTI_REF
|
||||
return cm->fc.comp_ref_prob[pred_context][0];
|
||||
#else
|
||||
return cm->fc.comp_ref_prob[pred_context];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
int vp9_get_pred_context_comp_ref_p1(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p1(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp9_get_pred_context_comp_ref_p1(cm, xd);
|
||||
return cm->fc.comp_ref_prob[pred_context][1];
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm,
|
||||
@ -144,6 +159,15 @@ static INLINE vp9_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm,
|
||||
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1];
|
||||
}
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
int vp9_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p3(const VP9_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p3(xd)][2];
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
int vp9_get_tx_size_context(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE const vp9_prob *get_tx_probs(TX_SIZE max_tx_size, int ctx,
|
||||
|
@ -56,16 +56,27 @@ static int is_compound_reference_allowed(const VP9_COMMON *cm) {
|
||||
|
||||
static void setup_compound_reference_mode(VP9_COMMON *cm) {
|
||||
if (cm->ref_frame_sign_bias[LAST_FRAME] ==
|
||||
cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
|
||||
cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
|
||||
cm->comp_fixed_ref = ALTREF_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
#if CONFIG_MULTI_REF
|
||||
cm->comp_var_ref[1] = LAST2_FRAME;
|
||||
cm->comp_var_ref[2] = GOLDEN_FRAME;
|
||||
#else
|
||||
cm->comp_var_ref[1] = GOLDEN_FRAME;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
|
||||
cm->ref_frame_sign_bias[ALTREF_FRAME]) {
|
||||
cm->ref_frame_sign_bias[ALTREF_FRAME]) {
|
||||
#if CONFIG_MULTI_REF
|
||||
assert(0);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cm->comp_fixed_ref = GOLDEN_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
cm->comp_var_ref[1] = ALTREF_FRAME;
|
||||
} else {
|
||||
} else { // same sign bias for GOLDEN / ALTREF
|
||||
#if CONFIG_MULTI_REF
|
||||
assert(0);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cm->comp_fixed_ref = LAST_FRAME;
|
||||
cm->comp_var_ref[0] = GOLDEN_FRAME;
|
||||
cm->comp_var_ref[1] = ALTREF_FRAME;
|
||||
@ -163,11 +174,20 @@ static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
|
||||
for (i = 0; i < REF_CONTEXTS; ++i) {
|
||||
vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]);
|
||||
vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]);
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_diff_update_prob(r, &fc->single_ref_prob[i][2]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE)
|
||||
for (i = 0; i < REF_CONTEXTS; ++i)
|
||||
for (i = 0; i < REF_CONTEXTS; ++i) {
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_diff_update_prob(r, &fc->comp_ref_prob[i][0]);
|
||||
vp9_diff_update_prob(r, &fc->comp_ref_prob[i][1]);
|
||||
#else
|
||||
vp9_diff_update_prob(r, &fc->comp_ref_prob[i]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
|
||||
static void update_mv_probs(vp9_prob *p, int n, vp9_reader *r) {
|
||||
@ -2789,12 +2809,22 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
||||
vp9_zero(tile_data->xd.left_seg_context);
|
||||
for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
|
||||
mi_col += MI_BLOCK_SIZE) {
|
||||
/*
|
||||
printf("\n============================================\n");
|
||||
printf("decode_tiles(): current_video_frame=%d, "
|
||||
"mi_row=%d, mi_col=%d\n",
|
||||
cm->current_video_frame, mi_row, mi_col);
|
||||
*/
|
||||
decode_partition(tile_data->cm, &tile_data->xd, &tile,
|
||||
#if CONFIG_SUPERTX
|
||||
0,
|
||||
#endif
|
||||
mi_row, mi_col,
|
||||
&tile_data->bit_reader, BLOCK_64X64);
|
||||
/*
|
||||
printf("tile_data->xd.corrupted=%d\n", tile_data->xd.corrupted);
|
||||
printf("============================================\n");
|
||||
*/
|
||||
}
|
||||
pbi->mb.corrupted |= tile_data->xd.corrupted;
|
||||
}
|
||||
@ -3111,6 +3141,14 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
|
||||
"Invalid frame sync code");
|
||||
|
||||
read_bitdepth_colorspace_sampling(cm, rb);
|
||||
#if CONFIG_MULTI_REF
|
||||
// TODO(zoeliu): When current frame is a KEY_FRAME, after the decoding of
|
||||
// the frame, LAST2_FRAME should not get refreshed. However, if so, error
|
||||
// will occur when decoding the next INTER_FRAME, during
|
||||
// read_uncompressed_header(), specifically, during
|
||||
// set_frame_size_with_refs(). This needs to be further investigated and
|
||||
// fixed in the right way.
|
||||
#endif // COFNIG_MULTI_REF
|
||||
pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
|
||||
|
||||
for (i = 0; i < REFS_PER_FRAME; ++i) {
|
||||
|
@ -767,12 +767,56 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
|
||||
if (mode == COMPOUND_REFERENCE) {
|
||||
const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
|
||||
const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
|
||||
#if CONFIG_MULTI_REF
|
||||
const int bit = vp9_read(r, fc->comp_ref_prob[ctx][0]);
|
||||
#else
|
||||
const int bit = vp9_read(r, fc->comp_ref_prob[ctx]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
#if CONFIG_MULTI_REF
|
||||
++counts->comp_ref[ctx][0][bit];
|
||||
#else
|
||||
++counts->comp_ref[ctx][bit];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
ref_frame[idx] = cm->comp_fixed_ref;
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
if (!bit) {
|
||||
const int ctx1 = vp9_get_pred_context_comp_ref_p1(cm, xd);
|
||||
const int bit1 = vp9_read(r, fc->comp_ref_prob[ctx1][1]);
|
||||
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
++counts->comp_ref[ctx1][1][bit1];
|
||||
|
||||
ref_frame[!idx] = cm->comp_var_ref[bit1 ? 0 : 1];
|
||||
} else {
|
||||
ref_frame[!idx] = cm->comp_var_ref[2];
|
||||
}
|
||||
#else
|
||||
ref_frame[!idx] = cm->comp_var_ref[bit];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else if (mode == SINGLE_REFERENCE) {
|
||||
#if CONFIG_MULTI_REF
|
||||
const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
|
||||
const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
++counts->single_ref[ctx0][0][bit0];
|
||||
if (bit0) {
|
||||
const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
|
||||
const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
++counts->single_ref[ctx1][1][bit1];
|
||||
ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
|
||||
} else {
|
||||
const int ctx2 = vp9_get_pred_context_single_ref_p3(xd);
|
||||
const int bit2 = vp9_read(r, fc->single_ref_prob[ctx2][2]);
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
++counts->single_ref[ctx2][2][bit2];
|
||||
ref_frame[0] = bit2 ? LAST2_FRAME : LAST_FRAME;
|
||||
}
|
||||
#else
|
||||
const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
|
||||
const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
|
||||
if (!cm->frame_parallel_decoding_mode)
|
||||
@ -786,6 +830,7 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
|
||||
} else {
|
||||
ref_frame[0] = LAST_FRAME;
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
ref_frame[1] = NONE;
|
||||
} else {
|
||||
@ -1340,6 +1385,7 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
|
||||
ref_mv, nearestmv, nearmv, is_compound,
|
||||
allow_hp, r);
|
||||
}
|
||||
|
||||
#if CONFIG_TX_SKIP
|
||||
mbmi->uv_mode = mbmi->mode;
|
||||
#endif
|
||||
|
@ -155,10 +155,19 @@ vpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm,
|
||||
// later commit that adds VP9-specific controls for this functionality.
|
||||
if (ref_frame_flag == VP9_LAST_FLAG) {
|
||||
ref_buf = &cm->frame_refs[0];
|
||||
#if CONFIG_MULTI_REF
|
||||
} else if (ref_frame_flag == VP9_LAST2_FLAG) {
|
||||
ref_buf = &cm->frame_refs[1];
|
||||
} else if (ref_frame_flag == VP9_GOLD_FLAG) {
|
||||
ref_buf = &cm->frame_refs[2];
|
||||
} else if (ref_frame_flag == VP9_ALT_FLAG) {
|
||||
ref_buf = &cm->frame_refs[3];
|
||||
#else
|
||||
} else if (ref_frame_flag == VP9_GOLD_FLAG) {
|
||||
ref_buf = &cm->frame_refs[1];
|
||||
} else if (ref_frame_flag == VP9_ALT_FLAG) {
|
||||
ref_buf = &cm->frame_refs[2];
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else {
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
|
||||
"Invalid reference frame");
|
||||
@ -191,9 +200,54 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
||||
int ref_index = 0, mask;
|
||||
VP9_COMMON *const cm = &pbi->common;
|
||||
|
||||
/*
|
||||
{
|
||||
int i;
|
||||
printf("\n==============================================================\n");
|
||||
printf("*******swap_frame_buffers(frame=%d): refresh_frame_flags=%d, "
|
||||
"new_fb_idx=%d, ref_frame_map=[",
|
||||
cm->current_video_frame, pbi->refresh_frame_flags, cm->new_fb_idx);
|
||||
for (i = 0; i < REF_FRAMES; ++i)
|
||||
printf(" %d", cm->ref_frame_map[i]);
|
||||
printf(" ]\n");
|
||||
}
|
||||
*/
|
||||
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
||||
#if CONFIG_MULTI_REF
|
||||
// NOTE(zoeliu):
|
||||
// (1) When ref_index == 1 and the mask bit is set, it indicates LAST2_FRAME
|
||||
// shall be refreshed, but it has already been handled when LAST_FRAME
|
||||
// is being refreshed, i.e., when ref_index == 0 and mask is set
|
||||
// correspondingly;
|
||||
// (2) The only exception is that when current frame is a KEY_FRAME, where
|
||||
// all the frames in the frame buffer (cm->frame_bufs) get refreshed.
|
||||
if ((mask & 1) &&
|
||||
((ref_index != 1) || (cm->frame_type == KEY_FRAME))) {
|
||||
#else
|
||||
if (mask & 1) {
|
||||
#endif // CONFIG_MULTI_REF
|
||||
const int old_idx = cm->ref_frame_map[ref_index];
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
if ((ref_index == 0) && (mask & 2) && (cm->frame_type != KEY_FRAME)) {
|
||||
// If current is LAST_FRAME and LAST2_FRAME needs to get refreshed
|
||||
// as well, then LAST2_FRAME should get handled first.
|
||||
const int ref_index_last2 = ref_index + 1;
|
||||
const int old_buf_idx_last2 =
|
||||
cm->ref_frame_map[ref_index_last2];
|
||||
|
||||
ref_cnt_fb(cm->frame_bufs,
|
||||
&cm->ref_frame_map[ref_index_last2],
|
||||
cm->ref_frame_map[ref_index]);
|
||||
if (old_buf_idx_last2 >= 0 &&
|
||||
cm->frame_bufs[old_buf_idx_last2].ref_count == 0) {
|
||||
cm->release_fb_cb(
|
||||
cm->cb_priv,
|
||||
&cm->frame_bufs[old_buf_idx_last2].raw_frame_buffer);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
ref_cnt_fb(cm->frame_bufs, &cm->ref_frame_map[ref_index],
|
||||
cm->new_fb_idx);
|
||||
if (old_idx >= 0 && cm->frame_bufs[old_idx].ref_count == 0)
|
||||
@ -202,12 +256,24 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
||||
}
|
||||
++ref_index;
|
||||
}
|
||||
/*
|
||||
{
|
||||
int i;
|
||||
printf("*******swap_frame_buffers(frame=%d): refresh_frame_flags=%d, "
|
||||
"new_fb_idx=%d, ref_frame_map=[",
|
||||
cm->current_video_frame, pbi->refresh_frame_flags, cm->new_fb_idx);
|
||||
for (i = 0; i < REF_FRAMES; ++i)
|
||||
printf(" %d", cm->ref_frame_map[i]);
|
||||
printf(" ]\n");
|
||||
printf("==============================================================\n");
|
||||
}
|
||||
*/
|
||||
|
||||
cm->frame_to_show = get_frame_new_buffer(cm);
|
||||
cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
||||
|
||||
// Invalidate these references until the next frame starts.
|
||||
for (ref_index = 0; ref_index < 3; ref_index++)
|
||||
for (ref_index = 0; ref_index < REFS_PER_FRAME; ref_index++)
|
||||
cm->frame_refs[ref_index].idx = INT_MAX;
|
||||
}
|
||||
|
||||
|
@ -495,15 +495,34 @@ static void write_ref_frames(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
}
|
||||
|
||||
if (is_compound) {
|
||||
vp9_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
|
||||
vp9_get_pred_prob_comp_ref_p(cm, xd));
|
||||
const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
|
||||
vp9_write(w, bit, vp9_get_pred_prob_comp_ref_p(cm, xd));
|
||||
#if CONFIG_MULTI_REF
|
||||
if (!bit) {
|
||||
const int bit1 = mbmi->ref_frame[0] == LAST_FRAME;
|
||||
vp9_write(w, bit1, vp9_get_pred_prob_comp_ref_p1(cm, xd));
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else {
|
||||
#if CONFIG_MULTI_REF
|
||||
const int bit0 = !(mbmi->ref_frame[0] == LAST_FRAME ||
|
||||
mbmi->ref_frame[0] == LAST2_FRAME);
|
||||
vp9_write(w, bit0, vp9_get_pred_prob_single_ref_p1(cm, xd));
|
||||
if (bit0) {
|
||||
const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
|
||||
vp9_write(w, bit1, vp9_get_pred_prob_single_ref_p2(cm, xd));
|
||||
} else {
|
||||
const int bit2 = mbmi->ref_frame[0] != LAST_FRAME;
|
||||
vp9_write(w, bit2, vp9_get_pred_prob_single_ref_p3(cm, xd));
|
||||
}
|
||||
#else
|
||||
const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
|
||||
vp9_write(w, bit0, vp9_get_pred_prob_single_ref_p1(cm, xd));
|
||||
if (bit0) {
|
||||
const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
|
||||
vp9_write(w, bit1, vp9_get_pred_prob_single_ref_p2(cm, xd));
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2139,6 +2158,9 @@ static int get_refresh_mask(VP9_COMP *cpi) {
|
||||
// and this needs to be generalized as other uses are implemented
|
||||
// (like RTC/temporal scalability).
|
||||
return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
|
||||
#if CONFIG_MULTI_REF
|
||||
(cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
|
||||
#endif // CONFIG_MULTI_REF
|
||||
(cpi->refresh_golden_frame << cpi->alt_fb_idx);
|
||||
} else {
|
||||
int arf_idx = cpi->alt_fb_idx;
|
||||
@ -2147,6 +2169,9 @@ static int get_refresh_mask(VP9_COMP *cpi) {
|
||||
arf_idx = gf_group->arf_update_idx[gf_group->index];
|
||||
}
|
||||
return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
|
||||
#if CONFIG_MULTI_REF
|
||||
(cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
|
||||
#endif // CONFIG_MULTI_REF
|
||||
(cpi->refresh_golden_frame << cpi->gld_fb_idx) |
|
||||
(cpi->refresh_alt_ref_frame << arf_idx);
|
||||
}
|
||||
@ -2350,6 +2375,11 @@ static void write_uncompressed_header(VP9_COMP *cpi,
|
||||
vp9_wb_write_bit(wb, cm->show_frame);
|
||||
vp9_wb_write_bit(wb, cm->error_resilient_mode);
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame =
|
||||
(cm->frame_type == KEY_FRAME || cpi->refresh_last_frame) ? 1 : 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
write_sync_code(wb);
|
||||
write_bitdepth_colorspace_sampling(cm, wb);
|
||||
@ -2474,7 +2504,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
||||
cm->tx_mode = ONLY_4X4;
|
||||
else
|
||||
encode_txfm_probs(cm, &header_bc);
|
||||
#endif
|
||||
#endif // CONFIG_TX_SKIP
|
||||
|
||||
update_coef_probs(cpi, &header_bc);
|
||||
update_skip_probs(cm, &header_bc);
|
||||
@ -2511,6 +2541,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
||||
vp9_write_bit(&header_bc, use_compound_pred);
|
||||
if (use_compound_pred) {
|
||||
vp9_write_bit(&header_bc, use_hybrid_pred);
|
||||
|
||||
if (use_hybrid_pred)
|
||||
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->comp_inter_prob[i],
|
||||
@ -2524,13 +2555,26 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
||||
cm->counts.single_ref[i][0]);
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
|
||||
cm->counts.single_ref[i][1]);
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][2],
|
||||
cm->counts.single_ref[i][2]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE)
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
if (cm->reference_mode != SINGLE_REFERENCE) {
|
||||
for (i = 0; i < REF_CONTEXTS; i++) {
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][0],
|
||||
cm->counts.comp_ref[i][0]);
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][1],
|
||||
cm->counts.comp_ref[i][1]);
|
||||
#else
|
||||
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
|
||||
cm->counts.comp_ref[i]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
|
||||
prob_diff_update(vp9_intra_mode_tree, cm->fc.y_mode_prob[i],
|
||||
|
@ -400,6 +400,10 @@ void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
|
||||
denoiser->running_avg_y[INTRA_FRAME]);
|
||||
}
|
||||
if (refresh_last_frame) {
|
||||
#if CONFIG_MULTI_REF
|
||||
copy_frame(denoiser->running_avg_y[LAST2_FRAME],
|
||||
denoiser->running_avg_y[LAST_FRAME]);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
copy_frame(denoiser->running_avg_y[LAST_FRAME],
|
||||
denoiser->running_avg_y[INTRA_FRAME]);
|
||||
}
|
||||
|
@ -1522,14 +1522,34 @@ static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
|
||||
[has_second_ref(mbmi)]++;
|
||||
|
||||
if (has_second_ref(mbmi)) {
|
||||
#if CONFIG_MULTI_REF
|
||||
counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)][0]
|
||||
[ref0 == GOLDEN_FRAME]++;
|
||||
if (ref0 != GOLDEN_FRAME) {
|
||||
counts->comp_ref[vp9_get_pred_context_comp_ref_p1(cm, xd)][1]
|
||||
[ref0 == LAST_FRAME]++;
|
||||
}
|
||||
#else
|
||||
counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
|
||||
[ref0 == GOLDEN_FRAME]++;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else {
|
||||
#if CONFIG_MULTI_REF
|
||||
counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
|
||||
[ref0 != LAST_FRAME && ref0 != LAST2_FRAME]++;
|
||||
if (ref0 != LAST_FRAME && ref0 != LAST2_FRAME)
|
||||
counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
|
||||
[ref0 != GOLDEN_FRAME]++;
|
||||
else
|
||||
counts->single_ref[vp9_get_pred_context_single_ref_p3(xd)][2]
|
||||
[ref0 != LAST_FRAME]++;
|
||||
#else
|
||||
counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
|
||||
[ref0 != LAST_FRAME]++;
|
||||
if (ref0 != LAST_FRAME)
|
||||
counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
|
||||
[ref0 != GOLDEN_FRAME]++;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3853,8 +3873,13 @@ static int check_dual_ref_flags(VP9_COMP *cpi) {
|
||||
if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
|
||||
return 0;
|
||||
} else {
|
||||
return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
|
||||
+ !!(ref_flags & VP9_ALT_FLAG)) >= 2;
|
||||
#if CONFIG_MULTI_REF
|
||||
return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) +
|
||||
!!(ref_flags & VP9_ALT_FLAG) + !!(ref_flags & VP9_LAST2_FLAG)) >= 2;
|
||||
#else
|
||||
return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) +
|
||||
!!(ref_flags & VP9_ALT_FLAG)) >= 2;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
|
||||
@ -3879,6 +3904,8 @@ static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
|
||||
else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
|
||||
return GOLDEN_FRAME;
|
||||
else
|
||||
// TODO(zoeliu): To investigate whether a frame_type of LAST2_FRAME needs to
|
||||
// be analyzed here to decide on the reference mode.
|
||||
return LAST_FRAME;
|
||||
}
|
||||
|
||||
@ -4270,7 +4297,12 @@ void vp9_encode_frame(VP9_COMP *cpi) {
|
||||
cm->allow_comp_inter_inter = 1;
|
||||
cm->comp_fixed_ref = ALTREF_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
#if CONFIG_MULTI_REF
|
||||
cm->comp_var_ref[1] = LAST2_FRAME;
|
||||
cm->comp_var_ref[2] = GOLDEN_FRAME;
|
||||
#else
|
||||
cm->comp_var_ref[1] = GOLDEN_FRAME;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
}
|
||||
|
||||
@ -4281,9 +4313,12 @@ void vp9_encode_frame(VP9_COMP *cpi) {
|
||||
// either compound, single or hybrid prediction as per whatever has
|
||||
// worked best for that type of frame in the past.
|
||||
// It also predicts whether another coding mode would have worked
|
||||
// better that this coding mode. If that is the case, it remembers
|
||||
// better than this coding mode. If that is the case, it remembers
|
||||
// that for subsequent frames.
|
||||
// It does the same analysis for transform size selection also.
|
||||
//
|
||||
// TODO(zoeliu): To investigate whether a frame_type of LAST2_FRAME needs to
|
||||
// be analyzed here to decide on the reference mode.
|
||||
const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
|
||||
int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
|
||||
int64_t *const filter_thrs = rd_opt->filter_threshes[frame_type];
|
||||
|
@ -578,8 +578,14 @@ static void set_tile_limits(VP9_COMP *cpi) {
|
||||
|
||||
static void init_buffer_indices(VP9_COMP *cpi) {
|
||||
cpi->lst_fb_idx = 0;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->lst2_fb_idx = 1;
|
||||
cpi->gld_fb_idx = 2;
|
||||
cpi->alt_fb_idx = 3;
|
||||
#else
|
||||
cpi->gld_fb_idx = 1;
|
||||
cpi->alt_fb_idx = 2;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
}
|
||||
|
||||
static void init_config(struct VP9_COMP *cpi, VP9EncoderConfig *oxcf) {
|
||||
@ -1469,6 +1475,9 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
|
||||
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_last_frame = 1;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame = 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cm->refresh_frame_context = 1;
|
||||
cm->reset_frame_context = 0;
|
||||
|
||||
@ -2230,7 +2239,7 @@ static void generate_psnr_packet(VP9_COMP *cpi) {
|
||||
}
|
||||
|
||||
int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags) {
|
||||
if (ref_frame_flags > 7)
|
||||
if (ref_frame_flags > ((1 << REFS_PER_FRAME) - 1))
|
||||
return -1;
|
||||
|
||||
cpi->ref_frame_flags = ref_frame_flags;
|
||||
@ -2241,6 +2250,9 @@ void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags) {
|
||||
cpi->ext_refresh_golden_frame = (ref_frame_flags & VP9_GOLD_FLAG) != 0;
|
||||
cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & VP9_ALT_FLAG) != 0;
|
||||
cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->ext_refresh_last2_frame = (ref_frame_flags & VP9_LAST2_FLAG) != 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cpi->ext_refresh_frame_flags_pending = 1;
|
||||
}
|
||||
|
||||
@ -2249,6 +2261,10 @@ static YV12_BUFFER_CONFIG *get_vp9_ref_frame_buffer(VP9_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame = NONE;
|
||||
if (ref_frame_flag == VP9_LAST_FLAG)
|
||||
ref_frame = LAST_FRAME;
|
||||
#if CONFIG_MULTI_REF
|
||||
else if (ref_frame_flag == VP9_LAST2_FLAG)
|
||||
ref_frame = LAST2_FRAME;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
else if (ref_frame_flag == VP9_GOLD_FLAG)
|
||||
ref_frame = GOLDEN_FRAME;
|
||||
else if (ref_frame_flag == VP9_ALT_FLAG)
|
||||
@ -2570,13 +2586,40 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
|
||||
}
|
||||
|
||||
if (cpi->refresh_last_frame) {
|
||||
#if CONFIG_MULTI_REF
|
||||
if (cpi->refresh_last2_frame) {
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
ref_cnt_fb(cm->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst2_fb_idx],
|
||||
cm->new_fb_idx);
|
||||
else
|
||||
ref_cnt_fb(cm->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst2_fb_idx],
|
||||
cm->ref_frame_map[cpi->lst_fb_idx]);
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_cnt_fb(cm->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst_fb_idx], cm->new_fb_idx);
|
||||
if (!cpi->rc.is_src_frame_alt_ref)
|
||||
|
||||
if (!cpi->rc.is_src_frame_alt_ref) {
|
||||
#if CONFIG_MULTI_REF
|
||||
if (cpi->refresh_last2_frame) {
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
vpx_memcpy(cpi->interp_filter_selected[LAST2_FRAME],
|
||||
cpi->interp_filter_selected[0],
|
||||
sizeof(cpi->interp_filter_selected[0]));
|
||||
else
|
||||
vpx_memcpy(cpi->interp_filter_selected[LAST2_FRAME],
|
||||
cpi->interp_filter_selected[LAST_FRAME],
|
||||
sizeof(cpi->interp_filter_selected[LAST_FRAME]));
|
||||
}
|
||||
#endif // CONFIG_MULTI_REF
|
||||
vpx_memcpy(cpi->interp_filter_selected[LAST_FRAME],
|
||||
cpi->interp_filter_selected[0],
|
||||
sizeof(cpi->interp_filter_selected[0]));
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
if (cpi->oxcf.noise_sensitivity > 0) {
|
||||
vp9_denoiser_update_frame_info(&cpi->denoiser,
|
||||
@ -2586,7 +2629,7 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
|
||||
cpi->refresh_golden_frame,
|
||||
cpi->refresh_last_frame);
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
||||
}
|
||||
|
||||
static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {
|
||||
@ -2624,7 +2667,12 @@ static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {
|
||||
void vp9_scale_references(VP9_COMP *cpi) {
|
||||
VP9_COMMON *cm = &cpi->common;
|
||||
MV_REFERENCE_FRAME ref_frame;
|
||||
#if CONFIG_MULTI_REF
|
||||
const VP9_REFFRAME ref_mask[4] = {
|
||||
VP9_LAST_FLAG, VP9_LAST2_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
||||
#else
|
||||
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
||||
const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
|
||||
@ -2659,7 +2707,7 @@ static void release_scaled_references(VP9_COMP *cpi) {
|
||||
VP9_COMMON *cm = &cpi->common;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i = 0; i < REFS_PER_FRAME; i++)
|
||||
cm->frame_bufs[cpi->scaled_ref_idx[i]].ref_count--;
|
||||
}
|
||||
|
||||
@ -2822,6 +2870,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||
vp9_free_palette_map(cm);
|
||||
#endif // CONFIG_PALETTE
|
||||
// transform / motion compensation build reconstruction frame
|
||||
|
||||
vp9_encode_frame(cpi);
|
||||
|
||||
// Update the skip mb flag probabilities based on the distribution
|
||||
@ -3014,7 +3063,15 @@ static int get_ref_frame_flags(const VP9_COMP *cpi) {
|
||||
const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
|
||||
const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
|
||||
const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
|
||||
#if CONFIG_MULTI_REF
|
||||
const int last2_is_last = map[cpi->lst2_fb_idx] == map[cpi->lst_fb_idx];
|
||||
const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst2_fb_idx];
|
||||
const int alt_is_last2 = map[cpi->alt_fb_idx] == map[cpi->lst2_fb_idx];
|
||||
|
||||
int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG | VP9_LAST2_FLAG;
|
||||
#else
|
||||
int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
if (gold_is_last)
|
||||
flags &= ~VP9_GOLD_FLAG;
|
||||
@ -3028,6 +3085,17 @@ static int get_ref_frame_flags(const VP9_COMP *cpi) {
|
||||
if (gold_is_alt)
|
||||
flags &= ~VP9_ALT_FLAG;
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
if (last2_is_last)
|
||||
flags &= ~VP9_LAST2_FLAG;
|
||||
|
||||
if (gld_is_last2)
|
||||
flags &= ~VP9_GOLD_FLAG;
|
||||
|
||||
if (alt_is_last2)
|
||||
flags &= ~VP9_ALT_FLAG;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -3042,6 +3110,9 @@ static void set_ext_overrides(VP9_COMP *cpi) {
|
||||
}
|
||||
if (cpi->ext_refresh_frame_flags_pending) {
|
||||
cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame = cpi->ext_refresh_last2_frame;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
|
||||
cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
|
||||
cpi->ext_refresh_frame_flags_pending = 0;
|
||||
@ -3127,9 +3198,11 @@ int setup_interp_filter_search_mask(VP9_COMP *cpi) {
|
||||
int ref_total[MAX_REF_FRAMES] = {0};
|
||||
MV_REFERENCE_FRAME ref;
|
||||
int mask = 0;
|
||||
|
||||
if (cpi->common.last_frame_type == KEY_FRAME ||
|
||||
cpi->refresh_alt_ref_frame)
|
||||
return mask;
|
||||
|
||||
for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
|
||||
for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter)
|
||||
ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
|
||||
@ -3137,12 +3210,17 @@ int setup_interp_filter_search_mask(VP9_COMP *cpi) {
|
||||
for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) {
|
||||
if ((ref_total[LAST_FRAME] &&
|
||||
cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
|
||||
#if CONFIG_MULTI_REF
|
||||
(ref_total[LAST2_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50
|
||||
< ref_total[LAST2_FRAME]) &&
|
||||
#endif // CONFIG_MULTI_REF
|
||||
(ref_total[GOLDEN_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50
|
||||
< ref_total[GOLDEN_FRAME]) &&
|
||||
< ref_total[GOLDEN_FRAME]) &&
|
||||
(ref_total[ALTREF_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[ALTREF_FRAME][ifilter] * 50
|
||||
< ref_total[ALTREF_FRAME]))
|
||||
< ref_total[ALTREF_FRAME]))
|
||||
mask |= 1 << ifilter;
|
||||
}
|
||||
return mask;
|
||||
@ -3186,7 +3264,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
cpi->sf.interp_filter_search_mask =
|
||||
setup_interp_filter_search_mask(cpi);
|
||||
|
||||
|
||||
// Set various flags etc to special state if it is a key frame.
|
||||
if (frame_is_intra_only(cm)) {
|
||||
// Reset the loop filter deltas and segmentation map.
|
||||
@ -3304,7 +3381,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Special case code to reduce pulsing when key frames are forced at a
|
||||
// fixed interval. Note the reconstruction error if it is the frame before
|
||||
// the force key frame
|
||||
@ -3344,6 +3420,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
update_reference_segmentation_map(cpi);
|
||||
|
||||
release_scaled_references(cpi);
|
||||
|
||||
vp9_update_reference_frames(cpi);
|
||||
|
||||
for (t = TX_4X4; t < TX_SIZES; t++)
|
||||
@ -3507,12 +3584,14 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int frame_is_reference(const VP9_COMP *cpi) {
|
||||
const VP9_COMMON *cm = &cpi->common;
|
||||
|
||||
return cm->frame_type == KEY_FRAME ||
|
||||
cpi->refresh_last_frame ||
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame ||
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cpi->refresh_golden_frame ||
|
||||
cpi->refresh_alt_ref_frame ||
|
||||
cm->refresh_frame_context ||
|
||||
@ -3630,7 +3709,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
// Normal defaults
|
||||
cm->reset_frame_context = 0;
|
||||
cm->refresh_frame_context = 1;
|
||||
|
||||
cpi->refresh_last_frame = 1;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame = 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_alt_ref_frame = 0;
|
||||
|
||||
@ -3654,6 +3737,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
cpi->refresh_alt_ref_frame = 1;
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_last_frame = 0;
|
||||
#if CONFIG_MULTI_REF
|
||||
cpi->refresh_last2_frame = 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rc->is_src_frame_alt_ref = 0;
|
||||
rc->source_alt_ref_pending = 0;
|
||||
} else {
|
||||
@ -3669,7 +3755,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
}
|
||||
|
||||
// Read in the source frame.
|
||||
source = vp9_lookahead_pop(cpi->lookahead, flush);
|
||||
source = vp9_lookahead_pop(cpi->lookahead, flush);
|
||||
if (source != NULL) {
|
||||
cm->show_frame = 1;
|
||||
cm->intra_only = 0;
|
||||
@ -3717,7 +3803,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
/* find a free buffer for the new frame, releasing the reference previously
|
||||
* held.
|
||||
*/
|
||||
cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
||||
if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0)
|
||||
cm->frame_bufs[cm->new_fb_idx].ref_count--;
|
||||
cm->new_fb_idx = get_free_fb(cm);
|
||||
|
||||
// For two pass encodes analyse the first pass stats and determine
|
||||
@ -3769,7 +3856,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
buf->y_crop_width, buf->y_crop_height,
|
||||
cm->width, cm->height,
|
||||
(buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
|
||||
1 : 0);
|
||||
1 : 0);
|
||||
#else
|
||||
vp9_setup_scale_factors_for_frame(&ref_buf->sf,
|
||||
buf->y_crop_width, buf->y_crop_height,
|
||||
@ -3862,7 +3949,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
// encoder is changed to use on-demand buffer allocation.
|
||||
vp9_deblock(cm->frame_to_show, &cm->post_proc_buffer,
|
||||
cm->lf.filter_level * 10 / 6);
|
||||
#endif
|
||||
#endif // CONFIG_VP9_POSTPROC
|
||||
vp9_clear_system_state();
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -3913,7 +4000,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
frame_psnr2, frame_ssim2);
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
#endif // 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -3938,7 +4025,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_INTERNAL_STATS
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ typedef enum {
|
||||
REALTIME
|
||||
} MODE;
|
||||
|
||||
// TODO(zoeliu): What is this - FRAMETYPE_FLAGS?
|
||||
typedef enum {
|
||||
FRAMEFLAGS_KEY = 1 << 0,
|
||||
FRAMEFLAGS_GOLDEN = 1 << 1,
|
||||
@ -234,17 +235,27 @@ typedef struct VP9_COMP {
|
||||
// For a still frame, this flag is set to 1 to skip partition search.
|
||||
int partition_search_skippable_frame;
|
||||
|
||||
int scaled_ref_idx[3];
|
||||
int scaled_ref_idx[REFS_PER_FRAME];
|
||||
int lst_fb_idx;
|
||||
#if CONFIG_MULTI_REF
|
||||
int lst2_fb_idx;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
int gld_fb_idx;
|
||||
int alt_fb_idx;
|
||||
|
||||
int refresh_last_frame;
|
||||
#if CONFIG_MULTI_REF
|
||||
int refresh_last2_frame;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
int refresh_golden_frame;
|
||||
int refresh_alt_ref_frame;
|
||||
|
||||
int ext_refresh_frame_flags_pending;
|
||||
|
||||
int ext_refresh_last_frame;
|
||||
#if CONFIG_MULTI_REF
|
||||
int ext_refresh_last2_frame;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
int ext_refresh_golden_frame;
|
||||
int ext_refresh_alt_ref_frame;
|
||||
|
||||
@ -481,6 +492,10 @@ static INLINE int get_ref_frame_idx(const VP9_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame) {
|
||||
if (ref_frame == LAST_FRAME) {
|
||||
return cpi->lst_fb_idx;
|
||||
#if CONFIG_MULTI_REF
|
||||
} else if (ref_frame == LAST2_FRAME) {
|
||||
return cpi->lst2_fb_idx;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else if (ref_frame == GOLDEN_FRAME) {
|
||||
return cpi->gld_fb_idx;
|
||||
} else {
|
||||
|
@ -90,13 +90,10 @@ static int mv_err_cost(const MV *mv, const MV *ref,
|
||||
|
||||
static int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, const MV *ref,
|
||||
int error_per_bit) {
|
||||
if (x->nmvsadcost) {
|
||||
const MV diff = { mv->row - ref->row,
|
||||
mv->col - ref->col };
|
||||
const int cost = mv_cost(&diff, x->nmvjointsadcost, x->nmvsadcost);
|
||||
return ROUND_POWER_OF_TWO(cost * error_per_bit, 8);
|
||||
}
|
||||
return 0;
|
||||
const MV diff = { mv->row - ref->row,
|
||||
mv->col - ref->col };
|
||||
return ROUND_POWER_OF_TWO(mv_cost(&diff, x->nmvjointsadcost,
|
||||
x->nmvsadcost) * error_per_bit, 8);
|
||||
}
|
||||
|
||||
void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride) {
|
||||
|
@ -627,10 +627,16 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
|
||||
if (sf->adaptive_rd_thresh) {
|
||||
rd->thresh_mult[THR_NEARESTMV] = 300;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARESTL2] = 300;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARESTG] = 300;
|
||||
rd->thresh_mult[THR_NEARESTA] = 300;
|
||||
} else {
|
||||
rd->thresh_mult[THR_NEARESTMV] = 0;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARESTL2] = 0;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARESTG] = 0;
|
||||
rd->thresh_mult[THR_NEARESTA] = 0;
|
||||
}
|
||||
@ -638,22 +644,34 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
rd->thresh_mult[THR_DC] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_NEWMV] += 1000;
|
||||
rd->thresh_mult[THR_NEWA] += 1000;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEWL2] += 1000;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEWG] += 1000;
|
||||
rd->thresh_mult[THR_NEWA] += 1000;
|
||||
|
||||
#if CONFIG_NEW_INTER
|
||||
rd->thresh_mult[THR_NEW2MV] += 1000;
|
||||
rd->thresh_mult[THR_NEW2A] += 1000;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEW2L2] += 1000;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEW2G] += 1000;
|
||||
rd->thresh_mult[THR_NEW2A] += 1000;
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
rd->thresh_mult[THR_NEARMV] += 1000;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARL2] += 1000;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
rd->thresh_mult[THR_NEARA] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_TM] += 1000;
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_ZEROMV] += 2000;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_ZEROL2] += 2000;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_ZEROG] += 2000;
|
||||
rd->thresh_mult[THR_ZEROA] += 2000;
|
||||
|
||||
@ -676,7 +694,20 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
rd->thresh_mult[THR_COMP_NEW_NEWGA] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZERO_ZEROLA] += 2500;
|
||||
rd->thresh_mult[THR_COMP_ZERO_ZEROGA] += 2500;
|
||||
#else
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_COMP_NEAREST_NEARESTL2A] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEAREST_NEARL2A] += 1200;
|
||||
rd->thresh_mult[THR_COMP_NEAR_NEARESTL2A] += 1200;
|
||||
rd->thresh_mult[THR_COMP_NEAREST_NEWL2A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEW_NEARESTL2A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEAR_NEWL2A] += 1700;
|
||||
rd->thresh_mult[THR_COMP_NEW_NEARL2A] += 1700;
|
||||
rd->thresh_mult[THR_COMP_NEW_NEWL2A] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZERO_ZEROL2A] += 2500;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#else // CONFIG_NEW_INTER
|
||||
rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTGA] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARLA] += 1500;
|
||||
@ -685,6 +716,14 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
rd->thresh_mult[THR_COMP_NEWGA] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZEROLA] += 2500;
|
||||
rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult[THR_COMP_NEARESTL2A] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARL2A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWL2A] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZEROL2A] += 2500;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
rd->thresh_mult[THR_H_PRED] += 2000;
|
||||
@ -724,10 +763,16 @@ void vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP *cpi) {
|
||||
rd->thresh_mult_sub8x8[i] = cpi->oxcf.mode == BEST ? -500 : 0;
|
||||
|
||||
rd->thresh_mult_sub8x8[THR_LAST] += 2500;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult_sub8x8[THR_LAST2] += 2500;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult_sub8x8[THR_GOLD] += 2500;
|
||||
rd->thresh_mult_sub8x8[THR_ALTR] += 2500;
|
||||
rd->thresh_mult_sub8x8[THR_INTRA] += 2500;
|
||||
rd->thresh_mult_sub8x8[THR_COMP_LA] += 4500;
|
||||
#if CONFIG_MULTI_REF
|
||||
rd->thresh_mult_sub8x8[THR_COMP_L2A] += 4500;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
rd->thresh_mult_sub8x8[THR_COMP_GA] += 4500;
|
||||
|
||||
// Check for masked out split cases.
|
||||
|
@ -40,55 +40,80 @@ extern "C" {
|
||||
#if CONFIG_NEW_INTER
|
||||
|
||||
#if CONFIG_INTERINTRA
|
||||
#define MAX_MODES 55
|
||||
#define MAX_MODES 69
|
||||
#else // CONFIG_INTERINTRA
|
||||
#define MAX_MODES 43
|
||||
#define MAX_MODES 57
|
||||
#endif // CONFIG_INTERINTRA
|
||||
|
||||
#else // CONFIG_NEW_INTER
|
||||
|
||||
#if CONFIG_INTERINTRA
|
||||
#define MAX_MODES 42
|
||||
#define MAX_MODES 50
|
||||
#else // CONFIG_INTERINTRA
|
||||
#define MAX_MODES 30
|
||||
#define MAX_MODES 38
|
||||
#endif // CONFIG_INTERINTRA
|
||||
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
#define MAX_REFS 8
|
||||
#else
|
||||
#define MAX_REFS 6
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
// This enumerator type needs to be kept aligned with the mode order in
|
||||
// const MODE_DEFINITION vp9_mode_order[MAX_MODES] used in the rd code.
|
||||
typedef enum {
|
||||
THR_NEARESTMV,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_NEARESTL2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_NEARESTA,
|
||||
THR_NEARESTG,
|
||||
|
||||
THR_DC,
|
||||
|
||||
THR_NEWMV,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_NEWL2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_NEWA,
|
||||
THR_NEWG,
|
||||
|
||||
#if CONFIG_NEW_INTER
|
||||
THR_NEW2MV,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_NEW2L2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_NEW2A,
|
||||
THR_NEW2G,
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
THR_NEARMV,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_NEARL2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_NEARA,
|
||||
THR_NEARG,
|
||||
|
||||
THR_ZEROMV,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_ZEROL2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_ZEROG,
|
||||
THR_ZEROA,
|
||||
|
||||
#if CONFIG_NEW_INTER
|
||||
THR_COMP_NEAREST_NEARESTLA,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_COMP_NEAREST_NEARESTL2A,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_COMP_NEAREST_NEARESTGA,
|
||||
#else
|
||||
THR_COMP_NEARESTLA,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_COMP_NEARESTL2A,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_COMP_NEARESTGA,
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
@ -115,7 +140,22 @@ typedef enum {
|
||||
|
||||
THR_COMP_ZERO_ZEROLA,
|
||||
THR_COMP_ZERO_ZEROGA,
|
||||
#else
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_COMP_NEAR_NEARESTL2A,
|
||||
THR_COMP_NEAREST_NEARL2A,
|
||||
|
||||
THR_COMP_NEW_NEARESTL2A,
|
||||
THR_COMP_NEAREST_NEWL2A,
|
||||
|
||||
THR_COMP_NEW_NEARL2A,
|
||||
THR_COMP_NEAR_NEWL2A,
|
||||
|
||||
THR_COMP_NEW_NEWL2A,
|
||||
THR_COMP_ZERO_ZEROL2A,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#else // CONFIG_NEW_INTER
|
||||
THR_COMP_NEARLA,
|
||||
THR_COMP_NEWLA,
|
||||
THR_COMP_NEARGA,
|
||||
@ -123,6 +163,13 @@ typedef enum {
|
||||
|
||||
THR_COMP_ZEROLA,
|
||||
THR_COMP_ZEROGA,
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_COMP_NEARL2A,
|
||||
THR_COMP_NEWL2A,
|
||||
THR_COMP_ZEROL2A,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
THR_H_PRED,
|
||||
@ -154,9 +201,15 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
THR_LAST,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_LAST2,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_GOLD,
|
||||
THR_ALTR,
|
||||
THR_COMP_LA,
|
||||
#if CONFIG_MULTI_REF
|
||||
THR_COMP_L2A,
|
||||
#endif // CONFIG_MULTI_REF
|
||||
THR_COMP_GA,
|
||||
THR_INTRA,
|
||||
} THR_MODES_SUB8X8;
|
||||
|
@ -48,6 +48,19 @@
|
||||
#define RD_THRESH_MAX_FACT 64
|
||||
#define RD_THRESH_INC 1
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
|
||||
#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME))
|
||||
#define LAST2_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST_FRAME) | (1 << INTRA_FRAME))
|
||||
#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME))
|
||||
#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME))
|
||||
|
||||
#else
|
||||
|
||||
#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << INTRA_FRAME))
|
||||
#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
@ -55,6 +68,8 @@
|
||||
#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
|
||||
(1 << INTRA_FRAME))
|
||||
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
|
||||
|
||||
#define MIN_EARLY_TERM_INDEX 3
|
||||
@ -91,34 +106,55 @@ struct rdcost_block_args {
|
||||
|
||||
static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
|
||||
{NEARESTMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEARESTMV, {LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEARESTMV, {ALTREF_FRAME, NONE}},
|
||||
{NEARESTMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
{DC_PRED, {INTRA_FRAME, NONE}},
|
||||
|
||||
{NEWMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEWMV, {LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEWMV, {ALTREF_FRAME, NONE}},
|
||||
{NEWMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
#if CONFIG_NEW_INTER
|
||||
{NEW2MV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEW2MV, {LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEW2MV, {ALTREF_FRAME, NONE}},
|
||||
{NEW2MV, {GOLDEN_FRAME, NONE}},
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
{NEARMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEARMV, {LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEARMV, {ALTREF_FRAME, NONE}},
|
||||
{NEARMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
{ZEROMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{ZEROMV, {LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{ZEROMV, {GOLDEN_FRAME, NONE}},
|
||||
{ZEROMV, {ALTREF_FRAME, NONE}},
|
||||
|
||||
#if CONFIG_NEW_INTER
|
||||
{NEAREST_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEAREST_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEAREST_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
#else
|
||||
#else // CONFIG_NEW_INTER
|
||||
{NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_NEW_INTER
|
||||
{TM_PRED, {INTRA_FRAME, NONE}},
|
||||
@ -144,7 +180,22 @@ static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
|
||||
|
||||
{ZERO_ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
{ZERO_ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
#else
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEAR_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEAREST_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{NEW_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEAREST_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{NEW_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEAR_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{NEW_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{ZERO_ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#else /// CONFIG_NEW_INTER
|
||||
{NEARMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
{NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
@ -152,6 +203,13 @@ static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
|
||||
|
||||
{ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
{ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
{NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
#endif // CONFIG_NEW_INTER
|
||||
|
||||
{H_PRED, {INTRA_FRAME, NONE}},
|
||||
@ -183,9 +241,15 @@ static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
|
||||
|
||||
static const REF_DEFINITION vp9_ref_order[MAX_REFS] = {
|
||||
{{LAST_FRAME, NONE}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{{LAST2_FRAME, NONE}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{{GOLDEN_FRAME, NONE}},
|
||||
{{ALTREF_FRAME, NONE}},
|
||||
{{LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_MULTI_REF
|
||||
{{LAST2_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_MULTI_REF
|
||||
{{GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
{{INTRA_FRAME, NONE}},
|
||||
};
|
||||
@ -2590,14 +2654,15 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
}
|
||||
|
||||
#if CONFIG_INTRABC
|
||||
static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
const TileInfo *const tile,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
BLOCK_SIZE block_size,
|
||||
int mi_row, int mi_col,
|
||||
int_mv frame_nearest_mv[MAX_REF_FRAMES],
|
||||
int_mv frame_near_mv[MAX_REF_FRAMES],
|
||||
struct buf_2d yv12_mb[4][MAX_MB_PLANE]);
|
||||
static void setup_buffer_inter(
|
||||
VP9_COMP *cpi, MACROBLOCK *x,
|
||||
const TileInfo *const tile,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
BLOCK_SIZE block_size,
|
||||
int mi_row, int mi_col,
|
||||
int_mv frame_nearest_mv[MAX_REF_FRAMES],
|
||||
int_mv frame_near_mv[MAX_REF_FRAMES],
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]);
|
||||
|
||||
// This function is used only for intra_only frames
|
||||
static int64_t rd_pick_intrabc_sb_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
@ -4294,34 +4359,67 @@ static void estimate_ref_frame_costs(const VP9_COMMON *cm,
|
||||
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
||||
vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd);
|
||||
vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd);
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_prob ref_single_p3 = vp9_get_pred_prob_single_ref_p3(cm, xd);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
base_cost += vp9_cost_bit(comp_inter_p, 0);
|
||||
|
||||
ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
|
||||
ref_costs_single[LAST_FRAME] =
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_costs_single[LAST2_FRAME] =
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_costs_single[GOLDEN_FRAME] =
|
||||
ref_costs_single[ALTREF_FRAME] = base_cost;
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[LAST2_FRAME] += vp9_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p3, 0);
|
||||
ref_costs_single[LAST2_FRAME] += vp9_cost_bit(ref_single_p3, 1);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
|
||||
ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
|
||||
#else
|
||||
ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
|
||||
ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
} else {
|
||||
ref_costs_single[LAST_FRAME] = 512;
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_costs_single[LAST2_FRAME] = 512;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_costs_single[GOLDEN_FRAME] = 512;
|
||||
ref_costs_single[ALTREF_FRAME] = 512;
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE) {
|
||||
vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
|
||||
vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
|
||||
#if CONFIG_MULTI_REF
|
||||
vp9_prob ref_comp_p1 = vp9_get_pred_prob_comp_ref_p1(cm, xd);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
base_cost += vp9_cost_bit(comp_inter_p, 1);
|
||||
|
||||
ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0);
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p1, 1);
|
||||
ref_costs_comp[LAST2_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0);
|
||||
ref_costs_comp[LAST2_FRAME] = base_cost + vp9_cost_bit(ref_comp_p1, 0);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1);
|
||||
} else {
|
||||
ref_costs_comp[LAST_FRAME] = 512;
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_costs_comp[LAST2_FRAME] = 512;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_costs_comp[GOLDEN_FRAME] = 512;
|
||||
}
|
||||
}
|
||||
@ -4351,14 +4449,15 @@ static void store_coding_context(
|
||||
sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
|
||||
}
|
||||
|
||||
static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
const TileInfo *const tile,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
BLOCK_SIZE block_size,
|
||||
int mi_row, int mi_col,
|
||||
int_mv frame_nearest_mv[MAX_REF_FRAMES],
|
||||
int_mv frame_near_mv[MAX_REF_FRAMES],
|
||||
struct buf_2d yv12_mb[4][MAX_MB_PLANE]) {
|
||||
static void setup_buffer_inter(
|
||||
VP9_COMP *cpi, MACROBLOCK *x,
|
||||
const TileInfo *const tile,
|
||||
MV_REFERENCE_FRAME ref_frame,
|
||||
BLOCK_SIZE block_size,
|
||||
int mi_row, int mi_col,
|
||||
int_mv frame_nearest_mv[MAX_REF_FRAMES],
|
||||
int_mv frame_near_mv[MAX_REF_FRAMES],
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
|
||||
const VP9_COMMON *cm = &cpi->common;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const YV12_BUFFER_CONFIG *yv12 =
|
||||
@ -6387,7 +6486,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
unsigned char segment_id = mbmi->segment_id;
|
||||
int comp_pred, i, k;
|
||||
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
|
||||
#if CONFIG_NEW_INTER
|
||||
int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
|
||||
#else
|
||||
@ -6395,8 +6494,13 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
#endif // CONFIG_NEW_INTER
|
||||
INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
#if CONFIG_MULTI_REF
|
||||
static const int flag_list[5] = {
|
||||
0, VP9_LAST_FLAG, VP9_LAST2_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG };
|
||||
#else
|
||||
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG };
|
||||
#endif // CONFIG_MULTI_REF
|
||||
int64_t best_rd = best_rd_so_far;
|
||||
int64_t best_tx_rd[TX_MODES];
|
||||
int64_t best_tx_diff[TX_MODES];
|
||||
@ -6571,14 +6675,19 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
// because they may result in zero-zero MVs but be cheaper.
|
||||
if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
|
||||
int_mv zmv;
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[0] = (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
|
||||
(1 << GOLDEN_FRAME);
|
||||
#else
|
||||
ref_frame_skip_mask[0] = (1 << LAST_FRAME) | (1 << GOLDEN_FRAME);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
|
||||
mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
zmv.as_int = cm->global_motion[ALTREF_FRAME][0].mv.as_int;
|
||||
#else
|
||||
zmv.as_int = 0;
|
||||
#endif
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zmv.as_int)
|
||||
mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
|
||||
if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zmv.as_int)
|
||||
@ -6719,6 +6828,12 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#if CONFIG_MULTI_REF
|
||||
case LAST2_FRAME:
|
||||
ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
case GOLDEN_FRAME:
|
||||
ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
@ -6740,6 +6855,11 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
if (mode_skip_mask[ref_frame] & (1 << this_mode))
|
||||
continue;
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
|
||||
continue;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
// Test best rd so far against threshold for trying this mode.
|
||||
if (best_mode_skippable && sf->schedule_mode_search)
|
||||
mode_threshold[mode_index] <<= 1;
|
||||
@ -7089,7 +7209,6 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
#else
|
||||
single_newmv,
|
||||
#endif // COFNIG_NEW_INTER
|
||||
|
||||
single_inter_filter,
|
||||
single_skippable,
|
||||
#if CONFIG_INTERINTRA
|
||||
@ -8094,9 +8213,14 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
|
||||
unsigned char segment_id = mbmi->segment_id;
|
||||
int comp_pred, i;
|
||||
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
|
||||
#if CONFIG_MULTI_REF
|
||||
static const int flag_list[5] = {
|
||||
0, VP9_LAST_FLAG, VP9_LAST2_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG };
|
||||
#else
|
||||
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG };
|
||||
#endif // CONFIG_MULTI_REF
|
||||
int64_t best_rd = best_rd_so_far;
|
||||
int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
|
||||
static const int64_t best_tx_diff[TX_MODES] = { 0 };
|
||||
@ -8223,6 +8347,11 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
ref_frame = vp9_ref_order[ref_index].ref_frame[0];
|
||||
second_ref_frame = vp9_ref_order[ref_index].ref_frame[1];
|
||||
|
||||
#if CONFIG_MULTI_REF
|
||||
if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
|
||||
continue;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
|
||||
// Look at the reference frame of the best mode so far and set the
|
||||
// skip mask to look at a subset of the remaining modes.
|
||||
if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
|
||||
@ -8231,15 +8360,37 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
case INTRA_FRAME:
|
||||
break;
|
||||
case LAST_FRAME:
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
|
||||
(1 << ALTREF_FRAME) | (1 << LAST2_FRAME);
|
||||
#else
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#if CONFIG_MULTI_REF
|
||||
case LAST2_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
|
||||
(1 << ALTREF_FRAME) | (1 << LAST_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
case GOLDEN_FRAME:
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
|
||||
(1 << ALTREF_FRAME) | (1 << LAST2_FRAME);
|
||||
#else
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << ALTREF_FRAME);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case ALTREF_FRAME:
|
||||
#if CONFIG_MULTI_REF
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
|
||||
(1 << LAST_FRAME) | (1 << LAST2_FRAME);
|
||||
#else
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << LAST_FRAME);
|
||||
#endif // CONFIG_MULTI_REF
|
||||
break;
|
||||
case NONE:
|
||||
case MAX_REF_FRAMES:
|
||||
@ -8373,8 +8524,13 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
this_rd_thresh = (ref_frame == LAST_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_LAST] :
|
||||
rd_opt->threshes[segment_id][bsize][THR_ALTR];
|
||||
#if CONFIG_MULTI_REF
|
||||
this_rd_thresh = (ref_frame == LAST2_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
|
||||
#endif // CONFIG_MULTI_REF
|
||||
this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
|
||||
|
||||
rd_opt->mask_filter = 0;
|
||||
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
|
||||
rd_opt->filter_cache[i] = INT64_MAX;
|
||||
|
9
vpxenc.c
9
vpxenc.c
@ -1768,14 +1768,11 @@ static void test_decode(struct stream_state *stream,
|
||||
if (!compare_img(&enc_img, &dec_img)) {
|
||||
int y[4], u[4], v[4];
|
||||
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
|
||||
if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
|
||||
if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)
|
||||
find_mismatch_high(&enc_img, &dec_img, y, u, v);
|
||||
} else {
|
||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||
}
|
||||
#else
|
||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||
else
|
||||
#endif
|
||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||
stream->decoder.err = 1;
|
||||
warn_or_exit_on_error(&stream->decoder, fatal == TEST_DECODE_FATAL,
|
||||
"Stream %d: Encode/decode mismatch on frame %d at"
|
||||
|
Loading…
x
Reference in New Issue
Block a user