Merge "Move frame allocations out of vp8_decode_frame()"
diff --git a/vp8/common/rtcd.c b/vp8/common/rtcd.c
index 4980f48..3150fff 100644
--- a/vp8/common/rtcd.c
+++ b/vp8/common/rtcd.c
@@ -11,16 +11,7 @@
 #define RTCD_C
 #include "vpx_rtcd.h"
 
-#if CONFIG_MULTITHREAD && HAVE_PTHREAD_H
-#include <pthread.h>
-static void once(void (*func)(void))
-{
-    static pthread_once_t lock = PTHREAD_ONCE_INIT;
-    pthread_once(&lock, func);
-}
-
-
-#elif CONFIG_MULTITHREAD && defined(_WIN32)
+#if CONFIG_MULTITHREAD && defined(_WIN32)
 #include <windows.h>
 static void once(void (*func)(void))
 {
@@ -44,6 +35,15 @@
 }
 
 
+#elif CONFIG_MULTITHREAD && HAVE_PTHREAD_H
+#include <pthread.h>
+static void once(void (*func)(void))
+{
+    static pthread_once_t lock = PTHREAD_ONCE_INIT;
+    pthread_once(&lock, func);
+}
+
+
 #else
 /* No-op version that performs no synchronization. vpx_rtcd() is idempotent,
  * so as long as your platform provides atomic loads/stores of pointers
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 838a31b..8027a07 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -48,7 +48,7 @@
 
 static void read_kf_modes(VP8D_COMP *pbi, MODE_INFO *mi)
 {
-    vp8_reader *const bc = & pbi->bc;
+    vp8_reader *const bc = & pbi->mbc[8];
     const int mis = pbi->common.mode_info_stride;
 
     mi->mbmi.ref_frame = INTRA_FRAME;
@@ -150,7 +150,7 @@
 
 static void mb_mode_mv_init(VP8D_COMP *pbi)
 {
-    vp8_reader *const bc = & pbi->bc;
+    vp8_reader *const bc = & pbi->mbc[8];
     MV_CONTEXT *const mvc = pbi->common.fc.mvc;
 
 #if CONFIG_ERROR_CONCEALMENT
@@ -338,7 +338,7 @@
 
 static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi)
 {
-    vp8_reader *const bc = & pbi->bc;
+    vp8_reader *const bc = & pbi->mbc[8];
     mbmi->ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, pbi->prob_intra);
     if (mbmi->ref_frame)    /* inter MB */
     {
@@ -596,14 +596,14 @@
      * By default on a key frame reset all MBs to segment 0
      */
     if (pbi->mb.update_mb_segmentation_map)
-        read_mb_features(&pbi->bc, &mi->mbmi, &pbi->mb);
+        read_mb_features(&pbi->mbc[8], &mi->mbmi, &pbi->mb);
     else if(pbi->common.frame_type == KEY_FRAME)
         mi->mbmi.segment_id = 0;
 
     /* Read the macroblock coeff skip flag if this feature is in use,
      * else default to 0 */
     if (pbi->common.mb_no_coeff_skip)
-        mi->mbmi.mb_skip_coeff = vp8_read(&pbi->bc, pbi->prob_skip_false);
+        mi->mbmi.mb_skip_coeff = vp8_read(&pbi->mbc[8], pbi->prob_skip_false);
     else
         mi->mbmi.mb_skip_coeff = 0;
 
@@ -645,7 +645,7 @@
 #if CONFIG_ERROR_CONCEALMENT
             /* look for corruption. set mvs_corrupt_from_mb to the current
              * mb_num if the frame is corrupt from this macroblock. */
-            if (vp8dx_bool_error(&pbi->bc) && mb_num <
+            if (vp8dx_bool_error(&pbi->mbc[8]) && mb_num <
                 (int)pbi->mvs_corrupt_from_mb)
             {
                 pbi->mvs_corrupt_from_mb = mb_num;
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index dbd4505..a4a00f6 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -823,7 +823,7 @@
 static void setup_token_decoder(VP8D_COMP *pbi,
                                 const unsigned char* token_part_sizes)
 {
-    vp8_reader *bool_decoder = &pbi->bc2;
+    vp8_reader *bool_decoder = &pbi->mbc[0];
     unsigned int partition_idx;
     unsigned int fragment_idx;
     unsigned int num_token_partitions;
@@ -831,14 +831,10 @@
                                           pbi->fragment_sizes[0];
 
     TOKEN_PARTITION multi_token_partition =
-            (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
-    if (!vp8dx_bool_error(&pbi->bc))
+            (TOKEN_PARTITION)vp8_read_literal(&pbi->mbc[8], 2);
+    if (!vp8dx_bool_error(&pbi->mbc[8]))
         pbi->common.multi_token_partition = multi_token_partition;
     num_token_partitions = 1 << pbi->common.multi_token_partition;
-    if (num_token_partitions > 1)
-    {
-        bool_decoder = &pbi->mbc[0];
-    }
 
     /* Check for partitions within the fragments and unpack the fragments
      * so that each fragment pointer points to its corresponding partition. */
@@ -983,7 +979,7 @@
 
 int vp8_decode_frame(VP8D_COMP *pbi)
 {
-    vp8_reader *const bc = & pbi->bc;
+    vp8_reader *const bc = & pbi->mbc[8];
     VP8_COMMON *const pc = & pbi->common;
     MACROBLOCKD *const xd  = & pbi->mb;
     const unsigned char *data = pbi->fragments[0];
@@ -1184,7 +1180,7 @@
 
     setup_token_decoder(pbi, data + first_partition_length_in_bytes);
 
-    xd->current_bc = &pbi->bc2;
+    xd->current_bc = &pbi->mbc[0];
 
     /* Read the default quantizers. */
     {
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
index 022c698..0063beb 100644
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -41,7 +41,8 @@
 
     DECLARE_ALIGNED(16, VP8_COMMON, common);
 
-    vp8_reader bc, bc2;
+    /* the last partition will be used for the modes/mvs */
+    vp8_reader mbc[MAX_PARTITIONS];
 
     VP8D_CONFIG oxcf;
 
@@ -79,7 +80,6 @@
     /* end of threading data */
 #endif
 
-    vp8_reader mbc[8];
     int64_t last_time_stamp;
     int   ready_for_new_data;
 
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
index a91281b..e52a707 100644
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -64,7 +64,7 @@
         mbd->mode_ref_lf_delta_enabled    = xd->mode_ref_lf_delta_enabled;
         mbd->mode_ref_lf_delta_update    = xd->mode_ref_lf_delta_update;
 
-        mbd->current_bc = &pbi->bc2;
+        mbd->current_bc = &pbi->mbc[0];
 
         vpx_memcpy(mbd->dequant_y1_dc, xd->dequant_y1_dc, sizeof(xd->dequant_y1_dc));
         vpx_memcpy(mbd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 4885587..fa66206 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -450,72 +450,52 @@
 /* A simple function to cyclically refresh the background at a lower Q */
 static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
 {
-    unsigned char *seg_map;
+    unsigned char *seg_map = cpi->segmentation_map;
     signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
     int i;
     int block_count = cpi->cyclic_refresh_mode_max_mbs_perframe;
     int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols;
 
-    /* Create a temporary map for segmentation data. */
-    CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+    cpi->cyclic_refresh_q = Q / 2;
 
-    cpi->cyclic_refresh_q = Q;
+    // Set every macroblock to be eligible for update.
+    // For key frame this will reset seg map to 0.
+    vpx_memset(cpi->segmentation_map, 0, mbs_in_frame);
 
-    for (i = Q; i > 0; i--)
-    {
-        if (vp8_bits_per_mb[cpi->common.frame_type][i] >= ((vp8_bits_per_mb[cpi->common.frame_type][Q]*(Q + 128)) / 64))
-        {
-            break;
-        }
-    }
-
-    cpi->cyclic_refresh_q = i;
-
-    /* Only update for inter frames */
     if (cpi->common.frame_type != KEY_FRAME)
     {
         /* Cycle through the macro_block rows */
         /* MB loop to set local segmentation map */
-        for (i = cpi->cyclic_refresh_mode_index; i < mbs_in_frame; i++)
+        i = cpi->cyclic_refresh_mode_index;
+        do
         {
-            /* If the MB is as a candidate for clean up then mark it for
-             * possible boost/refresh (segment 1) The segment id may get
-             * reset to 0 later if the MB gets coded anything other than
-             * last frame 0,0 as only (last frame 0,0) MBs are eligable for
-             * refresh : that is to say Mbs likely to be background blocks.
-             */
-            if (cpi->cyclic_refresh_map[i] == 0)
-            {
-                seg_map[i] = 1;
-            }
-            else
-            {
-                seg_map[i] = 0;
+          /* If the MB is as a candidate for clean up then mark it for
+           * possible boost/refresh (segment 1) The segment id may get
+           * reset to 0 later if the MB gets coded anything other than
+           * last frame 0,0 as only (last frame 0,0) MBs are eligable for
+           * refresh : that is to say Mbs likely to be background blocks.
+           */
+          if (cpi->cyclic_refresh_map[i] == 0)
+          {
+              seg_map[i] = 1;
+              block_count --;
+          }
+          else if (cpi->cyclic_refresh_map[i] < 0)
+              cpi->cyclic_refresh_map[i]++;
 
-                /* Skip blocks that have been refreshed recently anyway. */
-                if (cpi->cyclic_refresh_map[i] < 0)
-                    cpi->cyclic_refresh_map[i]++;
-            }
-
-
-            if (block_count > 0)
-                block_count--;
-            else
-                break;
+          i++;
+          if (i == mbs_in_frame)
+              i = 0;
 
         }
+        while(block_count && i != cpi->cyclic_refresh_mode_index);
 
-        /* If we have gone through the frame reset to the start */
         cpi->cyclic_refresh_mode_index = i;
-
-        if (cpi->cyclic_refresh_mode_index >= mbs_in_frame)
-            cpi->cyclic_refresh_mode_index = 0;
     }
 
-    /* Set the segmentation Map */
-    set_segmentation_map(cpi, seg_map);
-
     /* Activate segmentation. */
+    cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 1;
     enable_segmentation(cpi);
 
     /* Set up the quant segment data */
@@ -533,11 +513,6 @@
     /* Initialise the feature data structure */
     set_segment_data(cpi, &feature_data[0][0], SEGMENT_DELTADATA);
 
-    /* Delete sementation map */
-    vpx_free(seg_map);
-
-    seg_map = 0;
-
 }
 
 static void set_default_lf_deltas(VP8_COMP *cpi)
@@ -1828,7 +1803,7 @@
      * Currently this is tied to error resilliant mode
      */
     cpi->cyclic_refresh_mode_enabled = cpi->oxcf.error_resilient_mode;
-    cpi->cyclic_refresh_mode_max_mbs_perframe = (cpi->common.mb_rows * cpi->common.mb_cols) / 40;
+    cpi->cyclic_refresh_mode_max_mbs_perframe = (cpi->common.mb_rows * cpi->common.mb_cols) / 5;
     cpi->cyclic_refresh_mode_index = 0;
     cpi->cyclic_refresh_q = 32;