]> granicus.if.org Git - libvpx/blobdiff - vp8/encoder/onyx_if.c
Merge "ppc: Add vpx_sadnxmx4d_vsx for n,m = {8, 16, 32 ,64}"
[libvpx] / vp8 / encoder / onyx_if.c
index 4d64d6966d800d4839366a156a86259f994e33b2..9227f750d55979b572d6d6be054069c9e9ae972f 100644 (file)
@@ -16,6 +16,7 @@
 #include "vp8/common/blockd.h"
 #include "onyx_int.h"
 #include "vp8/common/systemdependent.h"
+#include "vp8/common/skin_detection.h"
 #include "vp8/encoder/quantize.h"
 #include "vp8/common/alloccommon.h"
 #include "mcomp.h"
@@ -33,6 +34,7 @@
 #include "vp8/common/reconintra.h"
 #include "vp8/common/swapyv12buffer.h"
 #include "vp8/common/threading.h"
+#include "vpx_ports/system_state.h"
 #include "vpx_ports/vpx_timer.h"
 #if ARCH_ARM
 #include "vpx_ports/arm.h"
@@ -42,6 +44,7 @@
 #endif
 #include "encodeframe.h"
 
+#include <assert.h>
 #include <math.h>
 #include <stdio.h>
 #include <limits.h>
@@ -85,6 +88,9 @@ FILE *yuv_file;
 #ifdef OUTPUT_YUV_DENOISED
 FILE *yuv_denoised_file;
 #endif
+#ifdef OUTPUT_YUV_SKINMAP
+FILE *yuv_skinmap_file = NULL;
+#endif
 
 #if 0
 FILE *framepsnr;
