Merge "Copy less when active map is in use"
diff --git a/CHANGELOG b/CHANGELOG
index 866b1ab..f560d05 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,33 @@
+2011-08-15 v0.9.7-p1 "Cayuga" patch 1
+  This is an incremental bugfix release against Cayuga. All users of that
+  release are strongly encouraged to upgrade.
+
+    - Fix potential OOB reads (cdae03a)
+
+          An unbounded out of bounds read was discovered when the
+          decoder was requested to perform error concealment (new in
+          Cayuga) given a frame with corrupt partition sizes.
+
+          A bounded out of bounds read was discovered affecting all
+          versions of libvpx. Given an multipartition input frame that
+          is truncated between the mode/mv partition and the first
+          residiual paritition (in the block of partition offsets), up
+          to 3 extra bytes could have been read from the source buffer.
+          The code will not take any action regardless of the contents
+          of these undefined bytes, as the truncated buffer is detected
+          immediately following the read based on the calculated
+          starting position of the coefficient partition.
+
+    - Fix potential error concealment crash when the very first frame
+      is missing or corrupt (a609be5)
+
+    - Fix significant artifacts in error concealment (a4c2211, 99d870a)
+
+    - Revert 1-pass CBR rate control changes (e961317)
+      Further testing showed this change produced undesirable visual
+      artifacts, rolling back for now.
+
+
 2011-08-02 v0.9.7 "Cayuga"
   Our third named release, focused on a faster, higher quality, encoder.
 
diff --git a/libs.mk b/libs.mk
index 757e068..fecc0da 100644
--- a/libs.mk
+++ b/libs.mk
@@ -132,6 +132,14 @@
 INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(CODEC_SRCS)
 INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS)
 
+
+# Generate a list of all enabled sources, in particular for exporting to gyp
+# based build systems.
+libvpx_srcs.txt:
+	@echo "    [CREATE] $@"
+	@echo $(CODEC_SRCS) | xargs -n1 echo | sort -u > $@
+
+
 ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
 ifeq ($(CONFIG_MSVS),yes)
 
diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h
index d3e5c2f..08f1cca 100644
--- a/vp8/common/onyxd.h
+++ b/vp8/common/onyxd.h
@@ -18,7 +18,6 @@
 extern "C"
 {
 #endif
-#include "vpx/vpx_codec.h"
 #include "type_aliases.h"
 #include "vpx_scale/yv12config.h"
 #include "ppflags.h"
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 0a7942d..54547d9 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -400,18 +400,18 @@
             /* Clip "next_nearest" so that it does not extend to far out of image */
             vp8_clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
                          mb_to_top_edge, mb_to_bottom_edge);
-            break;
+            goto propagate_mv;
 
         case NEARESTMV:
             mv->as_int = nearest.as_int;
             /* Clip "next_nearest" so that it does not extend to far out of image */
             vp8_clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
                          mb_to_top_edge, mb_to_bottom_edge);
-            break;
+            goto propagate_mv;
 
         case ZEROMV:
             mv->as_int = 0;
-            break;
+            goto propagate_mv;
 
         case NEWMV:
             read_mv(bc, &mv->as_mv, (const MV_CONTEXT *) mvc);
@@ -428,8 +428,30 @@
                                                       mb_to_right_edge,
                                                       mb_to_top_edge,
                                                       mb_to_bottom_edge);
-            break;
 
+        propagate_mv:  /* same MV throughout */
+#if CONFIG_ERROR_CONCEALMENT
+            if(pbi->ec_enabled)
+            {
+                mi->bmi[ 0].mv.as_int =
+                mi->bmi[ 1].mv.as_int =
+                mi->bmi[ 2].mv.as_int =
+                mi->bmi[ 3].mv.as_int =
+                mi->bmi[ 4].mv.as_int =
+                mi->bmi[ 5].mv.as_int =
+                mi->bmi[ 6].mv.as_int =
+                mi->bmi[ 7].mv.as_int =
+                mi->bmi[ 8].mv.as_int =
+                mi->bmi[ 9].mv.as_int =
+                mi->bmi[10].mv.as_int =
+                mi->bmi[11].mv.as_int =
+                mi->bmi[12].mv.as_int =
+                mi->bmi[13].mv.as_int =
+                mi->bmi[14].mv.as_int =
+                mi->bmi[15].mv.as_int = mv->as_int;
+            }
+#endif
+            break;
         default:;
   #if CONFIG_DEBUG
             assert(0);
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 9b35ffd..ddb0970 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -183,6 +183,7 @@
                               unsigned int mb_idx)
 {
     int eobtotal = 0;
+    int throw_residual = 0;
     MB_PREDICTION_MODE mode;
     int i;
 
@@ -203,7 +204,8 @@
 
     mode = xd->mode_info_context->mbmi.mode;
 
-    if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV)
+    if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV &&
+            !vp8dx_bool_error(xd->current_bc))
     {
         /* Special case:  Force the loopfilter to skip when eobtotal and
          * mb_skip_coeff are zero.
@@ -235,14 +237,21 @@
         vp8_build_inter_predictors_mb(xd);
     }
 
+    /* When we have independent partitions we can apply residual even
+     * though other partitions within the frame are corrupt.
+     */
+    throw_residual = (!pbi->independent_partitions &&
+                      pbi->frame_corrupt_residual);
+    throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));
+
 #if CONFIG_ERROR_CONCEALMENT
