diff options
Diffstat (limited to 'vp8/encoder/bitstream.c')
-rw-r--r-- | vp8/encoder/bitstream.c | 350 |
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; |