#include "dboolhuff.h"
#include "vp8/common/seg_common.h"
+#include "vp8/common/entropy.h"
#include <assert.h>
#include <stdio.h>
int dec_debug = 0;
#endif
+#if CONFIG_NEWUPDATE
+static int inv_remap_prob(int v, int m)
+{
+ const int n = 256;
+ int i;
+ //if (v <= n - 2 - s) v += s; else v = n - 2 - v;
+ //v = ((v&240)>>4) | ((v&15)<<4);
+ v = (v%15)*17 + (v/15);
+ if ((m<<1)<=n) {
+ i = inv_recenter_nonneg(v+1, m);
+ } else {
+ i = n-1-inv_recenter_nonneg(v+1, n-1-m);
+ }
+ return i;
+}
+#endif
+
void vp8cx_init_de_quantizer(VP8D_COMP *pbi)
{
int i;
}
+#if CONFIG_NEWUPDATE
+static void read_coef_probs3(VP8D_COMP *pbi)
+{
+ const vp8_prob grpupd = 216;
+ int i, j, k, l;
+ vp8_reader *const bc = & pbi->bc;
+ VP8_COMMON *const pc = & pbi->common;
+ for (i = 0; i < BLOCK_TYPES; i++)
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+ if(vp8_read(bc, grpupd))
+ {
+ //printf("Decoding %d\n", l);
+ for (j = !i; j < COEF_BANDS; j++)
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ {
+ vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
+ int u = vp8_read(bc, vp8_coef_update_probs [i][j][k][l]);
+ if (u)
+ {
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+ }
+ }
+ }
+ }
+
+ if(pbi->common.txfm_mode == ALLOW_8X8)
+ {
+ for (i = 0; i < BLOCK_TYPES; i++)
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+ if(vp8_read(bc, grpupd))
+ {
+ for (j = !i; j < COEF_BANDS; j++)
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ {
+ vp8_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
+ int u = vp8_read(bc, vp8_coef_update_probs_8x8 [i][j][k][l]);
+ if (u)
+ {
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void read_coef_probs2(VP8D_COMP *pbi)
+{
+ const vp8_prob grpupd = 192;
+ int i, j, k, l;
+ vp8_reader *const bc = & pbi->bc;
+ VP8_COMMON *const pc = & pbi->common;
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+ if(vp8_read(bc, grpupd))
+ {
+ //printf("Decoding %d\n", l);
+ for (i = 0; i < BLOCK_TYPES; i++)
+ for (j = !i; j < COEF_BANDS; j++)
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ {
+ vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
+ int u = vp8_read(bc, vp8_coef_update_probs [i][j][k][l]);
+ if (u)
+ {
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+ }
+ }
+ }
+ }
+ if(pbi->common.txfm_mode == ALLOW_8X8)
+ {
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+ if(vp8_read(bc, grpupd))
+ {
+ for (i = 0; i < BLOCK_TYPES; i++)
+ for (j = !i; j < COEF_BANDS; j++)
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ {
+ vp8_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
+
+ int u = vp8_read(bc, vp8_coef_update_probs_8x8 [i][j][k][l]);
+ if (u)
+ {
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+static void read_coef_probs(VP8D_COMP *pbi)
+{
+ int i, j, k, l;
+ vp8_reader *const bc = & pbi->bc;
+ VP8_COMMON *const pc = & pbi->common;
+
+ {
+ if(vp8_read_bit(bc))
+ {
+ /* read coef probability tree */
+ for (i = 0; i < BLOCK_TYPES; i++)
+#if CONFIG_NEWUPDATE
+ for (j = !i; j < COEF_BANDS; j++)
+#else
+ for (j = 0; j < COEF_BANDS; j++)
+#endif
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+ vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
+
+ if (vp8_read(bc, vp8_coef_update_probs [i][j][k][l]))
+ {
+#if CONFIG_NEWUPDATE
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ //printf("delp = %d/%d", *p, delp);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+ //printf("/%d\n", *p);
+#else
+ *p = (vp8_prob)vp8_read_literal(bc, 8);
+#endif
+ }
+ }
+ }
+ }
+
+ if(pbi->common.txfm_mode == ALLOW_8X8 && vp8_read_bit(bc))
+ {
+ // read coef probability tree
+ for (i = 0; i < BLOCK_TYPES; i++)
+#if CONFIG_NEWUPDATE
+ for (j = !i; j < COEF_BANDS; j++)
+#else
+ for (j = 0; j < COEF_BANDS; j++)
+#endif
+ for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+ for (l = 0; l < ENTROPY_NODES; l++)
+ {
+
+ vp8_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
+
+ if (vp8_read(bc, vp8_coef_update_probs_8x8 [i][j][k][l]))
+ {
+#if CONFIG_NEWUPDATE
+ int delp = vp8_decode_term_subexp(bc, SUBEXP_PARAM, 255);
+ *p = (vp8_prob)inv_remap_prob(delp, *p);
+#else
+ *p = (vp8_prob)vp8_read_literal(bc, 8);
+#endif
+ }
+ }
+ }
+}
+
int vp8_decode_frame(VP8D_COMP *pbi)
{
vp8_reader *const bc = & pbi->bc;
fclose(z);
}
- {
- if(vp8_read_bit(bc))
- {
- /* read coef probability tree */
- for (i = 0; i < BLOCK_TYPES; i++)
- for (j = 0; j < COEF_BANDS; j++)
- for (k = 0; k < PREV_COEF_CONTEXTS; k++)
- for (l = 0; l < ENTROPY_NODES; l++)
- {
- vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
-
- if (vp8_read(bc, vp8_coef_update_probs [i][j][k][l]))
- {
- *p = (vp8_prob)vp8_read_literal(bc, 8);
-
- }
- }
- }
- }
-
- if(pbi->common.txfm_mode == ALLOW_8X8 && vp8_read_bit(bc))
- {
- // read coef probability tree
- for (i = 0; i < BLOCK_TYPES; i++)
- for (j = 0; j < COEF_BANDS; j++)
- for (k = 0; k < PREV_COEF_CONTEXTS; k++)
- for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
- {
-
- vp8_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
-
- if (vp8_read(bc, vp8_coef_update_probs_8x8 [i][j][k][l]))
- {
- *p = (vp8_prob)vp8_read_literal(bc, 8);
-
- }
- }
- }
+#if COEFUPDATETYPE == 2
+ read_coef_probs2(pbi);
+#elif COEFUPDATETYPE == 3
+ read_coef_probs3(pbi);
+#else
+ read_coef_probs(pbi);
+#endif
vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG));
#include "vp8/common/seg_common.h"
#include "vp8/common/pred_common.h"
+#include "vp8/common/entropy.h"
#if defined(SECTIONBITS_OUTPUT)
unsigned __int64 Sectionbits[500];
#endif
#define vp8_cost_upd ((int)(vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8)
+#define vp8_cost_upd256 ((int)(vp8_cost_one(upd) - vp8_cost_zero(upd)))
+
+#if CONFIG_NEWUPDATE
+#define SEARCH_NEWP
+static int update_bits[255];
+
+static void compute_update_table()
+{
+ int i;
+ for (i=0; i<255; i++)
+ update_bits[i] = vp8_count_term_subexp(i, SUBEXP_PARAM, 255);
+}
+
+static int remap_prob(int v, int m)
+{
+ const int n = 256;
+ int i;
+ if ((m<<1)<=n)
+ i = recenter_nonneg(v, m) - 1;
+ else
+ i = recenter_nonneg(n-1-v, n-1-m) - 1;
+ //if (i >= s) i -= s; else i = n - 2 - i;
+ //i = ((i>>4)&15) | ((i((i>>4)&15) | ((i&15)<<4);&15)<<4);
+ i = (i%17)*15 + (i/17);
+ return i;
+}
+#endif
static void update_mode(
vp8_writer *const w,
const vp8_prob oldp, const vp8_prob newp,
const vp8_prob upd)
{
- const int old_b = vp8_cost_branch(ct, oldp);
- const int new_b = vp8_cost_branch(ct, newp);
- const int update_b = 8 + vp8_cost_upd;
+ const int old_b = vp8_cost_branch256(ct, oldp);
+ const int new_b = vp8_cost_branch256(ct, newp);
+#if CONFIG_NEWUPDATE
+ const int delp = remap_prob(newp, oldp);
+ const int update_b = update_bits[delp]*256 + vp8_cost_upd256;
+#else
+ const int update_b = 2048 + vp8_cost_upd256;
+#endif
+ return (old_b - new_b - update_b);
+}
+
+#if CONFIG_NEWUPDATE
+static int prob_update_savings_search(const unsigned int *ct,
+ const vp8_prob oldp, vp8_prob *bestp,
+ const vp8_prob upd)
+{
+ const int old_b = vp8_cost_branch256(ct, oldp);
+ int new_b, delp, update_b, savings, bestsavings, step;
+ vp8_prob newp, bestnewp;
+
+ bestsavings = 0;
+ bestnewp = oldp;
- return old_b - new_b - update_b;
+ step = (*bestp > oldp ? -1 : 1);
+ for (newp = *bestp; newp != oldp; newp+=step)
+ {
+ new_b = vp8_cost_branch256(ct, newp);
+ delp = remap_prob(newp, oldp);
+ update_b = update_bits[delp]*256 + vp8_cost_upd256;
+ savings = old_b - new_b - update_b;
+ if (savings > bestsavings)
+ {
+ bestsavings = savings;
+ bestnewp = newp;
+ }
+ }
+ *bestp = bestnewp;
+ return bestsavings;
}
+#endif
static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
{
int i = 0;
do
{
- int j = 0;
+#if CONFIG_NEWUPDATE
+ int j = !i;
+#else
+ int j = 0; /* token/prob index */
+#endif
do
{
int k = 0;
int t = 0; /* token/prob index */
-
vp8_tree_probs_from_distribution(
MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
cpi->frame_coef_probs [i][j][k],
do
{
const unsigned int *ct = cpi->frame_branch_ct [i][j][k][t];
- const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
const vp8_prob oldp = cpi->common.fc.coef_probs [i][j][k][t];
const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+
+#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP)
+ const int s = prob_update_savings_search(ct, oldp, &newp, upd);
+#else
const int s = prob_update_savings(ct, oldp, newp, upd);
+#endif
if (s > 0)
{
int k = 0;
do
{
+ int t;
vp8_tree_probs_from_distribution(
MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
cpi->frame_coef_probs [i][j][k],
cpi->coef_counts [i][j][k],
256, 1
);
+#ifdef ENTROPY_STATS
+ t = 0;
+ do
+ {
+ context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t];
+ }
+ while (++t < MAX_ENTROPY_TOKENS);
+#endif
}
while (++k < PREV_COEF_CONTEXTS);
}
{
do
{
- int j = 0;
+ int j = 0; /* token/prob index */
do
{
int k = 0;
cpi->coef_counts_8x8 [i][j][k],
256, 1
);
+#ifdef ENTROPY_STATS
+ t = 0;
+ do
+ {
+ context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t];
+ }
+ while (++t < MAX_ENTROPY_TOKENS);
+#endif
}
while (++k < PREV_COEF_CONTEXTS);
}
+#if CONFIG_NEWUPDATE
+static void update_coef_probs3(VP8_COMP *cpi)
+{
+ const vp8_prob grpupd = 216;
+ int i, j, k, t;
+ vp8_writer *const w = & cpi->bc;
+ int update[2];
+ int savings;
+ int bestupdndx[2*ENTROPY_NODES];
+
+ vp8_clear_system_state(); //__asm emms;
+ // Build the cofficient contexts based on counts collected in encode loop
+ build_coeff_contexts(cpi);
+
+ i = 0;
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (t = 0; t < ENTROPY_NODES; ++t)
+ {
+ /* dry run to see if there is any udpate at all needed */
+ savings = 0;
+ update[0] = update[1] = 0;
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold) u = 1;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, newp, upd);
+ if (s > 0) u = 1;
+ if (u)
+ savings += s;
+#endif
+ //printf(" %d %d %d: %d\n", i, j, k, u);
+ update[u]++;
+ }
+ }
+ if (update[1] == 0 || savings < 0)
+ {
+ vp8_write(w, 0, grpupd);
+ continue;
+ }
+ vp8_write(w, 1, grpupd);
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold) u = 1;
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, newp, upd);
+ if (s > 0) u = 1;
+#endif
+ //printf(" %d %d %d: %d (%d)\n", i, j, k, u, upd);
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ ++ tree_update_hist [i][j][k][t] [u];
+#endif
+ if (u)
+ { /* send/use new probability */
+ int delp = remap_prob(newp, *Pold);
+ vp8_encode_term_subexp(w, delp, SUBEXP_PARAM, 255);
+ *Pold = newp;
+ }
+
+ }
+ }
+ }
+ }
+
+ if(cpi->common.txfm_mode != ALLOW_8X8) return;
+
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (t = 0; t < ENTROPY_NODES; ++t)
+ {
+ /* dry run to see if there is any udpate at all needed */
+ savings = 0;
+ update[0] = update[1] = 0;
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+ if (u)
+ savings += s;
+#endif
+ update[u]++;
+ }
+ }
+ if (update[1] == 0 || savings < 0)
+ {
+ vp8_write(w, 0, grpupd);
+ continue;
+ }
+ vp8_write(w, 1, grpupd);
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+#endif
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ ++ tree_update_hist_8x8 [i][j][k][t] [u];
+#endif
+ if (u)
+ {
+ /* send/use new probability */
+ int delp = remap_prob(newp, *Pold);
+ vp8_encode_term_subexp( w, delp, SUBEXP_PARAM, 255);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void update_coef_probs2(VP8_COMP *cpi)
+{
+ const vp8_prob grpupd = 192;
+ int i, j, k, t;
+ vp8_writer *const w = & cpi->bc;
+ int update[2];
+ int savings;
+ int bestupdndx[2*ENTROPY_NODES];
+
+ vp8_clear_system_state(); //__asm emms;
+ // Build the cofficient contexts based on counts collected in encode loop
+ build_coeff_contexts(cpi);
+
+ for (t = 0; t < ENTROPY_NODES; ++t)
+ {
+ /* dry run to see if there is any udpate at all needed */
+ savings = 0;
+ update[0] = update[1] = 0;
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold) u = 1;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, newp, upd);
+ if (s > 0) u = 1;
+ if (u)
+ savings += s;
+#endif
+ //printf(" %d %d %d: %d\n", i, j, k, u);
+ update[u]++;
+ }
+ }
+ }
+ if (update[1] == 0 || savings < 0)
+ {
+ vp8_write(w, 0, grpupd);
+ continue;
+ }
+ vp8_write(w, 1, grpupd);
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold) u = 1;
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct [i][j][k][t], *Pold, newp, upd);
+ if (s > 0) u = 1;
+#endif
+ //printf(" %d %d %d: %d (%d)\n", i, j, k, u, upd);
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ ++ tree_update_hist [i][j][k][t] [u];
+#endif
+ if (u)
+ { /* send/use new probability */
+ int delp = remap_prob(newp, *Pold);
+ vp8_encode_term_subexp(w, delp, SUBEXP_PARAM, 255);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+
+ if(cpi->common.txfm_mode != ALLOW_8X8) return;
+
+ for (t = 0; t < ENTROPY_NODES; ++t)
+ {
+ /* dry run to see if there is any udpate at all needed */
+ savings = 0;
+ update[0] = update[1] = 0;
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+ if (u)
+ savings += s;
+#endif
+ update[u]++;
+ }
+ }
+ }
+ if (update[1] == 0 || savings < 0)
+ {
+ vp8_write(w, 0, grpupd);
+ continue;
+ }
+ vp8_write(w, 1, grpupd);
+ for (i = 0; i < BLOCK_TYPES; ++i)
+ {
+ for (j = !i; j < COEF_BANDS; ++j)
+ {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+ {
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
+ int s;
+ int u = 0;
+
+#if defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+#else
+ s = prob_update_savings(
+ cpi->frame_branch_ct_8x8 [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+#endif
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ ++ tree_update_hist_8x8 [i][j][k][t] [u];
+#endif
+ if (u)
+ {
+ /* send/use new probability */
+ int delp = remap_prob(newp, *Pold);
+ vp8_encode_term_subexp( w, delp, SUBEXP_PARAM, 255);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
static void update_coef_probs(VP8_COMP *cpi)
{
int i = 0;
vp8_writer *const w = & cpi->bc;
- int update = 0;
+ int update[2] = {0, 0};
+ int savings;
vp8_clear_system_state(); //__asm emms;
// Build the cofficient contexts based on counts collected in encode loop
build_coeff_contexts(cpi);
+ //vp8_prob bestupd = find_coef_update_prob(cpi);
+
/* dry run to see if there is any udpate at all needed */
+ savings = 0;
do
{
- int j = 0;
+#if CONFIG_NEWUPDATE
+ int j = !i;
+#else
+ int j = 0; /* token/prob index */
+#endif
do
{
int k = 0;
int t = 0; /* token/prob index */
do
{
- const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
int s = prev_coef_savings[t];
int u = 0;
+#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
s = prob_update_savings(
cpi->frame_branch_ct [i][j][k][t],
*Pold, newp, upd);
-
if (s > 0)
u = 1;
+ if (u)
+ savings += s;
+#endif
- update += u;
+ update[u]++;
}
while (++t < ENTROPY_NODES);
}
while (++j < COEF_BANDS);
}
while (++i < BLOCK_TYPES);
+
+ //printf("Update %d %d, savings %d\n", update[0], update[1], savings);
/* Is coef updated at all */
- if(update==0)
+#if CONFIG_NEWUPDATE
+ if(update[1] == 0 || savings < 0)
+#else
+ if(update[1] == 0)
+#endif
{
vp8_write_bit(w, 0);
}
i=0;
do
{
- int j = 0;
+#if CONFIG_NEWUPDATE
+ int j = !i;
+#else
+ int j = 0; /* token/prob index */
+#endif
do
{
int k = 0;
int t = 0; /* token/prob index */
do
{
- const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+ vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
int s = prev_coef_savings[t];
int u = 0;
+#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP)
+ s = prob_update_savings_search(
+ cpi->frame_branch_ct [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+#else
s = prob_update_savings(
cpi->frame_branch_ct [i][j][k][t],
*Pold, newp, upd);
-
if (s > 0)
u = 1;
+#endif
+
vp8_write(w, u, upd);
#ifdef ENTROPY_STATS
if (u)
{
/* send/use new probability */
- *Pold = newp;
+#if CONFIG_NEWUPDATE
+ vp8_encode_term_subexp(
+ w, remap_prob(newp, *Pold), SUBEXP_PARAM, 255);
+ //printf("delp = %d/%d/%d\n", *Pold, remap_prob(newp, *Pold, 256), newp);
+#else
vp8_write_literal(w, newp, 8);
+#endif
+ *Pold = newp;
}
}
while (++t < ENTROPY_NODES);
// Accum token counts for generation of default statistics
-#ifdef ENTROPY_STATS
+#if 0//def ENTROPY_STATS
t = 0;
do
{
if(cpi->common.txfm_mode == ALLOW_8X8)
{
/* dry run to see if update is necessary */
- update = 0;
+ update[0] = update[1] = 0;
+ savings = 0;
i = 0;
do
{
- int j = 0;
+#if CONFIG_NEWUPDATE
+ int j = !i;
+#else
+ int j = 0; /* token/prob index */
+#endif
do
{
int k = 0;
do
{
const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
- const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
- const vp8_prob old = *Pold;
+ const vp8_prob oldp = *Pold;
const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
- const int old_b = vp8_cost_branch(ct, old);
- const int new_b = vp8_cost_branch(ct, newp);
- const int update_b = 8 + vp8_cost_upd;
- const int s = old_b - new_b - update_b;
+#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP)
+ const int s = prob_update_savings_search(ct, oldp, &newp, upd);
+ const int u = s > 0 && newp != oldp ? 1 : 0;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ const int s = prob_update_savings(ct, oldp, newp, upd);
const int u = s > 0 ? 1 : 0;
+ if (u)
+ savings += s;
+#endif
#ifdef ENTROPY_STATS
++ tree_update_hist_8x8 [i][j][k][t] [u];
#endif
- update += u;
+ update[u]++;
}
while (++t < MAX_ENTROPY_TOKENS - 1);
// Accum token counts for generation of default statistics
-#ifdef ENTROPY_STATS
+#if 0//def ENTROPY_STATS
t = 0;
do
{
context_counters_8x8 [i][j][k][t] += cpi->coef_counts_8x8 [i][j][k][t];
}
- while (++t < MAX_ENTROPY_TOKENS);
+ while (++t < MAX_ENTROPY_TOKENS - 1);
#endif
}
}
while (++i < BLOCK_TYPES);
- if(update == 0)
+#if CONFIG_NEWUPDATE
+ if (update[1] == 0 || savings < 0)
+#else
+ if (update[1] == 0)
+#endif
{
vp8_write_bit(w, 0);
-
}
else
{
i = 0;
do
{
- int j = 0;
+#if CONFIG_NEWUPDATE
+ int j = !i;
+#else
+ int j = 0; /* token/prob index */
+#endif
do
{
int k = 0;
do
{
const unsigned int *ct = cpi->frame_branch_ct_8x8 [i][j][k][t];
- const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
+ vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
vp8_prob *Pold = cpi->common.fc.coef_probs_8x8 [i][j][k] + t;
- const vp8_prob old = *Pold;
+ const vp8_prob oldp = *Pold;
const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
- const int old_b = vp8_cost_branch(ct, old);
- const int new_b = vp8_cost_branch(ct, newp);
- const int update_b = 8 + vp8_cost_upd;
- const int s = old_b - new_b - update_b;
+#if CONFIG_NEWUPDATE && defined(SEARCH_NEWP)
+ const int s = prob_update_savings_search(ct, oldp, &newp, upd);
+ const int u = s > 0 && newp != oldp ? 1 : 0;
+#else
+ const int s = prob_update_savings(ct, oldp, newp, upd);
const int u = s > 0 ? 1 : 0;
+#endif
vp8_write(w, u, upd);
#ifdef ENTROPY_STATS
++ tree_update_hist_8x8 [i][j][k][t] [u];
if (u)
{
/* send/use new probability */
- *Pold = newp;
+#if CONFIG_NEWUPDATE
+ vp8_encode_term_subexp(
+ w, remap_prob(newp, oldp), SUBEXP_PARAM, 255);
+#else
vp8_write_literal(w, newp, 8);
+#endif
+ *Pold = newp;
}
}
while (++t < MAX_ENTROPY_TOKENS - 1);
// Accum token counts for generation of default statistics
-#ifdef ENTROPY_STATS
+#if 0//def ENTROPY_STATS
t = 0;
do
{
}
}
}
+
#ifdef PACKET_TESTING
FILE *vpxlogc = 0;
#endif
Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
#endif
+#if CONFIG_NEWUPDATE
+ compute_update_table();
+#endif
+
//vp8_kf_default_bmode_probs() is called in vp8_setup_key_frame() once for each
//K frame before encode frame. pc->kf_bmode_prob doesn't get changed anywhere
//else. No need to call it again here. --yw
vp8_clear_system_state(); //__asm emms;
+#if COEFUPDATETYPE == 2
+ update_coef_probs2(cpi);
+#elif COEFUPDATETYPE == 3
+ update_coef_probs3(cpi);
+#else
update_coef_probs(cpi);
+#endif
#ifdef ENTROPY_STATS
active_section = 2;