-    if (pbi->ec_enabled &&
-        (mb_idx >= pbi->mvs_corrupt_from_mb ||
-        vp8dx_bool_error(xd->current_bc)))
+    if (pbi->ec_active &&
+        (mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual))
     {
         /* MB with corrupt residuals or corrupt mode/motion vectors.
          * Better to use the predictor as reconstruction.
          */
+        pbi->frame_corrupt_residual = 1;
         vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
         vp8_conceal_corrupt_mb(xd);
         return;
@@ -376,22 +385,28 @@
         xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
 
 #if CONFIG_ERROR_CONCEALMENT
-        if (pbi->ec_enabled &&
-            xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME &&
-            vp8dx_bool_error(xd->current_bc))
         {
-            /* We have an intra block with corrupt coefficients, better to
-             * conceal with an inter block. Interpolate MVs from neighboring MBs
-             *
-             * Note that for the first mb with corrupt residual in a frame,
-             * we might not discover that before decoding the residual. That
-             * happens after this check, and therefore no inter concealment will
-             * be done.
-             */
-            vp8_interpolate_motion(xd,
-                                   mb_row, mb_col,
-                                   pc->mb_rows, pc->mb_cols,
-                                   pc->mode_info_stride);
+            int corrupt_residual = (!pbi->independent_partitions &&
+                                   pbi->frame_corrupt_residual) ||
+                                   vp8dx_bool_error(xd->current_bc);
+            if (pbi->ec_active &&
+                xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME &&
+                corrupt_residual)
+            {
+                /* We have an intra block with corrupt coefficients, better to
+                 * conceal with an inter block. Interpolate MVs from neighboring
+                 * MBs.
+                 *
+                 * Note that for the first mb with corrupt residual in a frame,
+                 * we might not discover that before decoding the residual. That
+                 * happens after this check, and therefore no inter concealment
+                 * will be done.
+                 */
+                vp8_interpolate_motion(xd,
+                                       mb_row, mb_col,
+                                       pc->mb_rows, pc->mb_cols,
+                                       pc->mode_info_stride);
+            }
         }
 #endif
 
@@ -495,6 +510,15 @@
 #endif
 }
 
+
+static int read_is_valid(const unsigned char *start,
+                         size_t               len,
+                         const unsigned char *end)
+{
+    return (start + len > start && start + len <= end);
+}
+
+
 static void setup_token_decoder(VP8D_COMP *pbi,
                                 const unsigned char *cx_data)
 {
@@ -510,7 +534,7 @@
             (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
     /* Only update the multi_token_partition field if we are sure the value
      * is correct. */
-    if (!pbi->ec_enabled || !vp8dx_bool_error(&pbi->bc))
+    if (!pbi->ec_active || !vp8dx_bool_error(&pbi->bc))
         pc->multi_token_partition = multi_token_partition;
 
     num_part = 1 << pc->multi_token_partition;
@@ -529,25 +553,41 @@
     for (i = 0; i < num_part; i++)
     {
         const unsigned char *partition_size_ptr = cx_data + i * 3;
-        ptrdiff_t            partition_size;
+        ptrdiff_t            partition_size, bytes_left;
+
+        bytes_left = user_data_end - partition;
 
         /* Calculate the length of this partition. The last partition
-         * size is implicit.
+         * size is implicit. If the partition size can't be read, then
+         * either use the remaining data in the buffer (for EC mode)
+         * or throw an error.
          */
         if (i < num_part - 1)
         {
-            partition_size = read_partition_size(partition_size_ptr);
+            if (read_is_valid(partition_size_ptr, 3, user_data_end))
+                partition_size = read_partition_size(partition_size_ptr);
+            else if (pbi->ec_active)
+                partition_size = bytes_left;
+            else
+                vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                                   "Truncated partition size data");
         }
         else
-        {
-            partition_size = user_data_end - partition;
-        }
+            partition_size = bytes_left;
 
-        if (!pbi->ec_enabled && (partition + partition_size > user_data_end
-            || partition + partition_size < partition))
-            vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
-                               "Truncated packet or corrupt partition "
-                               "%d length", i + 1);
+        /* Validate the calculated partition length. If the buffer
+         * described by the partition can't be fully read, then restrict
+         * it to the portion that can be (for EC mode) or throw an error.
+         */
+        if (!read_is_valid(partition, partition_size, user_data_end))
+        {
+            if (pbi->ec_active)
+                partition_size = bytes_left;
+            else
+                vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                                   "Truncated packet or corrupt partition "
+                                   "%d length", i + 1);
+        }
 
         if (vp8dx_start_decode(bool_decoder, partition, partition_size))
             vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
@@ -634,6 +674,9 @@
             xd->subpixel_predict8x8   = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x8);
             xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear16x16);
         }
+
+        if (pbi->decoded_key_frame && pbi->ec_enabled && !pbi->ec_active)
+            pbi->ec_active = 1;
     }
 
     xd->left_context = &pc->left_context;
@@ -656,6 +699,8 @@
     int mb_row;
     int i, j, k, l;
     const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
