Merge "ARMv6 optimized Intra4x4 prediction"
diff --git a/build/make/configure.sh b/build/make/configure.sh
index 1bb50af..1279f78 100755
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -901,8 +901,12 @@
         [ "${AS##*/}" = nasm ] && add_asflags -Ox
         AS_SFX=.asm
         case  ${tgt_os} in
-            win*)
-                add_asflags -f win${bits}
+            win32)
+                add_asflags -f win32
+                enabled debug && add_asflags -g cv8
+            ;;
+            win64)
+                add_asflags -f x64
                 enabled debug && add_asflags -g cv8
             ;;
             linux*|solaris*)
diff --git a/vp8/common/recon.c b/vp8/common/recon.c
deleted file mode 100644
index eebf6dc..0000000
--- a/vp8/common/recon.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-
-#include "vpx_config.h"
-#include "recon.h"
-#include "blockd.h"
-
-void vp8_recon_b_c
-(
-    unsigned char *pred_ptr,
-    short *diff_ptr,
-    unsigned char *dst_ptr,
-    int stride
-)
-{
-    int r, c;
-
-    for (r = 0; r < 4; r++)
-    {
-        for (c = 0; c < 4; c++)
-        {
-            int a = diff_ptr[c] + pred_ptr[c] ;
-
-            if (a < 0)
-                a = 0;
-
-            if (a > 255)
-                a = 255;
-
-            dst_ptr[c] = (unsigned char) a ;
-        }
-
-        dst_ptr += stride;
-        diff_ptr += 16;
-        pred_ptr += 16;
-    }
-}
-
-void vp8_recon4b_c
-(
-    unsigned char *pred_ptr,
-    short *diff_ptr,
-    unsigned char *dst_ptr,
-    int stride
-)
-{
-    int r, c;
-
-    for (r = 0; r < 4; r++)
-    {
-        for (c = 0; c < 16; c++)
-        {
-            int a = diff_ptr[c] + pred_ptr[c] ;
-
-            if (a < 0)
-                a = 0;
-
-            if (a > 255)
-                a = 255;
-
-            dst_ptr[c] = (unsigned char) a ;
-        }
-
-        dst_ptr += stride;
-        diff_ptr += 16;
-        pred_ptr += 16;
-    }
-}
-
-void vp8_recon2b_c
-(
-    unsigned char *pred_ptr,
-    short *diff_ptr,
-    unsigned char *dst_ptr,
-    int stride
-)
-{
-    int r, c;
-
-    for (r = 0; r < 4; r++)
-    {
-        for (c = 0; c < 8; c++)
-        {
-            int a = diff_ptr[c] + pred_ptr[c] ;
-
-            if (a < 0)
-                a = 0;
-
-            if (a > 255)
-                a = 255;
-
-            dst_ptr[c] = (unsigned char) a ;
-        }
-
-        dst_ptr += stride;
-        diff_ptr += 8;
-        pred_ptr += 8;
-    }
-}
-
-void vp8_recon_mby_c(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
-{
-#if ARCH_ARM
-    BLOCKD *b = &x->block[0];
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-
-    /*b = &x->block[4];*/
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-
-    /*b = &x->block[8];*/
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-
-    /*b = &x->block[12];*/
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-#else
-    int i;
-
-    for (i = 0; i < 16; i += 4)
-    {
-        BLOCKD *b = &x->block[i];
-
-        RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    }
-#endif
-}
-
-void vp8_recon_mb_c(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
-{
-#if ARCH_ARM
-    BLOCKD *b = &x->block[0];
-
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b += 4;
-    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b += 4;
-
-    /*b = &x->block[16];*/
-
-    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b++;
-    b++;
-    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b++;
-    b++;
-    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    b++;
-    b++;
-    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-#else
-    int i;
-
-    for (i = 0; i < 16; i += 4)
-    {
-        BLOCKD *b = &x->block[i];
-
-        RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    }
-
-    for (i = 16; i < 24; i += 2)
-    {
-        BLOCKD *b = &x->block[i];
-
-        RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
-    }
-#endif
-}
diff --git a/vp8/common/threading.h b/vp8/common/threading.h
index 5927cb1..da6347d 100644
--- a/vp8/common/threading.h
+++ b/vp8/common/threading.h
@@ -17,7 +17,6 @@
 /* Thread management macros */
 #ifdef _WIN32
 /* Win32 */
-#define _WIN32_WINNT 0x500 /* WINBASE.H - Enable signal_object_and_wait */
 #include <process.h>
 #include <windows.h>
 #define THREAD_FUNCTION DWORD WINAPI
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 45086cb..748b607 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -1214,20 +1214,20 @@
             int k = 0;
             unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = {0};
             int prev_coef_savings[MAX_ENTROPY_TOKENS] = {0};
+            const unsigned int (*probs)[MAX_ENTROPY_TOKENS];
             /* Calculate new probabilities given the constraint that
              * they must be equal over the prev coef contexts
              */
+
+            probs = (const unsigned int (*)[MAX_ENTROPY_TOKENS])
+                                                    cpi->coef_counts[i][j];
+
+            /* Reset to default probabilities at key frames */
             if (cpi->common.frame_type == KEY_FRAME)
-            {
-                /* Reset to default probabilities at key frames */
-                sum_probs_over_prev_coef_context(default_coef_counts[i][j],
-                                                 prev_coef_count_sum);
-            }
-            else
-            {
-                sum_probs_over_prev_coef_context(cpi->coef_counts[i][j],
-                                                 prev_coef_count_sum);
-            }
+                probs = default_coef_counts[i][j];
+
+            sum_probs_over_prev_coef_context(probs, prev_coef_count_sum);
+
             do
             {
                 /* at every context */
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 7f2b46d..e996368 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -465,7 +465,7 @@
             else
                 xd->mode_info_context->mbmi.segment_id = 0;
 
-            vp8cx_mb_init_quantizer(cpi, x);
+            vp8cx_mb_init_quantizer(cpi, x, 1);
         }
         else
             xd->mode_info_context->mbmi.segment_id = 0;         // Set to Segment 0 by default
@@ -1255,7 +1255,7 @@
                 xd->mode_info_context->mbmi.segment_id = 0;
 
                 /* segment_id changed, so update */
-                vp8cx_mb_init_quantizer(cpi, x);
+                vp8cx_mb_init_quantizer(cpi, x, 1);
             }
         }
     }
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
index 748942b..557080d 100644
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -20,7 +20,7 @@
                                          int recon_uvoffset);
 extern int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x,
                                           TOKENEXTRA **t);
-extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
+extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip);
 extern void vp8_build_block_offsets(MACROBLOCK *x);
 extern void vp8_setup_block_ptrs(MACROBLOCK *x);
 
@@ -163,7 +163,7 @@
                         else
                             xd->mode_info_context->mbmi.segment_id = 0;
 
-                        vp8cx_mb_init_quantizer(cpi, x);
+                        vp8cx_mb_init_quantizer(cpi, x, 1);
                     }
                     else
                         xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 5a1cf1f..1d00e67 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2605,6 +2605,7 @@
         recon += recon_stride;
     }
 
+    vp8_clear_system_state();
     return total_sse;
 }
 
@@ -3659,7 +3660,11 @@
         else if (cpi->decimation_count > 0)
         {
             cpi->decimation_count --;
+
             cpi->bits_off_target += cpi->av_per_frame_bandwidth;
+            if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
+                cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
+
             cm->current_video_frame++;
             cpi->frames_since_key++;
 
@@ -3676,9 +3681,11 @@
                 // Propagate bits saved by dropping the frame to higher layers
                 for (i=cpi->current_layer+1; i<cpi->oxcf.number_of_layers; i++)
                 {
-                    cpi->layer_context[i].bits_off_target
-                                              += cpi->av_per_frame_bandwidth;
-                    cpi->layer_context[i].buffer_level = cpi->bits_off_target;
+                    LAYER_CONTEXT *lc = &cpi->layer_context[i];
+                    lc->bits_off_target += cpi->av_per_frame_bandwidth;
+                    if (lc->bits_off_target > lc->maximum_buffer_size)
+                        lc->bits_off_target = lc->maximum_buffer_size;
+                    lc->buffer_level = lc->bits_off_target;
                 }
             }
 
@@ -4525,6 +4532,10 @@
     else
         cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
 
+    // Clip the buffer level to the maximum specified buffer size
+    if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
+        cpi->bits_off_target = cpi->oxcf.maximum_buffer_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;
     cpi->rolling_actual_bits = ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4;
@@ -4552,6 +4563,10 @@
 
             lc->bits_off_target += bits_off_for_this_layer;
 
+            // Clip buffer level to maximum buffer size for the layer
+            if (lc->bits_off_target > lc->maximum_buffer_size)
+                lc->bits_off_target = lc->maximum_buffer_size;
+
             lc->total_actual_bits += cpi->projected_frame_size;
             lc->total_target_vs_actual += bits_off_for_this_layer;
             lc->buffer_level = lc->bits_off_target;
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
index 9c759fd..e57a264 100644
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -583,7 +583,7 @@
        cpi->zbin_mode_boost +  \
        x->act_zbin_adj ) ) >> 7)
 
-void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x)
+void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip)
 {
     int i;
     int QIndex;
@@ -607,7 +607,10 @@
     else
         QIndex = cpi->common.base_qindex;
 
-    if (QIndex != x->q_index)
+    /* This initialization should be called at least once. Use ok_to_skip to
+     * decide if it is ok to skip.
+     */
+    if (!ok_to_skip || QIndex != x->q_index)
     {
         // Y
         zbin_extra = ZBIN_EXTRA_Y;
@@ -716,7 +719,7 @@
     cpi->zbin_mode_boost = 0;
 
     // MB level quantizer setup
-    vp8cx_mb_init_quantizer(cpi, &cpi->mb);
+    vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
 }
 
 
diff --git a/vp8/encoder/quantize.h b/vp8/encoder/quantize.h
index f1f0156..07b8813 100644
--- a/vp8/encoder/quantize.h
+++ b/vp8/encoder/quantize.h
@@ -86,7 +86,7 @@
 extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q);
 extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi);
 extern void vp8_update_zbin_extra(struct VP8_COMP *cpi, MACROBLOCK *x);
-extern void vp8cx_mb_init_quantizer(struct VP8_COMP *cpi, MACROBLOCK *x);
+extern void vp8cx_mb_init_quantizer(struct VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip);
 extern void vp8cx_init_quantizer(struct VP8_COMP *cpi);
 
 #endif
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 1ac9050..dc6feb9 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -990,6 +990,8 @@
         {
             // Update the buffer level variable.
             cpi->bits_off_target += cpi->av_per_frame_bandwidth;
+            if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size)
+              cpi->bits_off_target = cpi->oxcf.maximum_buffer_size;
             cpi->buffer_level = cpi->bits_off_target;
         }
         else
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index f966b06..e8abf84 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -43,7 +43,6 @@
 #endif
 
 
-extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
 extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);
 
 #define MAXF(a,b)            (((a) > (b)) ? (a) : (b))