@@ -726,6 +732,7 @@ void vp8_set_speed_features(VP8_COMP *cpi) {
   SPEED_FEATURES *sf = &cpi->sf;
   int Mode = cpi->compressor_speed;
   int Speed = cpi->Speed;
+  int Speed2;
   int i;
   VP8_COMMON *cm = &cpi->common;
   int last_improved_quant = sf->improved_quant;
@@ -827,9 +834,16 @@ void vp8_set_speed_features(VP8_COMP *cpi) {
   cpi->mode_check_freq[THR_V_PRED] = cpi->mode_check_freq[THR_H_PRED] =
       cpi->mode_check_freq[THR_B_PRED] =
           speed_map(Speed, mode_check_freq_map_vhbpred);
-  cpi->mode_check_freq[THR_NEW1] = speed_map(Speed, mode_check_freq_map_new1);
+
+  // For real-time mode at speed 10 keep the mode_check_freq threshold
+  // for NEW1 similar to that of speed 9.
+  Speed2 = Speed;
+  if (cpi->Speed == 10 && Mode == 2) Speed2 = RT(9);
+  cpi->mode_check_freq[THR_NEW1] = speed_map(Speed2, mode_check_freq_map_new1);
+
   cpi->mode_check_freq[THR_NEW2] = cpi->mode_check_freq[THR_NEW3] =
       speed_map(Speed, mode_check_freq_map_new2);
+
   cpi->mode_check_freq[THR_SPLIT1] =
       speed_map(Speed, mode_check_freq_map_split1);
   cpi->mode_check_freq[THR_SPLIT2] = cpi->mode_check_freq[THR_SPLIT3] =
@@ -1500,6 +1514,12 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
   cpi->baseline_gf_interval =
       cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
 
+  // GF behavior for 1 pass CBR, used when error_resilience is off.
+  if (!cpi->oxcf.error_resilient_mode &&
+      cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER &&
+      cpi->oxcf.Mode == MODE_REALTIME)
+    cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr;
+
 #if (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
   cpi->oxcf.token_partitions = 3;
 #endif
@@ -1626,8 +1646,7 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
   cm->sharpness_level = cpi->oxcf.Sharpness;
 
   if (cm->horiz_scale != NORMAL || cm->vert_scale != NORMAL) {
-    int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
-    int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+    int hr, hs, vr, vs;
 
     Scale2Ratio(cm->horiz_scale, &hr, &hs);
     Scale2Ratio(cm->vert_scale, &vr, &vs);
@@ -1799,9 +1818,13 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->mse_source_denoised = 0;
 
   /* Should we use the cyclic refresh method.
-   * Currently this is tied to error resilliant mode
+   * Currently there is no external control for this.
+   * Enable it for error_resilient_mode, or for 1 pass CBR mode.
    */
-  cpi->cyclic_refresh_mode_enabled = cpi->oxcf.error_resilient_mode;
+  cpi->cyclic_refresh_mode_enabled =
+      (cpi->oxcf.error_resilient_mode ||
+       (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER &&
+        cpi->oxcf.Mode <= 2));
   cpi->cyclic_refresh_mode_max_mbs_perframe =
       (cpi->common.mb_rows * cpi->common.mb_cols) / 7;
   if (cpi->oxcf.number_of_layers == 1) {
@@ -1814,6 +1837,23 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->cyclic_refresh_mode_index = 0;
   cpi->cyclic_refresh_q = 32;
 
+  // GF behavior for 1 pass CBR, used when error_resilience is off.
+  cpi->gf_update_onepass_cbr = 0;
+  cpi->gf_noboost_onepass_cbr = 0;
+  if (!cpi->oxcf.error_resilient_mode &&
+      cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER && cpi->oxcf.Mode <= 2) {
+    cpi->gf_update_onepass_cbr = 1;
+    cpi->gf_noboost_onepass_cbr = 1;
+    cpi->gf_interval_onepass_cbr =
+        cpi->cyclic_refresh_mode_max_mbs_perframe > 0
+            ? (2 * (cpi->common.mb_rows * cpi->common.mb_cols) /
+               cpi->cyclic_refresh_mode_max_mbs_perframe)
+            : 10;
+    cpi->gf_interval_onepass_cbr =
+        VPXMIN(40, VPXMAX(6, cpi->gf_interval_onepass_cbr));
+    cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr;
+  }
+
   if (cpi->cyclic_refresh_mode_enabled) {
     CHECK_MEM_ERROR(cpi->cyclic_refresh_map,
                     vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
@@ -1897,6 +1937,9 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
 #ifdef OUTPUT_YUV_DENOISED
   yuv_denoised_file = fopen("denoised.yuv", "ab");
 #endif
+#ifdef OUTPUT_YUV_SKINMAP
+  yuv_skinmap_file = fopen("skinmap.yuv", "ab");
+#endif
 
 #if 0
     framepsnr = fopen("framepsnr.stt", "a");
@@ -1948,9 +1991,6 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->fn_ptr[BLOCK_16X16].sdf = vpx_sad16x16;
   cpi->fn_ptr[BLOCK_16X16].vf = vpx_variance16x16;
   cpi->fn_ptr[BLOCK_16X16].svf = vpx_sub_pixel_variance16x16;
-  cpi->fn_ptr[BLOCK_16X16].svf_halfpix_h = vpx_variance_halfpixvar16x16_h;
-  cpi->fn_ptr[BLOCK_16X16].svf_halfpix_v = vpx_variance_halfpixvar16x16_v;
-  cpi->fn_ptr[BLOCK_16X16].svf_halfpix_hv = vpx_variance_halfpixvar16x16_hv;
   cpi->fn_ptr[BLOCK_16X16].sdx3f = vpx_sad16x16x3;
   cpi->fn_ptr[BLOCK_16X16].sdx8f = vpx_sad16x16x8;
   cpi->fn_ptr[BLOCK_16X16].sdx4df = vpx_sad16x16x4d;
@@ -1958,9 +1998,6 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->fn_ptr[BLOCK_16X8].sdf = vpx_sad16x8;
   cpi->fn_ptr[BLOCK_16X8].vf = vpx_variance16x8;
   cpi->fn_ptr[BLOCK_16X8].svf = vpx_sub_pixel_variance16x8;
-  cpi->fn_ptr[BLOCK_16X8].svf_halfpix_h = NULL;
-  cpi->fn_ptr[BLOCK_16X8].svf_halfpix_v = NULL;
-  cpi->fn_ptr[BLOCK_16X8].svf_halfpix_hv = NULL;
   cpi->fn_ptr[BLOCK_16X8].sdx3f = vpx_sad16x8x3;
   cpi->fn_ptr[BLOCK_16X8].sdx8f = vpx_sad16x8x8;
   cpi->fn_ptr[BLOCK_16X8].sdx4df = vpx_sad16x8x4d;
@@ -1968,9 +2005,6 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->fn_ptr[BLOCK_8X16].sdf = vpx_sad8x16;
   cpi->fn_ptr[BLOCK_8X16].vf = vpx_variance8x16;
   cpi->fn_ptr[BLOCK_8X16].svf = vpx_sub_pixel_variance8x16;
-  cpi->fn_ptr[BLOCK_8X16].svf_halfpix_h = NULL;
-  cpi->fn_ptr[BLOCK_8X16].svf_halfpix_v = NULL;
-  cpi->fn_ptr[BLOCK_8X16].svf_halfpix_hv = NULL;
   cpi->fn_ptr[BLOCK_8X16].sdx3f = vpx_sad8x16x3;
   cpi->fn_ptr[BLOCK_8X16].sdx8f = vpx_sad8x16x8;
   cpi->fn_ptr[BLOCK_8X16].sdx4df = vpx_sad8x16x4d;
@@ -1978,9 +2012,6 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->fn_ptr[BLOCK_8X8].sdf = vpx_sad8x8;
   cpi->fn_ptr[BLOCK_8X8].vf = vpx_variance8x8;
   cpi->fn_ptr[BLOCK_8X8].svf = vpx_sub_pixel_variance8x8;
-  cpi->fn_ptr[BLOCK_8X8].svf_halfpix_h = NULL;
-  cpi->fn_ptr[BLOCK_8X8].svf_halfpix_v = NULL;
-  cpi->fn_ptr[BLOCK_8X8].svf_halfpix_hv = NULL;
   cpi->fn_ptr[BLOCK_8X8].sdx3f = vpx_sad8x8x3;
   cpi->fn_ptr[BLOCK_8X8].sdx8f = vpx_sad8x8x8;
   cpi->fn_ptr[BLOCK_8X8].sdx4df = vpx_sad8x8x4d;
@@ -1988,9 +2019,6 @@ struct VP8_COMP *vp8_create_compressor(VP8_CONFIG *oxcf) {
   cpi->fn_ptr[BLOCK_4X4].sdf = vpx_sad4x4;
   cpi->fn_ptr[BLOCK_4X4].vf = vpx_variance4x4;
   cpi->fn_ptr[BLOCK_4X4].svf = vpx_sub_pixel_variance4x4;
-  cpi->fn_ptr[BLOCK_4X4].svf_halfpix_h = NULL;
-  cpi->fn_ptr[BLOCK_4X4].svf_halfpix_v = NULL;
-  cpi->fn_ptr[BLOCK_4X4].svf_halfpix_hv = NULL;
   cpi->fn_ptr[BLOCK_4X4].sdx3f = vpx_sad4x4x3;
   cpi->fn_ptr[BLOCK_4X4].sdx8f = vpx_sad4x4x8;
   cpi->fn_ptr[BLOCK_4X4].sdx4df = vpx_sad4x4x4d;
@@ -2077,11 +2105,7 @@ void vp8_remove_compressor(VP8_COMP **ptr) {
       double time_encoded =
           (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
           10000000.000;
-      double total_encode_time =
-          (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
       double dr = (double)cpi->bytes * 8.0 / 1000.0 / time_encoded;
-      const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
-      const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
 
       if (cpi->b_calculate_psnr) {
         if (cpi->oxcf.number_of_layers > 1) {
@@ -2089,7 +2113,7 @@ void vp8_remove_compressor(VP8_COMP **ptr) {
 
           fprintf(f,
                   "Layer\tBitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\t"
-                  "GLPsnrP\tVPXSSIM\t\n");
+                  "GLPsnrP\tVPXSSIM\n");
           for (i = 0; i < (int)cpi->oxcf.number_of_layers; ++i) {
             double dr =
                 (double)cpi->bytes_in_layer[i] * 8.0 / 1000.0 / time_encoded;
@@ -2121,14 +2145,12 @@ void vp8_remove_compressor(VP8_COMP **ptr) {
 
           fprintf(f,
                   "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\t"
-                  "GLPsnrP\tVPXSSIM\t  Time(us)  Rc-Err "
-                  "Abs Err\n");
+                  "GLPsnrP\tVPXSSIM\n");
           fprintf(f,
                   "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
-                  "%7.3f\t%8.0f %7.2f %7.2f\n",
+                  "%7.3f\n",
                   dr, cpi->total / cpi->count, total_psnr,
-                  cpi->totalp / cpi->count, total_psnr2, total_ssim,
-                  total_encode_time, rate_err, fabs(rate_err));
+                  cpi->totalp / cpi->count, total_psnr2, total_ssim);
         }
       }
       fclose(f);
@@ -2283,6 +2305,9 @@ void vp8_remove_compressor(VP8_COMP **ptr) {
 #ifdef OUTPUT_YUV_DENOISED
   fclose(yuv_denoised_file);
 #endif
+#ifdef OUTPUT_YUV_SKINMAP
+  fclose(yuv_skinmap_file);
+#endif
 
 #if 0
 
@@ -2345,7 +2370,7 @@ static uint64_t calc_plane_error(unsigned char *orig, int orig_stride,
     recon += recon_stride;
   }
 
-  vp8_clear_system_state();
+  vpx_clear_system_state();
   return total_sse;
 }
 
@@ -2459,10 +2484,11 @@ int vp8_update_entropy(VP8_COMP *cpi, int update) {
   return 0;
 }
 
-#if defined(OUTPUT_YUV_SRC) || defined(OUTPUT_YUV_DENOISED)
+#if defined(OUTPUT_YUV_SRC) || defined(OUTPUT_YUV_DENOISED) || \
+    defined(OUTPUT_YUV_SKINMAP)
 void vp8_write_yuv_frame(FILE *yuv_file, YV12_BUFFER_CONFIG *s) {
   unsigned char *src = s->y_buffer;
-  int h = s->y_height;
+  int h = s->y_crop_height;
 
   do {
     fwrite(src, s->y_width, 1, yuv_file);
@@ -2470,7 +2496,7 @@ void vp8_write_yuv_frame(FILE *yuv_file, YV12_BUFFER_CONFIG *s) {
   } while (--h);
 
   src = s->u_buffer;
-  h = s->uv_height;
+  h = s->uv_crop_height;
 
   do {
     fwrite(src, s->uv_width, 1, yuv_file);
@@ -2478,7 +2504,7 @@ void vp8_write_yuv_frame(FILE *yuv_file, YV12_BUFFER_CONFIG *s) {
   } while (--h);
 
   src = s->v_buffer;
-  h = s->uv_height;
+  h = s->uv_crop_height;
 
   do {
     fwrite(src, s->uv_width, 1, yuv_file);
@@ -2493,8 +2519,7 @@ static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {
   /* are we resizing the image */
   if (cm->horiz_scale != 0 || cm->vert_scale != 0) {
 #if CONFIG_SPATIAL_RESAMPLING
-    int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
-    int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+    int hr, hs, vr, vs;
     int tmp_height;
 
     if (cm->vert_scale == 3) {
@@ -2527,8 +2552,7 @@ static int resize_key_frame(VP8_COMP *cpi) {
    */
   if (cpi->oxcf.allow_spatial_resampling &&
       (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) {
-    int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
-    int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+    int hr, hs, vr, vs;
     int new_width, new_height;
 
     /* If we are below the resample DOWN watermark then scale down a
@@ -2740,7 +2764,7 @@ static int decide_key_frame(VP8_COMP *cpi) {
   if (cpi->Speed > 11) return 0;
 
   /* Clear down mmx registers */
-  vp8_clear_system_state();
+  vpx_clear_system_state();
 
   if ((cpi->compressor_speed == 2) && (cpi->Speed >= 5) && (cpi->sf.RD == 0)) {
     double change = 1.0 *
@@ -2795,7 +2819,7 @@ static int decide_key_frame(VP8_COMP *cpi) {
   return code_key_frame;
 }
 
-static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest,
+static void Pass1Encode(VP8_COMP *cpi, size_t *size, unsigned char *dest,
                         unsigned int *frame_flags) {
   (void)size;
   (void)dest;
@@ -3044,6 +3068,7 @@ static int measure_square_diff_partial(YV12_BUFFER_CONFIG *source,
   }
   // Only return non-zero if we have at least ~1/16 samples for estimate.
   if (num_blocks > (tot_num_blocks >> 4)) {
+    assert(num_blocks != 0);
     return (Total / num_blocks);
   } else {
     return 0;
@@ -3178,7 +3203,7 @@ void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) {
   } else {
     struct vpx_usec_timer timer;
 
-    vp8_clear_system_state();
+    vpx_clear_system_state();
 
     vpx_usec_timer_start(&timer);
     if (cpi->sf.auto_filter == 0) {
@@ -3234,7 +3259,7 @@ void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm) {
   vp8_yv12_extend_frame_borders(cm->frame_to_show);
 }
 
-static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
+static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
                                       unsigned char *dest,
                                       unsigned char *dest_end,
                                       unsigned int *frame_flags) {
@@ -3266,30 +3291,33 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
   int drop_mark25 = drop_mark / 8;
 
   /* Clear down mmx registers to allow floating point in what follows */
-  vp8_clear_system_state();
+  vpx_clear_system_state();
 
   if (cpi->force_next_frame_intra) {
     cm->frame_type = KEY_FRAME; /* delayed intra frame */
     cpi->force_next_frame_intra = 0;
   }
 
-/* For an alt ref frame in 2 pass we skip the call to the second pass
- * function that sets the target bandwidth
- */
+  /* For an alt ref frame in 2 pass we skip the call to the second pass
+   * function that sets the target bandwidth
+   */
+  switch (cpi->pass) {
 #if !CONFIG_REALTIME_ONLY
-
-  if (cpi->pass == 2) {
-    if (cpi->common.refresh_alt_ref_frame) {
-      /* Per frame bit target for the alt ref frame */
-      cpi->per_frame_bandwidth = cpi->twopass.gf_bits;
-      /* per second target bitrate */
-      cpi->target_bandwidth =
-          (int)(cpi->twopass.gf_bits * cpi->output_framerate);
-    }
-  } else
-#endif
-    cpi->per_frame_bandwidth =
-        (int)(cpi->target_bandwidth / cpi->output_framerate);
+    case 2:
+      if (cpi->common.refresh_alt_ref_frame) {
+        /* Per frame bit target for the alt ref frame */
+        cpi->per_frame_bandwidth = cpi->twopass.gf_bits;
+        /* per second target bitrate */
+        cpi->target_bandwidth =
+            (int)(cpi->twopass.gf_bits * cpi->output_framerate);
+      }
+      break;
+#endif  // !CONFIG_REALTIME_ONLY
+    default:
+      cpi->per_frame_bandwidth =
+          (int)(cpi->target_bandwidth / cpi->output_framerate);
+      break;
+  }
 
   /* Default turn off buffer to buffer copying */
   cm->copy_buffer_to_gf = 0;
@@ -3622,7 +3650,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
    * There is some odd behavior for one pass here that needs attention.
    */
   if ((cpi->pass == 2) || (cpi->ni_frames > 150)) {
-    vp8_clear_system_state();
+    vpx_clear_system_state();
 
     Q = cpi->active_worst_quality;
 
@@ -3848,7 +3876,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
 #endif
 
   do {
-    vp8_clear_system_state();
+    vpx_clear_system_state();
 
     vp8_set_quantizer(cpi, Q);
 
@@ -3972,7 +4000,6 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
 #else
     /* transform / motion compensation build reconstruction frame */
     vp8_encode_frame(cpi);
-
     if (cpi->oxcf.screen_content_mode == 2) {
       if (vp8_drop_encodedframe_overshoot(cpi, Q)) return;
     }
@@ -3981,7 +4008,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
     cpi->projected_frame_size =
         (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
 #endif
-    vp8_clear_system_state();
+    vpx_clear_system_state();
 
     /* Test to see if the stats generated for this frame indicate that
      * we should have coded a key frame (assuming that we didn't)!
@@ -4025,7 +4052,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
 #endif
     }
 
-    vp8_clear_system_state();
+    vpx_clear_system_state();
 
     if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
 
@@ -4049,15 +4076,17 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
 #if !CONFIG_REALTIME_ONLY
       top_index = cpi->active_worst_quality;
 #endif  // !CONFIG_REALTIME_ONLY
-        /* If we have updated the active max Q do not call
-         * vp8_update_rate_correction_factors() this loop.
-         */
+      /* If we have updated the active max Q do not call
+       * vp8_update_rate_correction_factors() this loop.
+       */
       active_worst_qchanged = 1;
     } else {
       active_worst_qchanged = 0;
     }
 
-#if !CONFIG_REALTIME_ONLY
+#if CONFIG_REALTIME_ONLY
+    Loop = 0;
+#else
     /* Special case handling for forced key frames */
     if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) {
       int last_q = Q;
@@ -4232,9 +4261,10 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
                                           : cpi->mb.zbin_over_quant;
 
       Loop = Q != last_q;
-    } else
-#endif
+    } else {
       Loop = 0;
+    }
+#endif  // CONFIG_REALTIME_ONLY
 
     if (cpi->is_src_frame_alt_ref) Loop = 0;
 
@@ -4247,6 +4277,20 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
     }
   } while (Loop == 1);
 
+#if defined(DROP_UNCODED_FRAMES)
+  /* if there are no coded macroblocks at all drop this frame */
+  if (cpi->common.MBs == cpi->mb.skip_true_count &&
+      (cpi->drop_frame_count & 7) != 7 && cm->frame_type != KEY_FRAME) {
+    cpi->common.current_video_frame++;
+    cpi->frames_since_key++;
+    cpi->drop_frame_count++;
+    // We advance the temporal pattern for dropped frames.
+    cpi->temporal_pattern_counter++;
+    return;
+  }
+  cpi->drop_frame_count = 0;
+#endif
+
 #if 0
     /* Experimental code for lagged and one pass
      * Update stats used for one pass GF selection
@@ -4388,10 +4432,17 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
   }
 #endif
 
+#ifdef OUTPUT_YUV_SKINMAP
+  if (cpi->common.current_video_frame > 1) {
+    compute_skin_map(cpi, yuv_skinmap_file);
+  }
+#endif
+
 #if CONFIG_MULTITHREAD
   if (cpi->b_multi_threaded) {
     /* start loopfilter in separate thread */
     sem_post(&cpi->h_event_start_lpf);
+    cpi->b_lpf_running = 1;
   } else
 #endif
   {
@@ -4420,20 +4471,13 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
   /* build the bitstream */
   vp8_pack_bitstream(cpi, dest, dest_end, size);
 
-#if CONFIG_MULTITHREAD
-  /* wait for the lpf thread done */
-  if (cpi->b_multi_threaded) {
-    sem_wait(&cpi->h_event_end_lpf);
-  }
-#endif
-
   /* Move storing frame_type out of the above loop since it is also
    * needed in motion search besides loopfilter */
   cm->last_frame_type = cm->frame_type;
 
   /* Update rate control heuristics */
   cpi->total_byte_count += (*size);
-  cpi->projected_frame_size = (*size) << 3;
+  cpi->projected_frame_size = (int)(*size) << 3;
 
   if (cpi->oxcf.number_of_layers > 1) {
     unsigned int i;
@@ -4598,7 +4642,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
     {
         FILE *f = fopen("tmp.stt", "a");
 
-        vp8_clear_system_state();
+        vpx_clear_system_state();
 
         if (cpi->twopass.total_left_stats.coded_error != 0.0)
             fprintf(f, "%10d %10d %10d %10d %10d %10"PRId64" %10"PRId64
@@ -4760,7 +4804,7 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size,
   /* vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show); */
 }
 #if !CONFIG_REALTIME_ONLY
-static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest,
+static void Pass2Encode(VP8_COMP *cpi, size_t *size, unsigned char *dest,
                         unsigned char *dest_end, unsigned int *frame_flags) {
   if (!cpi->common.refresh_alt_ref_frame) vp8_second_pass(cpi);
 
@@ -4813,7 +4857,7 @@ static int frame_is_reference(const VP8_COMP *cpi) {
 }
 
 int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
-                            unsigned long *size, unsigned char *dest,
+                            size_t *size, unsigned char *dest,
                             unsigned char *dest_end, int64_t *time_stamp,
                             int64_t *time_end, int flush) {
   VP8_COMMON *cm;
@@ -4828,7 +4872,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
 
   if (setjmp(cpi->common.error.jmp)) {
     cpi->common.error.setjmp = 0;
-    vp8_clear_system_state();
+    vpx_clear_system_state();
     return VPX_CODEC_CORRUPT_FRAME;
   }
 
@@ -5035,7 +5079,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
   *size = 0;
 
   /* Clear down mmx registers */
-  vp8_clear_system_state();
+  vpx_clear_system_state();
 
   cm->frame_type = INTER_FRAME;
   cm->frame_flags = *frame_flags;
@@ -5066,15 +5110,15 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
 
     assert(i < NUM_YV12_BUFFERS);
   }
+  switch (cpi->pass) {
 #if !CONFIG_REALTIME_ONLY
-
-  if (cpi->pass == 1) {
-    Pass1Encode(cpi, size, dest, frame_flags);
-  } else if (cpi->pass == 2) {
-    Pass2Encode(cpi, size, dest, dest_end, frame_flags);
-  } else
-#endif
-    encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags);
+    case 1: Pass1Encode(cpi, size, dest, frame_flags); break;
+    case 2: Pass2Encode(cpi, size, dest, dest_end, frame_flags); break;
+#endif  // !CONFIG_REALTIME_ONLY
+    default:
+      encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags);
+      break;
+  }
 
   if (cpi->compressor_speed == 2) {
     unsigned int duration, duration2;
@@ -5188,7 +5232,7 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
 
           vp8_deblock(cm, cm->frame_to_show, &cm->post_proc_buffer,
                       cm->filter_level * 10 / 6, 1, 0);
-          vp8_clear_system_state();
+          vpx_clear_system_state();
 
           ye = calc_plane_error(orig->y_buffer, orig->y_stride, pp->y_buffer,
                                 pp->y_stride, y_width, y_height);
@@ -5263,6 +5307,14 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags,
 
   cpi->common.error.setjmp = 0;
 
+#if CONFIG_MULTITHREAD
+  /* wait for the lpf thread done */
+  if (cpi->b_multi_threaded && cpi->b_lpf_running) {
+    sem_wait(&cpi->h_event_end_lpf);
+    cpi->b_lpf_running = 0;
+  }
+#endif
+
   return 0;
 }
 
@@ -5290,7 +5342,7 @@ int vp8_get_preview_raw_frame(VP8_COMP *cpi, YV12_BUFFER_CONFIG *dest,
     }
 
 #endif
-    vp8_clear_system_state();
+    vpx_clear_system_state();
     return ret;
   }
 }