+    int corrupt_tokens = 0;
+    int prev_independent_partitions = pbi->independent_partitions;
 
     if (pbi->input_partition)
     {
@@ -669,7 +714,7 @@
 
     if (data_end - data < 3)
     {
-        if (pbi->ec_enabled)
+        if (pbi->ec_active)
         {
             /* Declare the missing frame as an inter frame since it will
                be handled as an inter frame when we have estimated its
@@ -694,7 +739,7 @@
             (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
         data += 3;
 
-        if (!pbi->ec_enabled && (data + first_partition_length_in_bytes > data_end
+        if (!pbi->ec_active && (data + first_partition_length_in_bytes > data_end
             || data + first_partition_length_in_bytes < data))
             vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                                "Truncated packet or corrupt partition 0 length");
@@ -709,7 +754,7 @@
             /* When error concealment is enabled we should only check the sync
              * code if we have enough bits available
              */
-            if (!pbi->ec_enabled || data + 3 < data_end)
+            if (!pbi->ec_active || data + 3 < data_end)
             {
                 if (data[0] != 0x9d || data[1] != 0x01 || data[2] != 0x2a)
                     vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
@@ -720,7 +765,7 @@
              * if we have enough data. Otherwise we will end up with the wrong
              * size.
              */
-            if (!pbi->ec_enabled || data + 6 < data_end)
+            if (!pbi->ec_active || data + 6 < data_end)
             {
                 pc->Width = (data[3] | (data[4] << 8)) & 0x3fff;
                 pc->horiz_scale = data[4] >> 6;
@@ -919,7 +964,7 @@
 #if CONFIG_ERROR_CONCEALMENT
         /* Assume we shouldn't refresh golden if the bit is missing */
         xd->corrupted |= vp8dx_bool_error(bc);
-        if (pbi->ec_enabled && xd->corrupted)
+        if (pbi->ec_active && xd->corrupted)
             pc->refresh_golden_frame = 0;
 #endif
 
@@ -927,7 +972,7 @@
 #if CONFIG_ERROR_CONCEALMENT
         /* Assume we shouldn't refresh altref if the bit is missing */
         xd->corrupted |= vp8dx_bool_error(bc);
-        if (pbi->ec_enabled && xd->corrupted)
+        if (pbi->ec_active && xd->corrupted)
             pc->refresh_alt_ref_frame = 0;
 #endif
 
@@ -957,7 +1002,7 @@
 #if CONFIG_ERROR_CONCEALMENT
     /* Assume we should refresh the last frame if the bit is missing */
     xd->corrupted |= vp8dx_bool_error(bc);
-    if (pbi->ec_enabled && xd->corrupted)
+    if (pbi->ec_active && xd->corrupted)
         pc->refresh_last_frame = 1;
 #endif
 
@@ -975,6 +1020,8 @@
     }
 
     {
+        pbi->independent_partitions = 1;
+
         /* read coef probability tree */
         for (i = 0; i < BLOCK_TYPES; i++)
             for (j = 0; j < COEF_BANDS; j++)
@@ -989,6 +1036,9 @@
                             *p = (vp8_prob)vp8_read_literal(bc, 8);
 
                         }
+                        if (k > 0 && *p != pc->fc.coef_probs[i][j][k-1][l])
+                            pbi->independent_partitions = 0;
+
                     }
     }
 
@@ -1015,7 +1065,7 @@
     vp8_decode_mode_mvs(pbi);
 
 #if CONFIG_ERROR_CONCEALMENT
-    if (pbi->ec_enabled &&
+    if (pbi->ec_active &&
             pbi->mvs_corrupt_from_mb < (unsigned int)pc->mb_cols * pc->mb_rows)
     {
         /* Motion vectors are missing in this frame. We will try to estimate
@@ -1029,14 +1079,19 @@
 #if CONFIG_MULTITHREAD
     if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION)
     {
+        int i;
+        pbi->frame_corrupt_residual = 0;
         vp8mt_decode_mb_rows(pbi, xd);
         vp8_yv12_extend_frame_borders_ptr(&pc->yv12_fb[pc->new_fb_idx]);    /*cm->frame_to_show);*/
+        for (i = 0; i < pbi->decoding_thread_count; ++i)
+            corrupt_tokens |= pbi->mb_row_di[i].mbd.corrupted;
     }
     else
 #endif
     {
         int ibc = 0;
         int num_part = 1 << pc->multi_token_partition;
+        pbi->frame_corrupt_residual = 0;
 
         /* Decode the individual macro block */
         for (mb_row = 0; mb_row < pc->mb_rows; mb_row++)
@@ -1053,17 +1108,26 @@
 
             decode_mb_row(pbi, pc, mb_row, xd);
         }
+        corrupt_tokens |= xd->corrupted;
     }
 
     stop_token_decoder(pbi);
 
     /* Collect information about decoder corruption. */
     /* 1. Check first boolean decoder for errors. */
-    pc->yv12_fb[pc->new_fb_idx].corrupted =
-        vp8dx_bool_error(bc);
+    pc->yv12_fb[pc->new_fb_idx].corrupted = vp8dx_bool_error(bc);
     /* 2. Check the macroblock information */
-    pc->yv12_fb[pc->new_fb_idx].corrupted |=
-        xd->corrupted;
+    pc->yv12_fb[pc->new_fb_idx].corrupted |= corrupt_tokens;
+
+    if (!pbi->decoded_key_frame)
+    {
+        if (pc->frame_type == KEY_FRAME &&
+            !pc->yv12_fb[pc->new_fb_idx].corrupted)
+            pbi->decoded_key_frame = 1;
+        else
+            vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME,
+                               "A stream must start with a complete key frame");
+    }
 
     /* vpx_log("Decoder: Frame Decoded, Size Roughly:%d bytes  \n",bc->pos+pbi->bc2.pos); */
 
@@ -1077,6 +1141,7 @@
     if (pc->refresh_entropy_probs == 0)
     {
         vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
+        pbi->independent_partitions = prev_independent_partitions;
     }
 
 #ifdef PACKET_TESTING
diff --git a/vp8/decoder/error_concealment.c b/vp8/decoder/error_concealment.c
index 4f8f1a6..7051bb9 100644
--- a/vp8/decoder/error_concealment.c
+++ b/vp8/decoder/error_concealment.c
@@ -567,7 +567,6 @@
             else
             {
                 mv->as_int = 0;
-                mi->bmi[row*4 + col].as_mode = NEW4X4;
                 mi->mbmi.need_to_clamp_mvs = 0;
             }
         }
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index 2246194..db6528c 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -101,9 +101,21 @@
 #else
     pbi->ec_enabled = 0;
 #endif
