| Index: source/libvpx/vp8/encoder/bitstream.c | 
| =================================================================== | 
| --- source/libvpx/vp8/encoder/bitstream.c	(revision 96967) | 
| +++ source/libvpx/vp8/encoder/bitstream.c	(working copy) | 
| @@ -17,9 +17,12 @@ | 
| #include "vp8/common/systemdependent.h" | 
| #include <assert.h> | 
| #include <stdio.h> | 
| +#include <limits.h> | 
| #include "vp8/common/pragmas.h" | 
| +#include "vpx/vpx_encoder.h" | 
| #include "vpx_mem/vpx_mem.h" | 
| #include "bitstream.h" | 
| +#include "vp8/common/defaultcoefcounts.h" | 
|  | 
| const int vp8cx_base_skip_false_prob[128] = | 
| { | 
| @@ -40,9 +43,6 @@ | 
| 53,  50,  47,  44,  41,  38,  35, 32, | 
| 30,  28,  26,  24,  22,  20,  18, 16, | 
| }; | 
| -#ifdef VP8REF | 
| -#define __int64 long long | 
| -#endif | 
|  | 
| #if defined(SECTIONBITS_OUTPUT) | 
| unsigned __int64 Sectionbits[500]; | 
| @@ -50,7 +50,7 @@ | 
|  | 
| #ifdef ENTROPY_STATS | 
| int intra_mode_stats[10][10][10]; | 
| -static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] [2]; | 
| +static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] [2]; | 
| extern unsigned int active_section; | 
| #endif | 
|  | 
| @@ -158,18 +158,6 @@ | 
| ); | 
| } | 
|  | 
| -static const unsigned int norm[256] = | 
| -{ | 
| -    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 
| -    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 
| -    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 
| -    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 
| -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
| -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
| -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 
| -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 
| -}; | 
| - | 
| static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) | 
| { | 
| const TOKENEXTRA *const stop = p + xcount; | 
| @@ -211,7 +199,7 @@ | 
| range = split; | 
| } | 
|  | 
| -            shift = norm[range]; | 
| +            shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -271,7 +259,7 @@ | 
| range = split; | 
| } | 
|  | 
| -                    shift = norm[range]; | 
| +                    shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -377,6 +365,7 @@ | 
| unsigned int shift; | 
| vp8_writer *w = &cpi->bc2; | 
| *size = 3 * (num_part - 1); | 
| +    cpi->partition_sz[0] += *size; | 
| ptr = cx_data + (*size); | 
|  | 
| for (i = 0; i < num_part; i++) | 
| @@ -426,7 +415,7 @@ | 
| range = split; | 
| } | 
|  | 
| -                        shift = norm[range]; | 
| +                        shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -486,7 +475,7 @@ | 
| range = split; | 
| } | 
|  | 
| -                                shift = norm[range]; | 
| +                                shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -573,6 +562,9 @@ | 
| vp8_stop_encode(w); | 
| *size +=   w->pos; | 
|  | 
| +        /* The first partition size is set earlier */ | 
| +        cpi->partition_sz[i + 1] = w->pos; | 
| + | 
| if (i < (num_part - 1)) | 
| { | 
| write_partition_size(cx_data, w->pos); | 
| @@ -630,7 +622,7 @@ | 
| range = split; | 
| } | 
|  | 
| -                shift = norm[range]; | 
| +                shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -690,7 +682,7 @@ | 
| range = split; | 
| } | 
|  | 
| -                        shift = norm[range]; | 
| +                        shift = vp8_norm[range]; | 
| range <<= shift; | 
| count += shift; | 
|  | 
| @@ -779,9 +771,9 @@ | 
| vp8_writer *w, MB_PREDICTION_MODE m, const vp8_prob *p | 
| ) | 
| { | 
| - | 
| +#if CONFIG_DEBUG | 
| assert(NEARESTMV <= m  &&  m <= SPLITMV); | 
| - | 
| +#endif | 
| vp8_write_token(w, vp8_mv_ref_tree, p, | 
| vp8_mv_ref_encoding_array - NEARESTMV + m); | 
| } | 
| @@ -791,20 +783,21 @@ | 
| vp8_writer *w, B_PREDICTION_MODE m, const vp8_prob *p | 
| ) | 
| { | 
| +#if CONFIG_DEBUG | 
| assert(LEFT4X4 <= m  &&  m <= NEW4X4); | 
| - | 
| +#endif | 
| vp8_write_token(w, vp8_sub_mv_ref_tree, p, | 
| vp8_sub_mv_ref_encoding_array - LEFT4X4 + m); | 
| } | 
|  | 
| static void write_mv | 
| ( | 
| -    vp8_writer *w, const MV *mv, const MV *ref, const MV_CONTEXT *mvc | 
| +    vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT *mvc | 
| ) | 
| { | 
| MV e; | 
| -    e.row = mv->row - ref->row; | 
| -    e.col = mv->col - ref->col; | 
| +    e.row = mv->row - ref->as_mv.row; | 
| +    e.col = mv->col - ref->as_mv.col; | 
|  | 
| vp8_encode_motion_vector(w, &e, mvc); | 
| } | 
| @@ -948,8 +941,7 @@ | 
| int j = 0; | 
|  | 
| do | 
| -                        write_bmode(w, m->bmi[j].mode, pc->fc.bmode_prob); | 
| - | 
| +                        write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob); | 
| while (++j < 16); | 
| } | 
|  | 
| @@ -957,7 +949,7 @@ | 
| } | 
| else    /* inter coded */ | 
| { | 
| -                MV best_mv; | 
| +                int_mv best_mv; | 
| vp8_prob mv_ref_p [VP8_MVREFS-1]; | 
|  | 
| vp8_write(w, 1, cpi->prob_intra_coded); | 
| @@ -971,7 +963,7 @@ | 
| } | 
|  | 
| { | 
| -                    MV n1, n2; | 
| +                    int_mv n1, n2; | 
| int ct[4]; | 
|  | 
| vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf, cpi->common.ref_frame_sign_bias); | 
| @@ -1012,26 +1004,34 @@ | 
|  | 
| do | 
| { | 
| -                        const B_MODE_INFO *const b = cpi->mb.partition_info->bmi + j; | 
| +                        B_PREDICTION_MODE blockmode; | 
| +                        int_mv blockmv; | 
| const int *const  L = vp8_mbsplits [mi->partitioning]; | 
| int k = -1;  /* first block in subset j */ | 
| int mv_contz; | 
| +                        int_mv leftmv, abovemv; | 
|  | 
| +                        blockmode =  cpi->mb.partition_info->bmi[j].mode; | 
| +                        blockmv =  cpi->mb.partition_info->bmi[j].mv; | 
| +#if CONFIG_DEBUG | 
| while (j != L[++k]) | 
| if (k >= 16) | 
| assert(0); | 
| +#else | 
| +                        while (j != L[++k]); | 
| +#endif | 
| +                        leftmv.as_int = left_block_mv(m, k); | 
| +                        abovemv.as_int = above_block_mv(m, k, mis); | 
| +                        mv_contz = vp8_mv_cont(&leftmv, &abovemv); | 
|  | 
| -                        mv_contz = vp8_mv_cont | 
| -                                   (&(vp8_left_bmi(m, k)->mv.as_mv), | 
| -                                    &(vp8_above_bmi(m, k, mis)->mv.as_mv)); | 
| -                        write_sub_mv_ref(w, b->mode, vp8_sub_mv_ref_prob2 [mv_contz]); //pc->fc.sub_mv_ref_prob); | 
| +                        write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2 [mv_contz]); | 
|  | 
| -                        if (b->mode == NEW4X4) | 
| +                        if (blockmode == NEW4X4) | 
| { | 
| #ifdef ENTROPY_STATS | 
| active_section = 11; | 
| #endif | 
| -                            write_mv(w, &b->mv.as_mv, &best_mv, (const MV_CONTEXT *) mvc); | 
| +                            write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc); | 
| } | 
| } | 
| while (++j < cpi->mb.partition_info->count); | 
| @@ -1099,9 +1099,9 @@ | 
|  | 
| do | 
| { | 
| -                    const B_PREDICTION_MODE A = vp8_above_bmi(m, i, mis)->mode; | 
| -                    const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode; | 
| -                    const int bm = m->bmi[i].mode; | 
| +                    const B_PREDICTION_MODE A = above_block_mode(m, i, mis); | 
| +                    const B_PREDICTION_MODE L = left_block_mode(m, i); | 
| +                    const int bm = m->bmi[i].as_mode; | 
|  | 
| #ifdef ENTROPY_STATS | 
| ++intra_mode_stats [A] [L] [bm]; | 
| @@ -1118,11 +1118,203 @@ | 
| m++;    // skip L prediction border | 
| } | 
| } | 
| -int vp8_estimate_entropy_savings(VP8_COMP *cpi) | 
| + | 
| +/* This function is used for debugging probability trees. */ | 
| +static void print_prob_tree(vp8_prob | 
| +     coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) | 
| { | 
| +    /* print coef probability tree */ | 
| +    int i,j,k,l; | 
| +    FILE* f = fopen("enc_tree_probs.txt", "a"); | 
| +    fprintf(f, "{\n"); | 
| +    for (i = 0; i < BLOCK_TYPES; i++) | 
| +    { | 
| +        fprintf(f, "  {\n"); | 
| +        for (j = 0; j < COEF_BANDS; j++) | 
| +        { | 
| +            fprintf(f, "    {\n"); | 
| +            for (k = 0; k < PREV_COEF_CONTEXTS; k++) | 
| +            { | 
| +                fprintf(f, "      {"); | 
| +                for (l = 0; l < ENTROPY_NODES; l++) | 
| +                { | 
| +                    fprintf(f, "%3u, ", | 
| +                            (unsigned int)(coef_probs [i][j][k][l])); | 
| +                } | 
| +                fprintf(f, " }\n"); | 
| +            } | 
| +            fprintf(f, "    }\n"); | 
| +        } | 
| +        fprintf(f, "  }\n"); | 
| +    } | 
| +    fprintf(f, "}\n"); | 
| +    fclose(f); | 
| +} | 
| + | 
| +static void sum_probs_over_prev_coef_context( | 
| +        const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], | 
| +        unsigned int* out) | 
| +{ | 
| +    int i, j; | 
| +    for (i=0; i < MAX_ENTROPY_TOKENS; ++i) | 
| +    { | 
| +        for (j=0; j < PREV_COEF_CONTEXTS; ++j) | 
| +        { | 
| +            const int tmp = out[i]; | 
| +            out[i] += probs[j][i]; | 
| +            /* check for wrap */ | 
| +            if (out[i] < tmp) | 
| +                out[i] = UINT_MAX; | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +static int prob_update_savings(const unsigned int *ct, | 
| +                                   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_one(upd) - vp8_cost_zero(upd)) >> 8); | 
| + | 
| +    return old_b - new_b - update_b; | 
| +} | 
| + | 
| +static int independent_coef_context_savings(VP8_COMP *cpi) | 
| +{ | 
| +    int savings = 0; | 
| int i = 0; | 
| +    do | 
| +    { | 
| +        int j = 0; | 
| +        do | 
| +        { | 
| +            int k = 0; | 
| +            unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = {0}; | 
| +            int prev_coef_savings[MAX_ENTROPY_TOKENS] = {0}; | 
| +            /* Calculate new probabilities given the constraint that | 
| +             * they must be equal over the prev coef contexts | 
| +             */ | 
| +            if (cpi->common.frame_type == KEY_FRAME) | 
| +            { | 
| +                /* Reset to default probabilities at key frames */ | 
| +                sum_probs_over_prev_coef_context(vp8_default_coef_counts[i][j], | 
| +                                                 prev_coef_count_sum); | 
| +            } | 
| +            else | 
| +            { | 
| +                sum_probs_over_prev_coef_context(cpi->coef_counts[i][j], | 
| +                                                 prev_coef_count_sum); | 
| +            } | 
| +            do | 
| +            { | 
| +                /* 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]; | 
| + | 
| +                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], | 
| +                    cpi->frame_branch_ct [i][j][k], | 
| +                    prev_coef_count_sum, | 
| +                    256, 1); | 
| + | 
| +                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]; | 
| +                    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]; | 
| +                    const int s = prob_update_savings(ct, oldp, newp, upd); | 
| + | 
| +                    if (cpi->common.frame_type != KEY_FRAME || | 
| +                        (cpi->common.frame_type == KEY_FRAME && newp != oldp)) | 
| +                        prev_coef_savings[t] += s; | 
| +                } | 
| +                while (++t < ENTROPY_NODES); | 
| +            } | 
| +            while (++k < PREV_COEF_CONTEXTS); | 
| +            k = 0; | 
| +            do | 
| +            { | 
| +                /* We only update probabilities if we can save bits, except | 
| +                 * for key frames where we have to update all probabilities | 
| +                 * to get the equal probabilities across the prev coef | 
| +                 * contexts. | 
| +                 */ | 
| +                if (prev_coef_savings[k] > 0 || | 
| +                    cpi->common.frame_type == KEY_FRAME) | 
| +                    savings += prev_coef_savings[k]; | 
| +            } | 
| +            while (++k < ENTROPY_NODES); | 
| +        } | 
| +        while (++j < COEF_BANDS); | 
| +    } | 
| +    while (++i < BLOCK_TYPES); | 
| +    return savings; | 
| +} | 
| + | 
| +static int default_coef_context_savings(VP8_COMP *cpi) | 
| +{ | 
| int savings = 0; | 
| +    int i = 0; | 
| +    do | 
| +    { | 
| +        int j = 0; | 
| +        do | 
| +        { | 
| +            int k = 0; | 
| +            do | 
| +            { | 
| +                /* 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]; | 
| + | 
| +                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], | 
| +                    cpi->frame_branch_ct [i][j][k], | 
| +                    cpi->coef_counts [i][j][k], | 
| +                    256, 1 | 
| +                ); | 
| + | 
| +                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]; | 
| +                    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]; | 
| +                    const int s = prob_update_savings(ct, oldp, newp, upd); | 
| + | 
| +                    if (s > 0) | 
| +                    { | 
| +                        savings += s; | 
| +                    } | 
| +                } | 
| +                while (++t < ENTROPY_NODES); | 
| +            } | 
| +            while (++k < PREV_COEF_CONTEXTS); | 
| +        } | 
| +        while (++j < COEF_BANDS); | 
| +    } | 
| +    while (++i < BLOCK_TYPES); | 
| +    return savings; | 
| +} | 
| + | 
| +int vp8_estimate_entropy_savings(VP8_COMP *cpi) | 
| +{ | 
| +    int savings = 0; | 
| + | 
| const int *const rfct = cpi->count_mb_ref_frame_usage; | 
| const int rf_intra = rfct[INTRA_FRAME]; | 
| const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; | 
| @@ -1180,61 +1372,12 @@ | 
| } | 
|  | 
|  | 
| -    do | 
| -    { | 
| -        int j = 0; | 
| +    if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) | 
| +        savings += independent_coef_context_savings(cpi); | 
| +    else | 
| +        savings += default_coef_context_savings(cpi); | 
|  | 
| -        do | 
| -        { | 
| -            int k = 0; | 
|  | 
| -            do | 
| -            { | 
| -                /* at every context */ | 
| - | 
| -                /* calc probs and branch cts for this frame only */ | 
| -                //vp8_prob new_p           [vp8_coef_tokens-1]; | 
| -                //unsigned int branch_ct   [vp8_coef_tokens-1] [2]; | 
| - | 
| -                int t = 0;      /* token/prob index */ | 
| - | 
| -                vp8_tree_probs_from_distribution( | 
| -                    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree, | 
| -                    cpi->frame_coef_probs [i][j][k], cpi->frame_branch_ct [i][j][k], cpi->coef_counts [i][j][k], | 
| -                    256, 1 | 
| -                ); | 
| - | 
| -                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]; | 
| - | 
| -                    const vp8_prob old = cpi->common.fc.coef_probs [i][j][k][t]; | 
| -                    const vp8_prob upd = vp8_coef_update_probs [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_one(upd) - vp8_cost_zero(upd)) >> 8); | 
| - | 
| -                    const int s = old_b - new_b - update_b; | 
| - | 
| -                    if (s > 0) | 
| -                        savings += s; | 
| - | 
| - | 
| -                } | 
| -                while (++t < vp8_coef_tokens - 1); | 
| - | 
| - | 
| -            } | 
| -            while (++k < PREV_COEF_CONTEXTS); | 
| -        } | 
| -        while (++j < COEF_BANDS); | 
| -    } | 
| -    while (++i < BLOCK_TYPES); | 
| - | 
| return savings; | 
| } | 
|  | 
| @@ -1246,7 +1389,6 @@ | 
|  | 
| vp8_clear_system_state(); //__asm emms; | 
|  | 
| - | 
| do | 
| { | 
| int j = 0; | 
| @@ -1254,42 +1396,74 @@ | 
| do | 
| { | 
| int k = 0; | 
| +            int prev_coef_savings[ENTROPY_NODES] = {0}; | 
| +            if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) | 
| +            { | 
| +                for (k = 0; k < PREV_COEF_CONTEXTS; ++k) | 
| +                { | 
| +                    int t;      /* token/prob index */ | 
| +                    for (t = 0; t < ENTROPY_NODES; ++t) | 
| +                    { | 
| +                        const unsigned int *ct = cpi->frame_branch_ct [i][j] | 
| +                                                                      [k][t]; | 
| +                        const 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]; | 
|  | 
| +                        prev_coef_savings[t] += | 
| +                                prob_update_savings(ct, oldp, newp, upd); | 
| +                    } | 
| +                } | 
| +                k = 0; | 
| +            } | 
| do | 
| { | 
| //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here. | 
| /* at every context */ | 
|  | 
| /* calc probs and branch cts for this frame only */ | 
| -                //vp8_prob new_p           [vp8_coef_tokens-1]; | 
| -                //unsigned int branch_ct   [vp8_coef_tokens-1] [2]; | 
| +                //vp8_prob new_p           [ENTROPY_NODES]; | 
| +                //unsigned int branch_ct   [ENTROPY_NODES] [2]; | 
|  | 
| int t = 0;      /* token/prob index */ | 
|  | 
| //vp8_tree_probs_from_distribution( | 
| -                //    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree, | 
| +                //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, | 
| //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k], | 
| //    256, 1 | 
| //    ); | 
|  | 
| 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 *Pold = cpi->common.fc.coef_probs [i][j][k] + t; | 
| -                    const vp8_prob old = *Pold; | 
| const vp8_prob upd = vp8_coef_update_probs [i][j][k][t]; | 
|  | 
| -                    const int old_b = vp8_cost_branch(ct, old); | 
| -                    const int new_b = vp8_cost_branch(ct, newp); | 
| +                    int s = prev_coef_savings[t]; | 
| +                    int u = 0; | 
|  | 
| -                    const int update_b = 8 + | 
| -                                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8); | 
| +                    if (!(cpi->oxcf.error_resilient_mode & | 
| +                            VPX_ERROR_RESILIENT_PARTITIONS)) | 
| +                    { | 
| +                        s = prob_update_savings( | 
| +                                cpi->frame_branch_ct [i][j][k][t], | 
| +                                *Pold, newp, upd); | 
| +                    } | 
|  | 
| -                    const int s = old_b - new_b - update_b; | 
| -                    const int u = s > 0 ? 1 : 0; | 
| +                    if (s > 0) | 
| +                        u = 1; | 
|  | 
| +                    /* Force updates on key frames if the new is different, | 
| +                     * so that we can be sure we end up with equal probabilities | 
| +                     * over the prev coef contexts. | 
| +                     */ | 
| +                    if ((cpi->oxcf.error_resilient_mode & | 
| +                            VPX_ERROR_RESILIENT_PARTITIONS) && | 
| +                        cpi->common.frame_type == KEY_FRAME && newp != *Pold) | 
| +                        u = 1; | 
| + | 
| vp8_write(w, u, upd); | 
|  | 
|  | 
| @@ -1309,7 +1483,7 @@ | 
| } | 
|  | 
| } | 
| -                while (++t < vp8_coef_tokens - 1); | 
| +                while (++t < ENTROPY_NODES); | 
|  | 
| /* Accum token counts for generation of default statistics */ | 
| #ifdef ENTROPY_STATS | 
| @@ -1319,7 +1493,7 @@ | 
| { | 
| context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t]; | 
| } | 
| -                while (++t < vp8_coef_tokens); | 
| +                while (++t < MAX_ENTROPY_TOKENS); | 
|  | 
| #endif | 
|  | 
| @@ -1585,6 +1759,14 @@ | 
| vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]); | 
| } | 
|  | 
| +    if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) | 
| +    { | 
| +        if (pc->frame_type == KEY_FRAME) | 
| +            pc->refresh_entropy_probs = 1; | 
| +        else | 
| +            pc->refresh_entropy_probs = 0; | 
| +    } | 
| + | 
| vp8_write_bit(bc, pc->refresh_entropy_probs); | 
|  | 
| if (pc->frame_type != KEY_FRAME) | 
| @@ -1650,6 +1832,7 @@ | 
| } | 
|  | 
| *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc.pos; | 
| +    cpi->partition_sz[0] = *size; | 
|  | 
| if (pc->multi_token_partition != ONE_PARTITION) | 
| { | 
| @@ -1675,6 +1858,7 @@ | 
| vp8_stop_encode(&cpi->bc2); | 
|  | 
| *size += cpi->bc2.pos; | 
| +        cpi->partition_sz[1] = cpi->bc2.pos; | 
| } | 
| } | 
|  | 
| @@ -1685,7 +1869,7 @@ | 
| FILE *f = fopen("context.c", "a"); | 
| int Sum; | 
| fprintf(f, "\n/* Update probabilities for token entropy tree. */\n\n"); | 
| -    fprintf(f, "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] = {\n"); | 
| +    fprintf(f, "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {\n"); | 
|  | 
| for (i = 0; i < BLOCK_TYPES; i++) | 
| { | 
| @@ -1699,7 +1883,7 @@ | 
| { | 
| fprintf(f, "      {"); | 
|  | 
| -                for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++) | 
| +                for (l = 0; l < ENTROPY_NODES; l++) | 
| { | 
| Sum = tree_update_hist[i][j][k][l][0] + tree_update_hist[i][j][k][l][1]; | 
|  | 
|  |