encodeframe.c 73 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
      // Clear mb_skip_coeff if mb_no_coeff_skip is not set
      if (!cpi->common.mb_no_coeff_skip)
Paul Wilkins's avatar
Paul Wilkins committed
        mbmi->mb_skip_coeff = 0;
John Koleszar's avatar
John Koleszar committed
    } else {
      vp8_build_1st_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
                                             xd->dst.u_buffer, xd->dst.v_buffer,
                                             xd->dst.y_stride,
                                             xd->dst.uv_stride);
John Koleszar's avatar
John Koleszar committed
    }
John Koleszar's avatar
John Koleszar committed
  }
John Koleszar's avatar
John Koleszar committed
  if (!x->skip) {
#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
    if (enc_debug) {
      int i;
Paul Wilkins's avatar
Paul Wilkins committed
      printf("Segment=%d [%d, %d]: %d %d:\n", mbmi->segment_id, mb_col_debug,
             mb_row_debug, xd->mb_to_left_edge, xd->mb_to_top_edge);
John Koleszar's avatar
John Koleszar committed
      for (i = 0; i < 400; i++) {
        printf("%3d ", xd->qcoeff[i]);
        if (i % 16 == 15) printf("\n");
      }
      printf("\n");
      printf("eobs = ");
      for (i = 0; i < 25; i++)
        printf("%d:%d ", i, xd->block[i].eob);
      printf("\n");
      fflush(stdout);
    }

    vp8_tokenize_mb(cpi, xd, t, !output_enabled);

#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
    if (enc_debug) {
      printf("Tokenized\n");
      fflush(stdout);
John Koleszar's avatar
John Koleszar committed
#endif
  } else {
    int mb_skip_context =
      cpi->common.mb_no_coeff_skip ?
      (x->e_mbd.mode_info_context - 1)->mbmi.mb_skip_coeff +
      (x->e_mbd.mode_info_context - cpi->common.mode_info_stride)->mbmi.mb_skip_coeff :
      0;
    if (cpi->common.mb_no_coeff_skip) {
Paul Wilkins's avatar
Paul Wilkins committed
      mbmi->mb_skip_coeff = 1;
      if (output_enabled)
        cpi->skip_true_count[mb_skip_context]++;
John Koleszar's avatar
John Koleszar committed
      vp8_fix_contexts(xd);
    } else {
      vp8_stuff_mb(cpi, xd, t, !output_enabled);
Paul Wilkins's avatar
Paul Wilkins committed
      mbmi->mb_skip_coeff = 0;
      if (output_enabled)
        cpi->skip_false_count[mb_skip_context]++;
John Koleszar's avatar
John Koleszar committed
    }
John Koleszar's avatar
John Koleszar committed
  }
John Koleszar's avatar
John Koleszar committed
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed

#if CONFIG_SUPERBLOCKS
void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
                                   int recon_yoffset, int recon_uvoffset, int mb_col, int mb_row) {
  const int output_enabled = 1;
  VP8_COMMON *cm = &cpi->common;
  MACROBLOCKD *xd = &x->e_mbd;
  const uint8_t *src = x->src.y_buffer;
  uint8_t *dst = xd->dst.y_buffer;
  const uint8_t *usrc = x->src.u_buffer;
  uint8_t *udst = xd->dst.u_buffer;
  const uint8_t *vsrc = x->src.v_buffer;
  uint8_t *vdst = xd->dst.v_buffer;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
  int src_y_stride = x->src.y_stride, dst_y_stride = xd->dst.y_stride;
  int src_uv_stride = x->src.uv_stride, dst_uv_stride = xd->dst.uv_stride;
  const VP8_ENCODER_RTCD *rtcd = IF_RTCD(&cpi->rtcd);
  unsigned int segment_id = xd->mode_info_context->mbmi.segment_id;
  int seg_ref_active;
  unsigned char ref_pred_flag;
  int n;
  TOKENEXTRA *tp[4];
  int skip[4];
  MODE_INFO *mi = x->e_mbd.mode_info_context;
  ENTROPY_CONTEXT_PLANES ta[4], tl[4];

  x->skip = 0;

  if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
    // Adjust the zbin based on this MB rate.
    adjust_act_zbin(cpi, x);
  }

  {
    // Experimental code. Special case for gf and arf zeromv modes.
    // Increase zbin size to suppress noise
    cpi->zbin_mode_boost = 0;
    if (cpi->zbin_mode_boost_enabled) {
      if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
        if (xd->mode_info_context->mbmi.mode == ZEROMV) {
          if (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME)
            cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
          else
            cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
        } else if (xd->mode_info_context->mbmi.mode == SPLITMV)
          cpi->zbin_mode_boost = 0;
        else
          cpi->zbin_mode_boost = MV_ZBIN_BOOST;
      }
    }

    vp8_update_zbin_extra(cpi, x);
  }

  seg_ref_active = segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);

  // SET VARIOUS PREDICTION FLAGS

  // Did the chosen reference frame match its predicted value.
  ref_pred_flag = ((xd->mode_info_context->mbmi.ref_frame ==
                    get_pred_ref(cm, xd)));
  set_pred_flag(xd, PRED_REF, ref_pred_flag);

  /* test code: set transform size based on mode selection */
  if (cpi->common.txfm_mode == ALLOW_8X8
      && x->e_mbd.mode_info_context->mbmi.mode != B_PRED
      && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
    x->e_mbd.mode_info_context->mbmi.txfm_size = TX_8X8;
    cpi->t8x8_count++;
  } else {
    x->e_mbd.mode_info_context->mbmi.txfm_size = TX_4X4;
    cpi->t4x4_count++;
  }

  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_sby_s)(&x->e_mbd);
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_sbuv_s)(&x->e_mbd);
  } else {
    int ref_fb_idx;

    if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
      ref_fb_idx = cpi->common.lst_fb_idx;
    else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
      ref_fb_idx = cpi->common.gld_fb_idx;
    else
      ref_fb_idx = cpi->common.alt_fb_idx;

    xd->pre.y_buffer = cpi->common.yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
    xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
    xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;

    if (xd->mode_info_context->mbmi.second_ref_frame) {
      int second_ref_fb_idx;

      if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
        second_ref_fb_idx = cpi->common.lst_fb_idx;
      else if (xd->mode_info_context->mbmi.second_ref_frame == GOLDEN_FRAME)
        second_ref_fb_idx = cpi->common.gld_fb_idx;
      else
        second_ref_fb_idx = cpi->common.alt_fb_idx;

      xd->second_pre.y_buffer = cpi->common.yv12_fb[second_ref_fb_idx].y_buffer +
                                    recon_yoffset;
      xd->second_pre.u_buffer = cpi->common.yv12_fb[second_ref_fb_idx].u_buffer +
                                    recon_uvoffset;
      xd->second_pre.v_buffer = cpi->common.yv12_fb[second_ref_fb_idx].v_buffer +
                                    recon_uvoffset;
    }

    vp8_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
                                       xd->dst.u_buffer, xd->dst.v_buffer,
                                       xd->dst.y_stride, xd->dst.uv_stride);
  }

  assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
  for (n = 0; n < 4; n++)
  {
    int x_idx = n & 1, y_idx = n >> 1;

    vp8_subtract_mby_s_c(x->src_diff,
                         src + x_idx * 16 + y_idx * 16 * src_y_stride,
                         src_y_stride,
                         dst + x_idx * 16 + y_idx * 16 * dst_y_stride,
                         dst_y_stride);
    vp8_subtract_mbuv_s_c(x->src_diff,
                          usrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
                          vsrc + x_idx * 8 + y_idx * 8 * src_uv_stride,
                          src_uv_stride,
                          udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
                          vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
                          dst_uv_stride);
    if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
      vp8_transform_intra_mby_8x8(x);
    } else {
      vp8_transform_mby_8x8(x);
    }
    vp8_transform_mbuv_8x8(x);
    vp8_quantize_mby_8x8(x);
    vp8_quantize_mbuv_8x8(x);
    if (x->optimize) {
      vp8_optimize_mby_8x8(x, rtcd);
      vp8_optimize_mbuv_8x8(x, rtcd);
    }
    vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    vp8_recon_mby_s_c(IF_RTCD(&rtcd->common->recon), &x->e_mbd,
                      dst + x_idx * 16 + y_idx * 16 * dst_y_stride);
    vp8_recon_mbuv_s_c(IF_RTCD(&rtcd->common->recon), &x->e_mbd,
                       udst + x_idx * 8 + y_idx * 8 * dst_uv_stride,
                       vdst + x_idx * 8 + y_idx * 8 * dst_uv_stride);

    if (!x->skip) {
      if (output_enabled) {
        xd->left_context = cm->left_context + (n >> 1);
        xd->above_context = cm->above_context + mb_col + (n >> 1);
        memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
        memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
        tp[n] = *t;
        xd->mode_info_context = mi + x_idx + y_idx * cm->mode_info_stride;
        vp8_tokenize_mb(cpi, &x->e_mbd, t, 0);
        skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff;
      }
    } else {
      int mb_skip_context =
        cpi->common.mb_no_coeff_skip ?
          (x->e_mbd.mode_info_context - 1)->mbmi.mb_skip_coeff +
            (x->e_mbd.mode_info_context - cpi->common.mode_info_stride)->mbmi.mb_skip_coeff :
          0;
      if (cpi->common.mb_no_coeff_skip) {
        skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff = 1;
        xd->left_context = cm->left_context + (n >> 1);
        xd->above_context = cm->above_context + mb_col + (n >> 1);
        memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
        memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
        tp[n] = *t;
        cpi->skip_true_count[mb_skip_context]++;
        vp8_fix_contexts(xd);
      } else {
        vp8_stuff_mb(cpi, xd, t, 0);
        xd->mode_info_context->mbmi.mb_skip_coeff = 0;
        cpi->skip_false_count[mb_skip_context]++;
      }
    }
  }

  xd->mode_info_context = mi;
  update_sb_skip_coeff_state(cpi, x, ta, tl, tp, t, skip);
}
#endif