+    /* Error concealment is activated after a key frame has been
+     * decoded without errors when error concealment is enabled.
+     */
+    pbi->ec_active = 0;
+
+    pbi->decoded_key_frame = 0;
 
     pbi->input_partition = oxcf->input_partition;
 
+    /* Independent partitions is activated when a frame updates the
+     * token probability table to have equal probabilities over the
+     * PREV_COEF context.
+     */
+    pbi->independent_partitions = 0;
+
     return (VP8D_PTR) pbi;
 }
 
@@ -346,11 +358,15 @@
             /* If error concealment is disabled we won't signal missing frames to
              * the decoder.
              */
-            if (!pbi->ec_enabled)
+            if (!pbi->ec_active)
             {
                 /* Signal that we have no frame to show. */
                 cm->show_frame = 0;
 
+                pbi->num_partitions = 0;
+                if (pbi->input_partition)
+                    pbi->common.multi_token_partition = 0;
+
                 /* Nothing more to do. */
                 return 0;
             }
@@ -379,6 +395,10 @@
 #endif
             pbi->common.error.setjmp = 0;
 
+            pbi->num_partitions = 0;
+            if (pbi->input_partition)
+                pbi->common.multi_token_partition = 0;
+
            /* We do not know if the missing frame(s) was supposed to update
             * any of the reference buffers, but we act conservative and
             * mark only the last buffer as corrupted.
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
index eac57ab..4ece431 100644
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -132,7 +132,11 @@
     unsigned int mvs_corrupt_from_mb;
 #endif
     int ec_enabled;
+    int ec_active;
     int input_partition;
+    int decoded_key_frame;
+    int independent_partitions;
+    int frame_corrupt_residual;
 
 } VP8D_COMP;
 
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
index 1e03302..fdde04a 100644
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -93,6 +93,7 @@
 static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col)
 {
     int eobtotal = 0;
+    int throw_residual = 0;
     int i, do_clamp = xd->mode_info_context->mbmi.need_to_clamp_mvs;
 
     if (xd->mode_info_context->mbmi.mb_skip_coeff)
@@ -112,7 +113,7 @@
 
     eobtotal |= (xd->mode_info_context->mbmi.mode == B_PRED ||
                   xd->mode_info_context->mbmi.mode == SPLITMV);
-    if (!eobtotal)
+    if (!eobtotal && !vp8dx_bool_error(xd->current_bc))
     {
         /* Special case:  Force the loopfilter to skip when eobtotal and
          * mb_skip_coeff are zero.
@@ -154,14 +155,22 @@
         vp8_build_inter_predictors_mb(xd);
     }
 
+    /* When we have independent partitions we can apply residual even
+     * though other partitions within the frame are corrupt.
+     */
+    throw_residual = (!pbi->independent_partitions &&
+                      pbi->frame_corrupt_residual);
+    throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));
+
 #if CONFIG_ERROR_CONCEALMENT
