]> granicus.if.org Git - libvpx/commitdiff
Refactoring of encode loop and bitstream packing
authorPaul Wilkins <paulwilkins@google.com>
Wed, 11 Apr 2012 14:44:14 +0000 (15:44 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 11 Apr 2012 14:44:14 +0000 (15:44 +0100)
Some code re-factored / moved to allow the main
pack operation inside the recode loop so  that the
size estimate is accurate.

Deletion of some redundant code relating to one pass.

Aproximate improvement over March 27 code base:
Derf 0.0%, YT 0.5%, YThd 0.3% Std_hd 0.25%

Change-Id: Id2d071794ab44f0b52935f6fcdb5733d09a6bb86

vp8/common/onyxc_int.h
vp8/encoder/bitstream.c
vp8/encoder/encodeframe.c
vp8/encoder/firstpass.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/ratectrl.c
vp8/vp8_cx_iface.c

index 9b253e94c1f77d330aecd837617a1a3b0f217d80..ec737dd46d7caa314a9942764e47c41c094f9fcb 100644 (file)
@@ -55,10 +55,8 @@ typedef struct frame_contexts
     vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
     vp8_prob coef_probs_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
     MV_CONTEXT mvc[2];
-    MV_CONTEXT pre_mvc[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
 #if CONFIG_HIGH_PRECISION_MV
     MV_CONTEXT_HP mvc_hp[2];
-    MV_CONTEXT_HP pre_mvc_hp[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
 #endif
 } FRAME_CONTEXT;
 
index 065ea9f1b852ab88f865daa66bb4e8eeddd0b81f..8691ba356dc676bd8edeb0839133bfa74cbe4f85 100644 (file)
@@ -170,6 +170,106 @@ void update_skip_probs(VP8_COMP *cpi)
 #endif
 }
 
+// This function updates the reference frame prediction stats
+static void update_refpred_stats( VP8_COMP *cpi )
+{
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
+
+    int mb_row, mb_col;
+    int i;
+    int tot_count;
+    int ref_pred_count[PREDICTION_PROBS][2];
+    vp8_prob new_pred_probs[PREDICTION_PROBS];
+    unsigned char pred_context;
+    unsigned char pred_flag;
+
+    int old_cost, new_cost;
+
+    // Clear the prediction hit counters
+    vpx_memset(ref_pred_count, 0, sizeof(ref_pred_count));
+
+    // Set the prediction probability structures to defaults
+    if ( cm->frame_type == KEY_FRAME )
+    {
+        // Set the prediction probabilities to defaults
+        cm->ref_pred_probs[0] = 120;
+        cm->ref_pred_probs[1] = 80;
+        cm->ref_pred_probs[2] = 40;
+
+        vpx_memset(cpi->ref_pred_probs_update, 0,
+                   sizeof(cpi->ref_pred_probs_update) );
+    }
+    else
+    {
+        // For non-key frames.......
+
+        // Scan through the macroblocks and collate prediction counts.
+        xd->mode_info_context = cm->mi;
+        for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+        {
+            for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+            {
+                // Get the prediction context and status
+                pred_flag = get_pred_flag( xd, PRED_REF );
+                pred_context = get_pred_context( cm, xd, PRED_REF );
+
+                // Count prediction success
+                ref_pred_count[pred_context][pred_flag]++;
+
+                // Step on to the next mb
+                xd->mode_info_context++;
+            }
+
+            // this is to account for the border in mode_info_context
+            xd->mode_info_context++;
+        }
+
+        // From the prediction counts set the probabilities for each context
+        for ( i = 0; i < PREDICTION_PROBS; i++ )
+        {
+            // MB reference frame not relevent to key frame encoding
+            if ( cm->frame_type != KEY_FRAME )
+            {
+                // Work out the probabilities for the reference frame predictor
+                tot_count = ref_pred_count[i][0] + ref_pred_count[i][1];
+                if ( tot_count )
+                {
+                    new_pred_probs[i] =
+                        ( ref_pred_count[i][0] * 255 ) / tot_count;
+
+                    // Clamp to minimum allowed value
+                    new_pred_probs[i] += !new_pred_probs[i];
+                }
+                else
+                    new_pred_probs[i] = 128;
+            }
+            else
+                new_pred_probs[i] = 128;
+
+            // Decide whether or not to update the reference frame probs.
+            // Returned costs are in 1/256 bit units.
+            old_cost =
+                (ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
+                (ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));
+
+            new_cost =
+                (ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
+                (ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));
+
+            // Cost saving must be >= 8 bits (2048 in these units)
+            if ( (old_cost - new_cost) >= 2048 )
+            {
+                cpi->ref_pred_probs_update[i] = 1;
+                cm->ref_pred_probs[i] = new_pred_probs[i];
+            }
+            else
+                cpi->ref_pred_probs_update[i] = 0;
+
+        }
+    }
+}
+
 static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
 {
     vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
@@ -1307,88 +1407,35 @@ static int default_coef_context_savings(VP8_COMP *cpi)
     return savings;
 }
 
-int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+void build_coeff_contexts(VP8_COMP *cpi)
 {
-    int savings = 0;
-    int i=0;
-    VP8_COMMON *const cm = & cpi->common;
-    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];
-    int new_intra, new_last, new_gf_alt, oldtotal, newtotal;
-    int ref_frame_cost[MAX_REF_FRAMES];
-
-    vp8_clear_system_state(); //__asm emms;
-
-    // Estimate reference frame cost savings.
-    // For now this is just based on projected overall frequency of
-    // each reference frame coded using an unpredicted coding tree.
-    if (cpi->common.frame_type != KEY_FRAME)
+    int i = 0;
+    do
     {
-        new_intra = (rf_intra + rf_inter)
-                    ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
-        new_intra += !new_intra;
-
-        new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
-        new_last += !new_last;
-
-        new_gf_alt = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
-            ? (rfct[GOLDEN_FRAME] * 255) /
-              (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
-        new_gf_alt += !new_gf_alt;
-
-        // new costs
-        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(new_intra);
-        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(new_intra)
-                                        + vp8_cost_zero(new_last);
-        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(new_intra)
-                                        + vp8_cost_one(new_last)
-                                        + vp8_cost_zero(new_gf_alt);
-        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(new_intra)
-                                        + vp8_cost_one(new_last)
-                                        + vp8_cost_one(new_gf_alt);
-
-        newtotal =
-            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
-            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
-            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
-            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
-        // old costs
-        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cm->prob_intra_coded);
-        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_zero(cm->prob_last_coded);
-        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_one(cm->prob_last_coded)
-                                        + vp8_cost_zero(cm->prob_gf_coded);
-        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_one(cm->prob_last_coded)
-                                        + vp8_cost_one(cm->prob_gf_coded);
-
-        oldtotal =
-            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
-            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
-            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
-            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
-        savings += (oldtotal - newtotal) / 256;
-
-        // Update the reference frame probability numbers to reflect
-        // the observed counts in this frame. Doing this here insures
-        // that if there are multiple recode iterations the baseline
-        // probabilities used are updated in each iteration.
-        cm->prob_intra_coded = new_intra;
-        cm->prob_last_coded = new_last;
-        cm->prob_gf_coded = new_gf_alt;
+        int j = 0;
+        do
+        {
+            int k = 0;
+            do
+            {
+                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
+                );
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++j < COEF_BANDS);
     }
-
-    savings += default_coef_context_savings(cpi);
+    while (++i < BLOCK_TYPES);
 
 
-    /* do not do this if not evena allowed */
+    i= 0;
     if(cpi->common.txfm_mode == ALLOW_8X8)
     {
-        int savings8x8 = 0;
         do
         {
             int j = 0;
@@ -1410,40 +1457,14 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
                         256, 1
                         );
 
-                    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];
-
-                        const vp8_prob old = cpi->common.fc.coef_probs_8x8 [i][j][k][t];
-                        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 (s > 0)
-                            savings8x8 += s;
-
-
-                    }
-                    while (++t < MAX_ENTROPY_TOKENS - 1);
-
-
                 }
                 while (++k < PREV_COEF_CONTEXTS);
             }
             while (++j < COEF_BANDS);
         }
         while (++i < BLOCK_TYPES);
