summaryrefslogtreecommitdiff
path: root/vp8/encoder/bitstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder/bitstream.c')
-rw-r--r--vp8/encoder/bitstream.c350
1 files changed, 342 insertions, 8 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index a4df16fee..2f748015f 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -45,15 +45,33 @@ unsigned int tree_update_hist [BLOCK_TYPES]
[COEF_BANDS]
[PREV_COEF_CONTEXTS]
[ENTROPY_NODES][2];
+#if CONFIG_HYBRIDTRANSFORM
+unsigned int hybrid_tree_update_hist [BLOCK_TYPES]
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [ENTROPY_NODES][2];
+#endif
unsigned int tree_update_hist_8x8 [BLOCK_TYPES_8X8]
[COEF_BANDS]
[PREV_COEF_CONTEXTS]
[ENTROPY_NODES] [2];
-#if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16
+#if CONFIG_HYBRIDTRANSFORM8X8
+unsigned int hybrid_tree_update_hist_8x8 [BLOCK_TYPES_8X8]
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [ENTROPY_NODES] [2];
+#endif
+#if CONFIG_TX16X16
unsigned int tree_update_hist_16x16 [BLOCK_TYPES_16X16]
[COEF_BANDS]
[PREV_COEF_CONTEXTS]
[ENTROPY_NODES] [2];
+#if CONFIG_HYBRIDTRANSFORM16X16
+unsigned int hybrid_tree_update_hist_16x16 [BLOCK_TYPES_16X16]
+ [COEF_BANDS]
+ [PREV_COEF_CONTEXTS]
+ [ENTROPY_NODES] [2];
+#endif
#endif
extern unsigned int active_section;
@@ -1522,6 +1540,28 @@ void build_coeff_contexts(VP8_COMP *cpi) {
}
}
}
+#if CONFIG_HYBRIDTRANSFORM
+ for (i = 0; i < BLOCK_TYPES; ++i) {
+ for (j = 0; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+ vp8_tree_probs_from_distribution(
+ MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ cpi->frame_hybrid_coef_probs [i][j][k],
+ cpi->frame_hybrid_branch_ct [i][j][k],
+ cpi->hybrid_coef_counts [i][j][k],
+ 256, 1
+ );
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
+ hybrid_context_counters[i][j][k][t] += cpi->hybrid_coef_counts[i][j][k][t];
+#endif
+ }
+ }
+ }
+#endif
if (cpi->common.txfm_mode == ALLOW_8X8) {
@@ -1549,9 +1589,35 @@ void build_coeff_contexts(VP8_COMP *cpi) {
}
}
}
+#if CONFIG_HYBRIDTRANSFORM8X8
+ for (i = 0; i < BLOCK_TYPES_8X8; ++i) {
+ for (j = 0; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ /* at every context */
+ /* calc probs and branch cts for this frame only */
+ // vp8_prob new_p [ENTROPY_NODES];
+ // unsigned int branch_ct [ENTROPY_NODES] [2];
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+ vp8_tree_probs_from_distribution(
+ MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ cpi->frame_hybrid_coef_probs_8x8 [i][j][k],
+ cpi->frame_hybrid_branch_ct_8x8 [i][j][k],
+ cpi->hybrid_coef_counts_8x8 [i][j][k],
+ 256, 1
+ );
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
+ hybrid_context_counters_8x8[i][j][k][t] += cpi->hybrid_coef_counts_8x8[i][j][k][t];
+#endif
+ }
+ }
+ }
+#endif
}
-#if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16
+#if CONFIG_TX16X16
//16x16
for (i = 0; i < BLOCK_TYPES_16X16; ++i) {
for (j = 0; j < COEF_BANDS; ++j) {
@@ -1571,9 +1637,30 @@ void build_coeff_contexts(VP8_COMP *cpi) {
}
}
}
+#if CONFIG_HYBRIDTRANSFORM16X16
+ for (i = 0; i < BLOCK_TYPES_16X16; ++i) {
+ for (j = 0; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+ vp8_tree_probs_from_distribution(
+ MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+ cpi->frame_hybrid_coef_probs_16x16[i][j][k],
+ cpi->frame_hybrid_branch_ct_16x16[i][j][k],
+ cpi->hybrid_coef_counts_16x16[i][j][k], 256, 1);
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ for (t = 0; t < MAX_ENTROPY_TOKENS; ++t)
+ hybrid_context_counters_16x16[i][j][k][t] += cpi->hybrid_coef_counts_16x16[i][j][k][t];
+#endif
+ }
+ }
+ }
+#endif
#endif
}
+#if 0
static void update_coef_probs2(VP8_COMP *cpi) {
const vp8_prob grpupd = 192;
int i, j, k, t;
@@ -1741,6 +1828,7 @@ static void update_coef_probs2(VP8_COMP *cpi) {
}
}
}
+#endif
static void update_coef_probs(VP8_COMP *cpi) {
int i, j, k, t;
@@ -1844,6 +1932,96 @@ static void update_coef_probs(VP8_COMP *cpi) {
}
}
+#if CONFIG_HYBRIDTRANSFORM
+ savings = 0;
+ update[0] = update[1] = 0;
+ for (i = 0; i < BLOCK_TYPES; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ int prev_coef_savings[ENTROPY_NODES] = {0};
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ vp8_prob newp = cpi->frame_hybrid_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs [i][j][k] + t;
+ const vp8_prob upd = COEF_UPDATE_PROB;
+ int s = prev_coef_savings[t];
+ int u = 0;
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(
+ cpi->frame_hybrid_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_hybrid_branch_ct [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+ if (u)
+ savings += s;
+#endif
+
+ update[u]++;
+ }
+ }
+ }
+ }
+
+ // printf("Update %d %d, savings %d\n", update[0], update[1], savings);
+ /* Is coef updated at all */
+ if (update[1] == 0 || savings < 0)
+ vp8_write_bit(w, 0);
+ else {
+ vp8_write_bit(w, 1);
+ for (i = 0; i < BLOCK_TYPES; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ int prev_coef_savings[ENTROPY_NODES] = {0};
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ // calc probs and branch cts for this frame only
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ vp8_prob newp = cpi->frame_hybrid_coef_probs [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs [i][j][k] + t;
+ const vp8_prob upd = COEF_UPDATE_PROB;
+ int s = prev_coef_savings[t];
+ int u = 0;
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(
+ cpi->frame_hybrid_branch_ct [i][j][k][t],
+ *Pold, &newp, upd);
+ if (s > 0 && newp != *Pold)
+ u = 1;
+#else
+ s = prob_update_savings(
+ cpi->frame_hybrid_branch_ct [i][j][k][t],
+ *Pold, newp, upd);
+ if (s > 0)
+ u = 1;
+#endif
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ ++ hybrid_tree_update_hist [i][j][k][t] [u];
+#endif
+ if (u) {
+ /* send/use new probability */
+ write_prob_diff_update(w, newp, *Pold);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
/* do not do this if not even allowed */
if (cpi->common.txfm_mode == ALLOW_8X8) {
@@ -1921,9 +2099,84 @@ static void update_coef_probs(VP8_COMP *cpi) {
}
}
}
+#if CONFIG_HYBRIDTRANSFORM8X8
+ update[0] = update[1] = 0;
+ savings = 0;
+ for (i = 0; i < BLOCK_TYPES_8X8; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ // calc probs and branch cts for this frame only
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ const unsigned int *ct = cpi->frame_hybrid_branch_ct_8x8 [i][j][k][t];
+ vp8_prob newp = cpi->frame_hybrid_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob oldp = *Pold;
+ int s, u;
+ const vp8_prob upd = COEF_UPDATE_PROB_8X8;
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(ct, oldp, &newp, upd);
+ u = s > 0 && newp != oldp ? 1 : 0;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(ct, oldp, newp, upd);
+ u = s > 0 ? 1 : 0;
+ if (u)
+ savings += s;
+#endif
+ update[u]++;
+ }
+ }
+ }
+ }
+
+ if (update[1] == 0 || savings < 0)
+ vp8_write_bit(w, 0);
+ else {
+ vp8_write_bit(w, 1);
+ for (i = 0; i < BLOCK_TYPES_8X8; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ const unsigned int *ct = cpi->frame_hybrid_branch_ct_8x8 [i][j][k][t];
+ vp8_prob newp = cpi->frame_hybrid_coef_probs_8x8 [i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs_8x8 [i][j][k] + t;
+ const vp8_prob oldp = *Pold;
+ const vp8_prob upd = COEF_UPDATE_PROB_8X8;
+ int s, u;
+ if (k >= 3 && ((i == 0 && j == 1) ||
+ (i > 0 && j == 0)))
+ continue;
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(ct, oldp, &newp, upd);
+ u = s > 0 && newp != oldp ? 1 : 0;
+#else
+ s = prob_update_savings(ct, oldp, newp, upd);
+ u = s > 0 ? 1 : 0;
+#endif
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ ++ hybrid_tree_update_hist_8x8 [i][j][k][t] [u];
+#endif
+ if (u) {
+ /* send/use new probability */
+ write_prob_diff_update(w, newp, oldp);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
}
-#if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16
+#if CONFIG_TX16X16
// 16x16
/* dry run to see if update is necessary */
update[0] = update[1] = 0;
@@ -1999,6 +2252,81 @@ static void update_coef_probs(VP8_COMP *cpi) {
}
}
}
+#if CONFIG_HYBRIDTRANSFORM16X16
+ update[0] = update[1] = 0;
+ savings = 0;
+ for (i = 0; i < BLOCK_TYPES_16X16; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ // calc probs and branch cts for this frame only
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ const unsigned int *ct = cpi->frame_hybrid_branch_ct_16x16[i][j][k][t];
+ vp8_prob newp = cpi->frame_hybrid_coef_probs_16x16[i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs_16x16[i][j][k] + t;
+ const vp8_prob oldp = *Pold;
+ int s, u;
+ const vp8_prob upd = COEF_UPDATE_PROB_16X16;
+ if (k >= 3 && ((i == 0 && j == 1) || (i > 0 && j == 0)))
+ continue;
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(ct, oldp, &newp, upd);
+ u = s > 0 && newp != oldp ? 1 : 0;
+ if (u)
+ savings += s - (int)(vp8_cost_zero(upd));
+ else
+ savings -= (int)(vp8_cost_zero(upd));
+#else
+ s = prob_update_savings(ct, oldp, newp, upd);
+ u = s > 0 ? 1 : 0;
+ if (u)
+ savings += s;
+#endif
+ update[u]++;
+ }
+ }
+ }
+ }
+
+ if (update[1] == 0 || savings < 0)
+ vp8_write_bit(w, 0);
+ else {
+ vp8_write_bit(w, 1);
+ for (i = 0; i < BLOCK_TYPES_16X16; ++i) {
+ for (j = !i; j < COEF_BANDS; ++j) {
+ for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
+ for (t = 0; t < ENTROPY_NODES; ++t) {
+ const unsigned int *ct = cpi->frame_hybrid_branch_ct_16x16[i][j][k][t];
+ vp8_prob newp = cpi->frame_hybrid_coef_probs_16x16[i][j][k][t];
+ vp8_prob *Pold = cpi->common.fc.hybrid_coef_probs_16x16[i][j][k] + t;
+ const vp8_prob oldp = *Pold;
+ const vp8_prob upd = COEF_UPDATE_PROB_16X16;
+ int s, u;
+ if (k >= 3 && ((i == 0 && j == 1) ||
+ (i > 0 && j == 0)))
+ continue;
+#if defined(SEARCH_NEWP)
+ s = prob_diff_update_savings_search(ct, oldp, &newp, upd);
+ u = s > 0 && newp != oldp ? 1 : 0;
+#else
+ s = prob_update_savings(ct, oldp, newp, upd);
+ u = s > 0 ? 1 : 0;
+#endif
+ vp8_write(w, u, upd);
+#ifdef ENTROPY_STATS
+ if (!cpi->dummy_packing)
+ ++hybrid_tree_update_hist_16x16[i][j][k][t][u];
+#endif
+ if (u) {
+ /* send/use new probability */
+ write_prob_diff_update(w, newp, oldp);
+ *Pold = newp;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
#endif
}
@@ -2432,9 +2760,18 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
vp8_clear_system_state(); // __asm emms;
vp8_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs);
+#if CONFIG_HYBRIDTRANSFORM
+ vp8_copy(cpi->common.fc.pre_hybrid_coef_probs, cpi->common.fc.hybrid_coef_probs);
+#endif
vp8_copy(cpi->common.fc.pre_coef_probs_8x8, cpi->common.fc.coef_probs_8x8);
-#if CONFIG_TX16X16 || CONFIG_HYBRIDTRANSFORM16X16
+#if CONFIG_HYBRIDTRANSFORM8X8
+ vp8_copy(cpi->common.fc.pre_hybrid_coef_probs_8x8, cpi->common.fc.hybrid_coef_probs_8x8);
+#endif
+#if CONFIG_TX16X16
vp8_copy(cpi->common.fc.pre_coef_probs_16x16, cpi->common.fc.coef_probs_16x16);
+#if CONFIG_HYBRIDTRANSFORM16X16
+ vp8_copy(cpi->common.fc.pre_hybrid_coef_probs_16x16, cpi->common.fc.hybrid_coef_probs_16x16);
+#endif
#endif
vp8_copy(cpi->common.fc.pre_ymode_prob, cpi->common.fc.ymode_prob);
vp8_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob);
@@ -2452,11 +2789,8 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
vp8_zero(cpi->mbsplit_count);
vp8_zero(cpi->common.fc.mv_ref_ct)
vp8_zero(cpi->common.fc.mv_ref_ct_a)
-#if COEFUPDATETYPE == 2
- update_coef_probs2(cpi);
-#else
+
update_coef_probs(cpi);
-#endif
#ifdef ENTROPY_STATS
active_section = 2;