-    if (pbi->ec_enabled &&
+    if (pbi->ec_active &&
         (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
-        vp8dx_bool_error(xd->current_bc)))
+        throw_residual))
     {
         /* MB with corrupt residuals or corrupt mode/motion vectors.
          * Better to use the predictor as reconstruction.
          */
+        pbi->frame_corrupt_residual = 1;
         vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
         vp8_conceal_corrupt_mb(xd);
         return;
@@ -314,25 +323,32 @@
                         xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
 
 #if CONFIG_ERROR_CONCEALMENT
-                        if (pbi->ec_enabled &&
-                            (xd->mode_info_context->mbmi.ref_frame ==
-                                                                 INTRA_FRAME) &&
-                            vp8dx_bool_error(xd->current_bc))
                         {
-                            /* We have an intra block with corrupt coefficients,
-                             * better to conceal with an inter block.
-                             * Interpolate MVs from neighboring MBs
-                             *
-                             * Note that for the first mb with corrupt residual
-                             * in a frame, we might not discover that before
-                             * decoding the residual. That happens after this
-                             * check, and therefore no inter concealment will be
-                             * done.
-                             */
-                            vp8_interpolate_motion(xd,
-                                                   mb_row, mb_col,
-                                                   pc->mb_rows, pc->mb_cols,
-                                                   pc->mode_info_stride);
+                            int corrupt_residual =
+                                        (!pbi->independent_partitions &&
+                                        pbi->frame_corrupt_residual) ||
+                                        vp8dx_bool_error(xd->current_bc);
+                            if (pbi->ec_active &&
+                                (xd->mode_info_context->mbmi.ref_frame ==
+                                                                 INTRA_FRAME) &&
+                                corrupt_residual)
+                            {
+                                /* We have an intra block with corrupt
+                                 * coefficients, better to conceal with an inter
+                                 * block.
+                                 * Interpolate MVs from neighboring MBs
+                                 *
+                                 * Note that for the first mb with corrupt
+                                 * residual in a frame, we might not discover
+                                 * that before decoding the residual. That
+                                 * happens after this check, and therefore no
+                                 * inter concealment will be done.
+                                 */
+                                vp8_interpolate_motion(xd,
+                                                       mb_row, mb_col,
+                                                       pc->mb_rows, pc->mb_cols,
+                                                       pc->mode_info_stride);
+                            }
                         }
 #endif
 
@@ -355,9 +371,19 @@
                         xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
                         xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
 
+                        if (xd->mode_info_context->mbmi.ref_frame !=
+                                INTRA_FRAME)
+                        {
+                            /* propagate errors from reference frames */
+                            xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
+                        }
+
                         vp8_build_uvmvs(xd, pc->full_pixel);
                         decode_macroblock(pbi, xd, mb_row, mb_col);
 
+                        /* check if the boolean decoder has suffered an error */
+                        xd->corrupted |= vp8dx_bool_error(xd->current_bc);
+
                         if (pbi->common.filter_level)
                         {
                             int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
@@ -803,23 +829,28 @@
                 xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
 
 #if CONFIG_ERROR_CONCEALMENT
-                if (pbi->ec_enabled &&
-                    (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
-                    vp8dx_bool_error(xd->current_bc))
                 {
-                    /* We have an intra block with corrupt coefficients, better
-                     * to conceal with an inter block. Interpolate MVs from
-                     * neighboring MBs
-                     *
-                     * Note that for the first mb with corrupt residual in a
-                     * frame, we might not discover that before decoding the
-                     * residual. That happens after this check, and therefore no
-                     * inter concealment will be done.
-                     */
-                    vp8_interpolate_motion(xd,
-                                           mb_row, mb_col,
-                                           pc->mb_rows, pc->mb_cols,
-                                           pc->mode_info_stride);
+                    int corrupt_residual = (!pbi->independent_partitions &&
+                                            pbi->frame_corrupt_residual) ||
+                                            vp8dx_bool_error(xd->current_bc);
+                    if (pbi->ec_active &&
+                        (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
+                        corrupt_residual)
+                    {
+                        /* We have an intra block with corrupt coefficients,
+                         * better to conceal with an inter block. Interpolate
+                         * MVs from neighboring MBs
+                         *
+                         * Note that for the first mb with corrupt residual in a
+                         * frame, we might not discover that before decoding the
+                         * residual. That happens after this check, and
+                         * therefore no inter concealment will be done.
+                         */
+                        vp8_interpolate_motion(xd,
+                                               mb_row, mb_col,
+                                               pc->mb_rows, pc->mb_cols,
+                                               pc->mode_info_stride);
+                    }
                 }
 #endif
 
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index a4730a7..9cdc1e5 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -357,11 +357,25 @@
     int max_bits;
 
     // For CBR we need to also consider buffer fullness.
+    // If we are running below the optimal level then we need to gradually tighten up on max_bits.
     if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
     {
-        max_bits = 2 * cpi->av_per_frame_bandwidth;
-        max_bits -= cpi->buffered_av_per_frame_bandwidth;
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
+        double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
+
+        // For CBR base this on the target average bits per frame plus the maximum sedction rate passed in by the user
+        max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
+
+        // If our buffer is below the optimum level
+        if (buffer_fullness_ratio < 1.0)
+        {
+            // The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4.
+            int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
+
+            max_bits = (int)(max_bits * buffer_fullness_ratio);
+
+            if (max_bits < min_max_bits)
+                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
+        }
     }
     // VBR
     else
@@ -377,45 +391,6 @@
     return max_bits;
 }
 
-
-static int gf_group_max_bits(VP8_COMP *cpi)
-{
-    // Max allocation for a golden frame group
-    int max_bits;
-
-    // For CBR we need to also consider buffer fullness.
-    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
-    {
-        max_bits = cpi->av_per_frame_bandwidth * cpi->baseline_gf_interval;
-        if (max_bits > cpi->oxcf.optimal_buffer_level)
-        {
-            max_bits -= cpi->oxcf.optimal_buffer_level;
-            max_bits += cpi->buffer_level;
-        }
-        else
-        {
-            max_bits -= (cpi->buffered_av_per_frame_bandwidth
-                         - cpi->av_per_frame_bandwidth)
-                        * cpi->baseline_gf_interval;
-        }
-
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
-    }
-    else
-    {
-        // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
-        max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
-        max_bits *=  cpi->baseline_gf_interval;
-    }
-
-
-    // Trap case where we are out of bits
-    if (max_bits < 0)
-        max_bits = 0;
-
-    return max_bits;
-}
-
 void vp8_init_first_pass(VP8_COMP *cpi)
 {
     zero_stats(cpi->twopass.total_stats);
@@ -887,8 +862,6 @@
     double correction_factor;
     double corr_high;
     double speed_correction = 1.0;
-    double rolling_ratio;
-
     double pow_highq = 0.90;
     double pow_lowq = 0.40;
 
@@ -898,8 +871,10 @@
     target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
 
     // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
-    if ((cpi->rolling_target_bits > 0.0) && (cpi->active_worst_quality < cpi->worst_quality))
+    if ((cpi->rolling_target_bits > 0) && (cpi->active_worst_quality < cpi->worst_quality))
     {
+        double rolling_ratio;
+
         rolling_ratio = (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits;
 
         //if ( cpi->twopass.est_max_qcorrection_factor > rolling_ratio )
@@ -1626,7 +1601,7 @@
     double abs_mv_in_out_accumulator = 0.0;
     double mod_err_per_mb_accumulator = 0.0;
 
-    int max_group_bits;
+    int max_bits = frame_max_bits(cpi);     // Max for a single frame
 
     unsigned int allow_alt_ref =
                     cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
@@ -1988,9 +1963,8 @@
 
     // Clip cpi->twopass.gf_group_bits based on user supplied data rate
     // variability limit (cpi->oxcf.two_pass_vbrmax_section)
-    max_group_bits = gf_group_max_bits(cpi);
-    if (cpi->twopass.gf_group_bits > max_group_bits)
-        cpi->twopass.gf_group_bits = max_group_bits;
+    if (cpi->twopass.gf_group_bits > max_bits * cpi->baseline_gf_interval)
+        cpi->twopass.gf_group_bits = max_bits * cpi->baseline_gf_interval;
 
     // Reset the file position
     reset_fpf_position(cpi, start_pos);
@@ -2090,6 +2064,13 @@
             }
         }
 
+        // Apply an additional limit for CBR
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            if (cpi->twopass.gf_bits > (cpi->buffer_level >> 1))
+                cpi->twopass.gf_bits = cpi->buffer_level >> 1;
+        }
+
         // Dont allow a negative value for gf_bits
         if (gf_bits < 0)
             gf_bits = 0;
@@ -2126,6 +2107,10 @@
         if (cpi->twopass.gf_group_bits < 0)
             cpi->twopass.gf_group_bits = 0;
 
+        // This condition could fail if there are two kfs very close together
+        // despite (MIN_GF_INTERVAL) and would cause a devide by 0 in the
+        // calculation of cpi->twopass.alt_extra_bits.
+        if ( cpi->baseline_gf_interval >= 3 )
         {
 #if NEW_BOOST
             int boost = (cpi->source_alt_ref_pending)
@@ -2133,19 +2118,24 @@
 #else
             int boost = cpi->gfu_boost;
 #endif
-            // Set aside some bits for a mid gf sequence boost
-            if ((boost > 150) && (cpi->baseline_gf_interval > 5))
+            if ( boost >= 150 )
             {
-                int pct_extra = (boost - 100) / 50;
-                pct_extra = (pct_extra > 10) ? 10 : pct_extra;
+                int pct_extra;
 
-                cpi->twopass.mid_gf_extra_bits =
+                pct_extra = (boost - 100) / 50;
+                pct_extra = (pct_extra > 20) ? 20 : pct_extra;
+
+                cpi->twopass.alt_extra_bits =
                     (cpi->twopass.gf_group_bits * pct_extra) / 100;
-                cpi->twopass.gf_group_bits -= cpi->twopass.mid_gf_extra_bits;
+                cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits;
+                cpi->twopass.alt_extra_bits /=
+                    ((cpi->baseline_gf_interval-1)>>1);
             }
             else
-                cpi->twopass.mid_gf_extra_bits = 0;
+                cpi->twopass.alt_extra_bits = 0;
         }
+        else
+            cpi->twopass.alt_extra_bits = 0;
     }
 
     // Adjustment to estimate_max_q based on a measure of complexity of the section
@@ -2225,9 +2215,12 @@
 
     target_frame_size += cpi->min_frame_bandwidth;                                          // Add in the minimum number of bits that is set aside for every frame.
 
-    // Special case for the frame that lies half way between two gfs
-    if (cpi->common.frames_since_golden == cpi->baseline_gf_interval / 2)
-        target_frame_size += cpi->twopass.mid_gf_extra_bits;
+    // Every other frame gets a few extra bits
+    if ( (cpi->common.frames_since_golden & 0x01) &&
+         (cpi->frames_till_gf_update_due > 0) )
+    {
+        target_frame_size += cpi->twopass.alt_extra_bits;
+    }
 
     cpi->per_frame_bandwidth = target_frame_size;                                           // Per frame bit target for this frame
 }
@@ -2570,8 +2563,11 @@
             && lookup_next_frame_stats(cpi, &next_frame) != EOF)
         {
             // Normal scene cut check
-            if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
+            if ( ( i >= MIN_GF_INTERVAL ) &&
+                 test_candidate_kf(cpi, &last_frame, this_frame, &next_frame) )
+            {
                 break;
+            }
 
             // How fast is prediction quality decaying
             loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 3f7b868..ff9a641 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -1460,7 +1460,6 @@
     cpi->rolling_actual_bits          = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_target_bits     = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_actual_bits     = cpi->av_per_frame_bandwidth;
-    cpi->buffered_av_per_frame_bandwidth = cpi->av_per_frame_bandwidth;
 
     cpi->total_actual_bits            = 0;
     cpi->total_target_vs_actual       = 0;
@@ -1556,7 +1555,7 @@
         break;
     }
 