-
-        savings += savings8x8 >> 8;
     }
 
-    return savings;
 }
 
 static void update_coef_probs(VP8_COMP *cpi)
@@ -1453,6 +1474,10 @@ static void update_coef_probs(VP8_COMP *cpi)
     int update = 0;
 
     vp8_clear_system_state(); //__asm emms;
+
+    // Build the cofficient contexts based on counts collected in encode loop
+    build_coeff_contexts(cpi);
+
     /* dry run to see if there is any udpate at all needed */
     do
     {
@@ -1463,17 +1488,7 @@ static void update_coef_probs(VP8_COMP *cpi)
             int prev_coef_savings[ENTROPY_NODES] = {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           [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,
-                //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                //    256, 1
-                //    );
                 do
                 {
                     const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1492,7 +1507,6 @@ static void update_coef_probs(VP8_COMP *cpi)
                     update += u;
                 }
                 while (++t < ENTROPY_NODES);
-                /* Accum token counts for generation of default statistics */
             }
             while (++k < PREV_COEF_CONTEXTS);
         }
@@ -1518,18 +1532,8 @@ static void update_coef_probs(VP8_COMP *cpi)
 
                 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           [ENTROPY_NODES];
-                    //unsigned int branch_ct   [ENTROPY_NODES] [2];
+                    // calc probs and branch cts for this frame only
                     int t = 0;      /* token/prob index */
-                    //vp8_tree_probs_from_distribution(
-                    //    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 vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1557,7 +1561,8 @@ static void update_coef_probs(VP8_COMP *cpi)
                         }
                     }
                     while (++t < ENTROPY_NODES);
-                    /* Accum token counts for generation of default statistics */
+
+                    // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                     t = 0;
                     do
@@ -1589,17 +1594,8 @@ static void update_coef_probs(VP8_COMP *cpi)
                 int 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           [ENTROPY_NODES];
-                    //unsigned int branch_ct   [ENTROPY_NODES] [2];
+                    // calc probs and branch cts for this frame only
                     int t = 0;      /* token/prob index */
-                    //vp8_tree_probs_from_distribution(
-                    //    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_8x8 [i][j][k][t];
@@ -1620,7 +1616,7 @@ static void update_coef_probs(VP8_COMP *cpi)
                     }
                     while (++t < MAX_ENTROPY_TOKENS - 1);
 
-                    /* Accum token counts for generation of default statistics */
+                    // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                     t = 0;
 
@@ -1655,17 +1651,7 @@ static void update_coef_probs(VP8_COMP *cpi)
                     int 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           [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,
-                        //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                        //    256, 1
-                        //    );
                         do
                         {
                             const unsigned int *ct  = cpi->frame_branch_ct_8x8 [i][j][k][t];
@@ -1690,7 +1676,7 @@ static void update_coef_probs(VP8_COMP *cpi)
                             }
                         }
                         while (++t < MAX_ENTROPY_TOKENS - 1);
