Modeling default coef probs with distribution
Replaces the default tables for single coefficient magnitudes with those obtained from an appropriate distribution. The EOB node is left unchanged. The model is represeted as a 256-size codebook where the index corresponds to the probability of the Zero or the One node. Two variations are implemented corresponding to whether the Zero node or the One-node is used as the peg. The main advantage is that the default prob tables will become considerably smaller and manageable. Besides there is substantially less risk of over-fitting for a training set. Various distributions are tried and the one that gives the best results is the family of Generalized Gaussian distributions with shape parameter 0.75. The results are within about 0.2% of fully trained tables for the Zero peg variant, and within 0.1% of the One peg variant. The forward updates are optionally (controlled by a macro) model-based, i.e. restricted to only convey probabilities from the codebook. Backward updates can also be optionally (controlled by another macro) model-based, but is turned off by default. Currently model-based forward updates work about the same as unconstrained updates, but there is a drop in performance with backward-updates being model based. The model based approach also allows the probabilities for the key frames to be adjusted from the defaults based on the base_qindex of the frame. Currently the adjustment function is a placeholder that adjusts the prob of EOB and Zero node from the nominal one at higher quality (lower qindex) or lower quality (higher qindex) ends of the range. The rest of the probabilities are then derived based on the model from the adjusted prob of zero. Change-Id: Iae050f3cbcc6d8b3f204e8dc395ae47b3b2192c9
This commit is contained in:
Родитель
66eff0aa38
Коммит
fd18d5dffe
|
@ -247,6 +247,7 @@ EXPERIMENT_LIST="
|
|||
abovesprefmv
|
||||
code_nonzerocount
|
||||
useselectrefmv
|
||||
modelcoefprob
|
||||
"
|
||||
CONFIG_LIST="
|
||||
external_build
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
|
||||
/* Update probabilities for the nodes in the token entropy tree.
|
||||
Generated file included by vp9_entropy.c */
|
||||
#define COEF_UPDATE_PROB 252
|
||||
#define COEF_UPDATE_PROB_8X8 252
|
||||
#define COEF_UPDATE_PROB_16X16 252
|
||||
|
||||
static const vp9_prob vp9_coef_update_prob[ENTROPY_NODES] = {
|
||||
252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252
|
||||
};
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
#define NZC_UPDATE_PROB_4X4 252
|
||||
|
@ -25,4 +26,8 @@
|
|||
#define NZC_UPDATE_PROB_PCAT 252
|
||||
#endif
|
||||
|
||||
#if CONFIG_MODELCOEFPROB
|
||||
#define COEF_MODEL_UPDATE_PROB 16
|
||||
#endif
|
||||
|
||||
#endif // VP9_COMMON_VP9_COEFUPDATEPROBS_H__
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
/*Generated file, included by vp9_entropy.c*/
|
||||
|
||||
// NOTE: When the CONFIG_MODELCOEFPROB experiment is on, only the first
|
||||
// 2 or 3 from each row is actually used depending on whether
|
||||
// UNCONSTRAINDED_NODES is 2 or 3. If this experiment is merged
|
||||
// the tables below should be shortened accordingly.
|
||||
static const vp9_coeff_probs default_coef_probs_4x4[BLOCK_TYPES] = {
|
||||
{ /* block Type 0 */
|
||||
{ /* Intra */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,7 +15,6 @@
|
|||
#include "vp9/common/vp9_treecoder.h"
|
||||
#include "vp9/common/vp9_blockd.h"
|
||||
#include "vp9/common/vp9_common.h"
|
||||
#include "vp9/common/vp9_coefupdateprobs.h"
|
||||
|
||||
extern const int vp9_i8x8_block[4];
|
||||
|
||||
|
@ -33,8 +32,8 @@ extern const int vp9_i8x8_block[4];
|
|||
#define DCT_VAL_CATEGORY5 9 /* 35-66 Extra Bits 5+1 */
|
||||
#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 14+1 */
|
||||
#define DCT_EOB_TOKEN 11 /* EOB Extra Bits 0+0 */
|
||||
#define MAX_ENTROPY_TOKENS 12
|
||||
#define ENTROPY_NODES 11
|
||||
#define MAX_ENTROPY_TOKENS 12
|
||||
#define ENTROPY_NODES 11
|
||||
#define EOSB_TOKEN 127 /* Not signalled, encoder only */
|
||||
|
||||
#define INTER_MODE_CONTEXTS 7
|
||||
|
@ -142,6 +141,33 @@ static int get_coef_band(TX_SIZE tx_size, int coef_index) {
|
|||
}
|
||||
extern int vp9_get_coef_context(int * recent_energy, int token);
|
||||
|
||||
#if CONFIG_MODELCOEFPROB
|
||||
#define COEFPROB_BITS 8
|
||||
#define COEFPROB_MODELS (1 << COEFPROB_BITS)
|
||||
|
||||
// 2 => EOB and Zero nodes are unconstrained, rest are modeled
|
||||
// 3 => EOB, Zero and One nodes are unconstrained, rest are modeled
|
||||
#define UNCONSTRAINED_NODES 3 // Choose one of 2 or 3
|
||||
|
||||
// whether forward updates are model-based
|
||||
#define MODEL_BASED_UPDATE 0
|
||||
// if model-based how many nodes are unconstrained
|
||||
#define UNCONSTRAINED_UPDATE_NODES 3
|
||||
// whether backward updates are model-based
|
||||
#define MODEL_BASED_ADAPT 0
|
||||
#define UNCONSTRAINED_ADAPT_NODES 3
|
||||
|
||||
// whether to adjust the coef probs for key frames based on qindex
|
||||
#define ADJUST_KF_COEF_PROBS 0
|
||||
|
||||
typedef vp9_prob vp9_coeff_probs_model[REF_TYPES][COEF_BANDS]
|
||||
[PREV_COEF_CONTEXTS][2];
|
||||
extern const vp9_prob vp9_modelcoefprobs[COEFPROB_MODELS][ENTROPY_NODES - 1];
|
||||
void vp9_get_model_distribution(vp9_prob model, vp9_prob *tree_probs,
|
||||
int b, int r);
|
||||
void vp9_adjust_default_coef_probs(struct VP9Common *cm);
|
||||
#endif // CONFIG_MODELCOEFPROB
|
||||
|
||||
#if CONFIG_CODE_NONZEROCOUNT
|
||||
/* Alphabet for number of non-zero symbols in block */
|
||||
#define NZC_0 0 /* Used for all blocks */
|
||||
|
@ -224,4 +250,7 @@ extern const int vp9_extranzcbits[NZC32X32_TOKENS];
|
|||
extern const int vp9_basenzcvalue[NZC32X32_TOKENS];
|
||||
|
||||
#endif // CONFIG_CODE_NONZEROCOUNT
|
||||
|
||||
#include "vp9/common/vp9_coefupdateprobs.h"
|
||||
|
||||
#endif // VP9_COMMON_VP9_ENTROPY_H_
|
||||
|
|
|
@ -1197,6 +1197,12 @@ static void read_nzc_probs(VP9_COMMON *cm,
|
|||
static void read_coef_probs_common(BOOL_DECODER* const bc,
|
||||
vp9_coeff_probs *coef_probs,
|
||||
int block_types) {
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
const int entropy_nodes_update = UNCONSTRAINED_UPDATE_NODES;
|
||||
#else
|
||||
const int entropy_nodes_update = ENTROPY_NODES;
|
||||
#endif
|
||||
|
||||
int i, j, k, l, m;
|
||||
|
||||
if (vp9_read_bit(bc)) {
|
||||
|
@ -1206,11 +1212,15 @@ static void read_coef_probs_common(BOOL_DECODER* const bc,
|
|||
for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
|
||||
if (l >= 3 && k == 0)
|
||||
continue;
|
||||
for (m = CONFIG_CODE_NONZEROCOUNT; m < ENTROPY_NODES; m++) {
|
||||
for (m = CONFIG_CODE_NONZEROCOUNT; m < entropy_nodes_update; m++) {
|
||||
vp9_prob *const p = coef_probs[i][j][k][l] + m;
|
||||
|
||||
if (vp9_read(bc, COEF_UPDATE_PROB)) {
|
||||
if (vp9_read(bc, vp9_coef_update_prob[m])) {
|
||||
*p = read_prob_diff_update(bc, *p);
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
if (m == 1)
|
||||
vp9_get_model_distribution(*p, coef_probs[i][j][k][l], i, j);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1611,6 +1621,10 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#if CONFIG_MODELCOEFPROB && ADJUST_KF_COEF_PROBS
|
||||
if (pc->frame_type == KEY_FRAME)
|
||||
vp9_adjust_default_coef_probs(pc);
|
||||
#endif
|
||||
|
||||
#if CONFIG_NEW_MVREF
|
||||
// If Key frame reset mv ref id probabilities to defaults
|
||||
|
|
|
@ -399,6 +399,43 @@ static int prob_diff_update_savings_search(const unsigned int *ct,
|
|||
return bestsavings;
|
||||
}
|
||||
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
static int prob_diff_update_savings_search_model(const unsigned int *ct,
|
||||
const vp9_prob *oldp,
|
||||
vp9_prob *bestp,
|
||||
const vp9_prob upd,
|
||||
int b, int r) {
|
||||
int i, old_b, new_b, update_b, savings, bestsavings, step;
|
||||
int newp;
|
||||
vp9_prob bestnewp, newplist[ENTROPY_NODES];
|
||||
for (i = UNCONSTRAINED_NODES - 1, old_b = 0; i < ENTROPY_NODES; ++i)
|
||||
old_b += cost_branch256(ct + 2 * i, oldp[i]);
|
||||
|
||||
bestsavings = 0;
|
||||
bestnewp = oldp[UNCONSTRAINED_NODES - 1];
|
||||
|
||||
step = (*bestp > oldp[UNCONSTRAINED_NODES - 1] ? -1 : 1);
|
||||
newp = *bestp;
|
||||
// newp = *bestp - step * (abs(*bestp - oldp[UNCONSTRAINED_NODES - 1]) >> 1);
|
||||
for (; newp != oldp[UNCONSTRAINED_NODES - 1]; newp += step) {
|
||||
if (newp < 1 || newp > 255) continue;
|
||||
newplist[UNCONSTRAINED_NODES - 1] = newp;
|
||||
vp9_get_model_distribution(newp, newplist, b, r);
|
||||
for (i = UNCONSTRAINED_NODES - 1, new_b = 0; i < ENTROPY_NODES; ++i)
|
||||
new_b += cost_branch256(ct + 2 * i, newplist[i]);
|
||||
update_b = prob_diff_update_cost(newp, oldp[UNCONSTRAINED_NODES - 1]) +
|
||||
vp9_cost_upd256;
|
||||
savings = old_b - new_b - update_b;
|
||||
if (savings > bestsavings) {
|
||||
bestsavings = savings;
|
||||
bestnewp = newp;
|
||||
}
|
||||
}
|
||||
*bestp = bestnewp;
|
||||
return bestsavings;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void vp9_cond_prob_update(vp9_writer *bc, vp9_prob *oldp, vp9_prob upd,
|
||||
unsigned int *ct) {
|
||||
vp9_prob newp;
|
||||
|
@ -2014,6 +2051,11 @@ static void update_coef_probs_common(vp9_writer* const bc,
|
|||
int i, j, k, l, t;
|
||||
int update[2] = {0, 0};
|
||||
int savings;
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
const int entropy_nodes_update = UNCONSTRAINED_UPDATE_NODES;
|
||||
#else
|
||||
const int entropy_nodes_update = ENTROPY_NODES;
|
||||
#endif
|
||||
// vp9_prob bestupd = find_coef_update_prob(cpi);
|
||||
|
||||
/* dry run to see if there is any udpate at all needed */
|
||||
|
@ -2021,20 +2063,27 @@ static void update_coef_probs_common(vp9_writer* const bc,
|
|||
for (i = 0; i < block_types; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
int prev_coef_savings[ENTROPY_NODES] = {0};
|
||||
// int prev_coef_savings[ENTROPY_NODES] = {0};
|
||||
for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
|
||||
for (t = CONFIG_CODE_NONZEROCOUNT; t < ENTROPY_NODES; ++t) {
|
||||
for (t = CONFIG_CODE_NONZEROCOUNT; t < entropy_nodes_update; ++t) {
|
||||
vp9_prob newp = new_frame_coef_probs[i][j][k][l][t];
|
||||
const vp9_prob oldp = old_frame_coef_probs[i][j][k][l][t];
|
||||
const vp9_prob upd = COEF_UPDATE_PROB;
|
||||
int s = prev_coef_savings[t];
|
||||
const vp9_prob upd = vp9_coef_update_prob[t];
|
||||
int s; // = prev_coef_savings[t];
|
||||
int u = 0;
|
||||
|
||||
if (l >= 3 && k == 0)
|
||||
continue;
|
||||
#if defined(SEARCH_NEWP)
|
||||
s = prob_diff_update_savings_search(frame_branch_ct[i][j][k][l][t],
|
||||
oldp, &newp, upd);
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
if (t == UNCONSTRAINED_NODES - 1)
|
||||
s = prob_diff_update_savings_search_model(
|
||||
frame_branch_ct[i][j][k][l][0],
|
||||
old_frame_coef_probs[i][j][k][l], &newp, upd, i, j);
|
||||
else
|
||||
#endif
|
||||
s = prob_diff_update_savings_search(
|
||||
frame_branch_ct[i][j][k][l][t], oldp, &newp, upd);
|
||||
if (s > 0 && newp != oldp)
|
||||
u = 1;
|
||||
if (u)
|
||||
|
@ -2061,45 +2110,57 @@ static void update_coef_probs_common(vp9_writer* const bc,
|
|||
/* Is coef updated at all */
|
||||
if (update[1] == 0 || savings < 0) {
|
||||
vp9_write_bit(bc, 0);
|
||||
} else {
|
||||
vp9_write_bit(bc, 1);
|
||||
for (i = 0; i < block_types; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
int prev_coef_savings[ENTROPY_NODES] = {0};
|
||||
for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
|
||||
// calc probs and branch cts for this frame only
|
||||
for (t = CONFIG_CODE_NONZEROCOUNT; t < ENTROPY_NODES; ++t) {
|
||||
vp9_prob newp = new_frame_coef_probs[i][j][k][l][t];
|
||||
vp9_prob *oldp = old_frame_coef_probs[i][j][k][l] + t;
|
||||
const vp9_prob upd = COEF_UPDATE_PROB;
|
||||
int s = prev_coef_savings[t];
|
||||
int u = 0;
|
||||
if (l >= 3 && k == 0)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
vp9_write_bit(bc, 1);
|
||||
for (i = 0; i < block_types; ++i) {
|
||||
for (j = 0; j < REF_TYPES; ++j) {
|
||||
for (k = 0; k < COEF_BANDS; ++k) {
|
||||
// int prev_coef_savings[ENTROPY_NODES] = {0};
|
||||
for (l = 0; l < PREV_COEF_CONTEXTS; ++l) {
|
||||
// calc probs and branch cts for this frame only
|
||||
for (t = CONFIG_CODE_NONZEROCOUNT; t < entropy_nodes_update; ++t) {
|
||||
vp9_prob newp = new_frame_coef_probs[i][j][k][l][t];
|
||||
vp9_prob *oldp = old_frame_coef_probs[i][j][k][l] + t;
|
||||
const vp9_prob upd = vp9_coef_update_prob[t];
|
||||
int s; // = prev_coef_savings[t];
|
||||
int u = 0;
|
||||
if (l >= 3 && k == 0)
|
||||
continue;
|
||||
|
||||
#if defined(SEARCH_NEWP)
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
if (t == UNCONSTRAINED_NODES - 1)
|
||||
s = prob_diff_update_savings_search_model(
|
||||
frame_branch_ct[i][j][k][l][0],
|
||||
old_frame_coef_probs[i][j][k][l], &newp, upd, i, j);
|
||||
else
|
||||
#endif
|
||||
s = prob_diff_update_savings_search(
|
||||
frame_branch_ct[i][j][k][l][t],
|
||||
*oldp, &newp, upd);
|
||||
if (s > 0 && newp != *oldp)
|
||||
u = 1;
|
||||
frame_branch_ct[i][j][k][l][t],
|
||||
*oldp, &newp, upd);
|
||||
if (s > 0 && newp != *oldp)
|
||||
u = 1;
|
||||
#else
|
||||
s = prob_update_savings(frame_branch_ct[i][j][k][l][t],
|
||||
*oldp, newp, upd);
|
||||
if (s > 0)
|
||||
u = 1;
|
||||
s = prob_update_savings(frame_branch_ct[i][j][k][l][t],
|
||||
*oldp, newp, upd);
|
||||
if (s > 0)
|
||||
u = 1;
|
||||
#endif
|
||||
vp9_write(bc, u, upd);
|
||||
vp9_write(bc, u, upd);
|
||||
#ifdef ENTROPY_STATS
|
||||
if (!cpi->dummy_packing)
|
||||
++tree_update_hist[i][j][k][l][t][u];
|
||||
if (!cpi->dummy_packing)
|
||||
++tree_update_hist[i][j][k][l][t][u];
|
||||
#endif
|
||||
if (u) {
|
||||
/* send/use new probability */
|
||||
write_prob_diff_update(bc, newp, *oldp);
|
||||
*oldp = newp;
|
||||
#if CONFIG_MODELCOEFPROB && MODEL_BASED_UPDATE
|
||||
if (t == UNCONSTRAINED_NODES - 1)
|
||||
vp9_get_model_distribution(
|
||||
newp, old_frame_coef_probs[i][j][k][l], i, j);
|
||||
#endif
|
||||
if (u) {
|
||||
/* send/use new probability */
|
||||
write_prob_diff_update(bc, newp, *oldp);
|
||||
*oldp = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1287,9 +1287,6 @@ static void encode_frame_internal(VP9_COMP *cpi) {
|
|||
vp9_zero(cpi->mb_mv_ref_count);
|
||||
#endif
|
||||
|
||||
// force lossless mode
|
||||
if (cm->base_qindex <= 4)
|
||||
cm->base_qindex = 0;
|
||||
cpi->mb.e_mbd.lossless = (cm->base_qindex == 0 &&
|
||||
cm->y1dc_delta_q == 0 &&
|
||||
cm->uvdc_delta_q == 0 &&
|
||||
|
|
|
@ -3052,6 +3052,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||
}
|
||||
|
||||
// transform / motion compensation build reconstruction frame
|
||||
#if CONFIG_MODELCOEFPROB && ADJUST_KF_COEF_PROBS
|
||||
if (cm->frame_type == KEY_FRAME)
|
||||
vp9_adjust_default_coef_probs(cm);
|
||||
#endif
|
||||
|
||||
vp9_encode_frame(cpi);
|
||||
|
||||
|
|
|
@ -730,6 +730,10 @@ void vp9_set_quantizer(struct VP9_COMP *cpi, int Q) {
|
|||
|
||||
cm->base_qindex = Q;
|
||||
|
||||
// Set lossless mode
|
||||
if (cm->base_qindex <= 4)
|
||||
cm->base_qindex = 0;
|
||||
|
||||
// if any of the delta_q values are changing update flag will
|
||||
// have to be set.
|
||||
cm->y1dc_delta_q = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче