Merge "multi-res: force Key frame sychronization"
authorYunqing Wang <yunqingwang@google.com>
Tue, 22 May 2012 15:00:12 +0000 (08:00 -0700)
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>
Tue, 22 May 2012 15:00:12 +0000 (08:00 -0700)
1  2 
vp8/encoder/onyx_if.c
vp8/encoder/pickinter.c
vp8/vp8_cx_iface.c

diff --combined vp8/encoder/onyx_if.c
@@@ -36,7 -36,6 +36,7 @@@
  #if CONFIG_MULTI_RES_ENCODING
  #include "mr_dissim.h"
  #endif
 +#include "encodeframe.h"
  
  #include <math.h>
  #include <stdio.h>
@@@ -1017,10 -1016,8 +1017,10 @@@ void vp8_set_speed_features(VP8_COMP *c
  
  static void alloc_raw_frame_buffers(VP8_COMP *cpi)
  {
 +#if VP8_TEMPORAL_ALT_REF
      int width = (cpi->oxcf.Width + 15) & ~15;
      int height = (cpi->oxcf.Height + 15) & ~15;
 +#endif
  
      cpi->lookahead = vp8_lookahead_init(cpi->oxcf.Width, cpi->oxcf.Height,
                                          cpi->oxcf.lag_in_frames);
@@@ -1339,7 -1336,7 +1339,7 @@@ static void init_config(VP8_COMP *cpi, 
  #endif
  }
  
 -void update_layer_contexts (VP8_COMP *cpi)
 +static void update_layer_contexts (VP8_COMP *cpi)
  {
      VP8_CONFIG *oxcf = &cpi->oxcf;
  
@@@ -1401,24 -1398,12 +1401,24 @@@ void vp8_change_config(VP8_COMP *cpi, V
      if (!oxcf)
          return;
  
 +#if CONFIG_MULTITHREAD
 +    /*  wait for the last picture loopfilter thread done */
 +    if (cpi->b_lpf_running)
 +    {
 +        sem_wait(&cpi->h_event_end_lpf);
 +        cpi->b_lpf_running = 0;
 +    }
 +#endif
 +
      if (cm->version != oxcf->Version)
      {
          cm->version = oxcf->Version;
          vp8_setup_version(cm);
      }
  
 +    last_w = cpi->oxcf.Width;
 +    last_h = cpi->oxcf.Height;
 +
      cpi->oxcf = *oxcf;
  
      switch (cpi->oxcf.Mode)
      cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
  
  
 -    last_w = cm->Width;
 -    last_h = cm->Height;
 -
      cm->Width       = cpi->oxcf.Width;
      cm->Height      = cpi->oxcf.Height;
  
 -    cm->horiz_scale  = cpi->horiz_scale;
 -    cm->vert_scale   = cpi->vert_scale;
 +    /* TODO(jkoleszar): if an internal spatial resampling is active,
 +     * and we downsize the input image, maybe we should clear the
 +     * internal scale immediately rather than waiting for it to
 +     * correct.
 +     */
  
      // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
      if (cpi->oxcf.Sharpness > 7)
          cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
      }
  
 -    if (last_w != cm->Width || last_h != cm->Height)
 +    if (last_w != cpi->oxcf.Width || last_h != cpi->oxcf.Height)
          cpi->force_next_frame_intra = 1;
  
      if (((cm->Width + 15) & 0xfffffff0) !=
@@@ -3024,7 -3009,7 +3024,7 @@@ static int recode_loop_test( VP8_COMP *
      return force_recode;
  }
  
 -void update_reference_frames(VP8_COMMON *cm)
 +static void update_reference_frames(VP8_COMMON *cm)
  {
      YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb;
  
@@@ -3173,21 -3158,20 +3173,21 @@@ static void encode_frame_to_data_rat
  
      int Loop = 0;
      int loop_count;
 -    int this_q;
 -    int last_zbin_oq;
  
 +    VP8_COMMON *cm = &cpi->common;
 +    int active_worst_qchanged = 0;
 +
 +#if !(CONFIG_REALTIME_ONLY)
      int q_low;
      int q_high;
      int zbin_oq_high;
      int zbin_oq_low = 0;
      int top_index;
      int bottom_index;
 -    VP8_COMMON *cm = &cpi->common;
 -    int active_worst_qchanged = 0;
 -
      int overshoot_seen = 0;
      int undershoot_seen = 0;
 +#endif
 +
      int drop_mark = cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100;
      int drop_mark75 = drop_mark * 2 / 3;
      int drop_mark50 = drop_mark / 4;
      // Clear down mmx registers to allow floating point in what follows
      vp8_clear_system_state();
  
 +#if CONFIG_MULTITHREAD
 +    /*  wait for the last picture loopfilter thread done */
 +    if (cpi->b_lpf_running)
 +    {
 +        sem_wait(&cpi->h_event_end_lpf);
 +        cpi->b_lpf_running = 0;
 +    }
 +#endif
 +
      // Test code for segmentation of gf/arf (0,0)
      //segmentation_test_function( cpi);
  
          cm->frame_type = KEY_FRAME;
      }
  
+ #if CONFIG_MULTI_RES_ENCODING
+     /* In multi-resolution encoding, frame_type is decided by lowest-resolution
+      * encoder. Same frame_type is adopted while encoding at other resolution.
+      */
+     if (cpi->oxcf.mr_encoder_id)
+     {
+         cm->frame_type =
+             ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->frame_type;
+     }
+ #endif
      // Set default state for segment and mode based loop filter update flags
      cpi->mb.e_mbd.update_mb_segmentation_map = 0;
      cpi->mb.e_mbd.update_mb_segmentation_data = 0;
          {
              cpi->decimation_factor = 1;
          }
 -
          //vpx_log("Encoder: Decimation Factor: %d \n",cpi->decimation_factor);
      }
  
  
      // Determine initial Q to try
      Q = vp8_regulate_q(cpi, cpi->this_frame_target);
 -    last_zbin_oq = cpi->zbin_over_quant;
 +
 +#if !(CONFIG_REALTIME_ONLY)
  
      // Set highest allowed value for Zbin over quant
      if (cm->frame_type == KEY_FRAME)
      }
      else
          zbin_oq_high = ZBIN_OQ_MAX;
 +#endif
  
      // Setup background Q adjustment for error resilient mode.
      // For multi-layer encodes only enable this for the base layer.
  
      vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit);
  
 +#if !(CONFIG_REALTIME_ONLY)
      // Limit Q range for the adaptive loop.
      bottom_index = cpi->active_best_quality;
      top_index    = cpi->active_worst_quality;
      q_low  = cpi->active_best_quality;
      q_high = cpi->active_worst_quality;
 +#endif
  
      vp8_save_coding_context(cpi);
  
      loop_count = 0;
  
 -
      scale_and_extend_source(cpi->un_scaled_source, cpi);
 +
  #if !(CONFIG_REALTIME_ONLY) && CONFIG_POSTPROC && !(CONFIG_TEMPORAL_DENOISING)
  
      if (cpi->oxcf.noise_sensitivity > 0)
              */
  
          vp8_set_quantizer(cpi, Q);
 -        this_q = Q;
  
          // setup skip prob for costing in mode/mv decision
          if (cpi->common.mb_no_coeff_skip)
              vp8_setup_key_frame(cpi);
          }
  
 -#if CONFIG_MULTITHREAD
 -        /*  wait for the last picture loopfilter thread done */
 -        if (cpi->b_lpf_running)
 -        {
 -            sem_wait(&cpi->h_event_end_lpf);
 -            cpi->b_lpf_running = 0;
 -        }
 -#endif
 +
  
  #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
          {
              if (cpi->compressor_speed == 2)
              {
                  /* we don't do re-encoding in realtime mode
 -                 * if key frame is decided than we force it on next frame */
 +                 * if key frame is decided then we force it on next frame */
                  cpi->force_next_frame_intra = key_frame_decision;
              }
 +#if !(CONFIG_REALTIME_ONLY)
              else if (key_frame_decision)
              {
                  // Reset all our sizing numbers and recode
  
                  continue;
              }
 +#endif
          }
  
          vp8_clear_system_state();
              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 !(CONFIG_REALTIME_ONLY)
 +            top_index = cpi->active_worst_quality;
 +#endif
              // If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
              active_worst_qchanged = 1;
          }
              // Clamp cpi->zbin_over_quant
              cpi->zbin_over_quant = (cpi->zbin_over_quant < zbin_oq_low) ? zbin_oq_low : (cpi->zbin_over_quant > zbin_oq_high) ? zbin_oq_high : cpi->zbin_over_quant;
  
 -            //Loop = (Q != last_q) || (last_zbin_oq != cpi->zbin_over_quant);
              Loop = Q != last_q;
 -            last_zbin_oq = cpi->zbin_over_quant;
          }
          else
  #endif
@@@ -4819,7 -4808,7 +4830,7 @@@ int vp8_get_compressed_data(VP8_COMP *c
      }
  
      // adjust frame rates based on timestamps given
 -    if (!cm->refresh_alt_ref_frame || (cpi->oxcf.number_of_layers > 1))
 +    if (cm->show_frame)
      {
          int64_t this_duration;
          int step = 0;
  
              if (cpi->oxcf.number_of_layers > 1)
              {
 -                int i;
 +                unsigned int i;
  
                  // Update frame rates for each layer
                  for (i=0; i<cpi->oxcf.number_of_layers; i++)
diff --combined vp8/encoder/pickinter.c
@@@ -405,8 -405,8 +405,8 @@@ void get_lower_res_motion_info(VP8_COM
                                 MB_PREDICTION_MODE *parent_mode,
                                 int_mv *parent_ref_mv, int mb_row, int mb_col)
  {
-     LOWER_RES_INFO* store_mode_info
-                           = (LOWER_RES_INFO*)cpi->oxcf.mr_low_res_mode_info;
+     LOWER_RES_MB_INFO* store_mode_info
+                           = ((LOWER_RES_FRAME_INFO*)cpi->oxcf.mr_low_res_mode_info)->mb_info;
      unsigned int parent_mb_index;
      //unsigned int parent_mb_index = map_640x480_to_320x240[mb_row][mb_col];
  
@@@ -458,7 -458,7 +458,7 @@@ static void check_for_encode_breakout(u
      if (sse < x->encode_breakout)
      {
          // Check u and v to make sure skip is ok
 -        int sse2 = 0;
 +        unsigned int sse2 = 0;
  
          sse2 = VP8_UVSSE(x);
  
diff --combined vp8/vp8_cx_iface.c
  #include "vpx/internal/vpx_codec_internal.h"
  #include "vpx_version.h"
  #include "vp8/encoder/onyx_int.h"
 -#include "vpx/vp8e.h"
 +#include "vpx/vp8cx.h"
  #include "vp8/encoder/firstpass.h"
  #include "vp8/common/onyx.h"
  #include <stdlib.h>
  #include <string.h>
  
 -/* This value is a sentinel for determining whether the user has set a mode
 - * directly through the deprecated VP8E_SET_ENCODING_MODE control.
 - */
 -#define NO_MODE_SET 255
 -
  struct vp8_extracfg
  {
      struct vpx_codec_pkt_list *pkt_list;
@@@ -89,6 -94,7 +89,6 @@@ struct vpx_codec_alg_pri
      unsigned int            next_frame_flag;
      vp8_postproc_cfg_t      preview_ppcfg;
      vpx_codec_pkt_list_decl(64) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
 -    int                         deprecated_mode;
      unsigned int                fixed_kf_cntr;
  };
  
@@@ -177,16 -183,19 +177,16 @@@ static vpx_codec_err_t validate_config(
  
      RANGE_CHECK_BOOL(vp8_cfg,               enable_auto_alt_ref);
      RANGE_CHECK(vp8_cfg, cpu_used,           -16, 16);
 -#if CONFIG_TEMPORAL_DENOISING
 -    RANGE_CHECK(vp8_cfg, noise_sensitivity, 0, 1);
 -#endif
  #if !(CONFIG_REALTIME_ONLY)
      RANGE_CHECK(vp8_cfg, encoding_mode,      VP8_BEST_QUALITY_ENCODING, VP8_REAL_TIME_ENCODING);
 -#if !(CONFIG_TEMPORAL_DENOISING)
 -    RANGE_CHECK_HI(vp8_cfg, noise_sensitivity,  6);
 -#endif
  #else
      RANGE_CHECK(vp8_cfg, encoding_mode,      VP8_REAL_TIME_ENCODING, VP8_REAL_TIME_ENCODING);
 -#if !(CONFIG_TEMPORAL_DENOISING)
 -    RANGE_CHECK(vp8_cfg, noise_sensitivity,  0, 0);
  #endif
 +
 +#if CONFIG_REALTIME_ONLY && !CONFIG_TEMPORAL_DENOISING
 +    RANGE_CHECK(vp8_cfg, noise_sensitivity,  0, 0);
 +#else
 +    RANGE_CHECK_HI(vp8_cfg, noise_sensitivity,  6);
  #endif
  
      RANGE_CHECK(vp8_cfg, token_partitions,   VP8_ONE_TOKENPARTITION, VP8_EIGHT_TOKENPARTITION);
  
      if (cfg->ts_number_layers > 1)
      {
 -        int i;
 +        unsigned int i;
          RANGE_CHECK_HI(cfg, ts_periodicity, 16);
  
          for (i=1; i<cfg->ts_number_layers; i++)
@@@ -507,6 -516,7 +507,6 @@@ static vpx_codec_err_t set_param(vpx_co
  
      switch (ctrl_id)
      {
 -        MAP(VP8E_SET_ENCODING_MODE,         ctx->deprecated_mode);
          MAP(VP8E_SET_CPUUSED,               xcfg.cpu_used);
          MAP(VP8E_SET_ENABLEAUTOALTREF,      xcfg.enable_auto_alt_ref);
          MAP(VP8E_SET_NOISE_SENSITIVITY,     xcfg.noise_sensitivity);
  static vpx_codec_err_t vp8e_mr_alloc_mem(const vpx_codec_enc_cfg_t *cfg,
                                          void **mem_loc)
  {
-     vpx_codec_err_t res = 0;
  #if CONFIG_MULTI_RES_ENCODING
+     LOWER_RES_FRAME_INFO *shared_mem_loc;
      int mb_rows = ((cfg->g_w + 15) >>4);
      int mb_cols = ((cfg->g_h + 15) >>4);
  
-     *mem_loc = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_INFO));
-     if(!(*mem_loc))
+     shared_mem_loc = calloc(1, sizeof(LOWER_RES_FRAME_INFO));
+     if(!shared_mem_loc)
      {
-         free(*mem_loc);
-         res = VPX_CODEC_MEM_ERROR;
+         return VPX_CODEC_MEM_ERROR;
+     }
+     shared_mem_loc->mb_info = calloc(mb_rows*mb_cols, sizeof(LOWER_RES_MB_INFO));
+     if(!(shared_mem_loc->mb_info))
+     {
+         return VPX_CODEC_MEM_ERROR;
      }
      else
-         res = VPX_CODEC_OK;
+     {
+         *mem_loc = (void *)shared_mem_loc;
+         return VPX_CODEC_OK;
+     }
  #endif
-     return res;
  }
  
  static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
                                   vpx_codec_priv_enc_mr_cfg_t *mr_cfg)
  {
 -    vpx_codec_err_t        res = VPX_DEC_OK;
 +    vpx_codec_err_t        res = VPX_CODEC_OK;
      struct vpx_codec_alg_priv *priv;
      vpx_codec_enc_cfg_t       *cfg;
      unsigned int               i;
              return VPX_CODEC_MEM_ERROR;
          }
  
 -        priv->deprecated_mode = NO_MODE_SET;
 -
          res = validate_config(priv, &priv->cfg, &priv->vp8_cfg, 0);
  
          if (!res)
@@@ -647,7 -664,11 +652,11 @@@ static vpx_codec_err_t vp8e_destroy(vpx
  #if CONFIG_MULTI_RES_ENCODING
      /* Free multi-encoder shared memory */
      if (ctx->oxcf.mr_total_resolutions > 0 && (ctx->oxcf.mr_encoder_id == ctx->oxcf.mr_total_resolutions-1))
+     {
+         LOWER_RES_FRAME_INFO *shared_mem_loc = (LOWER_RES_FRAME_INFO *)ctx->oxcf.mr_low_res_mode_info;
+         free(shared_mem_loc->mb_info);
          free(ctx->oxcf.mr_low_res_mode_info);
+     }
  #endif
  
      free(ctx->cx_data);
@@@ -706,6 -727,19 +715,6 @@@ static void pick_quickcompress_mode(vpx
      new_qc = MODE_REALTIME;
  #endif
  
 -    switch (ctx->deprecated_mode)
 -    {
 -    case VP8_BEST_QUALITY_ENCODING:
 -        new_qc = MODE_BESTQUALITY;
 -        break;
 -    case VP8_GOOD_QUALITY_ENCODING:
 -        new_qc = MODE_GOODQUALITY;
 -        break;
 -    case VP8_REAL_TIME_ENCODING:
 -        new_qc = MODE_REALTIME;
 -        break;
 -    }
 -
      if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
          new_qc = MODE_FIRSTPASS;
      else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
@@@ -733,9 -767,6 +742,9 @@@ static vpx_codec_err_t vp8e_encode(vpx_
      if (!ctx->cfg.rc_target_bitrate)
          return res;
  
 +    if (!ctx->cfg.rc_target_bitrate)
 +        return res;
 +
      if (img)
          res = validate_img(ctx, img);
  
@@@ -1185,6 -1216,7 +1194,6 @@@ static vpx_codec_ctrl_fn_map_t vp8e_ctf
      {VP8E_SET_ROI_MAP,                  vp8e_set_roi_map},
      {VP8E_SET_ACTIVEMAP,                vp8e_set_activemap},
      {VP8E_SET_SCALEMODE,                vp8e_set_scalemode},
 -    {VP8E_SET_ENCODING_MODE,            set_param},
      {VP8E_SET_CPUUSED,                  set_param},
      {VP8E_SET_NOISE_SENSITIVITY,        set_param},
      {VP8E_SET_ENABLEAUTOALTREF,         set_param},
@@@ -1295,3 -1327,88 +1304,3 @@@ CODEC_INTERFACE(vpx_codec_vp8_cx) 
          vp8e_mr_alloc_mem,
      } /* encoder functions */
  };
 -
 -
 -/*
 - * BEGIN BACKWARDS COMPATIBILITY SHIM.
 - */
 -#define FORCE_KEY   2
 -static vpx_codec_err_t api1_control(vpx_codec_alg_priv_t *ctx,
 -                                    int                   ctrl_id,
 -                                    va_list               args)
 -{
 -    vpx_codec_ctrl_fn_map_t *entry;
 -
 -    switch (ctrl_id)
 -    {
 -    case VP8E_SET_FLUSHFLAG:
 -        /* VP8 sample code did VP8E_SET_FLUSHFLAG followed by
 -         * vpx_codec_get_cx_data() rather than vpx_codec_encode().
 -         */
 -        return vp8e_encode(ctx, NULL, 0, 0, 0, 0);
 -    case VP8E_SET_FRAMETYPE:
 -        ctx->base.enc.tbd |= FORCE_KEY;
 -        return VPX_CODEC_OK;
 -    }
 -
 -    for (entry = vp8e_ctf_maps; entry && entry->fn; entry++)
 -    {
 -        if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
 -        {
 -            return entry->fn(ctx, ctrl_id, args);
 -        }
 -    }
 -
 -    return VPX_CODEC_ERROR;
 -}
 -
 -
 -static vpx_codec_ctrl_fn_map_t api1_ctrl_maps[] =
 -{
 -    {0, api1_control},
 -    { -1, NULL}
 -};
 -
 -
 -static vpx_codec_err_t api1_encode(vpx_codec_alg_priv_t  *ctx,
 -                                   const vpx_image_t     *img,
 -                                   vpx_codec_pts_t        pts,
 -                                   unsigned long          duration,
 -                                   vpx_enc_frame_flags_t  flags,
 -                                   unsigned long          deadline)
 -{
 -    int force = ctx->base.enc.tbd;
 -
 -    ctx->base.enc.tbd = 0;
 -    return vp8e_encode
 -           (ctx,
 -            img,
 -            pts,
 -            duration,
 -            flags | ((force & FORCE_KEY) ? VPX_EFLAG_FORCE_KF : 0),
 -            deadline);
 -}
 -
 -
 -vpx_codec_iface_t vpx_enc_vp8_algo =
 -{
 -    "WebM Project VP8 Encoder (Deprecated API)" VERSION_STRING,
 -    VPX_CODEC_INTERNAL_ABI_VERSION,
 -    VPX_CODEC_CAP_ENCODER,
 -    /* vpx_codec_caps_t          caps; */
 -    vp8e_init,          /* vpx_codec_init_fn_t       init; */
 -    vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
 -    api1_ctrl_maps,     /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
 -    NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
 -    NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
 -    {NOT_IMPLEMENTED},  /* decoder functions */
 -    {
 -        vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
 -        api1_encode,        /* vpx_codec_encode_fn_t      encode; */
 -        vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
 -        vp8e_set_config,
 -        NOT_IMPLEMENTED,
 -        vp8e_get_preview,
 -        vp8e_mr_alloc_mem,
 -    } /* encoder functions */
 -};