-                        /* Accum token counts for generation of default statistics */
+                        // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                         t = 0;
                         do
@@ -1851,7 +1837,18 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
 
         // If it is, then indicate the method that will be used.
         if ( xd->update_mb_segmentation_map )
+        {
+            // Select the coding strategy (temporal or spatial)
+            choose_segmap_coding_method( cpi );
+
+            // Take a copy of the segment map if it changed for
+            // future comparison
+            vpx_memcpy( pc->last_frame_seg_map,
+                        cpi->segmentation_map, pc->MBs );
+
+            // Write out the chosen coding method.
             vp8_write_bit(bc, (pc->temporal_update) ? 1:0);
+        }
 
         vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
 
@@ -2002,6 +1999,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
 
     // Encode the common prediction model status flag probability updates for
     // the reference frame
+    update_refpred_stats( cpi );
     if ( pc->frame_type != KEY_FRAME )
     {
         for (i = 0; i < PREDICTION_PROBS; i++)
@@ -2112,6 +2110,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
         vp8_write_bit(bc, pc->refresh_golden_frame);
         vp8_write_bit(bc, pc->refresh_alt_ref_frame);
 
+        // For inter frames the current default behavior is that when
+        // cm->refresh_golden_frame is set we copy the old GF over to
+        // the ARF buffer. This is purely an encoder decision at present.
+        if (pc->refresh_golden_frame)
+            pc->copy_buffer_to_arf  = 2;
+
         // If not being updated from current frame should either GF or ARF be updated from another buffer
         if (!pc->refresh_golden_frame)
             vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
index e742809c8e2ff1d02715c681ea3021366b63cf48..5032cbdce24c5de6cb9c3a7001b4d4c7f2796a6f 100644 (file)
@@ -1217,55 +1217,6 @@ static void encode_frame_internal(VP8_COMP *cpi)
     // projected_frame_size in units of BYTES
     cpi->projected_frame_size = totalrate >> 8;
 
-    // Make a note of the percentage MBs coded Intra.
-    if (cm->frame_type == KEY_FRAME)
-    {
-        cpi->this_frame_percent_intra = 100;
-    }
-    else
-    {
-        int tot_modes;
-
-        tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
-                    + cpi->count_mb_ref_frame_usage[LAST_FRAME]
-                    + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
-                    + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
-
-        if (tot_modes)
-            cpi->this_frame_percent_intra =
-                   cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
-
-    }
-
-#if 0
-    {
-        int cnt = 0;
-        int flag[2] = {0, 0};
-
-        for (cnt = 0; cnt < MVPcount; cnt++)
-        {
-            if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
-            {
-                flag[0] = 1;
-                vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
-                break;
-            }
-        }
-
-        for (cnt = 0; cnt < MVPcount; cnt++)
-        {
-            if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
-            {
-                flag[1] = 1;
-                vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
-                break;
-            }
-        }
-
-        if (flag[0] || flag[1])
-            vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
-    }
-#endif
 
 #if 0
     // Keep record of the total distortion this time around for future use
index b561ea3380e06b85466f2f5fb536cf678a9988a9..1e8594d7b4720aae30b6784d8977055c50ccf29c 100644 (file)
@@ -1845,6 +1845,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 
     // Should we use the alternate refernce frame
     if (allow_alt_ref &&
+        (i < cpi->oxcf.lag_in_frames ) &&
         (i >= MIN_GF_INTERVAL) &&
         // dont use ARF very near next kf
         (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
index a758b19274d99fae0674165556cb517518212952..e547c9ddfe0de88b42a05730b337fcabfb32dd77 100644 (file)
@@ -70,7 +70,6 @@ extern void vp8_yv12_copy_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFF
 extern void vp8_yv12_copy_src_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
 #endif
 
-int vp8_estimate_entropy_savings(VP8_COMP *cpi);
 int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
 
 extern void vp8_temporal_filter_prepare_c(VP8_COMP *cpi, int distance);
@@ -413,6 +412,8 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
     cpi->segmentation_map = 0;
     vpx_free(cpi->common.last_frame_seg_map);
     cpi->common.last_frame_seg_map = 0;
+    vpx_free(cpi->coding_context.last_frame_seg_map_copy);
+    cpi->coding_context.last_frame_seg_map_copy = 0;
 
     vpx_free(cpi->active_map);
     cpi->active_map = 0;
@@ -1660,6 +1661,11 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
     CHECK_MEM_ERROR(cm->last_frame_seg_map,
         vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
 
+    // And a place holder structure is the coding context
+    // for use if we want to save and restore it
+    CHECK_MEM_ERROR(cpi->coding_context.last_frame_seg_map_copy,
+        vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+
     CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
     vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
     cpi->active_map_enabled = 0;
@@ -2480,47 +2486,6 @@ static void update_golden_frame_stats(VP8_COMP *cpi)
     }
 }
 
-// 1 = key, 0 = inter
-static int decide_key_frame(VP8_COMP *cpi)
-{
-    VP8_COMMON *cm = &cpi->common;
-
-    int code_key_frame = FALSE;
-
-    cpi->kf_boost = 0;
-
-    if (cpi->Speed > 11)
-        return FALSE;
-
-    // Clear down mmx registers
-    vp8_clear_system_state();  //__asm emms;
-
-    // If the following are true we might as well code a key frame
-    if (((cpi->this_frame_percent_intra == 100) &&
-         (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) ||
-        ((cpi->this_frame_percent_intra > 95) &&
-         (cpi->this_frame_percent_intra >= (cpi->last_frame_percent_intra + 5))))
-    {
-        code_key_frame = TRUE;
-    }
-    // in addition if the following are true and this is not a golden frame then code a key frame
-    // Note that on golden frames there often seems to be a pop in intra useage anyway hence this
-    // restriction is designed to prevent spurious key frames. The Intra pop needs to be investigated.
-    else if (((cpi->this_frame_percent_intra > 60) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 2))) ||
-             ((cpi->this_frame_percent_intra > 75) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 3 / 2))) ||
-             ((cpi->this_frame_percent_intra > 90) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 10))))
-    {
-        if (!cm->refresh_golden_frame)
-            code_key_frame = TRUE;
-    }
-
-    return code_key_frame;
-
-}
-
 int find_fp_qindex()
 {
     int i;
@@ -2812,106 +2777,6 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
 
 }
 
