Merge "Add "entropy" experiment" into nextgenv2
This commit is contained in:
Коммит
daf2fb42e6
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -27,6 +27,12 @@ extern "C" {
|
|||
#define DIFF_UPDATE_PROB 252
|
||||
#define GROUP_DIFF_UPDATE_PROB 252
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
#define COEF_PROBS_BUFS 16
|
||||
#define QCTX_BIN_BITS 2
|
||||
#define QCTX_BINS (1 << QCTX_BIN_BITS)
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
// Coefficient token alphabet
|
||||
#define ZERO_TOKEN 0 // 0 Extra Bits 0+0
|
||||
#define ONE_TOKEN 1 // 1 Extra Bits 0+1
|
||||
|
@ -139,6 +145,9 @@ typedef unsigned int vp10_coeff_stats[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS]
|
|||
struct VP10Common;
|
||||
void vp10_default_coef_probs(struct VP10Common *cm);
|
||||
void vp10_adapt_coef_probs(struct VP10Common *cm);
|
||||
#if CONFIG_ENTROPY
|
||||
void vp10_partial_adapt_probs(struct VP10Common *cm, int mi_row, int mi_col);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
// This is the index in the scan order beyond which all coefficients for
|
||||
// 8x8 transform and above are in the top band.
|
||||
|
|
|
@ -283,6 +283,18 @@ typedef struct VP10Common {
|
|||
unsigned int frame_context_idx; /* Context to use/update */
|
||||
FRAME_COUNTS counts;
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
// The initial probabilities for a frame, before any subframe backward update,
|
||||
// and after forward update.
|
||||
vp10_coeff_probs_model starting_coef_probs[TX_SIZES][PLANE_TYPES];
|
||||
// Number of subframe backward updates already done
|
||||
uint8_t coef_probs_update_idx;
|
||||
// Signal if the backward update is subframe or end-of-frame
|
||||
uint8_t partial_prob_update;
|
||||
// Frame level flag to turn on/off subframe backward update
|
||||
uint8_t do_subframe_update;
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
unsigned int current_video_frame;
|
||||
BITSTREAM_PROFILE profile;
|
||||
|
||||
|
|
|
@ -3014,6 +3014,11 @@ static const uint8_t *decode_tiles(VP10Decoder *pbi,
|
|||
int mi_row, mi_col;
|
||||
TileData *tile_data = NULL;
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
cm->do_subframe_update =
|
||||
cm->log2_tile_cols == 0 && cm->log2_tile_rows == 0;
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
if (cm->lf.filter_level && !cm->skip_loop_filter &&
|
||||
pbi->lf_worker.data1 == NULL) {
|
||||
CHECK_MEM_ERROR(cm, pbi->lf_worker.data1,
|
||||
|
@ -3112,6 +3117,18 @@ static const uint8_t *decode_tiles(VP10Decoder *pbi,
|
|||
if (pbi->mb.corrupted)
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Failed to decode tile data");
|
||||
#if CONFIG_ENTROPY
|
||||
if (cm->do_subframe_update &&
|
||||
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
if ((mi_row + MI_SIZE) % (MI_SIZE *
|
||||
VPXMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) == 0 &&
|
||||
mi_row + MI_SIZE < cm->mi_rows &&
|
||||
cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
|
||||
vp10_partial_adapt_probs(cm, mi_row, mi_col);
|
||||
++cm->coef_probs_update_idx;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
}
|
||||
#if !CONFIG_VAR_TX
|
||||
// Loopfilter one row.
|
||||
|
@ -3634,6 +3651,17 @@ static size_t read_uncompressed_header(VP10Decoder *pbi,
|
|||
xd->bd = (int)cm->bit_depth;
|
||||
#endif
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
vp10_default_coef_probs(cm);
|
||||
if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
|
||||
cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
|
||||
for (i = 0; i < FRAME_CONTEXTS; ++i)
|
||||
cm->frame_contexts[i] = *cm->fc;
|
||||
} else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
|
||||
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
setup_segmentation(cm, rb);
|
||||
|
||||
{
|
||||
|
@ -4035,6 +4063,11 @@ void vp10_decode_frame(VP10Decoder *pbi,
|
|||
vp10_frameworker_unlock_stats(worker);
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
vp10_copy(cm->starting_coef_probs, cm->fc->coef_probs);
|
||||
cm->coef_probs_update_idx = 0;
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
if (pbi->max_threads > 1 && tile_rows == 1 && tile_cols > 1) {
|
||||
// Multi-threaded tile decoder
|
||||
*p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end);
|
||||
|
@ -4065,6 +4098,9 @@ void vp10_decode_frame(VP10Decoder *pbi,
|
|||
|
||||
if (!xd->corrupted) {
|
||||
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
#if CONFIG_ENTROPY
|
||||
cm->partial_prob_update = 0;
|
||||
#endif // CONFIG_ENTROPY
|
||||
vp10_adapt_coef_probs(cm);
|
||||
vp10_adapt_intra_frame_probs(cm);
|
||||
|
||||
|
|
|
@ -2052,10 +2052,250 @@ static void update_coef_probs_common(vpx_writer* const bc, VP10_COMP *cpi,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
// Calculate the token counts between subsequent subframe updates.
|
||||
static void get_coef_counts_diff(VP10_COMP *cpi, int index,
|
||||
vp10_coeff_count
|
||||
coef_counts[TX_SIZES][PLANE_TYPES],
|
||||
unsigned int eob_counts[TX_SIZES]
|
||||
[PLANE_TYPES][REF_TYPES][COEF_BANDS]
|
||||
[COEFF_CONTEXTS]) {
|
||||
int i, j, k, l, m, tx_size, val;
|
||||
const int max_idx = cpi->common.coef_probs_update_idx;
|
||||
const TX_MODE tx_mode = cpi->common.tx_mode;
|
||||
const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
|
||||
const SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
|
||||
|
||||
assert(max_idx < COEF_PROBS_BUFS);
|
||||
|
||||
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
|
||||
for (i = 0; i < PLANE_TYPES; ++i)
|
||||
for (j = 0; j < REF_TYPES; ++j)
|
||||
for (k = 0; k < COEF_BANDS; ++k)
|
||||
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
|
||||
if (index == max_idx) {
|
||||
val = cpi->common.counts.eob_branch[tx_size][i][j][k][l] -
|
||||
subframe_stats->eob_counts_buf[max_idx][tx_size][i][j][k][l];
|
||||
} else {
|
||||
val = subframe_stats->eob_counts_buf[index + 1][tx_size]
|
||||
[i][j][k][l] -
|
||||
subframe_stats->eob_counts_buf[index][tx_size][i][j][k][l];
|
||||
}
|
||||
assert(val >= 0);
|
||||
eob_counts[tx_size][i][j][k][l] = val;
|
||||
|
||||
for (m = 0; m < ENTROPY_TOKENS; ++m) {
|
||||
if (index == max_idx) {
|
||||
val = cpi->td.rd_counts.coef_counts[tx_size][i][j][k][l][m] -
|
||||
subframe_stats->coef_counts_buf[max_idx][tx_size]
|
||||
[i][j][k][l][m];
|
||||
} else {
|
||||
val = subframe_stats->coef_counts_buf[index + 1]
|
||||
[tx_size][i][j][k][l][m] -
|
||||
subframe_stats->coef_counts_buf[index][tx_size]
|
||||
[i][j][k][l][m];
|
||||
}
|
||||
assert(val >= 0);
|
||||
coef_counts[tx_size][i][j][k][l][m] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_coef_probs_subframe(vpx_writer* const bc, VP10_COMP *cpi,
|
||||
TX_SIZE tx_size,
|
||||
vp10_coeff_stats
|
||||
branch_ct[COEF_PROBS_BUFS][TX_SIZES]
|
||||
[PLANE_TYPES],
|
||||
vp10_coeff_probs_model *new_coef_probs) {
|
||||
vp10_coeff_probs_model *old_coef_probs = cpi->common.fc->coef_probs[tx_size];
|
||||
const vpx_prob upd = DIFF_UPDATE_PROB;
|
||||
const int entropy_nodes_update = UNCONSTRAINED_NODES;
|
||||
int i, j, k, l, t;
|
||||
int stepsize = cpi->sf.coeff_prob_appx_step;
|
||||
const int max_idx = cpi->common.coef_probs_update_idx;
|
||||
int idx;
|
||||
unsigned int this_branch_ct[ENTROPY_NODES][COEF_PROBS_BUFS][2];
|
||||
|
||||
switch (cpi->sf.use_fast_coef_updates) {
|
||||
case TWO_LOOP: {
|
||||
/* dry run to see if there is any update at all needed */
|
||||
int savings = 0;
|
||||
int update[2] = {0, 0};
|
||||
for (i = 0; i < PLANE_TYPES; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
|
||||
for (t = 0; t < ENTROPY_NODES; ++t) {
|
||||
for (idx = 0; idx <= max_idx; ++idx) {
|
||||
memcpy(this_branch_ct[t][idx],
|
||||
branch_ct[idx][tx_size][i][j][k][l][t],
|
||||
2 * sizeof(this_branch_ct[t][idx][0]));
|
||||
}
|
||||
}
|
||||
for (t = 0; t < entropy_nodes_update; ++t) {
|
||||
vpx_prob newp = new_coef_probs[i][j][k][l][t];
|
||||
const vpx_prob oldp = old_coef_probs[i][j][k][l][t];
|
||||
int s, u = 0;
|
||||
|
||||
if (t == PIVOT_NODE)
|
||||
s = vp10_prob_update_search_model_subframe(this_branch_ct,
|
||||
old_coef_probs[i][j][k][l], &newp, upd,
|
||||
stepsize, max_idx);
|
||||
else
|
||||
s = vp10_prob_update_search_subframe(this_branch_ct[t],
|
||||
oldp, &newp, upd,
|
||||
max_idx);
|
||||
if (s > 0 && newp != oldp)
|
||||
u = 1;
|
||||
if (u)
|
||||
savings += s - (int)(vp10_cost_zero(upd));
|
||||
else
|
||||
savings -= (int)(vp10_cost_zero(upd));
|
||||
update[u]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Is coef updated at all */
|
||||
if (update[1] == 0 || savings < 0) {
|
||||
vpx_write_bit(bc, 0);
|
||||
return;
|
||||
}
|
||||
vpx_write_bit(bc, 1);
|
||||
for (i = 0; i < PLANE_TYPES; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
|
||||
for (t = 0; t < ENTROPY_NODES; ++t) {
|
||||
for (idx = 0; idx <= max_idx; ++idx) {
|
||||
memcpy(this_branch_ct[t][idx],
|
||||
branch_ct[idx][tx_size][i][j][k][l][t],
|
||||
2 * sizeof(this_branch_ct[t][idx][0]));
|
||||
}
|
||||
}
|
||||
for (t = 0; t < entropy_nodes_update; ++t) {
|
||||
vpx_prob newp = new_coef_probs[i][j][k][l][t];
|
||||
vpx_prob *oldp = old_coef_probs[i][j][k][l] + t;
|
||||
const vpx_prob upd = DIFF_UPDATE_PROB;
|
||||
int s;
|
||||
int u = 0;
|
||||
|
||||
if (t == PIVOT_NODE)
|
||||
s = vp10_prob_update_search_model_subframe(this_branch_ct,
|
||||
old_coef_probs[i][j][k][l], &newp, upd,
|
||||
stepsize, max_idx);
|
||||
else
|
||||
s = vp10_prob_update_search_subframe(this_branch_ct[t],
|
||||
*oldp, &newp, upd,
|
||||
max_idx);
|
||||
if (s > 0 && newp != *oldp)
|
||||
u = 1;
|
||||
vpx_write(bc, u, upd);
|
||||
if (u) {
|
||||
/* send/use new probability */
|
||||
vp10_write_prob_diff_update(bc, newp, *oldp);
|
||||
*oldp = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case ONE_LOOP_REDUCED: {
|
||||
int updates = 0;
|
||||
int noupdates_before_first = 0;
|
||||
for (i = 0; i < PLANE_TYPES; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
|
||||
for (t = 0; t < ENTROPY_NODES; ++t) {
|
||||
for (idx = 0; idx <= max_idx; ++idx) {
|
||||
memcpy(this_branch_ct[t][idx],
|
||||
branch_ct[idx][tx_size][i][j][k][l][t],
|
||||
2 * sizeof(this_branch_ct[t][idx][0]));
|
||||
}
|
||||
}
|
||||
for (t = 0; t < entropy_nodes_update; ++t) {
|
||||
vpx_prob newp = new_coef_probs[i][j][k][l][t];
|
||||
vpx_prob *oldp = old_coef_probs[i][j][k][l] + t;
|
||||
int s;
|
||||
int u = 0;
|
||||
|
||||
if (t == PIVOT_NODE)
|
||||
s = vp10_prob_update_search_model_subframe(this_branch_ct,
|
||||
old_coef_probs[i][j][k][l], &newp, upd,
|
||||
stepsize, max_idx);
|
||||
else
|
||||
s = vp10_prob_update_search_subframe(this_branch_ct[t],
|
||||
*oldp, &newp, upd,
|
||||
max_idx);
|
||||
if (s > 0 && newp != *oldp)
|
||||
u = 1;
|
||||
updates += u;
|
||||
if (u == 0 && updates == 0) {
|
||||
noupdates_before_first++;
|
||||
continue;
|
||||
}
|
||||
if (u == 1 && updates == 1) {
|
||||
int v;
|
||||
// first update
|
||||
vpx_write_bit(bc, 1);
|
||||
for (v = 0; v < noupdates_before_first; ++v)
|
||||
vpx_write(bc, 0, upd);
|
||||
}
|
||||
vpx_write(bc, u, upd);
|
||||
if (u) {
|
||||
/* send/use new probability */
|
||||
vp10_write_prob_diff_update(bc, newp, *oldp);
|
||||
*oldp = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updates == 0) {
|
||||
vpx_write_bit(bc, 0); // no updates
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
static void update_coef_probs(VP10_COMP *cpi, vpx_writer* w) {
|
||||
const TX_MODE tx_mode = cpi->common.tx_mode;
|
||||
const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
|
||||
TX_SIZE tx_size;
|
||||
#if CONFIG_ENTROPY
|
||||
VP10_COMMON *cm = &cpi->common;
|
||||
SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
|
||||
unsigned int eob_counts_copy[TX_SIZES][PLANE_TYPES][REF_TYPES]
|
||||
[COEF_BANDS][COEFF_CONTEXTS];
|
||||
int i;
|
||||
vp10_coeff_count coef_counts[COEF_PROBS_BUFS][TX_SIZES][PLANE_TYPES];
|
||||
unsigned int eob_counts[COEF_PROBS_BUFS][TX_SIZES][PLANE_TYPES]
|
||||
[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS];
|
||||
vp10_coeff_stats branch_ct[COEF_PROBS_BUFS][TX_SIZES][PLANE_TYPES];
|
||||
vp10_coeff_probs_model dummy_frame_coef_probs[PLANE_TYPES];
|
||||
|
||||
if (cm->do_subframe_update &&
|
||||
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
vp10_copy(cpi->common.fc->coef_probs,
|
||||
subframe_stats->enc_starting_coef_probs);
|
||||
for (i = 0; i <= cpi->common.coef_probs_update_idx; ++i) {
|
||||
get_coef_counts_diff(cpi, i, coef_counts[i], eob_counts[i]);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size) {
|
||||
vp10_coeff_stats frame_branch_ct[PLANE_TYPES];
|
||||
vp10_coeff_probs_model frame_coef_probs[PLANE_TYPES];
|
||||
|
@ -2063,12 +2303,59 @@ static void update_coef_probs(VP10_COMP *cpi, vpx_writer* w) {
|
|||
(tx_size >= TX_16X16 && cpi->sf.tx_size_search_method == USE_TX_8X8)) {
|
||||
vpx_write_bit(w, 0);
|
||||
} else {
|
||||
build_tree_distribution(cpi, tx_size, frame_branch_ct,
|
||||
frame_coef_probs);
|
||||
update_coef_probs_common(w, cpi, tx_size, frame_branch_ct,
|
||||
frame_coef_probs);
|
||||
#if CONFIG_ENTROPY
|
||||
if (cm->do_subframe_update &&
|
||||
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
unsigned int eob_counts_copy[PLANE_TYPES][REF_TYPES]
|
||||
[COEF_BANDS][COEFF_CONTEXTS];
|
||||
vp10_coeff_count coef_counts_copy[PLANE_TYPES];
|
||||
vp10_copy(eob_counts_copy, cpi->common.counts.eob_branch[tx_size]);
|
||||
vp10_copy(coef_counts_copy, cpi->td.rd_counts.coef_counts[tx_size]);
|
||||
build_tree_distribution(cpi, tx_size, frame_branch_ct,
|
||||
frame_coef_probs);
|
||||
for (i = 0; i <= cpi->common.coef_probs_update_idx; ++i) {
|
||||
vp10_copy(cpi->common.counts.eob_branch[tx_size],
|
||||
eob_counts[i][tx_size]);
|
||||
vp10_copy(cpi->td.rd_counts.coef_counts[tx_size],
|
||||
coef_counts[i][tx_size]);
|
||||
build_tree_distribution(cpi, tx_size, branch_ct[i][tx_size],
|
||||
dummy_frame_coef_probs);
|
||||
}
|
||||
vp10_copy(cpi->common.counts.eob_branch[tx_size], eob_counts_copy);
|
||||
vp10_copy(cpi->td.rd_counts.coef_counts[tx_size], coef_counts_copy);
|
||||
|
||||
update_coef_probs_subframe(w, cpi, tx_size, branch_ct,
|
||||
frame_coef_probs);
|
||||
} else {
|
||||
#endif // CONFIG_ENTROPY
|
||||
build_tree_distribution(cpi, tx_size, frame_branch_ct,
|
||||
frame_coef_probs);
|
||||
update_coef_probs_common(w, cpi, tx_size, frame_branch_ct,
|
||||
frame_coef_probs);
|
||||
#if CONFIG_ENTROPY
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
vp10_copy(cm->starting_coef_probs, cm->fc->coef_probs);
|
||||
vp10_copy(subframe_stats->coef_probs_buf[0], cm->fc->coef_probs);
|
||||
if (cm->do_subframe_update &&
|
||||
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
vp10_copy(eob_counts_copy, cm->counts.eob_branch);
|
||||
for (i = 1; i <= cpi->common.coef_probs_update_idx; ++i) {
|
||||
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
|
||||
full_to_model_counts(cm->counts.coef[tx_size],
|
||||
subframe_stats->coef_counts_buf[i][tx_size]);
|
||||
vp10_copy(cm->counts.eob_branch, subframe_stats->eob_counts_buf[i]);
|
||||
vp10_partial_adapt_probs(cm, 0, 0);
|
||||
vp10_copy(subframe_stats->coef_probs_buf[i], cm->fc->coef_probs);
|
||||
}
|
||||
vp10_copy(cm->fc->coef_probs, subframe_stats->coef_probs_buf[0]);
|
||||
vp10_copy(cm->counts.eob_branch, eob_counts_copy);
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
}
|
||||
|
||||
#if CONFIG_LOOP_RESTORATION
|
||||
|
|
|
@ -4238,6 +4238,31 @@ static void encode_rd_sb_row(VP10_COMP *cpi,
|
|||
INT64_MAX, td->pc_root);
|
||||
}
|
||||
}
|
||||
#if CONFIG_ENTROPY
|
||||
if (cm->do_subframe_update &&
|
||||
cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
if ((mi_row + MI_SIZE) % (MI_SIZE *
|
||||
VPXMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) == 0 &&
|
||||
mi_row + MI_SIZE < cm->mi_rows &&
|
||||
cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
|
||||
TX_SIZE t;
|
||||
SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
|
||||
|
||||
for (t = TX_4X4; t <= TX_32X32; ++t)
|
||||
full_to_model_counts(cpi->td.counts->coef[t],
|
||||
cpi->td.rd_counts.coef_counts[t]);
|
||||
vp10_partial_adapt_probs(cm, mi_row, mi_col);
|
||||
++cm->coef_probs_update_idx;
|
||||
vp10_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
|
||||
cm->fc->coef_probs);
|
||||
vp10_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
|
||||
cpi->td.rd_counts.coef_counts);
|
||||
vp10_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
|
||||
cm->counts.eob_branch);
|
||||
fill_token_costs(x->token_costs, cm->fc->coef_probs);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
}
|
||||
|
||||
static void init_encode_frame_mb_context(VP10_COMP *cpi) {
|
||||
|
|
|
@ -3335,8 +3335,13 @@ static void full_to_model_count(unsigned int *model_count,
|
|||
model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
void full_to_model_counts(vp10_coeff_count_model *model_count,
|
||||
vp10_coeff_count *full_count) {
|
||||
#else
|
||||
static void full_to_model_counts(vp10_coeff_count_model *model_count,
|
||||
vp10_coeff_count *full_count) {
|
||||
#endif // CONFIG_ENTROPY
|
||||
int i, j, k, l;
|
||||
|
||||
for (i = 0; i < PLANE_TYPES; ++i)
|
||||
|
@ -3666,6 +3671,16 @@ static void encode_without_recode_loop(VP10_COMP *cpi) {
|
|||
|
||||
setup_frame(cpi);
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
cm->do_subframe_update =
|
||||
cm->log2_tile_cols == 0 && cm->log2_tile_rows == 0;
|
||||
vp10_copy(cm->starting_coef_probs, cm->fc->coef_probs);
|
||||
vp10_copy(cpi->subframe_stats.enc_starting_coef_probs,
|
||||
cm->fc->coef_probs);
|
||||
cm->coef_probs_update_idx = 0;
|
||||
vp10_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
suppress_active_map(cpi);
|
||||
// Variance adaptive and in frame q adjustment experiments are mutually
|
||||
// exclusive.
|
||||
|
@ -3768,6 +3783,44 @@ static void encode_with_recode_loop(VP10_COMP *cpi,
|
|||
if (loop_count == 0)
|
||||
setup_frame(cpi);
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
// Base q-index may have changed, so we need to assign proper default coef
|
||||
// probs before every iteration.
|
||||
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
|
||||
int i;
|
||||
vp10_default_coef_probs(cm);
|
||||
if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
|
||||
cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
|
||||
for (i = 0; i < FRAME_CONTEXTS; ++i)
|
||||
cm->frame_contexts[i] = *cm->fc;
|
||||
} else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
|
||||
cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
cm->do_subframe_update =
|
||||
cm->log2_tile_cols == 0 && cm->log2_tile_rows == 0;
|
||||
if (loop_count == 0 || frame_is_intra_only(cm) ||
|
||||
cm->error_resilient_mode) {
|
||||
vp10_copy(cm->starting_coef_probs, cm->fc->coef_probs);
|
||||
vp10_copy(cpi->subframe_stats.enc_starting_coef_probs,
|
||||
cm->fc->coef_probs);
|
||||
} else {
|
||||
if (cm->do_subframe_update) {
|
||||
vp10_copy(cm->fc->coef_probs,
|
||||
cpi->subframe_stats.enc_starting_coef_probs);
|
||||
vp10_copy(cm->starting_coef_probs,
|
||||
cpi->subframe_stats.enc_starting_coef_probs);
|
||||
vp10_zero(cpi->subframe_stats.coef_counts_buf);
|
||||
vp10_zero(cpi->subframe_stats.eob_counts_buf);
|
||||
}
|
||||
}
|
||||
cm->coef_probs_update_idx = 0;
|
||||
vp10_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
// Variance adaptive and in frame q adjustment experiments are mutually
|
||||
// exclusive.
|
||||
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
|
||||
|
@ -4283,6 +4336,9 @@ static void encode_frame_to_data_rate(VP10_COMP *cpi,
|
|||
cpi->td.rd_counts.coef_counts[t]);
|
||||
|
||||
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
|
||||
#if CONFIG_ENTROPY
|
||||
cm->partial_prob_update = 0;
|
||||
#endif // CONFIG_ENTROPY
|
||||
vp10_adapt_coef_probs(cm);
|
||||
vp10_adapt_intra_frame_probs(cm);
|
||||
}
|
||||
|
|
|
@ -290,6 +290,19 @@ typedef struct {
|
|||
YV12_BUFFER_CONFIG buf;
|
||||
} EncRefCntBuffer;
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
typedef struct SUBFRAME_STATS {
|
||||
vp10_coeff_probs_model
|
||||
coef_probs_buf[COEF_PROBS_BUFS][TX_SIZES][PLANE_TYPES];
|
||||
vp10_coeff_count
|
||||
coef_counts_buf[COEF_PROBS_BUFS][TX_SIZES][PLANE_TYPES];
|
||||
unsigned int
|
||||
eob_counts_buf[COEF_PROBS_BUFS]
|
||||
[TX_SIZES][PLANE_TYPES][REF_TYPES][COEF_BANDS][COEFF_CONTEXTS];
|
||||
vp10_coeff_probs_model enc_starting_coef_probs[TX_SIZES][PLANE_TYPES];
|
||||
} SUBFRAME_STATS;
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
typedef struct VP10_COMP {
|
||||
QUANTS quants;
|
||||
ThreadData td;
|
||||
|
@ -555,6 +568,9 @@ typedef struct VP10_COMP {
|
|||
VPxWorker *workers;
|
||||
struct EncWorkerData *tile_thr_data;
|
||||
VP9LfSync lf_row_sync;
|
||||
#if CONFIG_ENTROPY
|
||||
SUBFRAME_STATS subframe_stats;
|
||||
#endif // CONFIG_ENTROPY
|
||||
} VP10_COMP;
|
||||
|
||||
void vp10_initialize_enc(void);
|
||||
|
@ -602,6 +618,11 @@ int vp10_set_size_literal(VP10_COMP *cpi, unsigned int width,
|
|||
|
||||
int vp10_get_quantizer(struct VP10_COMP *cpi);
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
void full_to_model_counts(vp10_coeff_count_model *model_count,
|
||||
vp10_coeff_count *full_count);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
static INLINE int frame_is_kf_gf_arf(const VP10_COMP *cpi) {
|
||||
return frame_is_intra_only(&cpi->common) ||
|
||||
cpi->refresh_alt_ref_frame ||
|
||||
|
|
|
@ -149,8 +149,13 @@ static void fill_mode_costs(VP10_COMP *cpi) {
|
|||
#endif // CONFIG_EXT_INTRA
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
void fill_token_costs(vp10_coeff_cost *c,
|
||||
vp10_coeff_probs_model (*p)[PLANE_TYPES]) {
|
||||
#else
|
||||
static void fill_token_costs(vp10_coeff_cost *c,
|
||||
vp10_coeff_probs_model (*p)[PLANE_TYPES]) {
|
||||
#endif // CONFIG_ENTROPY
|
||||
int i, j, k, l;
|
||||
TX_SIZE t;
|
||||
for (t = TX_4X4; t <= TX_32X32; ++t)
|
||||
|
|
|
@ -340,6 +340,11 @@ void vp10_set_rd_speed_thresholds_sub8x8(struct VP10_COMP *cpi);
|
|||
void vp10_update_rd_thresh_fact(int (*fact)[MAX_MODES], int rd_thresh,
|
||||
int bsize, int best_mode_index);
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
void fill_token_costs(vp10_coeff_cost *c,
|
||||
vp10_coeff_probs_model (*p)[PLANE_TYPES]);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
static INLINE int rd_less_than_thresh(int64_t best_rd, int thresh,
|
||||
int thresh_fact) {
|
||||
return best_rd < ((int64_t)thresh * thresh_fact >> 5) || thresh == INT_MAX;
|
||||
|
|
|
@ -180,6 +180,88 @@ int vp10_prob_diff_update_savings_search_model(const unsigned int *ct,
|
|||
return bestsavings;
|
||||
}
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
static int get_cost(unsigned int ct[][2], vpx_prob p, int n) {
|
||||
int i, p0 = p;
|
||||
unsigned int total_ct[2] = {0 , 0};
|
||||
int cost = 0;
|
||||
|
||||
for (i = 0; i <= n; ++i) {
|
||||
cost += cost_branch256(ct[i], p);
|
||||
total_ct[0] += ct[i][0];
|
||||
total_ct[1] += ct[i][1];
|
||||
if (i < n)
|
||||
p = merge_probs(p0, total_ct, 24, 112);
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
int vp10_prob_update_search_subframe(unsigned int ct[][2],
|
||||
vpx_prob oldp, vpx_prob *bestp,
|
||||
vpx_prob upd, int n) {
|
||||
const int old_b = get_cost(ct, oldp, n);
|
||||
int bestsavings = 0;
|
||||
vpx_prob newp, bestnewp = oldp;
|
||||
const int step = *bestp > oldp ? -1 : 1;
|
||||
|
||||
for (newp = *bestp; newp != oldp; newp += step) {
|
||||
const int new_b = get_cost(ct, newp, n);
|
||||
const int update_b = prob_diff_update_cost(newp, oldp) + vp10_cost_upd256;
|
||||
const int savings = old_b - new_b - update_b;
|
||||
if (savings > bestsavings) {
|
||||
bestsavings = savings;
|
||||
bestnewp = newp;
|
||||
}
|
||||
}
|
||||
*bestp = bestnewp;
|
||||
return bestsavings;
|
||||
}
|
||||
|
||||
int vp10_prob_update_search_model_subframe(unsigned int ct[ENTROPY_NODES]
|
||||
[COEF_PROBS_BUFS][2],
|
||||
const vpx_prob *oldp,
|
||||
vpx_prob *bestp, vpx_prob upd,
|
||||
int stepsize, int n) {
|
||||
int i, old_b, new_b, update_b, savings, bestsavings;
|
||||
int newp;
|
||||
const int step_sign = *bestp > oldp[PIVOT_NODE] ? -1 : 1;
|
||||
const int step = stepsize * step_sign;
|
||||
vpx_prob bestnewp, newplist[ENTROPY_NODES], oldplist[ENTROPY_NODES];
|
||||
vp10_model_to_full_probs(oldp, oldplist);
|
||||
memcpy(newplist, oldp, sizeof(vpx_prob) * UNCONSTRAINED_NODES);
|
||||
for (i = UNCONSTRAINED_NODES, old_b = 0; i < ENTROPY_NODES; ++i)
|
||||
old_b += get_cost(ct[i], oldplist[i], n);
|
||||
old_b += get_cost(ct[PIVOT_NODE], oldplist[PIVOT_NODE], n);
|
||||
|
||||
bestsavings = 0;
|
||||
bestnewp = oldp[PIVOT_NODE];
|
||||
|
||||
assert(stepsize > 0);
|
||||
|
||||
for (newp = *bestp; (newp - oldp[PIVOT_NODE]) * step_sign < 0;
|
||||
newp += step) {
|
||||
if (newp < 1 || newp > 255)
|
||||
continue;
|
||||
newplist[PIVOT_NODE] = newp;
|
||||
vp10_model_to_full_probs(newplist, newplist);
|
||||
for (i = UNCONSTRAINED_NODES, new_b = 0; i < ENTROPY_NODES; ++i)
|
||||
new_b += get_cost(ct[i], newplist[i], n);
|
||||
new_b += get_cost(ct[PIVOT_NODE], newplist[PIVOT_NODE], n);
|
||||
update_b = prob_diff_update_cost(newp, oldp[PIVOT_NODE]) +
|
||||
vp10_cost_upd256;
|
||||
savings = old_b - new_b - update_b;
|
||||
if (savings > bestsavings) {
|
||||
bestsavings = savings;
|
||||
bestnewp = newp;
|
||||
}
|
||||
}
|
||||
|
||||
*bestp = bestnewp;
|
||||
return bestsavings;
|
||||
}
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
void vp10_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp,
|
||||
const unsigned int ct[2]) {
|
||||
const vpx_prob upd = DIFF_UPDATE_PROB;
|
||||
|
|
|
@ -38,6 +38,18 @@ int vp10_prob_diff_update_savings_search_model(const unsigned int *ct,
|
|||
int stepsize);
|
||||
int vp10_cond_prob_diff_update_savings(vpx_prob *oldp,
|
||||
const unsigned int ct[2]);
|
||||
|
||||
#if CONFIG_ENTROPY
|
||||
int vp10_prob_update_search_subframe(unsigned int ct[][2],
|
||||
vpx_prob oldp, vpx_prob *bestp,
|
||||
vpx_prob upd, int n);
|
||||
int vp10_prob_update_search_model_subframe(unsigned int ct[ENTROPY_NODES]
|
||||
[COEF_PROBS_BUFS][2],
|
||||
const vpx_prob *oldp,
|
||||
vpx_prob *bestp, vpx_prob upd,
|
||||
int stepsize, int n);
|
||||
#endif // CONFIG_ENTROPY
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
@ -455,8 +455,14 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
|
|||
const int ref = is_inter_block(mbmi);
|
||||
unsigned int (*const counts)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
|
||||
td->rd_counts.coef_counts[tx_size][type][ref];
|
||||
#if CONFIG_ENTROPY
|
||||
vpx_prob (*coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
|
||||
cpi->subframe_stats.coef_probs_buf[cpi->common.coef_probs_update_idx]
|
||||
[tx_size][type][ref];
|
||||
#else
|
||||
vpx_prob (*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
|
||||
cpi->common.fc->coef_probs[tx_size][type][ref];
|
||||
#endif // CONFIG_ENTROPY
|
||||
unsigned int (*const eob_branch)[COEFF_CONTEXTS] =
|
||||
td->counts->eob_branch[tx_size][type][ref];
|
||||
const uint8_t *const band = get_band_translate(tx_size);
|
||||
|
|
Загрузка…
Ссылка в новой задаче