コード例 #1
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static void interpolate_comp(mv_data_t* mv_data, uint8_t* p0, int s0, uint8_t* p1, int s1,
    uint8_t* out, int so, int wP, int hP, int pad, int chroma)
{
  const int bw=mv_data->bw;
  const int bh=mv_data->bh;
  const int bs=chroma ? mv_data->bs/2 :  mv_data->bs;

  for (int yp=0; yp<bh; yp++) {
    for (int xp=0; xp<bw; xp++) {

      int xstart=xp*bs;
      int ystart=yp*bs;
      mv_t mv0=mv_data->mv[0][yp*bw+xp];
      mv_t mv1=mv_data->mv[1][yp*bw+xp];
      if (chroma){
        mv1.x >>= 1;
        mv1.y >>= 1;
        mv0 = scale_mv(mv1, -mv_data->wt[1], mv_data->wt[0]);
      }
      mot_comp_avg(xstart, ystart, p0, s0, p1, s1, out, so, mv0, mv1, wP, hP, pad, bs, mv_data->wt);

    }
  }

}
コード例 #2
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static void merge_candidate_search(mv_t* cand_list, int num_cands, mv_data_t* mv_data, mv_t* mv0, mv_t* mv1, yuv_frame_t* picdata[2], int xp, int yp)
{
  int xstart=xp*mv_data->bs;
  int ystart=yp*mv_data->bs;

  // Do this search on the smaller blocks
  int size=mv_data->bs;

  uint32_t best_cost=COST_MAX;
  mv_t best_mv={0,0};
  mv_t best_scaled_mv={0,0};
  for (int i=0; i<num_cands; ++i){
    mv_t rmv;
    mv_t mv[2];
    rmv=cand_list[i];
    // Vectors are normalised to 1 for pic1, which is always further away. This means that we get enough accuracy, as the nearest mvs will be smaller.
    mv[1].x = rmv.x;
    mv[1].y = rmv.y;
    mv[0] = scale_mv(rmv, -mv_data->wt[1], mv_data->wt[0]);
    uint32_t bcost=0;
    bcost = sad_cost(xstart, ystart, picdata, mv, size, bcost, best_cost);
    if (bcost<best_cost){
      best_cost=bcost;
      best_mv=rmv;
      best_scaled_mv=mv[0];
    }
  }
  mv1[yp*mv_data->bw+xp]=best_mv;
  mv0[yp*mv_data->bw+xp]=best_scaled_mv;
  mv_data->cost[0][yp*mv_data->bw+xp]=best_cost;
  mv_data->cost[1][yp*mv_data->bw+xp]=best_cost;

}
コード例 #3
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static void upscale_mv_data_2x2(mv_data_t* mv_data_in, mv_data_t* mv_data_out)
{

  assert(mv_data_in->ratio==mv_data_out->ratio);
  assert(mv_data_in->pos==mv_data_out->pos);
  assert(mv_data_in->wt[0]==mv_data_out->wt[0]);
  assert(mv_data_in->wt[1]==mv_data_out->wt[1]);

  int bwo=mv_data_out->bw;
  int bho=mv_data_out->bh;
  int bwi=mv_data_in->bw;

  memset(mv_data_out->mv[0], 0, sizeof(mv_t)*bwo*bho);
  memset(mv_data_out->mv[1], 0, sizeof(mv_t)*bwo*bho);

  for (int i=0; i<bho; ++i) {
    for (int j=0; j<bwo; ++j) {
      int po=i*bwo+j;
      int pi=(i/2)*bwi+(j/2);
      mv_data_out->mv[1][po].x=mv_data_in->mv[1][pi].x<<1;
      mv_data_out->mv[1][po].y=mv_data_in->mv[1][pi].y<<1;
      mv_data_out->mv[0][po]=scale_mv(mv_data_out->mv[1][po], -mv_data_out->wt[1], mv_data_out->wt[0]);
    }
  }
}
コード例 #4
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static void make_skip_vector(mv_data_t* mv_data, int xp, int yp, int xstep, int ystep)
{
  int bw=mv_data->bw;
  mv_data->skip_mv.x=0;
  mv_data->skip_mv.y=0;
  mv_t vlist[3];
  int num=0;
  if (yp>0 && xp<bw-xstep) vlist[num++]=mv_data->mv[1][(yp-ystep)*bw+xp+xstep];
  if (xp>0) vlist[num++]=mv_data->mv[1][yp*bw+xp-xstep];
  if (yp>0) vlist[num++]=mv_data->mv[1][(yp-ystep)*bw+xp];
  if (num) mv_data->skip_mv=mv_absdist_filter(vlist,num);
  mv_data->scaled_skip_mv=scale_mv(mv_data->skip_mv, -mv_data->wt[1], mv_data->wt[0]);
}
コード例 #5
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static int get_cands(mv_data_t* mv_data, mv_t* cand_list, mv_data_t** guide_mv_data, int num_guides, int xp, int yp, int max_cands, int xstep, int ystep) {

  // Zero
  int len=0;
  mv_t zero={0,0};
  int pos=yp*mv_data->bw+xp;
  len=add_cand(cand_list, max_cands, len, zero);

  for (int i=0; i<num_guides; ++i) {
    mv_data_t* gmv_data=guide_mv_data[i];
    int numer=(mv_data->reversed==gmv_data->reversed)? mv_data->wt[0] : -mv_data->wt[0];
    int denom=gmv_data->wt[0];
    mv_t gmv;
    gmv = scale_mv(gmv_data->mv[1][pos], numer, denom);
    len=add_cand(cand_list, max_cands, len, gmv);
//    if (xp<mv_data->bw-xstep && yp<mv_data->bh-ystep) {
//      gmv = scale_mv(gmv_data->mv[1][pos+mv_data->bw*ystep+xstep], numer, denom);
//      len=add_cand(cand_list, max_cands, len, gmv);
//    }
//    if (xp<mv_data->bw-xstep) {
//      gmv = scale_mv(gmv_data->mv[1][pos+xstep], numer, denom);
//      len=add_cand(cand_list, max_cands, len, gmv);
//    }
//    if (yp<mv_data->bh-ystep) {
//      gmv = scale_mv(gmv_data->mv[1][pos+ystep*mv_data->bw], numer, denom);
//      len=add_cand(cand_list, max_cands, len, gmv);
//    }
//

  }


  if (yp>0 && xp<mv_data->bw-xstep) {
    len=add_cand(cand_list, max_cands, len, mv_data->mv[1][(yp-ystep)*mv_data->bw+xp+xstep]);
  }
//  if (yp>0 && xp>0) {
//    len=add_cand(cand_list, max_cands, len, mv_data->mv[1][(yp-ystep)*mv_data->bw+xp-xstep]);
//  }
  if (xp>0) {
    len=add_cand(cand_list, max_cands, len, mv_data->mv[1][yp*mv_data->bw+xp-xstep]);
  }
  if (yp>0) {
    len=add_cand(cand_list, max_cands, len, mv_data->mv[1][(yp-ystep)*mv_data->bw+xp]);
  }



  return len;
}
コード例 #6
0
ファイル: vp9_mvref_common.c プロジェクト: Kindpire/synciga
// This function searches the neighbourhood of a given MB/SB and populates a
// list of candidate reference vectors.
//
void vp9_find_mv_refs(
  MACROBLOCKD *xd,
  MODE_INFO *here,
  MODE_INFO *lf_here,
  MV_REFERENCE_FRAME ref_frame,
  int_mv *mv_ref_list,
  int *ref_sign_bias
) {

  int i;
  MODE_INFO *candidate_mi;
  MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
  int_mv candidate_mvs[MAX_MV_REF_CANDIDATES];
  int_mv c_refmv;
  int_mv c2_refmv;
  MV_REFERENCE_FRAME c_ref_frame;
  MV_REFERENCE_FRAME c2_ref_frame;
  int candidate_scores[MAX_MV_REF_CANDIDATES];
  int index = 0;
  int split_count = 0;
  int (*mv_ref_search)[2];
  int *ref_distance_weight;

  // Blank the reference vector lists and other local structures.
  vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
  vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
  vpx_memset(candidate_scores, 0, sizeof(candidate_scores));

  if (mbmi->sb_type) {
    mv_ref_search = sb_mv_ref_search;
    ref_distance_weight = sb_ref_distance_weight;
  } else {
    mv_ref_search = mb_mv_ref_search;
    ref_distance_weight = mb_ref_distance_weight;
  }

  // We first scan for candidate vectors that match the current reference frame
  // Look at nearest neigbours
  for (i = 0; i < 2; ++i) {
    if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
        ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {

      candidate_mi = here + mv_ref_search[i][0] +
                     (mv_ref_search[i][1] * xd->mode_info_stride);

      if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
        clamp_mv(xd, &c_refmv);
        addmv_and_shuffle(candidate_mvs, candidate_scores,
                          &index, c_refmv, ref_distance_weight[i] + 16);
      }
      split_count += (candidate_mi->mbmi.mode == SPLITMV);
    }
  }
  // Look in the last frame
  candidate_mi = lf_here;
  if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
    clamp_mv(xd, &c_refmv);
    addmv_and_shuffle(candidate_mvs, candidate_scores,
                      &index, c_refmv, 18);
  }
  // More distant neigbours
  for (i = 2; (i < MVREF_NEIGHBOURS) &&
              (index < (MAX_MV_REF_CANDIDATES - 1)); ++i) {
    if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
        ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
      candidate_mi = here + mv_ref_search[i][0] +
                     (mv_ref_search[i][1] * xd->mode_info_stride);

      if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
        clamp_mv(xd, &c_refmv);
        addmv_and_shuffle(candidate_mvs, candidate_scores,
                          &index, c_refmv, ref_distance_weight[i] + 16);
      }
    }
  }

  // If we have not found enough candidates consider ones where the
  // reference frame does not match. Break out when we have
  // MAX_MV_REF_CANDIDATES candidates.
  // Look first at spatial neighbours
  if (index < (MAX_MV_REF_CANDIDATES - 1)) {
    for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
      if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
          ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {

        candidate_mi = here + mv_ref_search[i][0] +
                       (mv_ref_search[i][1] * xd->mode_info_stride);

        get_non_matching_candidates(candidate_mi, ref_frame,
                                    &c_ref_frame, &c_refmv,
                                    &c2_ref_frame, &c2_refmv);

        if (c_ref_frame != INTRA_FRAME) {
          scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
          addmv_and_shuffle(candidate_mvs, candidate_scores,
                            &index, c_refmv, ref_distance_weight[i]);
        }

        if (c2_ref_frame != INTRA_FRAME) {
          scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
          addmv_and_shuffle(candidate_mvs, candidate_scores,
                            &index, c2_refmv, ref_distance_weight[i]);
        }
      }

      if (index >= (MAX_MV_REF_CANDIDATES - 1)) {
        break;
      }
    }
  }
  // Look at the last frame
  if (index < (MAX_MV_REF_CANDIDATES - 1)) {
    candidate_mi = lf_here;
    get_non_matching_candidates(candidate_mi, ref_frame,
                                &c_ref_frame, &c_refmv,
                                &c2_ref_frame, &c2_refmv);

    if (c_ref_frame != INTRA_FRAME) {
      scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
      addmv_and_shuffle(candidate_mvs, candidate_scores,
                        &index, c_refmv, 2);
    }

    if (c2_ref_frame != INTRA_FRAME) {
      scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
      addmv_and_shuffle(candidate_mvs, candidate_scores,
                        &index, c2_refmv, 2);
    }
  }

  // Define inter mode coding context.
  // 0,0 was best
  if (candidate_mvs[0].as_int == 0) {
    // 0,0 is only candidate
    if (index <= 1) {
      mbmi->mb_mode_context[ref_frame] = 0;
    // non zero candidates candidates available
    } else if (split_count == 0) {
      mbmi->mb_mode_context[ref_frame] = 1;
    } else {
      mbmi->mb_mode_context[ref_frame] = 2;
    }
  // Non zero best, No Split MV cases
  } else if (split_count == 0) {
    if (candidate_scores[0] >= 32) {
      mbmi->mb_mode_context[ref_frame] = 3;
    } else {
      mbmi->mb_mode_context[ref_frame] = 4;
    }
  // Non zero best, some split mv
  } else {
    if (candidate_scores[0] >= 32) {
      mbmi->mb_mode_context[ref_frame] = 5;
    } else {
      mbmi->mb_mode_context[ref_frame] = 6;
    }
  }

  // 0,0 is always a valid reference.
  for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
    if (candidate_mvs[i].as_int == 0)
      break;
  }
  if (i == MAX_MV_REF_CANDIDATES) {
    candidate_mvs[MAX_MV_REF_CANDIDATES-1].as_int = 0;
  }

  // Copy over the candidate list.
  vpx_memcpy(mv_ref_list, candidate_mvs, sizeof(candidate_mvs));
}
コード例 #7
0
ファイル: temporal_interp.c プロジェクト: leloulight/thor
static void adaptive_search_v2(mv_data_t* mv_data, int guided, mv_t * cand_list, int num_cands, yuv_frame_t* picdata[2], int xp, int yp, int xstep, int ystep)
{
  // Do the search with the larger size, but data is stored at the smaller
  int xstart=xp*mv_data->bs;
  int ystart=yp*mv_data->bs;

  mv_t cross[4];

  int size=mv_data->bbs;

  mv_t best_mv=cand_list[0];
  mv_t best_scaled_mv;
  best_scaled_mv=scale_mv(best_mv, -mv_data->wt[1], mv_data->wt[0]);
  mv_t mv[2];
  mv[1] = best_mv;
  mv[0] = best_scaled_mv;
  uint32_t best_cost=COST_MAX;

  mv_t cand_refine_list[MAX_CANDS];
  mv_t cand_refine_scaled_list[MAX_CANDS];
  uint32_t cand_best_costs[MAX_CANDS];

  uint32_t lambda = guided ? LAMBDA/4 : LAMBDA;

  for (int c=0; c<num_cands; c++) {

    mv[1].x = cand_list[c].x;
    mv[1].y = cand_list[c].y;
    mv[0] = scale_mv(cand_list[c], -mv_data->wt[1], mv_data->wt[0]);

    cand_best_costs[c]=get_mv_cost(cand_list[c], mv_data, 1, xp, yp, xstep, ystep, lambda);
    cand_best_costs[c] = sad_cost(xstart, ystart, picdata, mv, size, cand_best_costs[c], COST_MAX);
    cand_refine_list[c]=mv[1];
    cand_refine_scaled_list[c]=mv[0];

    if ((((4+c)*cand_best_costs[c])/8) < best_cost) {
      int shift=guided ? 0+ACC_BITS : 3+ACC_BITS;
      int count=guided ? 8 : 64;
      while (shift>=ACC_BITS && count>0) {

        make_cross(cross, 1<<shift, cand_refine_list[c]);
        int better=0;
        for (int i=0; i<4; ++i) {
          mv_t rmv=cross[i];
          mv[1].x = rmv.x;
          mv[1].y = rmv.y;
          mv[0] = scale_mv(rmv, -mv_data->wt[1], mv_data->wt[0]);

          uint32_t bcost=get_mv_cost(rmv, mv_data, 1, xp, yp, xstep, ystep, lambda);
          bcost = sad_cost(xstart, ystart, picdata, mv, size, bcost, cand_best_costs[c]);

          if (bcost<cand_best_costs[c]){
            cand_best_costs[c]=bcost;
            cand_refine_list[c]=rmv;
            cand_refine_scaled_list[c]=mv[0];
            better=1;
          }
        }
        if (!better)
          shift--;
        count -= 4;
      };
    }
    if (cand_best_costs[c]<best_cost) {
      best_mv=cand_refine_list[c];
      best_scaled_mv=cand_refine_scaled_list[c];
      best_cost=cand_best_costs[c];
    }
  }

  mv_data->mv[1][yp*mv_data->bw+xp]=best_mv;
  mv_data->mv[0][yp*mv_data->bw+xp]=best_scaled_mv;
  mv_data->cost[1][yp*mv_data->bw+xp]=best_cost;
  mv_data->cost[0][yp*mv_data->bw+xp]=best_cost;

}