-// This function updates the reference frame prediction stats
-static void update_refpred_stats( VP8_COMP *cpi )
-{
-    VP8_COMMON *const cm = & cpi->common;
-    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
-
-    int mb_row, mb_col;
-    int i;
-    int tot_count;
-    int ref_pred_count[PREDICTION_PROBS][2];
-    vp8_prob new_pred_probs[PREDICTION_PROBS];
-    unsigned char pred_context;
-    unsigned char pred_flag;
-
-    int old_cost, new_cost;
-
-    // Clear the prediction hit counters
-    vpx_memset(ref_pred_count, 0, sizeof(ref_pred_count));
-
-    // Set the prediction probability structures to defaults
-    if ( cm->frame_type == KEY_FRAME )
-    {
-        // Set the prediction probabilities to defaults
-        cm->ref_pred_probs[0] = 120;
-        cm->ref_pred_probs[1] = 80;
-        cm->ref_pred_probs[2] = 40;
-
-        vpx_memset(cpi->ref_pred_probs_update, 0,
-                   sizeof(cpi->ref_pred_probs_update) );
-    }
-    else
-    {
-        // For non-key frames.......
-
-        // Scan through the macroblocks and collate prediction counts.
-        xd->mode_info_context = cm->mi;
-        for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
-        {
-            for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
-            {
-                // Get the prediction context and status
-                pred_flag = get_pred_flag( xd, PRED_REF );
-                pred_context = get_pred_context( cm, xd, PRED_REF );
-
-                // Count prediction success
-                ref_pred_count[pred_context][pred_flag]++;
-
-                // Step on to the next mb
-                xd->mode_info_context++;
-            }
-
-            // this is to account for the border in mode_info_context
-            xd->mode_info_context++;
-        }
-
-        // From the prediction counts set the probabilities for each context
-        for ( i = 0; i < PREDICTION_PROBS; i++ )
-        {
-            // MB reference frame not relevent to key frame encoding
-            if ( cm->frame_type != KEY_FRAME )
-            {
-                // Work out the probabilities for the reference frame predictor
-                tot_count = ref_pred_count[i][0] + ref_pred_count[i][1];
-                if ( tot_count )
-                {
-                    new_pred_probs[i] =
-                        ( ref_pred_count[i][0] * 255 ) / tot_count;
-
-                    // Clamp to minimum allowed value
-                    new_pred_probs[i] += !new_pred_probs[i];
-                }
-                else
-                    new_pred_probs[i] = 128;
-            }
-            else
-                new_pred_probs[i] = 128;
-
-            // Decide whether or not to update the reference frame probs.
-            // Returned costs are in 1/256 bit units.
-            old_cost =
-                (ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
-                (ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));
-
-            new_cost =
-                (ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
-                (ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));
-
-            // Cost saving must be >= 8 bits (2048 in these units)
-            if ( (old_cost - new_cost) >= 2048 )
-            {
-                cpi->ref_pred_probs_update[i] = 1;
-                cm->ref_pred_probs[i] = new_pred_probs[i];
-            }
-            else
-                cpi->ref_pred_probs_update[i] = 0;
-
-        }
-    }
-}
-
 static void encode_frame_to_data_rate
 (
     VP8_COMP *cpi,
@@ -3028,12 +2893,7 @@ static void encode_frame_to_data_rate
     init_seg_features( cpi );
 
     // Decide how big to make the frame
-    if (!vp8_pick_frame_size(cpi))
-    {
-        cm->current_video_frame++;
-        cpi->frames_since_key++;
-        return;
-    }
+    vp8_pick_frame_size(cpi);
 
     vp8_clear_system_state();
 
@@ -3156,7 +3016,6 @@ static void encode_frame_to_data_rate
     q_low  = cpi->active_best_quality;
     q_high = cpi->active_worst_quality;
 
-    vp8_save_coding_context(cpi);
 
     loop_count = 0;
 
@@ -3235,97 +3094,100 @@ static void encode_frame_to_data_rate
         vp8_set_quantizer(cpi, Q);
         this_q = Q;
 
-        // setup skip prob for costing in mode/mv decision
-        if (cpi->common.mb_no_coeff_skip)
+        if ( loop_count == 0 )
         {
+            // setup skip prob for costing in mode/mv decision
+            if (cpi->common.mb_no_coeff_skip)
+            {
 #if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; k++)
-                cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
+                int k;
+                for (k=0; k<MBSKIP_CONTEXTS; k++)
+                    cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
 #else
-            cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
+                cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
 #endif
 
-            if (cm->frame_type != KEY_FRAME)
-            {
-                if (cpi->common.refresh_alt_ref_frame)
+                if (cm->frame_type != KEY_FRAME)
                 {
-#if CONFIG_NEWENTROPY
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
+                    if (cpi->common.refresh_alt_ref_frame)
                     {
-                        if (cpi->last_skip_false_probs[2][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
-                    }
+#if CONFIG_NEWENTROPY
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[2][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[2] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[2];
+                        if (cpi->last_skip_false_probs[2] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[2];
 #endif
-                }
-                else if (cpi->common.refresh_golden_frame)
-                {
-#if CONFIG_NEWENTROPY
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
-                    {
-                        if (cpi->last_skip_false_probs[1][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
                     }
+                    else if (cpi->common.refresh_golden_frame)
+                    {
+#if CONFIG_NEWENTROPY
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[1][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[1] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[1];
+                        if (cpi->last_skip_false_probs[1] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[1];
 #endif
-                }
-                else
-                {
-#if CONFIG_NEWENTROPY
-                    int k;
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
-                    {
-                        if (cpi->last_skip_false_probs[0][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
                     }
+                    else
+                    {
+#if CONFIG_NEWENTROPY
+                        int k;
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[0][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[0] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[0];
+                        if (cpi->last_skip_false_probs[0] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[0];
 #endif
-                }
+                    }
 
-                // as this is for cost estimate, let's make sure it does not
-                // get extreme either way
+                    // as this is for cost estimate, let's make sure it does not
+                    // get extreme either way
 #if CONFIG_NEWENTROPY
-                {
-                    int k;
-                    for (k=0; k<MBSKIP_CONTEXTS; ++k)
                     {
-                    if (cm->mbskip_pred_probs[k] < 5)
-                        cm->mbskip_pred_probs[k] = 5;
-
-                    if (cm->mbskip_pred_probs[k] > 250)
-                        cm->mbskip_pred_probs[k] = 250;
-
-                    if (cpi->is_src_frame_alt_ref)
-                        cm->mbskip_pred_probs[k] = 1;
+                        int k;
+                        for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                        {
+                        if (cm->mbskip_pred_probs[k] < 5)
+                            cm->mbskip_pred_probs[k] = 5;
+
+                        if (cm->mbskip_pred_probs[k] > 250)
+                            cm->mbskip_pred_probs[k] = 250;
+
+                        if (cpi->is_src_frame_alt_ref)
+                            cm->mbskip_pred_probs[k] = 1;
+                        }
                     }
-                }
 #else
-                if (cpi->prob_skip_false < 5)
-                    cpi->prob_skip_false = 5;
+                    if (cpi->prob_skip_false < 5)
+                        cpi->prob_skip_false = 5;
 
-                if (cpi->prob_skip_false > 250)
-                    cpi->prob_skip_false = 250;
+                    if (cpi->prob_skip_false > 250)
+                        cpi->prob_skip_false = 250;
 
-                if (cpi->is_src_frame_alt_ref)
-                    cpi->prob_skip_false = 1;
+                    if (cpi->is_src_frame_alt_ref)
+                        cpi->prob_skip_false = 1;
 #endif
 
 
+                }
             }
-        }
 
-        // Set up entropy depending on frame type.
-        if (cm->frame_type == KEY_FRAME)
-            vp8_setup_key_frame(cpi);
-        else
-            vp8_setup_inter_frame(cpi);
+            // Set up entropy depending on frame type.
+            if (cm->frame_type == KEY_FRAME)
+                vp8_setup_key_frame(cpi);
+            else
+                vp8_setup_inter_frame(cpi);
+        }
 
         // transform / motion compensation build reconstruction frame
         vp8_encode_frame(cpi);
@@ -3334,9 +3196,6 @@ static void encode_frame_to_data_rate
         // seen in the last encoder iteration.
         update_base_skip_probs( cpi );
 
-        cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
-        cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
-
         vp8_clear_system_state();  //__asm emms;
 
         if (frame_over_shoot_limit == 0)
@@ -3344,6 +3203,14 @@ static void encode_frame_to_data_rate
 
         active_worst_qchanged = FALSE;
 
+        // Dummy pack of the bitstream using up to date stats to get an
+        // accurate estimate of output frame size to determine if we need
+        // to recode.
+        vp8_save_coding_context(cpi);
+        vp8_pack_bitstream(cpi, dest, size);
+        cpi->projected_frame_size = (*size) << 3;
+        vp8_restore_coding_context(cpi);
+
         // Special case handling for forced key frames
         if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced )
         {
@@ -3353,7 +3220,7 @@ static void encode_frame_to_data_rate
                                          IF_RTCD(&cpi->rtcd.variance));
 
             int high_err_target = cpi->ambient_err;
-            int low_err_target = ((cpi->ambient_err * 3) >> 2);
+            int low_err_target = (cpi->ambient_err >> 1);
 
             // Prevent possible divide by zero error below for perfect KF
             kf_err += (!kf_err);
@@ -3521,7 +3388,6 @@ static void encode_frame_to_data_rate
 
         if (Loop == TRUE)
         {
-            vp8_restore_coding_context(cpi);
             loop_count++;
 #if CONFIG_INTERNAL_STATS
             cpi->tot_recode_hits++;
@@ -3530,28 +3396,6 @@ static void encode_frame_to_data_rate
     }
     while (Loop == TRUE);
 
-#if 0
-    // Experimental code for lagged and one pass
-    // Update stats used for one pass GF selection
-    {
-        /*
-            int frames_so_far;
-            double frame_intra_error;
-            double frame_coded_error;
-            double frame_pcnt_inter;
-            double frame_pcnt_motion;
-            double frame_mvr;
-            double frame_mvr_abs;
-            double frame_mvc;
-            double frame_mvc_abs;
-        */
-
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_coded_error = (double)cpi->prediction_error;
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_intra_error = (double)cpi->intra_error;
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_pcnt_inter = (double)(100 - cpi->this_frame_percent_intra) / 100.0;
-    }
-#endif
-
     // Special case code to reduce pulsing when key frames are forced at a
     // fixed interval. Note the reconstruction error if it is the frame before
     // the force key frame
@@ -3562,13 +3406,15 @@ static void encode_frame_to_data_rate
                                            IF_RTCD(&cpi->rtcd.variance));
     }
 
-    // This frame's MVs are saved and will be used in next frame's MV prediction.
-    // Last frame has one more line(add to bottom) and one more column(add to right) than cm->mip. The edge elements are initialized to 0.
+    // This frame's MVs are saved and will be used in next frame's MV
+    // prediction. Last frame has one more line(add to bottom) and one
+    // more column(add to right) than cm->mip. The edge elements are
+    // initialized to 0.
     if(cm->show_frame)   //do not save for altref frame
     {
         int mb_row;
         int mb_col;
-        MODE_INFO *tmp = cm->mip; //point to beginning of allocated MODE_INFO arrays.
+        MODE_INFO *tmp = cm->mip;
 
         if(cm->frame_type != KEY_FRAME)
         {
@@ -3588,8 +3434,8 @@ static void encode_frame_to_data_rate
     }
 
     // Update the GF useage maps.
-    // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
-    // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
+    // This is done after completing the compression of a frame when all modes
+    // etc. are finalized but before loop filter
     vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
 
     if (cm->frame_type == KEY_FRAME)
@@ -3603,12 +3449,6 @@ static void encode_frame_to_data_rate
     }
 #endif
 
-    // For inter frames the current default behavior is that when
-    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
-    // This is purely an encoder decision at present.
-    if (cm->refresh_golden_frame)
-        cm->copy_buffer_to_arf  = 2;
-
     cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
 
 #if WRITE_RECON_BUFFER
@@ -3620,34 +3460,13 @@ static void encode_frame_to_data_rate
             cm->current_video_frame+1000);
 #endif
 
-    {
-        loopfilter_frame(cpi, cm);
-    }
-
-    if(cm->show_frame)
-        write_yuv_frame_to_file(cm->frame_to_show);
-
-    update_reference_frames(cm);
-
-    // Work out the segment probabilities if segmentation is enabled and
-    // the map is due to be updated
-    if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
-    {
-        // Select the coding strategy for the segment map (temporal or spatial)
-        choose_segmap_coding_method( cpi );
-
-        // Take a copy of the segment map if it changed for future comparison
-        vpx_memcpy( cm->last_frame_seg_map,
-                    cpi->segmentation_map, cm->MBs );
-    }
-
-    // Update the common prediction model probabilities to reflect
-    // the what was seen in the current frame.
-    update_refpred_stats( cpi );
+    // Pick the loop filter level for the frame.
+    loopfilter_frame(cpi, cm);
 
     // build the bitstream
     vp8_pack_bitstream(cpi, dest, size);
 
+    update_reference_frames(cm);
 
     /* Move storing frame_type out of the above loop since it is also
      * needed in motion search besides loopfilter */
@@ -3745,53 +3564,7 @@ static void encode_frame_to_data_rate
     // Update the skip mb flag probabilities based on the distribution seen
     // in this frame.
     update_base_skip_probs( cpi );
-/*
-    if (cm->frame_type != KEY_FRAME)
-    {
-        if (cpi->common.refresh_alt_ref_frame)
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[2] = cm->base_qindex;
-        }
-        else if (cpi->common.refresh_golden_frame)
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[1] = cm->base_qindex;
-        }
-        else
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[0] = cm->base_qindex;
-
-            //update the baseline
-#if CONFIG_NEWENTROPY
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->base_skip_false_prob[cm->base_qindex][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
-#endif
 
-        }
-    }
-*/
 #if 0 && CONFIG_INTERNAL_STATS
     {
         FILE *f = fopen("tmp.stt", "a");
@@ -3942,14 +3715,10 @@ static void encode_frame_to_data_rate
 
         // As this frame is a key frame  the next defaults to an inter frame.
         cm->frame_type = INTER_FRAME;
-
-        cpi->last_frame_percent_intra = 100;
     }
     else
     {
         *frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
-
-        cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
     }
 
     // Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
index e2788c0efedad6264fa8eb933e43db88fee20564..932e8ca7c5ed5fe0f278ce1c369d93db474f7379 100644 (file)
 
 typedef struct
 {
-    int kf_indicated;
-    unsigned int frames_since_key;
-    unsigned int frames_since_golden;
-    int filter_level;
-    int frames_till_gf_update_due;
-    int recent_ref_frame_usage[MAX_REF_FRAMES];
-
     MV_CONTEXT mvc[2];
     int mvcosts[2][MVvals+1];
 #if CONFIG_HIGH_PRECISION_MV
@@ -79,30 +72,28 @@ typedef struct
     int inter_uv_modes[VP8_UV_MODES];
     int inter_b_modes[B_MODE_COUNT];
 #endif
-    /* interframe intra mode probs */
-    vp8_prob ymode_prob[VP8_YMODES-1];
-    /* keyframe intra mode probs */
-#if CONFIG_QIMODE
-    vp8_prob kf_ymode_prob[8][VP8_YMODES-1];
-#else
-    vp8_prob kf_ymode_prob[VP8_YMODES-1];
-#endif
 
-#if CONFIG_UVINTRA
-    vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
-    vp8_prob uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
-#else
-    vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1];
-    vp8_prob uv_mode_prob[VP8_UV_MODES-1];
-#endif
-    /* intra MB type cts this frame */
-    int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES];
+    vp8_prob segment_pred_probs[PREDICTION_PROBS];
+    unsigned char ref_pred_probs_update[PREDICTION_PROBS];
+    vp8_prob ref_pred_probs[PREDICTION_PROBS];
+    vp8_prob prob_comppred[COMP_PRED_CONTEXTS];
 
-    int count_mb_ref_frame_usage[MAX_REF_FRAMES];
+    unsigned char * last_frame_seg_map_copy;
+
+    // 0 = Intra, Last, GF, ARF
+    signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];
+    // 0 = BPRED, ZERO_MV, MV, SPLIT
+    signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
 
-    int this_frame_percent_intra;
-    int last_frame_percent_intra;
+    vp8_prob coef_probs[BLOCK_TYPES]
+                       [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
+    vp8_prob coef_probs_8x8[BLOCK_TYPES]
+                           [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
 
+    int mv_ref_ct[6][4][2];
+    int mode_context[6][4];
+    int mv_ref_ct_a[6][4][2];
+    int mode_context_a[6][4];
 
 } CODING_CONTEXT;
 
@@ -490,17 +481,15 @@ typedef struct VP8_COMP
     int pass;
 
 #if CONFIG_NEWENTROPY
-    int last_skip_false_probs[3][MBSKIP_CONTEXTS];
+    vp8_prob last_skip_false_probs[3][MBSKIP_CONTEXTS];
 #else
-    int prob_skip_false;
-    int last_skip_false_probs[3];
+    vp8_prob prob_skip_false;
+    vp8_prob last_skip_false_probs[3];
 #endif
     int last_skip_probs_q[3];
 
     int recent_ref_frame_usage[MAX_REF_FRAMES];
     int count_mb_ref_frame_usage[MAX_REF_FRAMES];
-    int this_frame_percent_intra;
-    int last_frame_percent_intra;
     int ref_frame_flags;
 
     unsigned char ref_pred_probs_update[PREDICTION_PROBS];
index a57996612db344944bb0c6214cef7f1d823158aa..1ff13754f540c24366dbcd0fb07573ec62f0262b 100644 (file)
@@ -135,32 +135,25 @@ int vp8_bits_per_mb( FRAME_TYPE frame_type, int qindex  )
 void vp8_save_coding_context(VP8_COMP *cpi)
 {
     CODING_CONTEXT *const cc = & cpi->coding_context;
+    VP8_COMMON *cm = &cpi->common;
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     // Stores a snapshot of key state variables which can subsequently be
     // restored with a call to vp8_restore_coding_context. These functions are
     // intended for use in a re-code loop in vp8_compress_frame where the
     // quantizer value is adjusted between loop iterations.
 
-    cc->frames_since_key          = cpi->frames_since_key;
-    cc->filter_level             = cpi->common.filter_level;
-    cc->frames_till_gf_update_due   = cpi->frames_till_gf_update_due;
-    cc->frames_since_golden       = cpi->common.frames_since_golden;
-
-    vp8_copy(cc->mvc,      cpi->common.fc.mvc);
+    vp8_copy(cc->mvc,      cm->fc.mvc);
     vp8_copy(cc->mvcosts,  cpi->mb.mvcosts);
 #if CONFIG_HIGH_PRECISION_MV
-    vp8_copy(cc->mvc_hp,      cpi->common.fc.mvc_hp);
+    vp8_copy(cc->mvc_hp,     cm->fc.mvc_hp);
     vp8_copy(cc->mvcosts_hp,  cpi->mb.mvcosts_hp);
 #endif
 
-    vp8_copy(cc->kf_ymode_prob,   cpi->common.kf_ymode_prob);
-    vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
-    vp8_copy(cc->kf_uv_mode_prob,  cpi->common.kf_uv_mode_prob);
-    vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
-
-    vp8_copy(cc->ymode_count, cpi->ymode_count);
-    vp8_copy(cc->uv_mode_count, cpi->uv_mode_count);
-
+    vp8_copy( cc->mv_ref_ct, cm->mv_ref_ct );
+    vp8_copy( cc->mode_context, cm->mode_context );
+    vp8_copy( cc->mv_ref_ct_a, cm->mv_ref_ct_a );
+    vp8_copy( cc->mode_context_a, cm->mode_context_a );
 
     // Stats
 #ifdef MODE_STATS
@@ -172,37 +165,41 @@ void vp8_save_coding_context(VP8_COMP *cpi)
     vp8_copy(cc->inter_b_modes,  inter_b_modes);
 #endif
 
-    cc->this_frame_percent_intra = cpi->this_frame_percent_intra;
-}
+    vp8_copy( cc->segment_pred_probs, cm->segment_pred_probs );
+    vp8_copy( cc->ref_pred_probs_update, cpi->ref_pred_probs_update );
+    vp8_copy( cc->ref_pred_probs, cm->ref_pred_probs );
+    vp8_copy( cc->prob_comppred, cm->prob_comppred );
 
+    vpx_memcpy( cpi->coding_context.last_frame_seg_map_copy,
+                cm->last_frame_seg_map, (cm->mb_rows * cm->mb_cols) );
+
+    vp8_copy( cc->last_ref_lf_deltas, xd->last_ref_lf_deltas );
+    vp8_copy( cc->last_mode_lf_deltas, xd->last_mode_lf_deltas );
+
+    vp8_copy( cc->coef_probs, cm->fc.coef_probs );
+    vp8_copy( cc->coef_probs_8x8, cm->fc.coef_probs_8x8 );
+}
 
 void vp8_restore_coding_context(VP8_COMP *cpi)
 {
     CODING_CONTEXT *const cc = & cpi->coding_context;
+    VP8_COMMON *cm = &cpi->common;
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     // Restore key state variables to the snapshot state stored in the
     // previous call to vp8_save_coding_context.
 
-    cpi->frames_since_key         =   cc->frames_since_key;
-    cpi->common.filter_level     =   cc->filter_level;
-    cpi->frames_till_gf_update_due  =   cc->frames_till_gf_update_due;
-    cpi->common.frames_since_golden       =   cc->frames_since_golden;
-
-    vp8_copy(cpi->common.fc.mvc, cc->mvc);
-
+    vp8_copy(cm->fc.mvc, cc->mvc);
     vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
 #if CONFIG_HIGH_PRECISION_MV
-    vp8_copy(cpi->common.fc.mvc_hp, cc->mvc_hp);
-
+    vp8_copy(cm->fc.mvc_hp, cc->mvc_hp);
     vp8_copy(cpi->mb.mvcosts_hp, cc->mvcosts_hp);
 #endif
-    vp8_copy(cpi->common.kf_ymode_prob,   cc->kf_ymode_prob);
-    vp8_copy(cpi->common.fc.ymode_prob,   cc->ymode_prob);
-    vp8_copy(cpi->common.kf_uv_mode_prob,  cc->kf_uv_mode_prob);
-    vp8_copy(cpi->common.fc.uv_mode_prob,  cc->uv_mode_prob);
 
-    vp8_copy(cpi->ymode_count, cc->ymode_count);
-    vp8_copy(cpi->uv_mode_count, cc->uv_mode_count);
+    vp8_copy( cm->mv_ref_ct, cc->mv_ref_ct );
+    vp8_copy( cm->mode_context, cc->mode_context );
+    vp8_copy( cm->mv_ref_ct_a, cc->mv_ref_ct_a );
+    vp8_copy( cm->mode_context_a, cc->mode_context_a );
 
     // Stats
 #ifdef MODE_STATS
@@ -214,8 +211,20 @@ void vp8_restore_coding_context(VP8_COMP *cpi)
     vp8_copy(inter_b_modes, cc->inter_b_modes);
 #endif
 
+    vp8_copy( cm->segment_pred_probs, cc->segment_pred_probs );
+    vp8_copy( cpi->ref_pred_probs_update, cc->ref_pred_probs_update );
+    vp8_copy( cm->ref_pred_probs, cc->ref_pred_probs );
+    vp8_copy( cm->prob_comppred, cc->prob_comppred );
+
+    vpx_memcpy( cm->last_frame_seg_map,
+                cpi->coding_context.last_frame_seg_map_copy,
+                (cm->mb_rows * cm->mb_cols) );
 
-    cpi->this_frame_percent_intra = cc->this_frame_percent_intra;
+    vp8_copy( xd->last_ref_lf_deltas, cc->last_ref_lf_deltas );
+    vp8_copy( xd->last_mode_lf_deltas, cc->last_mode_lf_deltas );
+
+    vp8_copy( cm->fc.coef_probs, cc->coef_probs );
+    vp8_copy( cm->fc.coef_probs_8x8, cc->coef_probs_8x8 );
 }
 
 
@@ -231,14 +240,12 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
         int flag[2] = {1, 1};
         vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag);
     }
-    vpx_memset(cpi->common.fc.pre_mvc, 0, sizeof(cpi->common.fc.pre_mvc));  //initialize pre_mvc to all zero.
 #if CONFIG_HIGH_PRECISION_MV
     vpx_memcpy(cpi->common.fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp));
     {
         int flag[2] = {1, 1};
         vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag);
     }
-    vpx_memset(cpi->common.fc.pre_mvc_hp, 0, sizeof(cpi->common.fc.pre_mvc_hp));  //initialize pre_mvc to all zero.
 #endif
 
     cpi->common.txfm_mode = ONLY_4X4;
@@ -270,17 +277,6 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
                 default_vp8_mode_contexts,
                 sizeof(default_vp8_mode_contexts));
 
-    /* make sure coding_context is correct in key frame recode */
-    {
-        CODING_CONTEXT *const cc = & cpi->coding_context;
-
-        vp8_copy(cc->mvc,      cpi->common.fc.mvc);
-#if CONFIG_HIGH_PRECISION_MV
-        vp8_copy(cc->mvc_hp,      cpi->common.fc.mvc_hp);
-#endif
-        vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
-        vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
-    }
 }
 void vp8_setup_inter_frame(VP8_COMP *cpi)
 {
index 4f34569e02abf78c51d15d54465afb0306530502..96dcedca9061a9057741d57527d7f39a517d884c 100644 (file)
@@ -144,7 +144,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t      *ctx,
     RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
     RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
     RANGE_CHECK_HI(cfg, g_threads,          64);
-    RANGE_CHECK_HI(cfg, g_lag_in_frames,    25);
+    RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
     RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_CQ);
     RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
     RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);