-    if (cpi->pass == 0 && cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER)
+    if (cpi->pass == 0)
         cpi->auto_worst_q = 1;
 
     cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
@@ -3198,116 +3197,6 @@
 
 }
 
-
-static void update_buffer_level(VP8_COMP *cpi)
-{
-    int64_t tmp;
-
-    /* Update the buffered average bitrate.
-     *
-     * The buffered average bitrate tracks the bitrate over the buffer
-     * window. Here we simulate taking a frame of average size out
-     * of the buffer, and putting in the new frame just encoded.
-     * It is calculated accordingly:
-     *
-     * A = Average Bits Per Frame In The Buffer
-     * P = New Frame Size
-     * N = Number of bits in the buffer
-     *
-     * We recalculate the average as so:
-     *      (N-A)*A + A*P    A * (N - A + P)
-     * A' = ------------- =  ---------------
-     *            N                 N
-     *
-     * This is modeled after a the standard algorithm for a moving
-     * average with fixed weighting (eg A' = ((N-1)*A + 1*P) / N). This makes
-     * the step response nonlinear but consistent with expected behavior --
-     * when A is large, the model adapts more quickly, since there are
-     * fewer frames in the buffer and conversely when A is small there
-     * will be more frames in the buffer so the average will adapt
-     * slowly.
-     *
-     * TODO(jkoleszar): This may give poor step response in some situations,
-     * for example motion following a long static section. It might be
-     * worth experimenting more with weighting by av_per_frame_bandwidth
-     * rather than buffered_av_per_frame_bandwidth or using a more accurate
-     * algorithm to get faster response. Current testing showed worse results
-     * with that setting though.
-     *
-     */
-
-    /* Guard against buffered_av_per_frame_bandwidth falling to 0. Should
-     * never happen, but without this check, it would be irrecoverable.
-     */
-    if(cpi->buffered_av_per_frame_bandwidth == 0)
-        cpi->buffered_av_per_frame_bandwidth = 1;
-
-    tmp = cpi->oxcf.maximum_buffer_size
-                - cpi->buffered_av_per_frame_bandwidth
-                + cpi->projected_frame_size;
-    tmp *= cpi->buffered_av_per_frame_bandwidth;
-    cpi->buffered_av_per_frame_bandwidth = tmp
-                                           / cpi->oxcf.maximum_buffer_size;
-
-    if(cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
-    {
-        /* In CBR mode, buffer level is synthesized from the buffered
-         * average per-frame bandwidth to get the response characteristics
-         * of that model, rather than using the unbounded (wrt buffer size)
-         * bits_off_target. ie, the long term average bitrate doesn't
-         * matter in CBR mode. If the clip is consistently undershooting
-         * because it is very static, for example, you don't want to blow
-         * your short term bitrate budget trying to the the long term spend
-         * up to the target when you hit a motion section.
-         *
-         * Instead, the ratio of buffered_av_per_frame_bandwidth to the
-         * target av_per_frame_bandwidth is taken, scaled by
-         * maximum_buffer_size and centered around optimal_buffer_level,
-         * which presents the expected behavior of buffer_level for the other
-         * parts of the rate control code which handle the targeting.
-         *
-         * Note that this only happens after the starting_buffer_level
-         * has passed, to give the model a chance to stabilize.
-         */
-        if(cpi->total_actual_bits > cpi->oxcf.starting_buffer_level)
-        {
-            tmp = (int64_t)cpi->buffered_av_per_frame_bandwidth
-                  * cpi->oxcf.maximum_buffer_size
-                  / cpi->av_per_frame_bandwidth;
-            cpi->buffer_level = cpi->oxcf.maximum_buffer_size
-                                - tmp
-                                + cpi->oxcf.optimal_buffer_level;
-        }
-        else
-            cpi->buffer_level = cpi->oxcf.optimal_buffer_level;
-
-        /* Accumulate recent overshoot error.
-         *
-         * If this frame is larger than the target, then accumulate
-         * that error to apply as a damping factor later. Only care about
-         * recent overshoot, so this value decays by (N-P)/N
-         */
-        if(cpi->total_actual_bits > cpi->oxcf.starting_buffer_level)
-        {
-            int64_t decayed_overshoot;
-
-            decayed_overshoot = cpi->accumulated_overshoot;
-            decayed_overshoot *= (cpi->oxcf.maximum_buffer_size
-                                  - cpi->projected_frame_size);
-            decayed_overshoot /= cpi->oxcf.maximum_buffer_size;
-            cpi->accumulated_overshoot = decayed_overshoot;
-
-            cpi->accumulated_overshoot +=
-                (cpi->projected_frame_size > cpi->av_per_frame_bandwidth)
-                ? cpi->projected_frame_size - cpi->av_per_frame_bandwidth
-                : 0;
-        }
-    }
-    else
-        cpi->buffer_level = cpi->bits_off_target;
-}
-
-
 static void encode_frame_to_data_rate
 (
     VP8_COMP *cpi,
@@ -3553,8 +3442,7 @@
     // For CBR if the buffer reaches its maximum level then we can no longer
     // save up bits for later frames so we might as well use them up
     // on the current frame.
-    if (cpi->pass == 2
-        && (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+    if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
         (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && cpi->buffered_mode)
     {
         int Adjustment = cpi->active_worst_quality / 4;       // Max adjustment is 1/4
@@ -3645,10 +3533,6 @@
         }
         else
         {
-            if(cpi->pass != 2)
-                Q = cpi->auto_worst_q?
-                    cpi->active_worst_quality:cpi->avg_frame_qindex;
-
             cpi->active_best_quality = inter_minq[Q];
 
             // For the constant/constrained quality mode we dont want
@@ -3950,17 +3834,15 @@
             (cpi->active_worst_quality < cpi->worst_quality)      &&
             (cpi->projected_frame_size > frame_over_shoot_limit))
         {
-            /* step down active_worst_quality such that the corresponding
-             * active_best_quality will be equal to the current
-             * active_worst_quality + 1. Once the limit on active_best_quality
-             * is reached, active_worst_quality will equal worst_quality.
-             */
-            int i;
+            int over_size_percent = ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / frame_over_shoot_limit;
 
-            for(i=cpi->active_worst_quality; i<cpi->worst_quality; i++)
-                if(inter_minq[i] >= cpi->active_worst_quality + 1)
-                    break;
-            cpi->active_worst_quality = i;
+            // If so is there any scope for relaxing it
+            while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
+            {
+                cpi->active_worst_quality++;
+                top_index = cpi->active_worst_quality;
+                over_size_percent = (int)(over_size_percent * 0.96);        // Assume 1 qstep = about 4% on frame size.
+            }
 
             // If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
             active_worst_qchanged = TRUE;
@@ -4348,9 +4230,10 @@
 
     // Update the buffer level variable.
     // Non-viewable frames are a special case and are treated as pure overhead.
-    if ( cm->show_frame )
-        cpi->bits_off_target += cpi->av_per_frame_bandwidth;
-    cpi->bits_off_target -= cpi->projected_frame_size;
+    if ( !cm->show_frame )
+        cpi->bits_off_target -= cpi->projected_frame_size;
+    else
+        cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
 
     // Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
     cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
@@ -4364,7 +4247,7 @@
     // Debug stats
     cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size);
 
-    update_buffer_level(cpi);
+    cpi->buffer_level = cpi->bits_off_target;
 
     // Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
     if (cm->frame_type == KEY_FRAME)
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 0d347e3..f75f6cb 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -348,10 +348,6 @@
     int per_frame_bandwidth;          // Current section per frame bandwidth target
     int av_per_frame_bandwidth;        // Average frame size target for clip
     int min_frame_bandwidth;          // Minimum allocation that should be used for any frame
-    int buffered_av_per_frame_bandwidth; // Average bitrate over the last buffer
-    int buffered_av_per_frame_bandwidth_rem; // Average bitrate remainder
-    int accumulated_overshoot;           // Accumulated # of bits spent > target
-
     int inter_frame_target;
     double output_frame_rate;
     int64_t last_time_stamp_seen;
@@ -556,7 +552,7 @@
 
         int gf_group_bits;                // Projected Bits available for a group of frames including 1 GF or ARF
         int gf_bits;                     // Bits for the golden frame or ARF - 2 pass only
-        int mid_gf_extra_bits;             // A few extra bits for the frame half way between two gfs.
+        int alt_extra_bits;
         double est_max_qcorrection_factor;
     } twopass;
 
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 769c91a..46e1d9d 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -608,7 +608,7 @@
     int min_frame_target;
     int Adjustment;
 
-    min_frame_target = 1;
+    min_frame_target = 0;
 
     if (cpi->pass == 2)
     {
@@ -617,11 +617,9 @@
         if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
             min_frame_target = cpi->av_per_frame_bandwidth >> 5;
     }
-    else
-    {
-        if (min_frame_target < cpi->per_frame_bandwidth / 4)
-            min_frame_target = cpi->per_frame_bandwidth / 4;
-    }
+    else if (min_frame_target < cpi->per_frame_bandwidth / 4)
+        min_frame_target = cpi->per_frame_bandwidth / 4;
+
 
     // Special alt reference frame case
     if (cpi->common.refresh_alt_ref_frame)
@@ -1114,33 +1112,6 @@
 
         }
     }
-
-    if (cpi->pass==0
-        && cpi->common.refresh_golden_frame
-        && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
-        int64_t adjust;
-
-        /*
-        frames_in_buffer = cpi->oxcf.maximum_buffer_size
-                           / cpi->av_per_frame_bandwidth;
-        gf_in_buffer = frames_in_buffer /
-                       cpi->frames_till_gf_update_due;
-        overshoot_per_gf = cpi->accumulated_overshoot / gf_in_buffer;
-
-        */
-
-        adjust = cpi->accumulated_overshoot;
-        adjust *= cpi->frames_till_gf_update_due + 1;
-        adjust *= cpi->av_per_frame_bandwidth;
-        adjust /= cpi->oxcf.maximum_buffer_size;
-
-        if (adjust > (cpi->this_frame_target - min_frame_target))
-            adjust = (cpi->this_frame_target - min_frame_target);
-        else if (adjust < 0)
-            adjust = 0;
-
-        cpi->this_frame_target -= adjust;
-    }
 }