Added 3 more reference frames for inter prediction.
Under the experiment of EXT_REFS: LAST2_FRAME, LAST3_FRAME, and LAST4_FRAME. Coding efficiency: derflr +1.601%; hevchr +1.895% Speed: Encoder slowed down by ~75% Change-Id: Ifeee5f049c2c1f7cb29bc897622ef88897082ecf
This commit is contained in:
@@ -65,9 +65,18 @@ typedef struct {
|
||||
#define NONE -1
|
||||
#define INTRA_FRAME 0
|
||||
#define LAST_FRAME 1
|
||||
#if CONFIG_EXT_REFS
|
||||
#define LAST2_FRAME 2
|
||||
#define LAST3_FRAME 3
|
||||
#define LAST4_FRAME 4
|
||||
#define GOLDEN_FRAME 5
|
||||
#define ALTREF_FRAME 6
|
||||
#define MAX_REF_FRAMES 7
|
||||
#else
|
||||
#define GOLDEN_FRAME 2
|
||||
#define ALTREF_FRAME 3
|
||||
#define MAX_REF_FRAMES 4
|
||||
#endif // CONFIG_EXT_REFS
|
||||
typedef int8_t MV_REFERENCE_FRAME;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -215,16 +215,33 @@ static const vpx_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
|
||||
239, 183, 119, 96, 41
|
||||
};
|
||||
|
||||
static const vpx_prob default_comp_ref_p[REF_CONTEXTS] = {
|
||||
50, 126, 123, 221, 226
|
||||
static const vpx_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = {
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(zoeliu): To adjust the initial prob values.
|
||||
{ 33, 16, 16, 16 },
|
||||
{ 77, 74, 74, 74 },
|
||||
{ 142, 142, 142, 142 },
|
||||
{ 172, 170, 170, 170 },
|
||||
{ 238, 247, 247, 247 }
|
||||
#else
|
||||
{ 50 }, { 126 }, { 123 }, { 221 }, { 226 }
|
||||
#endif // CONFIG_EXT_REFS
|
||||
};
|
||||
|
||||
static const vpx_prob default_single_ref_p[REF_CONTEXTS][2] = {
|
||||
static const vpx_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
|
||||
#if CONFIG_EXT_REFS
|
||||
{ 33, 16, 16, 16, 16 },
|
||||
{ 77, 74, 74, 74, 74 },
|
||||
{ 142, 142, 142, 142, 142 },
|
||||
{ 172, 170, 170, 170, 170 },
|
||||
{ 238, 247, 247, 247, 247 }
|
||||
#else
|
||||
{ 33, 16 },
|
||||
{ 77, 74 },
|
||||
{ 142, 142 },
|
||||
{ 172, 170 },
|
||||
{ 238, 247 }
|
||||
#endif // CONFIG_EXT_REFS
|
||||
};
|
||||
|
||||
static const struct tx_probs default_tx_probs = {
|
||||
@@ -1109,10 +1126,11 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
|
||||
fc->comp_inter_prob[i] = mode_mv_merge_probs(pre_fc->comp_inter_prob[i],
|
||||
counts->comp_inter[i]);
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
fc->comp_ref_prob[i] = mode_mv_merge_probs(pre_fc->comp_ref_prob[i],
|
||||
counts->comp_ref[i]);
|
||||
for (j = 0; j < (COMP_REFS - 1); j++)
|
||||
fc->comp_ref_prob[i][j] = mode_mv_merge_probs(pre_fc->comp_ref_prob[i][j],
|
||||
counts->comp_ref[i][j]);
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
for (j = 0; j < (SINGLE_REFS - 1); j++)
|
||||
fc->single_ref_prob[i][j] = mode_mv_merge_probs(
|
||||
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
|
||||
|
||||
@@ -1233,6 +1251,11 @@ static void set_default_lf_deltas(struct loopfilter *lf) {
|
||||
|
||||
lf->ref_deltas[INTRA_FRAME] = 1;
|
||||
lf->ref_deltas[LAST_FRAME] = 0;
|
||||
#if CONFIG_EXT_REFS
|
||||
lf->ref_deltas[LAST2_FRAME] = lf->ref_deltas[LAST_FRAME];
|
||||
lf->ref_deltas[LAST3_FRAME] = lf->ref_deltas[LAST_FRAME];
|
||||
lf->ref_deltas[LAST4_FRAME] = lf->ref_deltas[LAST_FRAME];
|
||||
#endif // CONFIG_EXT_REFS
|
||||
lf->ref_deltas[GOLDEN_FRAME] = -1;
|
||||
lf->ref_deltas[ALTREF_FRAME] = -1;
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ typedef struct frame_contexts {
|
||||
vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
|
||||
vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
|
||||
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
|
||||
vpx_prob single_ref_prob[REF_CONTEXTS][2];
|
||||
vpx_prob comp_ref_prob[REF_CONTEXTS];
|
||||
vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
|
||||
vpx_prob comp_ref_prob[REF_CONTEXTS][COMP_REFS-1];
|
||||
struct tx_probs tx_probs;
|
||||
#if CONFIG_VAR_TX
|
||||
vpx_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
|
||||
@@ -96,8 +96,8 @@ typedef struct FRAME_COUNTS {
|
||||
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
|
||||
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
|
||||
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
|
||||
unsigned int single_ref[REF_CONTEXTS][2][2];
|
||||
unsigned int comp_ref[REF_CONTEXTS][2];
|
||||
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
|
||||
unsigned int comp_ref[REF_CONTEXTS][COMP_REFS-1][2];
|
||||
struct tx_counts tx;
|
||||
#if CONFIG_VAR_TX
|
||||
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
|
||||
|
||||
@@ -123,8 +123,16 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
VP9_LAST_FLAG = 1 << 0,
|
||||
#if CONFIG_EXT_REFS
|
||||
VP9_LAST2_FLAG = 1 << 1,
|
||||
VP9_LAST3_FLAG = 1 << 2,
|
||||
VP9_LAST4_FLAG = 1 << 3,
|
||||
VP9_GOLD_FLAG = 1 << 4,
|
||||
VP9_ALT_FLAG = 1 << 5,
|
||||
#else
|
||||
VP9_GOLD_FLAG = 1 << 1,
|
||||
VP9_ALT_FLAG = 1 << 2,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} VP9_REFFRAME;
|
||||
|
||||
typedef enum {
|
||||
@@ -210,6 +218,14 @@ typedef uint8_t PREDICTION_MODE;
|
||||
typedef TX_SIZE TXFM_CONTEXT;
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
#define SINGLE_REFS 6
|
||||
#define COMP_REFS 5
|
||||
#else
|
||||
#define SINGLE_REFS 3
|
||||
#define COMP_REFS 2
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,8 @@ struct loopfilter {
|
||||
uint8_t mode_ref_delta_enabled;
|
||||
uint8_t mode_ref_delta_update;
|
||||
|
||||
// 0 = Intra, Last, GF, ARF
|
||||
// 0 = Intra, Last, Last2+Last3+LAST4(CONFIG_EXT_REFS),
|
||||
// GF, ARF
|
||||
signed char ref_deltas[MAX_REF_FRAMES];
|
||||
signed char last_ref_deltas[MAX_REF_FRAMES];
|
||||
|
||||
|
||||
@@ -174,6 +174,12 @@ typedef struct VP10Common {
|
||||
#endif
|
||||
|
||||
FRAME_TYPE last_frame_type; /* last frame's frame type for motion search.*/
|
||||
#if CONFIG_EXT_REFS
|
||||
// frame type of the frame before last frame
|
||||
FRAME_TYPE last2_frame_type;
|
||||
// frame type of the frame two frames before last frame
|
||||
FRAME_TYPE last3_frame_type;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
FRAME_TYPE frame_type;
|
||||
|
||||
int show_frame;
|
||||
@@ -260,7 +266,7 @@ typedef struct VP10Common {
|
||||
|
||||
// Context probabilities for reference frame prediction
|
||||
MV_REFERENCE_FRAME comp_fixed_ref;
|
||||
MV_REFERENCE_FRAME comp_var_ref[2];
|
||||
MV_REFERENCE_FRAME comp_var_ref[COMP_REFS];
|
||||
REFERENCE_MODE reference_mode;
|
||||
|
||||
FRAME_CONTEXT *fc; /* this frame entropy */
|
||||
|
||||
@@ -103,6 +103,421 @@ int vp10_get_reference_mode_context(const VP10_COMMON *cm,
|
||||
return ctx;
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
|
||||
// TODO(zoeliu): Future work will be conducted to optimize the context design
|
||||
// for the coding of the reference frames.
|
||||
|
||||
#define CHECK_LAST_OR_LAST2(ref_frame) \
|
||||
((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME))
|
||||
|
||||
#define CHECK_GOLDEN_LAST3_LAST4(ref_frame) \
|
||||
((ref_frame == GOLDEN_FRAME) || (ref_frame == LAST3_FRAME) || \
|
||||
(ref_frame == LAST4_FRAME))
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// Signal the first reference frame for a compound mode is either
|
||||
// GOLDEN/LAST3/LAST4, or LAST/LAST2.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is either
|
||||
// GOLDEN_FRAME/LAST3_FRAME/LAST4_FRAME.
|
||||
int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int above_in_image = xd->up_available;
|
||||
const int left_in_image = xd->left_available;
|
||||
|
||||
// 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 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]));
|
||||
else // comp pred (1/3)
|
||||
pred_context = 1 +
|
||||
2 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[var_ref_idx]));
|
||||
} 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 && CHECK_GOLDEN_LAST3_LAST4(vrfa)) {
|
||||
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 is GOLDEN / LAST3 / LAST4
|
||||
// NOTE(zoeliu): Following assert may be removed once confirmed.
|
||||
assert(CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
|
||||
CHECK_GOLDEN_LAST3_LAST4(vrfl));
|
||||
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 (CHECK_GOLDEN_LAST3_LAST4(vrfc) && !CHECK_GOLDEN_LAST3_LAST4(rfs))
|
||||
pred_context = 1;
|
||||
else if (CHECK_GOLDEN_LAST3_LAST4(rfs) &&
|
||||
!CHECK_GOLDEN_LAST3_LAST4(vrfc))
|
||||
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(CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
|
||||
CHECK_GOLDEN_LAST3_LAST4(vrfl));
|
||||
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 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[var_ref_idx]));
|
||||
else
|
||||
pred_context = 3 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]));
|
||||
}
|
||||
} 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 either LAST/LAST2.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME,
|
||||
// conditioning on it is either LAST_FRAME or LAST2_FRAME.
|
||||
int vp10_get_pred_context_comp_ref_p1(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int above_in_image = xd->up_available;
|
||||
const int left_in_image = xd->left_available;
|
||||
|
||||
// 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 (CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
|
||||
CHECK_GOLDEN_LAST3_LAST4(vrfl))
|
||||
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 || CHECK_GOLDEN_LAST3_LAST4(rfs));
|
||||
} else { // comp/comp
|
||||
if (vrfa == LAST_FRAME || vrfl == LAST_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 + (CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
|
||||
CHECK_GOLDEN_LAST3_LAST4(vrfl));
|
||||
}
|
||||
}
|
||||
} 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 + CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]);
|
||||
}
|
||||
}
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#define CHECK_LAST3_OR_LAST4(ref_frame) \
|
||||
((ref_frame == LAST3_FRAME) || (ref_frame == LAST4_FRAME))
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// Signal the first reference frame for a compound mode is GOLDEN,
|
||||
// conditioning on that it is known either GOLDEN/LAST3/LAST4.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME,
|
||||
// conditioning on it is either GOLDEN / LAST3 / LAST4.
|
||||
int vp10_get_pred_context_comp_ref_p2(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int above_in_image = xd->up_available;
|
||||
const int left_in_image = xd->left_available;
|
||||
|
||||
// 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 == GOLDEN_FRAME || vrfl == GOLDEN_FRAME)
|
||||
pred_context = 1;
|
||||
else if (CHECK_LAST_OR_LAST2(vrfa) || CHECK_LAST_OR_LAST2(vrfl))
|
||||
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 == GOLDEN_FRAME && rfs != GOLDEN_FRAME)
|
||||
pred_context = 1;
|
||||
else if (rfs == GOLDEN_FRAME && vrfc != GOLDEN_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 +
|
||||
(CHECK_LAST3_OR_LAST4(vrfc) || CHECK_LAST_OR_LAST2(rfs));
|
||||
} else { // comp/comp
|
||||
if (vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 +
|
||||
(CHECK_LAST_OR_LAST2(vrfa) || CHECK_LAST_OR_LAST2(vrfl));
|
||||
}
|
||||
}
|
||||
} 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 {
|
||||
if (edge_mbmi->ref_frame[0] == GOLDEN_FRAME)
|
||||
pred_context = 0;
|
||||
else
|
||||
pred_context = 2 + CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
|
||||
}
|
||||
}
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#define CHECK_LAST_LAST2_GOLDEN(ref_frame) \
|
||||
((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME) || \
|
||||
(ref_frame == GOLDEN_FRAME))
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
// Signal the first reference frame for a compound mode is LAST3,
|
||||
// conditioning on that it is known either LAST3/LAST4.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is LAST3_FRAME,
|
||||
// conditioning on it is either LAST3 / LAST4.
|
||||
int vp10_get_pred_context_comp_ref_p3(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int above_in_image = xd->up_available;
|
||||
const int left_in_image = xd->left_available;
|
||||
|
||||
// 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] != LAST3_FRAME);
|
||||
else // comp pred (1/3)
|
||||
pred_context = 1 +
|
||||
2 * (edge_mbmi->ref_frame[var_ref_idx] != LAST3_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 == LAST3_FRAME)
|
||||
pred_context = 0;
|
||||
else if (l_sg && a_sg) { // single/single
|
||||
if (vrfa == LAST3_FRAME || vrfl == LAST3_FRAME)
|
||||
pred_context = 1;
|
||||
else if (CHECK_LAST_LAST2_GOLDEN(vrfa) || CHECK_LAST_LAST2_GOLDEN(vrfl))
|
||||
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 == LAST3_FRAME && rfs != LAST3_FRAME)
|
||||
pred_context = 1;
|
||||
else if (rfs == LAST3_FRAME && vrfc != LAST3_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 +
|
||||
(vrfc == LAST4_FRAME || CHECK_LAST_LAST2_GOLDEN(rfs));
|
||||
} else { // comp/comp
|
||||
if (vrfa == LAST3_FRAME || vrfl == LAST3_FRAME)
|
||||
pred_context = 2;
|
||||
else
|
||||
pred_context = 3 +
|
||||
(CHECK_LAST_LAST2_GOLDEN(vrfa) || CHECK_LAST_LAST2_GOLDEN(vrfl));
|
||||
}
|
||||
}
|
||||
} 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] != LAST3_FRAME);
|
||||
} else {
|
||||
if (edge_mbmi->ref_frame[0] == LAST3_FRAME)
|
||||
pred_context = 0;
|
||||
else
|
||||
pred_context = 2 + CHECK_LAST_LAST2_GOLDEN(edge_mbmi->ref_frame[0]);
|
||||
}
|
||||
}
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#else // CONFIG_EXT_REFS
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
@@ -186,6 +601,472 @@ int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
|
||||
#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 ALTREF_FRAME
|
||||
// or a GOLDEN_FRAME.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF/GOLDEN.
|
||||
int vp10_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// 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_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]));
|
||||
else
|
||||
pred_context = 1 + (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(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_GOLDEN_OR_ALTREF(above0) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(above1) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(left0) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(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_GOLDEN_OR_ALTREF(rfs))
|
||||
pred_context = 3 + (!CHECK_GOLDEN_OR_ALTREF(crf1) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(crf2));
|
||||
else
|
||||
pred_context = !CHECK_GOLDEN_OR_ALTREF(crf1) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(crf2);
|
||||
} else {
|
||||
pred_context = 2 * (!CHECK_GOLDEN_OR_ALTREF(above0)) +
|
||||
2 * (!CHECK_GOLDEN_OR_ALTREF(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_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]));
|
||||
else
|
||||
pred_context = 1 + (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
|
||||
!CHECK_GOLDEN_OR_ALTREF(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 ALTREF_FRAME or
|
||||
// GOLDEN_FRAME, knowing that it shall be either of these 2 choices.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF_FRAME, conditioning
|
||||
// on it is either ALTREF_FRAME/GOLDEN_FRAME.
|
||||
int vp10_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// 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] == 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_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 == 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_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] == 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;
|
||||
}
|
||||
|
||||
// For the bit to signal whether the single reference is LAST3/LAST4 or
|
||||
// LAST2/LAST, knowing that it shall be either of these 2 choices.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is LAST3/LAST4, conditioning
|
||||
// on it is either LAST3/LAST4/LAST2/LAST.
|
||||
int vp10_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// 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 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
|
||||
} else {
|
||||
pred_context = 1 +
|
||||
2 * (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) {
|
||||
if (above0 == left0 && above1 == left1)
|
||||
pred_context = 3 * (CHECK_LAST_OR_LAST2(above0) ||
|
||||
CHECK_LAST_OR_LAST2(above1) ||
|
||||
CHECK_LAST_OR_LAST2(left0) ||
|
||||
CHECK_LAST_OR_LAST2(left1));
|
||||
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 (CHECK_LAST_OR_LAST2(rfs))
|
||||
pred_context = 3 + (CHECK_LAST_OR_LAST2(crf1) ||
|
||||
CHECK_LAST_OR_LAST2(crf2));
|
||||
else if (rfs == LAST3_FRAME || rfs == LAST4_FRAME)
|
||||
pred_context = (CHECK_LAST_OR_LAST2(crf1) ||
|
||||
CHECK_LAST_OR_LAST2(crf2));
|
||||
else
|
||||
pred_context = 1 + 2 * (CHECK_LAST_OR_LAST2(crf1) ||
|
||||
CHECK_LAST_OR_LAST2(crf2));
|
||||
} 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 * CHECK_LAST_OR_LAST2(edge0);
|
||||
} 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) ||
|
||||
(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 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]));
|
||||
else
|
||||
pred_context = 3 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
|
||||
CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
// For the bit to signal whether the single reference is LAST2_FRAME or
|
||||
// LAST_FRAME, knowing that it shall be either of these 2 choices.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is LAST2_FRAME, conditioning
|
||||
// on it is either LAST2_FRAME/LAST_FRAME.
|
||||
int vp10_get_pred_context_single_ref_p4(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// 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] == 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_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 == 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_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] == 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;
|
||||
}
|
||||
|
||||
// For the bit to signal whether the single reference is LAST4_FRAME or
|
||||
// LAST3_FRAME, knowing that it shall be either of these 2 choices.
|
||||
//
|
||||
// NOTE(zoeliu): The probability of ref_frame[0] is LAST4_FRAME, conditioning
|
||||
// on it is either LAST4_FRAME/LAST3_FRAME.
|
||||
int vp10_get_pred_context_single_ref_p5(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// 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_LAST3_OR_LAST4(edge_mbmi->ref_frame[0]))
|
||||
pred_context = 3;
|
||||
else
|
||||
pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST3_FRAME);
|
||||
} else {
|
||||
pred_context = 1 +
|
||||
2 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == LAST3_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 == LAST3_FRAME || above1 == LAST3_FRAME ||
|
||||
left0 == LAST3_FRAME || left1 == LAST3_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 == LAST3_FRAME)
|
||||
pred_context = 3 + (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
|
||||
else if (rfs == LAST4_FRAME)
|
||||
pred_context = (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
|
||||
else
|
||||
pred_context = 1 + 2 * (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
|
||||
} else {
|
||||
if (!CHECK_LAST3_OR_LAST4(above0) &&
|
||||
!CHECK_LAST3_OR_LAST4(left0)) {
|
||||
pred_context = 2 + (above0 == left0);
|
||||
} else if (!CHECK_LAST3_OR_LAST4(above0) ||
|
||||
!CHECK_LAST3_OR_LAST4(left0)) {
|
||||
const MV_REFERENCE_FRAME edge0 =
|
||||
!CHECK_LAST3_OR_LAST4(above0) ? left0 : above0;
|
||||
pred_context = 4 * (edge0 == LAST3_FRAME);
|
||||
} else {
|
||||
pred_context = 2 * (above0 == LAST3_FRAME) +
|
||||
2 * (left0 == LAST3_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_LAST3_OR_LAST4(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] == LAST3_FRAME);
|
||||
else
|
||||
pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
|
||||
edge_mbmi->ref_frame[1] == LAST3_FRAME);
|
||||
} else { // no edges available (2)
|
||||
pred_context = 2;
|
||||
}
|
||||
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#else // CONFIG_EXT_REFS
|
||||
|
||||
int vp10_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
|
||||
int pred_context;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
@@ -337,3 +1218,5 @@ int vp10_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
|
||||
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
|
||||
return pred_context;
|
||||
}
|
||||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
@@ -89,9 +89,38 @@ int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
|
||||
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp10_get_pred_context_comp_ref_p(cm, xd);
|
||||
return cm->fc->comp_ref_prob[pred_context];
|
||||
return cm->fc->comp_ref_prob[pred_context][0];
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
int vp10_get_pred_context_comp_ref_p1(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p1(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp10_get_pred_context_comp_ref_p1(cm, xd);
|
||||
return cm->fc->comp_ref_prob[pred_context][1];
|
||||
}
|
||||
|
||||
int vp10_get_pred_context_comp_ref_p2(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p2(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp10_get_pred_context_comp_ref_p2(cm, xd);
|
||||
return cm->fc->comp_ref_prob[pred_context][2];
|
||||
}
|
||||
|
||||
int vp10_get_pred_context_comp_ref_p3(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p3(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
const int pred_context = vp10_get_pred_context_comp_ref_p3(cm, xd);
|
||||
return cm->fc->comp_ref_prob[pred_context][3];
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
int vp10_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p1(const VP10_COMMON *cm,
|
||||
@@ -106,6 +135,29 @@ static INLINE vpx_prob vp10_get_pred_prob_single_ref_p2(const VP10_COMMON *cm,
|
||||
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p2(xd)][1];
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
int vp10_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p3(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p3(xd)][2];
|
||||
}
|
||||
|
||||
int vp10_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p4(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p4(xd)][3];
|
||||
}
|
||||
|
||||
int vp10_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
|
||||
|
||||
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p5(const VP10_COMMON *cm,
|
||||
const MACROBLOCKD *xd) {
|
||||
return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p5(xd)][4];
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -379,13 +379,14 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
|
||||
cm->counts.comp_inter[i][j] += counts->comp_inter[i][j];
|
||||
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
for (j = 0; j < (SINGLE_REFS - 1); j++)
|
||||
for (k = 0; k < 2; k++)
|
||||
cm->counts.single_ref[i][j][k] += counts->single_ref[i][j][k];
|
||||
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
cm->counts.comp_ref[i][j] += counts->comp_ref[i][j];
|
||||
for (j = 0; j < (COMP_REFS - 1); j++)
|
||||
for (k = 0; k < 2; k++)
|
||||
cm->counts.comp_ref[i][j][k] += counts->comp_ref[i][j][k];
|
||||
|
||||
for (i = 0; i < TX_SIZE_CONTEXTS; i++) {
|
||||
for (j = 0; j < TX_SIZES; j++)
|
||||
|
||||
@@ -61,13 +61,26 @@ static void setup_compound_reference_mode(VP10_COMMON *cm) {
|
||||
cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
|
||||
cm->comp_fixed_ref = ALTREF_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
#if CONFIG_EXT_REFS
|
||||
cm->comp_var_ref[1] = LAST2_FRAME;
|
||||
cm->comp_var_ref[2] = LAST3_FRAME;
|
||||
cm->comp_var_ref[3] = LAST4_FRAME;
|
||||
cm->comp_var_ref[4] = GOLDEN_FRAME;
|
||||
#else
|
||||
cm->comp_var_ref[1] = GOLDEN_FRAME;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
|
||||
cm->ref_frame_sign_bias[ALTREF_FRAME]) {
|
||||
#if CONFIG_EXT_REFS
|
||||
assert(0);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cm->comp_fixed_ref = GOLDEN_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
cm->comp_var_ref[1] = ALTREF_FRAME;
|
||||
} else {
|
||||
#if CONFIG_EXT_REFS
|
||||
assert(0);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cm->comp_fixed_ref = LAST_FRAME;
|
||||
cm->comp_var_ref[0] = GOLDEN_FRAME;
|
||||
cm->comp_var_ref[1] = ALTREF_FRAME;
|
||||
@@ -130,21 +143,27 @@ static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
|
||||
|
||||
static void read_frame_reference_mode_probs(VP10_COMMON *cm, vpx_reader *r) {
|
||||
FRAME_CONTEXT *const fc = cm->fc;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
|
||||
vp10_diff_update_prob(r, &fc->comp_inter_prob[i]);
|
||||
|
||||
if (cm->reference_mode != COMPOUND_REFERENCE)
|
||||
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
||||
for (i = 0; i < REF_CONTEXTS; ++i) {
|
||||
vp10_diff_update_prob(r, &fc->single_ref_prob[i][0]);
|
||||
vp10_diff_update_prob(r, &fc->single_ref_prob[i][1]);
|
||||
for (j = 0; j < (SINGLE_REFS - 1); ++j) {
|
||||
vp10_diff_update_prob(r, &fc->single_ref_prob[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE)
|
||||
for (i = 0; i < REF_CONTEXTS; ++i)
|
||||
vp10_diff_update_prob(r, &fc->comp_ref_prob[i]);
|
||||
if (cm->reference_mode != SINGLE_REFERENCE) {
|
||||
for (i = 0; i < REF_CONTEXTS; ++i) {
|
||||
for (j = 0; j < (COMP_REFS - 1); ++j) {
|
||||
vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) {
|
||||
@@ -1938,6 +1957,10 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
|
||||
int i, mask, ref_index = 0;
|
||||
size_t sz;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
cm->last3_frame_type = cm->last2_frame_type;
|
||||
cm->last2_frame_type = cm->last_frame_type;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cm->last_frame_type = cm->frame_type;
|
||||
cm->last_intra_only = cm->intra_only;
|
||||
|
||||
@@ -2106,20 +2129,70 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
|
||||
// Generate next_ref_frame_map.
|
||||
lock_buffer_pool(pool);
|
||||
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
||||
#if CONFIG_EXT_REFS
|
||||
// TODO(zoeliu): To move the following #define's to a header file
|
||||
#define PBI_LST_FB_IDX 0
|
||||
#define PBI_LST2_FB_IDX 1
|
||||
#define PBI_LST3_FB_IDX 2
|
||||
#define PBI_LST4_FB_IDX 3
|
||||
#define PBI_GLD_FB_IDX 4
|
||||
#define PBI_ALT_FB_IDX 5
|
||||
// NOTE(zoeliu):
|
||||
// (1) When ref_index == PBI_LST2_FB_IDX and the corresponding mask bit is
|
||||
// set, it indicates that LAST2_FRAME shall be refreshed, but keep in
|
||||
// mind that this has already been handled when LAST_FRAME is being
|
||||
// refreshed, i.e., when ref_index == PBI_LST_FB_IDX and the mask bit
|
||||
// is being set correspondingly;
|
||||
// (2) The only exception is that when current frame is a KEY_FRAME, where
|
||||
// all the frames in the frame buffer shall get refreshed;
|
||||
// (3) Similar handling for when ref_index == PBI_LST3_FB_IDX or when
|
||||
// ref_indx == PBI_LST4_FB_IDX.
|
||||
if ((mask & 1) &&
|
||||
(cm->frame_type == KEY_FRAME || (ref_index != PBI_LST2_FB_IDX &&
|
||||
ref_index != PBI_LST3_FB_IDX &&
|
||||
ref_index != PBI_LST4_FB_IDX))) {
|
||||
// The reference frame map for the decoding of the next frame is updated
|
||||
// and held by either current thread or possibly another decoder thread.
|
||||
if (cm->frame_type != KEY_FRAME && ref_index == PBI_LST_FB_IDX &&
|
||||
(mask & (1 << PBI_LST2_FB_IDX))) {
|
||||
if (mask & (1 << PBI_LST3_FB_IDX)) {
|
||||
if (mask & (1 << PBI_LST4_FB_IDX)) {
|
||||
cm->next_ref_frame_map[PBI_LST4_FB_IDX] =
|
||||
cm->next_ref_frame_map[PBI_LST3_FB_IDX];
|
||||
++frame_bufs[cm->next_ref_frame_map[PBI_LST3_FB_IDX]].ref_count;
|
||||
}
|
||||
cm->next_ref_frame_map[PBI_LST3_FB_IDX] =
|
||||
cm->next_ref_frame_map[PBI_LST2_FB_IDX];
|
||||
++frame_bufs[cm->next_ref_frame_map[PBI_LST2_FB_IDX]].ref_count;
|
||||
}
|
||||
cm->next_ref_frame_map[PBI_LST2_FB_IDX] =
|
||||
cm->next_ref_frame_map[PBI_LST_FB_IDX];
|
||||
++frame_bufs[cm->next_ref_frame_map[PBI_LST_FB_IDX]].ref_count;
|
||||
}
|
||||
cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
|
||||
++frame_bufs[cm->new_fb_idx].ref_count;
|
||||
} else if (!(mask & 1)) {
|
||||
cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
|
||||
}
|
||||
#else
|
||||
if (mask & 1) {
|
||||
cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
|
||||
++frame_bufs[cm->new_fb_idx].ref_count;
|
||||
} else {
|
||||
cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
// Current thread holds the reference frame.
|
||||
if (cm->ref_frame_map[ref_index] >= 0)
|
||||
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
||||
|
||||
++ref_index;
|
||||
}
|
||||
|
||||
for (; ref_index < REF_FRAMES; ++ref_index) {
|
||||
cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];
|
||||
|
||||
// Current thread holds the reference frame.
|
||||
if (cm->ref_frame_map[ref_index] >= 0)
|
||||
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
||||
|
||||
@@ -534,12 +534,68 @@ static void read_ref_frames(VP10_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 = vp10_get_pred_context_comp_ref_p(cm, xd);
|
||||
const int bit = vpx_read(r, fc->comp_ref_prob[ctx]);
|
||||
const int bit = vpx_read(r, fc->comp_ref_prob[ctx][0]);
|
||||
if (counts)
|
||||
++counts->comp_ref[ctx][bit];
|
||||
++counts->comp_ref[ctx][0][bit];
|
||||
ref_frame[idx] = cm->comp_fixed_ref;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
if (!bit) {
|
||||
const int ctx1 = vp10_get_pred_context_comp_ref_p1(cm, xd);
|
||||
const int bit1 = vpx_read(r, fc->comp_ref_prob[ctx1][1]);
|
||||
if (counts)
|
||||
++counts->comp_ref[ctx1][1][bit1];
|
||||
ref_frame[!idx] = cm->comp_var_ref[bit1 ? 0 : 1];
|
||||
} else {
|
||||
const int ctx2 = vp10_get_pred_context_comp_ref_p2(cm, xd);
|
||||
const int bit2 = vpx_read(r, fc->comp_ref_prob[ctx2][2]);
|
||||
if (counts)
|
||||
++counts->comp_ref[ctx2][2][bit2];
|
||||
if (!bit2) {
|
||||
const int ctx3 = vp10_get_pred_context_comp_ref_p3(cm, xd);
|
||||
const int bit3 = vpx_read(r, fc->comp_ref_prob[ctx3][3]);
|
||||
if (counts)
|
||||
++counts->comp_ref[ctx3][3][bit3];
|
||||
ref_frame[!idx] = cm->comp_var_ref[bit3 ? 2 : 3];
|
||||
} else {
|
||||
ref_frame[!idx] = cm->comp_var_ref[4];
|
||||
}
|
||||
}
|
||||
#else
|
||||
ref_frame[!idx] = cm->comp_var_ref[bit];
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else if (mode == SINGLE_REFERENCE) {
|
||||
#if CONFIG_EXT_REFS
|
||||
const int ctx0 = vp10_get_pred_context_single_ref_p1(xd);
|
||||
const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]);
|
||||
if (counts)
|
||||
++counts->single_ref[ctx0][0][bit0];
|
||||
if (bit0) {
|
||||
const int ctx1 = vp10_get_pred_context_single_ref_p2(xd);
|
||||
const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]);
|
||||
if (counts)
|
||||
++counts->single_ref[ctx1][1][bit1];
|
||||
ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
|
||||
} else {
|
||||
const int ctx2 = vp10_get_pred_context_single_ref_p3(xd);
|
||||
const int bit2 = vpx_read(r, fc->single_ref_prob[ctx2][2]);
|
||||
if (counts)
|
||||
++counts->single_ref[ctx2][2][bit2];
|
||||
if (bit2) {
|
||||
const int ctx4 = vp10_get_pred_context_single_ref_p5(xd);
|
||||
const int bit4 = vpx_read(r, fc->single_ref_prob[ctx4][4]);
|
||||
if (counts)
|
||||
++counts->single_ref[ctx4][4][bit4];
|
||||
ref_frame[0] = bit4 ? LAST4_FRAME : LAST3_FRAME;
|
||||
} else {
|
||||
const int ctx3 = vp10_get_pred_context_single_ref_p4(xd);
|
||||
const int bit3 = vpx_read(r, fc->single_ref_prob[ctx3][3]);
|
||||
if (counts)
|
||||
++counts->single_ref[ctx3][3][bit3];
|
||||
ref_frame[0] = bit3 ? LAST2_FRAME : LAST_FRAME;
|
||||
}
|
||||
}
|
||||
#else
|
||||
const int ctx0 = vp10_get_pred_context_single_ref_p1(xd);
|
||||
const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]);
|
||||
if (counts)
|
||||
@@ -553,6 +609,7 @@ static void read_ref_frames(VP10_COMMON *const cm, MACROBLOCKD *const xd,
|
||||
} else {
|
||||
ref_frame[0] = LAST_FRAME;
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
ref_frame[1] = NONE;
|
||||
} else {
|
||||
|
||||
@@ -196,10 +196,23 @@ vpx_codec_err_t vp10_set_reference_dec(VP10_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_EXT_REFS
|
||||
} else if (ref_frame_flag == VP9_LAST2_FLAG) {
|
||||
ref_buf = &cm->frame_refs[1];
|
||||
} else if (ref_frame_flag == VP9_LAST3_FLAG) {
|
||||
ref_buf = &cm->frame_refs[2];
|
||||
} else if (ref_frame_flag == VP9_LAST4_FLAG) {
|
||||
ref_buf = &cm->frame_refs[3];
|
||||
} else if (ref_frame_flag == VP9_GOLD_FLAG) {
|
||||
ref_buf = &cm->frame_refs[4];
|
||||
} else if (ref_frame_flag == VP9_ALT_FLAG) {
|
||||
ref_buf = &cm->frame_refs[5];
|
||||
#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_EXT_REFS
|
||||
} else {
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
|
||||
"Invalid reference frame");
|
||||
@@ -243,10 +256,10 @@ static void swap_frame_buffers(VP10Decoder *pbi) {
|
||||
// Current thread releases the holding of reference frame.
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
|
||||
// Release the reference frame in reference map.
|
||||
if ((mask & 1) && old_idx >= 0) {
|
||||
// Release the reference frame holding in the reference map for the decoding
|
||||
// of the next frame.
|
||||
if (mask & 1)
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
}
|
||||
cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
|
||||
++ref_index;
|
||||
}
|
||||
@@ -268,7 +281,7 @@ static void swap_frame_buffers(VP10Decoder *pbi) {
|
||||
}
|
||||
|
||||
// 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 = -1;
|
||||
}
|
||||
|
||||
@@ -326,7 +339,6 @@ int vp10_receive_compressed_data(VP10Decoder *pbi,
|
||||
pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
|
||||
}
|
||||
|
||||
|
||||
if (setjmp(cm->error.jmp)) {
|
||||
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||
int i;
|
||||
@@ -350,10 +362,10 @@ int vp10_receive_compressed_data(VP10Decoder *pbi,
|
||||
// Current thread releases the holding of reference frame.
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
|
||||
// Release the reference frame in reference map.
|
||||
if ((mask & 1) && old_idx >= 0) {
|
||||
// Release the reference frame holding in the reference map for the
|
||||
// decoding of the next frame.
|
||||
if (mask & 1)
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
}
|
||||
++ref_index;
|
||||
}
|
||||
|
||||
|
||||
@@ -484,15 +484,58 @@ static void write_ref_frames(const VP10_COMMON *cm, const MACROBLOCKD *xd,
|
||||
}
|
||||
|
||||
if (is_compound) {
|
||||
vpx_write(w, mbmi->ref_frame[0] == GOLDEN_FRAME,
|
||||
vp10_get_pred_prob_comp_ref_p(cm, xd));
|
||||
#if CONFIG_EXT_REFS
|
||||
const int bit = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
|
||||
mbmi->ref_frame[0] == LAST3_FRAME ||
|
||||
mbmi->ref_frame[0] == LAST4_FRAME);
|
||||
#else
|
||||
const int bit = mbmi->ref_frame[0] == GOLDEN_FRAME;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
vpx_write(w, bit, vp10_get_pred_prob_comp_ref_p(cm, xd));
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
if (!bit) {
|
||||
const int bit1 = mbmi->ref_frame[0] == LAST_FRAME;
|
||||
vpx_write(w, bit1, vp10_get_pred_prob_comp_ref_p1(cm, xd));
|
||||
} else {
|
||||
const int bit2 = mbmi->ref_frame[0] == GOLDEN_FRAME;
|
||||
vpx_write(w, bit2, vp10_get_pred_prob_comp_ref_p2(cm, xd));
|
||||
if (!bit2) {
|
||||
const int bit3 = mbmi->ref_frame[0] == LAST3_FRAME;
|
||||
vpx_write(w, bit3, vp10_get_pred_prob_comp_ref_p3(cm, xd));
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else {
|
||||
#if CONFIG_EXT_REFS
|
||||
const int bit0 = (mbmi->ref_frame[0] == GOLDEN_FRAME ||
|
||||
mbmi->ref_frame[0] == ALTREF_FRAME);
|
||||
vpx_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
|
||||
|
||||
if (bit0) {
|
||||
const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
|
||||
vpx_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
|
||||
} else {
|
||||
const int bit2 = (mbmi->ref_frame[0] == LAST3_FRAME ||
|
||||
mbmi->ref_frame[0] == LAST4_FRAME);
|
||||
vpx_write(w, bit2, vp10_get_pred_prob_single_ref_p3(cm, xd));
|
||||
|
||||
if (!bit2) {
|
||||
const int bit3 = mbmi->ref_frame[0] != LAST_FRAME;
|
||||
vpx_write(w, bit3, vp10_get_pred_prob_single_ref_p4(cm, xd));
|
||||
} else {
|
||||
const int bit4 = mbmi->ref_frame[0] != LAST3_FRAME;
|
||||
vpx_write(w, bit4, vp10_get_pred_prob_single_ref_p5(cm, xd));
|
||||
}
|
||||
}
|
||||
#else
|
||||
const int bit0 = mbmi->ref_frame[0] != LAST_FRAME;
|
||||
vpx_write(w, bit0, vp10_get_pred_prob_single_ref_p1(cm, xd));
|
||||
if (bit0) {
|
||||
const int bit1 = mbmi->ref_frame[0] != GOLDEN_FRAME;
|
||||
vpx_write(w, bit1, vp10_get_pred_prob_single_ref_p2(cm, xd));
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1406,6 +1449,11 @@ static int get_refresh_mask(VP10_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_EXT_REFS
|
||||
(cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
|
||||
(cpi->refresh_last3_frame << cpi->lst3_fb_idx) |
|
||||
(cpi->refresh_last4_frame << cpi->lst4_fb_idx) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(cpi->refresh_golden_frame << cpi->alt_fb_idx);
|
||||
} else {
|
||||
int arf_idx = cpi->alt_fb_idx;
|
||||
@@ -1414,6 +1462,11 @@ static int get_refresh_mask(VP10_COMP *cpi) {
|
||||
arf_idx = gf_group->arf_update_idx[gf_group->index];
|
||||
}
|
||||
return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
|
||||
#if CONFIG_EXT_REFS
|
||||
(cpi->refresh_last2_frame << cpi->lst2_fb_idx) |
|
||||
(cpi->refresh_last3_frame << cpi->lst3_fb_idx) |
|
||||
(cpi->refresh_last4_frame << cpi->lst4_fb_idx) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(cpi->refresh_golden_frame << cpi->gld_fb_idx) |
|
||||
(cpi->refresh_alt_ref_frame << arf_idx);
|
||||
}
|
||||
@@ -1584,6 +1637,13 @@ static void write_uncompressed_header(VP10_COMP *cpi,
|
||||
vpx_wb_write_bit(wb, cm->show_frame);
|
||||
vpx_wb_write_bit(wb, cm->error_resilient_mode);
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame =
|
||||
(cm->frame_type == KEY_FRAME || cpi->refresh_last_frame) ? 1 : 0;
|
||||
cpi->refresh_last3_frame = cpi->refresh_last2_frame ? 1 : 0;
|
||||
cpi->refresh_last4_frame = cpi->refresh_last3_frame ? 1 : 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
write_sync_code(wb);
|
||||
write_bitdepth_colorspace_sampling(cm, wb);
|
||||
@@ -1715,17 +1775,21 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
|
||||
|
||||
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
||||
for (i = 0; i < REF_CONTEXTS; i++) {
|
||||
vp10_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
|
||||
counts->single_ref[i][0]);
|
||||
vp10_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
|
||||
counts->single_ref[i][1]);
|
||||
for (j = 0; j < (SINGLE_REFS - 1); j ++) {
|
||||
vp10_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][j],
|
||||
counts->single_ref[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE)
|
||||
for (i = 0; i < REF_CONTEXTS; i++)
|
||||
vp10_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
|
||||
counts->comp_ref[i]);
|
||||
if (cm->reference_mode != SINGLE_REFERENCE) {
|
||||
for (i = 0; i < REF_CONTEXTS; i++) {
|
||||
for (j = 0; j < (COMP_REFS - 1); j ++) {
|
||||
vp10_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][j],
|
||||
counts->comp_ref[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i)
|
||||
prob_diff_update(vp10_intra_mode_tree, cm->fc->y_mode_prob[i],
|
||||
|
||||
@@ -398,6 +398,14 @@ void vp10_denoiser_update_frame_info(VP9_DENOISER *denoiser,
|
||||
&denoiser->running_avg_y[INTRA_FRAME]);
|
||||
}
|
||||
if (refresh_last_frame) {
|
||||
#if CONFIG_EXT_REFS
|
||||
swap_frame_buffer(&denoiser->running_avg_y[LAST4_FRAME],
|
||||
&denoiser->running_avg_y[LAST3_FRAME]);
|
||||
swap_frame_buffer(&denoiser->running_avg_y[LAST3_FRAME],
|
||||
&denoiser->running_avg_y[LAST2_FRAME]);
|
||||
swap_frame_buffer(&denoiser->running_avg_y[LAST2_FRAME],
|
||||
&denoiser->running_avg_y[LAST_FRAME]);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
swap_frame_buffer(&denoiser->running_avg_y[LAST_FRAME],
|
||||
&denoiser->running_avg_y[INTRA_FRAME]);
|
||||
}
|
||||
|
||||
@@ -1282,14 +1282,51 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td) {
|
||||
[has_second_ref(mbmi)]++;
|
||||
|
||||
if (has_second_ref(mbmi)) {
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p(cm, xd)]
|
||||
[ref0 == GOLDEN_FRAME]++;
|
||||
#if CONFIG_EXT_REFS
|
||||
const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME ||
|
||||
ref0 == LAST4_FRAME);
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
|
||||
if (!bit) {
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p1(cm, xd)][1]
|
||||
[ref0 == LAST_FRAME]++;
|
||||
} else {
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p2(cm, xd)][2]
|
||||
[ref0 == GOLDEN_FRAME]++;
|
||||
if (ref0 != GOLDEN_FRAME) {
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p3(cm, xd)][3]
|
||||
[ref0 == LAST3_FRAME]++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
counts->comp_ref[vp10_get_pred_context_comp_ref_p(cm, xd)][0]
|
||||
[ref0 == GOLDEN_FRAME]++;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else {
|
||||
#if CONFIG_EXT_REFS
|
||||
const int bit = (ref0 == ALTREF_FRAME || ref0 == GOLDEN_FRAME);
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p1(xd)][0][bit]++;
|
||||
if (bit) {
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p2(xd)][1]
|
||||
[ref0 != GOLDEN_FRAME]++;
|
||||
} else {
|
||||
const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p3(xd)][2]
|
||||
[bit1]++;
|
||||
if (!bit1) {
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p4(xd)][3]
|
||||
[ref0 != LAST_FRAME]++;
|
||||
} else {
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p5(xd)][4]
|
||||
[ref0 != LAST3_FRAME]++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p1(xd)][0]
|
||||
[ref0 != LAST_FRAME]++;
|
||||
if (ref0 != LAST_FRAME)
|
||||
counts->single_ref[vp10_get_pred_context_single_ref_p2(xd)][1]
|
||||
[ref0 != GOLDEN_FRAME]++;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2670,8 +2707,14 @@ static int check_dual_ref_flags(VP10_COMP *cpi) {
|
||||
if (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;
|
||||
return (!!(ref_flags & VP9_GOLD_FLAG) +
|
||||
!!(ref_flags & VP9_LAST_FLAG) +
|
||||
#if CONFIG_EXT_REFS
|
||||
!!(ref_flags & VP9_LAST2_FLAG) +
|
||||
!!(ref_flags & VP9_LAST3_FLAG) +
|
||||
!!(ref_flags & VP9_LAST4_FLAG) +
|
||||
#endif // CONFIG_EXT_REFS
|
||||
!!(ref_flags & VP9_ALT_FLAG)) >= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2696,6 +2739,8 @@ static MV_REFERENCE_FRAME get_frame_type(const VP10_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 other than
|
||||
// INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
|
||||
return LAST_FRAME;
|
||||
}
|
||||
|
||||
@@ -2914,7 +2959,14 @@ void vp10_encode_frame(VP10_COMP *cpi) {
|
||||
cpi->allow_comp_inter_inter = 1;
|
||||
cm->comp_fixed_ref = ALTREF_FRAME;
|
||||
cm->comp_var_ref[0] = LAST_FRAME;
|
||||
#if CONFIG_EXT_REFS
|
||||
cm->comp_var_ref[1] = LAST2_FRAME;
|
||||
cm->comp_var_ref[2] = LAST3_FRAME;
|
||||
cm->comp_var_ref[3] = LAST4_FRAME;
|
||||
cm->comp_var_ref[4] = GOLDEN_FRAME;
|
||||
#else
|
||||
cm->comp_var_ref[1] = GOLDEN_FRAME;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
}
|
||||
} else {
|
||||
cpi->allow_comp_inter_inter = 0;
|
||||
@@ -2930,9 +2982,12 @@ void vp10_encode_frame(VP10_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 other than
|
||||
// INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
|
||||
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];
|
||||
|
||||
@@ -718,8 +718,16 @@ static void update_frame_size(VP10_COMP *cpi) {
|
||||
|
||||
static void init_buffer_indices(VP10_COMP *cpi) {
|
||||
cpi->lst_fb_idx = 0;
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->lst2_fb_idx = 1;
|
||||
cpi->lst3_fb_idx = 2;
|
||||
cpi->lst4_fb_idx = 3;
|
||||
cpi->gld_fb_idx = 4;
|
||||
cpi->alt_fb_idx = 5;
|
||||
#else
|
||||
cpi->gld_fb_idx = 1;
|
||||
cpi->alt_fb_idx = 2;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
}
|
||||
|
||||
static void init_config(struct VP10_COMP *cpi, VP10EncoderConfig *oxcf) {
|
||||
@@ -1422,6 +1430,12 @@ void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) {
|
||||
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_last_frame = 1;
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame = 0;
|
||||
cpi->refresh_last3_frame = 0;
|
||||
cpi->refresh_last4_frame = 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
cm->refresh_frame_context =
|
||||
oxcf->error_resilient_mode ? REFRESH_FRAME_CONTEXT_OFF :
|
||||
oxcf->frame_parallel_decoding_mode ? REFRESH_FRAME_CONTEXT_FORWARD
|
||||
@@ -2279,7 +2293,7 @@ static void generate_psnr_packet(VP10_COMP *cpi) {
|
||||
}
|
||||
|
||||
int vp10_use_as_reference(VP10_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;
|
||||
@@ -2290,6 +2304,11 @@ void vp10_update_reference(VP10_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_EXT_REFS
|
||||
cpi->ext_refresh_last2_frame = (ref_frame_flags & VP9_LAST2_FLAG) != 0;
|
||||
cpi->ext_refresh_last3_frame = (ref_frame_flags & VP9_LAST3_FLAG) != 0;
|
||||
cpi->ext_refresh_last4_frame = (ref_frame_flags & VP9_LAST4_FLAG) != 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->ext_refresh_frame_flags_pending = 1;
|
||||
}
|
||||
|
||||
@@ -2298,6 +2317,14 @@ static YV12_BUFFER_CONFIG *get_vp10_ref_frame_buffer(VP10_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame = NONE;
|
||||
if (ref_frame_flag == VP9_LAST_FLAG)
|
||||
ref_frame = LAST_FRAME;
|
||||
#if CONFIG_EXT_REFS
|
||||
else if (ref_frame_flag == VP9_LAST2_FLAG)
|
||||
ref_frame = LAST2_FRAME;
|
||||
else if (ref_frame_flag == VP9_LAST3_FLAG)
|
||||
ref_frame = LAST3_FRAME;
|
||||
else if (ref_frame_flag == VP9_LAST4_FLAG)
|
||||
ref_frame = LAST4_FRAME;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
else if (ref_frame_flag == VP9_GOLD_FLAG)
|
||||
ref_frame = GOLDEN_FRAME;
|
||||
else if (ref_frame_flag == VP9_ALT_FLAG)
|
||||
@@ -2634,13 +2661,83 @@ void vp10_update_reference_frames(VP10_COMP *cpi) {
|
||||
}
|
||||
|
||||
if (cpi->refresh_last_frame) {
|
||||
#if CONFIG_EXT_REFS
|
||||
if (cpi->refresh_last2_frame) {
|
||||
if (cpi->refresh_last3_frame) {
|
||||
if (cpi->refresh_last4_frame) {
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst4_fb_idx],
|
||||
cm->new_fb_idx);
|
||||
else
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst4_fb_idx],
|
||||
cm->ref_frame_map[cpi->lst3_fb_idx]);
|
||||
}
|
||||
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst3_fb_idx],
|
||||
cm->new_fb_idx);
|
||||
else
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst3_fb_idx],
|
||||
cm->ref_frame_map[cpi->lst2_fb_idx]);
|
||||
}
|
||||
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst2_fb_idx],
|
||||
cm->new_fb_idx);
|
||||
else
|
||||
ref_cnt_fb(pool->frame_bufs,
|
||||
&cm->ref_frame_map[cpi->lst2_fb_idx],
|
||||
cm->ref_frame_map[cpi->lst_fb_idx]);
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
ref_cnt_fb(pool->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_EXT_REFS
|
||||
if (cpi->refresh_last2_frame) {
|
||||
if (cpi->refresh_last3_frame) {
|
||||
if (cpi->refresh_last4_frame) {
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
memcpy(cpi->interp_filter_selected[LAST4_FRAME],
|
||||
cpi->interp_filter_selected[0],
|
||||
sizeof(cpi->interp_filter_selected[0]));
|
||||
else
|
||||
memcpy(cpi->interp_filter_selected[LAST4_FRAME],
|
||||
cpi->interp_filter_selected[LAST3_FRAME],
|
||||
sizeof(cpi->interp_filter_selected[LAST3_FRAME]));
|
||||
}
|
||||
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
memcpy(cpi->interp_filter_selected[LAST3_FRAME],
|
||||
cpi->interp_filter_selected[0],
|
||||
sizeof(cpi->interp_filter_selected[0]));
|
||||
else
|
||||
memcpy(cpi->interp_filter_selected[LAST3_FRAME],
|
||||
cpi->interp_filter_selected[LAST2_FRAME],
|
||||
sizeof(cpi->interp_filter_selected[LAST2_FRAME]));
|
||||
}
|
||||
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
memcpy(cpi->interp_filter_selected[LAST2_FRAME],
|
||||
cpi->interp_filter_selected[0],
|
||||
sizeof(cpi->interp_filter_selected[0]));
|
||||
else
|
||||
memcpy(cpi->interp_filter_selected[LAST2_FRAME],
|
||||
cpi->interp_filter_selected[LAST_FRAME],
|
||||
sizeof(cpi->interp_filter_selected[LAST_FRAME]));
|
||||
}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
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) {
|
||||
vp10_denoiser_update_frame_info(&cpi->denoiser,
|
||||
@@ -2706,7 +2803,16 @@ static INLINE void alloc_frame_mvs(const VP10_COMMON *cm,
|
||||
void vp10_scale_references(VP10_COMP *cpi) {
|
||||
VP10_COMMON *cm = &cpi->common;
|
||||
MV_REFERENCE_FRAME ref_frame;
|
||||
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
|
||||
const VP9_REFFRAME ref_mask[REFS_PER_FRAME] = {
|
||||
VP9_LAST_FLAG,
|
||||
#if CONFIG_EXT_REFS
|
||||
VP9_LAST2_FLAG,
|
||||
VP9_LAST3_FLAG,
|
||||
VP9_LAST4_FLAG,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG
|
||||
};
|
||||
|
||||
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
|
||||
// Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
|
||||
@@ -2791,10 +2897,18 @@ static void release_scaled_references(VP10_COMP *cpi) {
|
||||
if (cpi->oxcf.pass == 0) {
|
||||
// Only release scaled references under certain conditions:
|
||||
// if reference will be updated, or if scaled reference has same resolution.
|
||||
int refresh[3];
|
||||
int refresh[REFS_PER_FRAME];
|
||||
refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
|
||||
#if CONFIG_EXT_REFS
|
||||
refresh[1] = (cpi->refresh_last2_frame) ? 1 : 0;
|
||||
refresh[2] = (cpi->refresh_last3_frame) ? 1 : 0;
|
||||
refresh[3] = (cpi->refresh_last4_frame) ? 1 : 0;
|
||||
refresh[4] = (cpi->refresh_golden_frame) ? 1 : 0;
|
||||
refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
|
||||
#else
|
||||
refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
|
||||
refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
|
||||
const int idx = cpi->scaled_ref_idx[i - 1];
|
||||
RefCntBuffer *const buf = idx != INVALID_IDX ?
|
||||
@@ -3428,7 +3542,30 @@ static int get_ref_frame_flags(const VP10_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_EXT_REFS
|
||||
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];
|
||||
|
||||
const int last3_is_last = map[cpi->lst3_fb_idx] == map[cpi->lst_fb_idx];
|
||||
const int last3_is_last2 = map[cpi->lst3_fb_idx] == map[cpi->lst2_fb_idx];
|
||||
const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst3_fb_idx];
|
||||
const int alt_is_last3 = map[cpi->alt_fb_idx] == map[cpi->lst3_fb_idx];
|
||||
|
||||
const int last4_is_last = map[cpi->lst4_fb_idx] == map[cpi->lst_fb_idx];
|
||||
const int last4_is_last2 = map[cpi->lst4_fb_idx] == map[cpi->lst2_fb_idx];
|
||||
const int last4_is_last3 = map[cpi->lst4_fb_idx] == map[cpi->lst3_fb_idx];
|
||||
const int gld_is_last4 = map[cpi->gld_fb_idx] == map[cpi->lst4_fb_idx];
|
||||
const int alt_is_last4 = map[cpi->alt_fb_idx] == map[cpi->lst4_fb_idx];
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
|
||||
#if CONFIG_EXT_REFS
|
||||
flags |= VP9_LAST2_FLAG;
|
||||
flags |= VP9_LAST3_FLAG;
|
||||
flags |= VP9_LAST4_FLAG;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
if (gold_is_last)
|
||||
flags &= ~VP9_GOLD_FLAG;
|
||||
@@ -3442,6 +3579,35 @@ static int get_ref_frame_flags(const VP10_COMP *cpi) {
|
||||
if (gold_is_alt)
|
||||
flags &= ~VP9_ALT_FLAG;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
if (last4_is_last || last4_is_last2 || last4_is_last3)
|
||||
flags &= ~VP9_LAST4_FLAG;
|
||||
|
||||
if (gld_is_last4)
|
||||
flags &= ~VP9_GOLD_FLAG;
|
||||
|
||||
if (alt_is_last4)
|
||||
flags &= ~VP9_ALT_FLAG;
|
||||
|
||||
if (last3_is_last || last3_is_last2)
|
||||
flags &= ~VP9_LAST3_FLAG;
|
||||
|
||||
if (gld_is_last3)
|
||||
flags &= ~VP9_GOLD_FLAG;
|
||||
|
||||
if (alt_is_last3)
|
||||
flags &= ~VP9_ALT_FLAG;
|
||||
|
||||
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_EXT_REFS
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -3456,6 +3622,11 @@ static void set_ext_overrides(VP10_COMP *cpi) {
|
||||
}
|
||||
if (cpi->ext_refresh_frame_flags_pending) {
|
||||
cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame = cpi->ext_refresh_last2_frame;
|
||||
cpi->refresh_last3_frame = cpi->ext_refresh_last3_frame;
|
||||
cpi->refresh_last4_frame = cpi->ext_refresh_last4_frame;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
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;
|
||||
@@ -3524,6 +3695,17 @@ static int setup_interp_filter_search_mask(VP10_COMP *cpi) {
|
||||
for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) {
|
||||
if ((ref_total[LAST_FRAME] &&
|
||||
cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
|
||||
#if CONFIG_EXT_REFS
|
||||
(ref_total[LAST2_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50
|
||||
< ref_total[LAST2_FRAME]) &&
|
||||
(ref_total[LAST3_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 50
|
||||
< ref_total[LAST3_FRAME]) &&
|
||||
(ref_total[LAST4_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[LAST4_FRAME][ifilter] * 50
|
||||
< ref_total[LAST4_FRAME]) &&
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(ref_total[GOLDEN_FRAME] == 0 ||
|
||||
cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50
|
||||
< ref_total[GOLDEN_FRAME]) &&
|
||||
@@ -3691,6 +3873,10 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi,
|
||||
|
||||
cpi->ref_frame_flags = get_ref_frame_flags(cpi);
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
cm->last3_frame_type = cm->last2_frame_type;
|
||||
cm->last2_frame_type = cm->last_frame_type;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cm->last_frame_type = cm->frame_type;
|
||||
|
||||
vp10_rc_postencode_update(cpi, *size);
|
||||
@@ -3854,6 +4040,11 @@ static int frame_is_reference(const VP10_COMP *cpi) {
|
||||
|
||||
return cm->frame_type == KEY_FRAME ||
|
||||
cpi->refresh_last_frame ||
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame ||
|
||||
cpi->refresh_last3_frame ||
|
||||
cpi->refresh_last4_frame ||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->refresh_golden_frame ||
|
||||
cpi->refresh_alt_ref_frame ||
|
||||
cm->refresh_frame_context != REFRESH_FRAME_CONTEXT_OFF ||
|
||||
@@ -3990,6 +4181,11 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
|
||||
: REFRESH_FRAME_CONTEXT_BACKWARD;
|
||||
|
||||
cpi->refresh_last_frame = 1;
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame = 0;
|
||||
cpi->refresh_last3_frame = 0;
|
||||
cpi->refresh_last4_frame = 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_alt_ref_frame = 0;
|
||||
|
||||
@@ -4014,6 +4210,11 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags,
|
||||
cpi->refresh_alt_ref_frame = 1;
|
||||
cpi->refresh_golden_frame = 0;
|
||||
cpi->refresh_last_frame = 0;
|
||||
#if CONFIG_EXT_REFS
|
||||
cpi->refresh_last2_frame = 0;
|
||||
cpi->refresh_last3_frame = 0;
|
||||
cpi->refresh_last4_frame = 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rc->is_src_frame_alt_ref = 0;
|
||||
rc->source_alt_ref_pending = 0;
|
||||
} else {
|
||||
|
||||
@@ -304,15 +304,30 @@ typedef struct VP10_COMP {
|
||||
|
||||
int scaled_ref_idx[MAX_REF_FRAMES];
|
||||
int lst_fb_idx;
|
||||
#if CONFIG_EXT_REFS
|
||||
int lst2_fb_idx;
|
||||
int lst3_fb_idx;
|
||||
int lst4_fb_idx;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int gld_fb_idx;
|
||||
int alt_fb_idx;
|
||||
|
||||
int refresh_last_frame;
|
||||
#if CONFIG_EXT_REFS
|
||||
int refresh_last2_frame;
|
||||
int refresh_last3_frame;
|
||||
int refresh_last4_frame;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int refresh_golden_frame;
|
||||
int refresh_alt_ref_frame;
|
||||
|
||||
int ext_refresh_frame_flags_pending;
|
||||
int ext_refresh_last_frame;
|
||||
#if CONFIG_EXT_REFS
|
||||
int ext_refresh_last2_frame;
|
||||
int ext_refresh_last3_frame;
|
||||
int ext_refresh_last4_frame;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
int ext_refresh_golden_frame;
|
||||
int ext_refresh_alt_ref_frame;
|
||||
|
||||
@@ -554,6 +569,14 @@ static INLINE int get_ref_frame_map_idx(const VP10_COMP *cpi,
|
||||
MV_REFERENCE_FRAME ref_frame) {
|
||||
if (ref_frame == LAST_FRAME) {
|
||||
return cpi->lst_fb_idx;
|
||||
#if CONFIG_EXT_REFS
|
||||
} else if (ref_frame == LAST2_FRAME) {
|
||||
return cpi->lst2_fb_idx;
|
||||
} else if (ref_frame == LAST3_FRAME) {
|
||||
return cpi->lst3_fb_idx;
|
||||
} else if (ref_frame == LAST4_FRAME) {
|
||||
return cpi->lst4_fb_idx;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else if (ref_frame == GOLDEN_FRAME) {
|
||||
return cpi->gld_fb_idx;
|
||||
} else {
|
||||
|
||||
@@ -608,10 +608,20 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
|
||||
|
||||
if (sf->adaptive_rd_thresh) {
|
||||
rd->thresh_mult[THR_NEARESTMV] = 300;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARESTL2] = 300;
|
||||
rd->thresh_mult[THR_NEARESTL3] = 300;
|
||||
rd->thresh_mult[THR_NEARESTL4] = 300;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARESTG] = 300;
|
||||
rd->thresh_mult[THR_NEARESTA] = 300;
|
||||
} else {
|
||||
rd->thresh_mult[THR_NEARESTMV] = 0;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARESTL2] = 0;
|
||||
rd->thresh_mult[THR_NEARESTL3] = 0;
|
||||
rd->thresh_mult[THR_NEARESTL4] = 0;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARESTG] = 0;
|
||||
rd->thresh_mult[THR_NEARESTA] = 0;
|
||||
}
|
||||
@@ -619,26 +629,61 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
|
||||
rd->thresh_mult[THR_DC] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_NEWMV] += 1000;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEWL2] += 1000;
|
||||
rd->thresh_mult[THR_NEWL3] += 1000;
|
||||
rd->thresh_mult[THR_NEWL4] += 1000;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEWA] += 1000;
|
||||
rd->thresh_mult[THR_NEWG] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_NEARMV] += 1000;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARL2] += 1000;
|
||||
rd->thresh_mult[THR_NEARL3] += 1000;
|
||||
rd->thresh_mult[THR_NEARL4] += 1000;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_NEARA] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTGA] += 1000;
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_ZEROMV] += 2000;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_ZEROL2] += 2000;
|
||||
rd->thresh_mult[THR_ZEROL3] += 2000;
|
||||
rd->thresh_mult[THR_ZEROL4] += 2000;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_ZEROG] += 2000;
|
||||
rd->thresh_mult[THR_ZEROA] += 2000;
|
||||
|
||||
rd->thresh_mult[THR_TM] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_COMP_NEARESTL2A] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTL3A] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTL4A] += 1000;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_COMP_NEARESTGA] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_COMP_NEARLA] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWLA] += 2000;
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARGA] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWGA] += 2000;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_COMP_NEARL2A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWL2A] += 2000;
|
||||
rd->thresh_mult[THR_COMP_NEARL3A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWL3A] += 2000;
|
||||
rd->thresh_mult[THR_COMP_NEARL4A] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWL4A] += 2000;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
rd->thresh_mult[THR_ZEROMV] += 2000;
|
||||
rd->thresh_mult[THR_ZEROG] += 2000;
|
||||
rd->thresh_mult[THR_ZEROA] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZEROLA] += 2500;
|
||||
#if CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_COMP_ZEROL2A] += 2500;
|
||||
rd->thresh_mult[THR_COMP_ZEROL3A] += 2500;
|
||||
rd->thresh_mult[THR_COMP_ZEROL4A] += 2500;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
|
||||
|
||||
rd->thresh_mult[THR_H_PRED] += 2000;
|
||||
@@ -652,9 +697,15 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
|
||||
}
|
||||
|
||||
void vp10_set_rd_speed_thresholds_sub8x8(VP10_COMP *cpi) {
|
||||
static const int thresh_mult[2][MAX_REFS] =
|
||||
{{2500, 2500, 2500, 4500, 4500, 2500},
|
||||
{2000, 2000, 2000, 4000, 4000, 2000}};
|
||||
static const int thresh_mult[2][MAX_REFS] = {
|
||||
#if CONFIG_EXT_REFS
|
||||
{2500, 2500, 2500, 2500, 2500, 2500, 4500, 4500, 4500, 4500, 4500, 2500},
|
||||
{2000, 2000, 2000, 2000, 2000, 2000, 4000, 4000, 4000, 4000, 4000, 2000}
|
||||
#else
|
||||
{2500, 2500, 2500, 4500, 4500, 2500},
|
||||
{2000, 2000, 2000, 4000, 4000, 2000}
|
||||
#endif // CONFIG_EXT_REFS
|
||||
};
|
||||
RD_OPT *const rd = &cpi->rd;
|
||||
const int idx = cpi->oxcf.mode == BEST;
|
||||
memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], sizeof(thresh_mult[idx]));
|
||||
|
||||
@@ -33,8 +33,17 @@ extern "C" {
|
||||
|
||||
#define INVALID_MV 0x80008000
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
#define MAX_MODES 54
|
||||
#else
|
||||
#define MAX_MODES 30
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
#define MAX_REFS 12
|
||||
#else
|
||||
#define MAX_REFS 6
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#define RD_THRESH_MAX_FACT 64
|
||||
#define RD_THRESH_INC 1
|
||||
@@ -43,34 +52,72 @@ extern "C" {
|
||||
// const MODE_DEFINITION vp10_mode_order[MAX_MODES] used in the rd code.
|
||||
typedef enum {
|
||||
THR_NEARESTMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEARESTL2,
|
||||
THR_NEARESTL3,
|
||||
THR_NEARESTL4,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEARESTA,
|
||||
THR_NEARESTG,
|
||||
|
||||
THR_DC,
|
||||
|
||||
THR_NEWMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEWL2,
|
||||
THR_NEWL3,
|
||||
THR_NEWL4,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEWA,
|
||||
THR_NEWG,
|
||||
|
||||
THR_NEARMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_NEARL2,
|
||||
THR_NEARL3,
|
||||
THR_NEARL4,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_NEARA,
|
||||
THR_NEARG,
|
||||
|
||||
THR_ZEROMV,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_ZEROL2,
|
||||
THR_ZEROL3,
|
||||
THR_ZEROL4,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_ZEROG,
|
||||
THR_ZEROA,
|
||||
|
||||
THR_COMP_NEARESTLA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEARESTL2A,
|
||||
THR_COMP_NEARESTL3A,
|
||||
THR_COMP_NEARESTL4A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_NEARESTGA,
|
||||
|
||||
THR_TM,
|
||||
|
||||
THR_COMP_NEARLA,
|
||||
THR_COMP_NEWLA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_NEARL2A,
|
||||
THR_COMP_NEWL2A,
|
||||
THR_COMP_NEARL3A,
|
||||
THR_COMP_NEWL3A,
|
||||
THR_COMP_NEARL4A,
|
||||
THR_COMP_NEWL4A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_NEARGA,
|
||||
THR_COMP_NEWGA,
|
||||
|
||||
THR_COMP_ZEROLA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_ZEROL2A,
|
||||
THR_COMP_ZEROL3A,
|
||||
THR_COMP_ZEROL4A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_ZEROGA,
|
||||
|
||||
THR_H_PRED,
|
||||
@@ -85,9 +132,19 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
THR_LAST,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_LAST2,
|
||||
THR_LAST3,
|
||||
THR_LAST4,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_GOLD,
|
||||
THR_ALTR,
|
||||
THR_COMP_LA,
|
||||
#if CONFIG_EXT_REFS
|
||||
THR_COMP_L2A,
|
||||
THR_COMP_L3A,
|
||||
THR_COMP_L4A,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
THR_COMP_GA,
|
||||
THR_INTRA,
|
||||
} THR_MODES_SUB8X8;
|
||||
|
||||
@@ -43,6 +43,29 @@
|
||||
#include "vp10/encoder/rdopt.h"
|
||||
#include "vp10/encoder/aq_variance.h"
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
|
||||
#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST3_FRAME) | (1 << LAST4_FRAME))
|
||||
#define LAST2_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST3_FRAME) | (1 << LAST4_FRAME))
|
||||
#define LAST3_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << LAST4_FRAME))
|
||||
#define LAST4_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << LAST3_FRAME))
|
||||
#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST3_FRAME) | (1 << LAST4_FRAME))
|
||||
#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
|
||||
(1 << LAST2_FRAME) | (1 << INTRA_FRAME) | \
|
||||
(1 << LAST3_FRAME) | (1 << LAST4_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) | \
|
||||
@@ -50,6 +73,8 @@
|
||||
#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \
|
||||
(1 << INTRA_FRAME))
|
||||
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
|
||||
|
||||
#define MIN_EARLY_TERM_INDEX 3
|
||||
@@ -89,34 +114,72 @@ struct rdcost_block_args {
|
||||
#define LAST_NEW_MV_INDEX 6
|
||||
static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
|
||||
{NEARESTMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{NEARESTMV, {LAST2_FRAME, NONE}},
|
||||
{NEARESTMV, {LAST3_FRAME, NONE}},
|
||||
{NEARESTMV, {LAST4_FRAME, NONE}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{NEARESTMV, {ALTREF_FRAME, NONE}},
|
||||
{NEARESTMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
{DC_PRED, {INTRA_FRAME, NONE}},
|
||||
|
||||
{NEWMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{NEWMV, {LAST2_FRAME, NONE}},
|
||||
{NEWMV, {LAST3_FRAME, NONE}},
|
||||
{NEWMV, {LAST4_FRAME, NONE}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{NEWMV, {ALTREF_FRAME, NONE}},
|
||||
{NEWMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
{NEARMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{NEARMV, {LAST2_FRAME, NONE}},
|
||||
{NEARMV, {LAST3_FRAME, NONE}},
|
||||
{NEARMV, {LAST4_FRAME, NONE}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{NEARMV, {ALTREF_FRAME, NONE}},
|
||||
{NEARMV, {GOLDEN_FRAME, NONE}},
|
||||
|
||||
{ZEROMV, {LAST_FRAME, NONE}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{ZEROMV, {LAST2_FRAME, NONE}},
|
||||
{ZEROMV, {LAST3_FRAME, NONE}},
|
||||
{ZEROMV, {LAST4_FRAME, NONE}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{ZEROMV, {GOLDEN_FRAME, NONE}},
|
||||
{ZEROMV, {ALTREF_FRAME, NONE}},
|
||||
|
||||
{NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
|
||||
{NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{TM_PRED, {INTRA_FRAME, NONE}},
|
||||
|
||||
{NEARMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
|
||||
{NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
{NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
|
||||
{ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
|
||||
{ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
|
||||
{H_PRED, {INTRA_FRAME, NONE}},
|
||||
@@ -131,9 +194,19 @@ static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
|
||||
|
||||
static const REF_DEFINITION vp10_ref_order[MAX_REFS] = {
|
||||
{{LAST_FRAME, NONE}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{{LAST2_FRAME, NONE}},
|
||||
{{LAST3_FRAME, NONE}},
|
||||
{{LAST4_FRAME, NONE}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{{GOLDEN_FRAME, NONE}},
|
||||
{{ALTREF_FRAME, NONE}},
|
||||
{{LAST_FRAME, ALTREF_FRAME}},
|
||||
#if CONFIG_EXT_REFS
|
||||
{{LAST2_FRAME, ALTREF_FRAME}},
|
||||
{{LAST3_FRAME, ALTREF_FRAME}},
|
||||
{{LAST4_FRAME, ALTREF_FRAME}},
|
||||
#endif // CONFIG_EXT_REFS
|
||||
{{GOLDEN_FRAME, ALTREF_FRAME}},
|
||||
{{INTRA_FRAME, NONE}},
|
||||
};
|
||||
@@ -3677,34 +3750,108 @@ static void estimate_ref_frame_costs(const VP10_COMMON *cm,
|
||||
if (cm->reference_mode != COMPOUND_REFERENCE) {
|
||||
vpx_prob ref_single_p1 = vp10_get_pred_prob_single_ref_p1(cm, xd);
|
||||
vpx_prob ref_single_p2 = vp10_get_pred_prob_single_ref_p2(cm, xd);
|
||||
#if CONFIG_EXT_REFS
|
||||
vpx_prob ref_single_p3 = vp10_get_pred_prob_single_ref_p3(cm, xd);
|
||||
vpx_prob ref_single_p4 = vp10_get_pred_prob_single_ref_p4(cm, xd);
|
||||
vpx_prob ref_single_p5 = vp10_get_pred_prob_single_ref_p5(cm, xd);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
base_cost += vp10_cost_bit(comp_inter_p, 0);
|
||||
|
||||
ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
|
||||
ref_costs_single[LAST_FRAME] =
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_single[LAST2_FRAME] =
|
||||
ref_costs_single[LAST3_FRAME] =
|
||||
ref_costs_single[LAST4_FRAME] =
|
||||
#endif // CONFIG_EXT_REFS
|
||||
ref_costs_single[GOLDEN_FRAME] =
|
||||
ref_costs_single[ALTREF_FRAME] = base_cost;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
|
||||
|
||||
ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p3, 0);
|
||||
ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p3, 0);
|
||||
ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p3, 1);
|
||||
ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p3, 1);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
|
||||
ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
|
||||
|
||||
ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p4, 0);
|
||||
ref_costs_single[LAST2_FRAME] += vp10_cost_bit(ref_single_p4, 1);
|
||||
ref_costs_single[LAST3_FRAME] += vp10_cost_bit(ref_single_p5, 0);
|
||||
ref_costs_single[LAST4_FRAME] += vp10_cost_bit(ref_single_p5, 1);
|
||||
#else
|
||||
ref_costs_single[LAST_FRAME] += vp10_cost_bit(ref_single_p1, 0);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p1, 1);
|
||||
ref_costs_single[GOLDEN_FRAME] += vp10_cost_bit(ref_single_p2, 0);
|
||||
ref_costs_single[ALTREF_FRAME] += vp10_cost_bit(ref_single_p2, 1);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else {
|
||||
ref_costs_single[LAST_FRAME] = 512;
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_single[LAST2_FRAME] = 512;
|
||||
ref_costs_single[LAST3_FRAME] = 512;
|
||||
ref_costs_single[LAST4_FRAME] = 512;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
ref_costs_single[GOLDEN_FRAME] = 512;
|
||||
ref_costs_single[ALTREF_FRAME] = 512;
|
||||
}
|
||||
|
||||
if (cm->reference_mode != SINGLE_REFERENCE) {
|
||||
vpx_prob ref_comp_p = vp10_get_pred_prob_comp_ref_p(cm, xd);
|
||||
#if CONFIG_EXT_REFS
|
||||
vpx_prob ref_comp_p1 = vp10_get_pred_prob_comp_ref_p1(cm, xd);
|
||||
vpx_prob ref_comp_p2 = vp10_get_pred_prob_comp_ref_p2(cm, xd);
|
||||
vpx_prob ref_comp_p3 = vp10_get_pred_prob_comp_ref_p3(cm, xd);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
unsigned int base_cost = vp10_cost_bit(intra_inter_p, 1);
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
base_cost += vp10_cost_bit(comp_inter_p, 1);
|
||||
|
||||
ref_costs_comp[LAST_FRAME] = base_cost + vp10_cost_bit(ref_comp_p, 0);
|
||||
ref_costs_comp[GOLDEN_FRAME] = base_cost + vp10_cost_bit(ref_comp_p, 1);
|
||||
ref_costs_comp[LAST_FRAME] =
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_comp[LAST2_FRAME] =
|
||||
ref_costs_comp[LAST3_FRAME] =
|
||||
ref_costs_comp[LAST4_FRAME] =
|
||||
#endif // CONFIG_EXT_REFS
|
||||
ref_costs_comp[GOLDEN_FRAME] = base_cost;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
|
||||
ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p, 0);
|
||||
ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p, 1);
|
||||
ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p, 1);
|
||||
ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
|
||||
|
||||
ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p1, 1);
|
||||
ref_costs_comp[LAST2_FRAME] += vp10_cost_bit(ref_comp_p1, 0);
|
||||
ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
|
||||
ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p2, 0);
|
||||
ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p2, 1);
|
||||
|
||||
ref_costs_comp[LAST3_FRAME] += vp10_cost_bit(ref_comp_p3, 1);
|
||||
ref_costs_comp[LAST4_FRAME] += vp10_cost_bit(ref_comp_p3, 0);
|
||||
#else
|
||||
ref_costs_comp[LAST_FRAME] += vp10_cost_bit(ref_comp_p, 0);
|
||||
ref_costs_comp[GOLDEN_FRAME] += vp10_cost_bit(ref_comp_p, 1);
|
||||
#endif // CONFIG_EXT_REFS
|
||||
} else {
|
||||
ref_costs_comp[LAST_FRAME] = 512;
|
||||
#if CONFIG_EXT_REFS
|
||||
ref_costs_comp[LAST2_FRAME] = 512;
|
||||
ref_costs_comp[LAST3_FRAME] = 512;
|
||||
ref_costs_comp[LAST4_FRAME] = 512;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
ref_costs_comp[GOLDEN_FRAME] = 512;
|
||||
}
|
||||
}
|
||||
@@ -3732,13 +3879,14 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
|
||||
sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
|
||||
}
|
||||
|
||||
static void setup_buffer_inter(VP10_COMP *cpi, MACROBLOCK *x,
|
||||
static void setup_buffer_inter(
|
||||
VP10_COMP *cpi, MACROBLOCK *x,
|
||||
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]) {
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE]) {
|
||||
const VP10_COMMON *cm = &cpi->common;
|
||||
const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
@@ -4551,12 +4699,21 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
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];
|
||||
int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
|
||||
INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG };
|
||||
static const int flag_list[REFS_PER_FRAME + 1] = {
|
||||
0,
|
||||
VP9_LAST_FLAG,
|
||||
#if CONFIG_EXT_REFS
|
||||
VP9_LAST2_FLAG,
|
||||
VP9_LAST3_FLAG,
|
||||
VP9_LAST4_FLAG,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG
|
||||
};
|
||||
int64_t best_rd = best_rd_so_far;
|
||||
int64_t best_pred_diff[REFERENCE_MODES];
|
||||
int64_t best_pred_rd[REFERENCE_MODES];
|
||||
@@ -4664,7 +4821,14 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
// an unfiltered alternative. We allow near/nearest as well
|
||||
// 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)) {
|
||||
ref_frame_skip_mask[0] = (1 << LAST_FRAME) | (1 << GOLDEN_FRAME);
|
||||
ref_frame_skip_mask[0] =
|
||||
(1 << LAST_FRAME) |
|
||||
#if CONFIG_EXT_REFS
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(1 << GOLDEN_FRAME);
|
||||
ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
|
||||
mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
|
||||
if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
|
||||
@@ -4750,6 +4914,20 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#if CONFIG_EXT_REFS
|
||||
case LAST2_FRAME:
|
||||
ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case LAST3_FRAME:
|
||||
ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case LAST4_FRAME:
|
||||
ref_frame_skip_mask[0] |= LAST4_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
case GOLDEN_FRAME:
|
||||
ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
@@ -4771,6 +4949,20 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
if (mode_skip_mask[ref_frame] & (1 << this_mode))
|
||||
continue;
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
|
||||
continue;
|
||||
|
||||
if ((cm->last2_frame_type == KEY_FRAME ||
|
||||
cm->last_frame_type == KEY_FRAME) && ref_frame == LAST3_FRAME)
|
||||
continue;
|
||||
|
||||
if ((cm->last3_frame_type == KEY_FRAME ||
|
||||
cm->last2_frame_type == KEY_FRAME ||
|
||||
cm->last_frame_type == KEY_FRAME) && ref_frame == LAST4_FRAME)
|
||||
continue;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
// Test best rd so far against threshold for trying this mode.
|
||||
if (best_mode_skippable && sf->schedule_mode_search)
|
||||
mode_threshold[mode_index] <<= 1;
|
||||
@@ -5373,9 +5565,18 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
|
||||
unsigned char segment_id = mbmi->segment_id;
|
||||
int comp_pred, i;
|
||||
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
|
||||
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
|
||||
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG };
|
||||
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
|
||||
static const int flag_list[REFS_PER_FRAME + 1] = {
|
||||
0,
|
||||
VP9_LAST_FLAG,
|
||||
#if CONFIG_EXT_REFS
|
||||
VP9_LAST2_FLAG,
|
||||
VP9_LAST3_FLAG,
|
||||
VP9_LAST4_FLAG,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
VP9_GOLD_FLAG,
|
||||
VP9_ALT_FLAG
|
||||
};
|
||||
int64_t best_rd = best_rd_so_far;
|
||||
int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
|
||||
int64_t best_pred_diff[REFERENCE_MODES];
|
||||
@@ -5462,6 +5663,20 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
|
||||
ref_frame = vp10_ref_order[ref_index].ref_frame[0];
|
||||
second_ref_frame = vp10_ref_order[ref_index].ref_frame[1];
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
if (cm->last_frame_type == KEY_FRAME && ref_frame == LAST2_FRAME)
|
||||
continue;
|
||||
|
||||
if ((cm->last2_frame_type == KEY_FRAME ||
|
||||
cm->last_frame_type == KEY_FRAME) && ref_frame == LAST3_FRAME)
|
||||
continue;
|
||||
|
||||
if ((cm->last3_frame_type == KEY_FRAME ||
|
||||
cm->last2_frame_type == KEY_FRAME ||
|
||||
cm->last_frame_type == KEY_FRAME) && ref_frame == LAST4_FRAME)
|
||||
continue;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
// 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) {
|
||||
@@ -5470,15 +5685,59 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
|
||||
case INTRA_FRAME:
|
||||
break;
|
||||
case LAST_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
|
||||
#if CONFIG_EXT_REFS
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#if CONFIG_EXT_REFS
|
||||
case LAST2_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
(1 << GOLDEN_FRAME) |
|
||||
(1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case LAST3_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
(1 << GOLDEN_FRAME) |
|
||||
(1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case LAST4_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << GOLDEN_FRAME) |
|
||||
(1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
case GOLDEN_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
|
||||
#if CONFIG_EXT_REFS
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(1 << ALTREF_FRAME);
|
||||
ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
|
||||
break;
|
||||
case ALTREF_FRAME:
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) | (1 << LAST_FRAME);
|
||||
ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
|
||||
#if CONFIG_EXT_REFS
|
||||
(1 << LAST2_FRAME) |
|
||||
(1 << LAST3_FRAME) |
|
||||
(1 << LAST4_FRAME) |
|
||||
#endif // CONFIG_EXT_REFS
|
||||
(1 << LAST_FRAME);
|
||||
break;
|
||||
case NONE:
|
||||
case MAX_REF_FRAMES:
|
||||
@@ -5610,6 +5869,14 @@ void vp10_rd_pick_inter_mode_sub8x8(VP10_COMP *cpi,
|
||||
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_EXT_REFS
|
||||
this_rd_thresh = (ref_frame == LAST2_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_LAST2] : this_rd_thresh;
|
||||
this_rd_thresh = (ref_frame == LAST3_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_LAST3] : this_rd_thresh;
|
||||
this_rd_thresh = (ref_frame == LAST4_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_LAST4] : this_rd_thresh;
|
||||
#endif // CONFIG_EXT_REFS
|
||||
this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
|
||||
rd_opt->threshes[segment_id][bsize][THR_GOLD] : this_rd_thresh;
|
||||
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
|
||||
|
||||
@@ -192,6 +192,7 @@ int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const int has_above = xd->up_available;
|
||||
const int has_left = xd->left_available;
|
||||
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries correpsonding to real macroblocks.
|
||||
|
||||
@@ -237,15 +237,16 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
||||
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
||||
|
||||
lock_buffer_pool(pool);
|
||||
|
||||
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
||||
const int old_idx = cm->ref_frame_map[ref_index];
|
||||
// Current thread releases the holding of reference frame.
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
|
||||
// Release the reference frame in reference map.
|
||||
if (mask & 1) {
|
||||
if (mask & 1)
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
}
|
||||
|
||||
cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
|
||||
++ref_index;
|
||||
}
|
||||
@@ -267,7 +268,7 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
||||
}
|
||||
|
||||
// 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 = -1;
|
||||
}
|
||||
|
||||
@@ -325,7 +326,6 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
|
||||
pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
|
||||
}
|
||||
|
||||
|
||||
if (setjmp(cm->error.jmp)) {
|
||||
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||
int i;
|
||||
@@ -350,9 +350,8 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
|
||||
// Release the reference frame in reference map.
|
||||
if (mask & 1) {
|
||||
if (mask & 1)
|
||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||
}
|
||||
++ref_index;
|
||||
}
|
||||
|
||||
|
||||
@@ -4047,7 +4047,7 @@ 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.
|
||||
const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
|
||||
|
||||
@@ -590,6 +590,12 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
|
||||
rd->thresh_mult[THR_NEARMV] += 1000;
|
||||
rd->thresh_mult[THR_NEARA] += 1000;
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
|
||||
rd->thresh_mult[THR_ZEROMV] += 2000;
|
||||
rd->thresh_mult[THR_ZEROG] += 2000;
|
||||
rd->thresh_mult[THR_ZEROA] += 2000;
|
||||
|
||||
rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARESTGA] += 1000;
|
||||
|
||||
@@ -597,13 +603,9 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
|
||||
rd->thresh_mult[THR_COMP_NEARLA] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWLA] += 2000;
|
||||
rd->thresh_mult[THR_NEARG] += 1000;
|
||||
rd->thresh_mult[THR_COMP_NEARGA] += 1500;
|
||||
rd->thresh_mult[THR_COMP_NEWGA] += 2000;
|
||||
|
||||
rd->thresh_mult[THR_ZEROMV] += 2000;
|
||||
rd->thresh_mult[THR_ZEROG] += 2000;
|
||||
rd->thresh_mult[THR_ZEROA] += 2000;
|
||||
rd->thresh_mult[THR_COMP_ZEROLA] += 2500;
|
||||
rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
|
||||
|
||||
@@ -618,9 +620,10 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
|
||||
}
|
||||
|
||||
void vp9_set_rd_speed_thresholds_sub8x8(VP9_COMP *cpi) {
|
||||
static const int thresh_mult[2][MAX_REFS] =
|
||||
{{2500, 2500, 2500, 4500, 4500, 2500},
|
||||
{2000, 2000, 2000, 4000, 4000, 2000}};
|
||||
static const int thresh_mult[2][MAX_REFS] = {
|
||||
{2500, 2500, 2500, 4500, 4500, 2500},
|
||||
{2000, 2000, 2000, 4000, 4000, 2000}
|
||||
};
|
||||
RD_OPT *const rd = &cpi->rd;
|
||||
const int idx = cpi->oxcf.mode == BEST;
|
||||
memcpy(rd->thresh_mult_sub8x8, thresh_mult[idx], sizeof(thresh_mult[idx]));
|
||||
|
||||
@@ -3988,6 +3988,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
int64_t rs_rd;
|
||||
MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
|
||||
mbmi->interp_filter = switchable_filter_index;
|
||||
|
||||
tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
|
||||
&mbmi_ext->ref_mvs[ref_frame][0],
|
||||
second_ref, best_yrd, &rate,
|
||||
|
||||
Reference in New Issue
Block a user