Merge "Add "entropy" experiment" into nextgenv2

This commit is contained in:
Hui Su 2016-03-23 17:50:56 +00:00 коммит произвёл Gerrit Code Review
Родитель a06e39a945 83b47af18d
Коммит daf2fb42e6
13 изменённых файлов: 2368 добавлений и 6 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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);