⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 me_epzs.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        int block_available_right,
                        int block_available_below,
                        int blockshape_x,
                        int blockshape_y,
                        int stopCriterion,
                        int min_mcost)
{
  int mvScale = mv_scale[list + list_offset][ref][0];
  short ***col_mv = (list_offset == 0) ? EPZSCo_located->mv[list]
    : (list_offset == 2) ? EPZSCo_located->top_mv[list] : EPZSCo_located->bottom_mv[list];
  short temp_shift_mv = 8 + mv_rescale; // 16 - invmv_precision + mv_rescale
  int *cur_mv = predictor->point[*prednum].mv;

  cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x][0]), temp_shift_mv);
  cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x][1]), temp_shift_mv);
  *prednum += (cur_mv[0] | cur_mv[1])!=0;

  if (min_mcost > stopCriterion && ref < 2)
  {
    if (block_available_left)
    {
      cur_mv = predictor->point[*prednum].mv;
      cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x - 1][0]), temp_shift_mv);
      cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x - 1][1]), temp_shift_mv);
      *prednum += (cur_mv[0] | cur_mv[1])!=0;

      //Up_Left
      if (block_available_up)
      {
        cur_mv = predictor->point[*prednum].mv;
        cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x - 1][0]), temp_shift_mv);
        cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x - 1][1]), temp_shift_mv);
        *prednum += (cur_mv[0] | cur_mv[1])!=0;
      }
      //Down_Left
      if (block_available_below)
      {
        cur_mv = predictor->point[*prednum].mv;
        cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][0]), temp_shift_mv);
        cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][1]), temp_shift_mv);
        *prednum += (cur_mv[0] | cur_mv[1])!=0;
      }
    }
    // Up
    if (block_available_up)
    {
      cur_mv = predictor->point[*prednum].mv;
      cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x][0]), temp_shift_mv);
      cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x][1]), temp_shift_mv);
      *prednum += (cur_mv[0] | cur_mv[1])!=0;
    }

    // Up - Right
    if (block_available_right)
    {
      cur_mv = predictor->point[*prednum].mv;
      cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x + blockshape_x][0]), temp_shift_mv);
      cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x + blockshape_x][1]), temp_shift_mv);
      *prednum += (cur_mv[0] | cur_mv[1])!=0;

      if (block_available_up)
      {
        cur_mv = predictor->point[*prednum].mv;
        cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][0]), temp_shift_mv);
        cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][1]), temp_shift_mv);
        *prednum += (cur_mv[0] | cur_mv[1])!=0;
      }
      if (block_available_below)
      {
        cur_mv = predictor->point[*prednum].mv;
        cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][0]), temp_shift_mv);
        cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][1]), temp_shift_mv);
        *prednum += (cur_mv[0] | cur_mv[1])!=0;
      }
    }

    if (block_available_below)
    {
      cur_mv = predictor->point[*prednum].mv;
      cur_mv[0] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x][0]), temp_shift_mv);
      cur_mv[1] = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x][1]), temp_shift_mv);
      *prednum += (cur_mv[0] | cur_mv[1])!=0;
    }
  }
}

/*!
************************************************************************
* \brief
*    EPZS Block Type Predictors
************************************************************************
*/
static void EPZSBlockTypePredictors (int block_x, int block_y, int blocktype, int ref, int list,
                                     EPZSStructure * predictor, int *prednum)
{
  short ***all_mv = img->all_mv[block_y][block_x][list];
  short block_shift_mv = 8 + mv_rescale;
  int *cur_mv = predictor->point[*prednum].mv;

  cur_mv[0] = rshift_rnd((all_mv[ref][blk_parent[blocktype]][0]), mv_rescale);
  cur_mv[1] = rshift_rnd((all_mv[ref][blk_parent[blocktype]][1]), mv_rescale);
  *prednum += (cur_mv[0] | cur_mv[1])!=0;

  if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
  {
    cur_mv = predictor->point[*prednum].mv;
    cur_mv[0] = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][0]), block_shift_mv );
    cur_mv[1] = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][1]), block_shift_mv );
    *prednum += (cur_mv[0] | cur_mv[1])!=0;

    cur_mv = predictor->point[*prednum].mv;
    cur_mv[0] = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][0]), block_shift_mv );
    cur_mv[1] = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][1]), block_shift_mv );
    *prednum += (cur_mv[0] | cur_mv[1])!=0;
  }

  if (blocktype != 1)
  {
    cur_mv = predictor->point[*prednum].mv;
    cur_mv[0] = rshift_rnd((all_mv[ref][1][0]), mv_rescale);
    cur_mv[1] = rshift_rnd((all_mv[ref][1][1]), mv_rescale);
    *prednum += (cur_mv[0] | cur_mv[1])!=0;
  }

  if (blocktype != 4)
  {
    cur_mv = predictor->point[*prednum].mv;
    cur_mv[0] = rshift_rnd((all_mv[ref][4][0]), mv_rescale);
    cur_mv[1] = rshift_rnd((all_mv[ref][4][1]), mv_rescale);
    *prednum += (cur_mv[0] | cur_mv[1])!=0;
  }
}

/*!
************************************************************************
* \brief
*    EPZS Window Based Predictors
************************************************************************
*/
static void EPZSWindowPredictors (short mv[2], EPZSStructure *predictor, int *prednum, int extended)
{
  int pos;
  EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;

  for (pos = 0; pos < windowPred->searchPoints; pos++)
  {
    predictor->point[(*prednum)  ].mv[0] = mv[0] + windowPred->point[pos].mv[0];
    predictor->point[(*prednum)++].mv[1] = mv[1] + windowPred->point[pos].mv[1];
  }
}

/*!
***********************************************************************
* \brief
*    FAST Motion Estimation using EPZS
*    AMT/HYC
***********************************************************************
*/
int                                           //  ==> minimum motion cost after search
EPZSPelBlockMotionSearch (imgpel * cur_pic,  // <--  original pixel values for the AxB block
                          short ref,          // <--  reference picture
                          int list,           // <--  reference list
                          int list_offset,    // <--  offset for Mbaff
                          char ***refPic,     // <--  reference array
                          short ****tmp_mv,   // <--  mv array
                          int pic_pix_x,      // <--  absolute x-coordinate of regarded AxB block
                          int pic_pix_y,      // <--  absolute y-coordinate of regarded AxB block
                          int blocktype,      // <--  block type (1-16x16 ... 7-4x4)
                          short pred_mv[2],    // <--  motion vector predictor (x) in sub-pel units
                          short mv[2],        // <--> in: search center (x) / out: motion vector (x) - in pel units
                          int search_range,   // <--  1-d search range in pel units
                          int min_mcost,      // <--  minimum motion cost (cost for center or huge value)
                          int lambda_factor)      // <--  lagrangian parameter for determining motion cost
{
  StorablePicture *ref_picture = listX[list+list_offset][ref];
  short blocksize_y = input->blc_size[blocktype][1];  // vertical block size
  short blocksize_x = input->blc_size[blocktype][0];  // horizontal block size
  short blockshape_x = (blocksize_x >> 2);  // horizontal block size in 4-pel units
  short blockshape_y = (blocksize_y >> 2);  // vertical block size in 4-pel units

  short mb_x = pic_pix_x - img->opix_x;
  short mb_y = pic_pix_y - img->opix_y;
  short pic_pix_x2 = pic_pix_x >> 2;
  short pic_pix_y2 = pic_pix_y >> 2;
  short block_x = (mb_x >> 2);
  short block_y = (mb_y >> 2);

  int   pred_x = (pic_pix_x << 2) + pred_mv[0];  // predicted position x (in sub-pel units)
  int   pred_y = (pic_pix_y << 2) + pred_mv[1];  // predicted position y (in sub-pel units)
  int   center_x = (pic_pix_x << (2 - mv_rescale))+ mv[0]; // center position x (in pel units)
  int   center_y = (pic_pix_y << (2 - mv_rescale))+ mv[1]; // center position y (in pel units)
  int   cand_x = center_x << mv_rescale;
  int   cand_y = center_y << mv_rescale;
  int   tempmv[2]  = {mv[0], mv[1]};
  int   tempmv2[2] = {0, 0};
  int   stopCriterion = medthres[blocktype];
  int   mapCenter_x = search_range - mv[0];
  int   mapCenter_y = search_range - mv[1];
  int   second_mcost = INT_MAX;
  short apply_weights = (active_pps->weighted_pred_flag > 0 || (active_pps->weighted_bipred_idc && (img->type == B_SLICE))) && input->UseWeightedReferenceME;
  int   *prevSad = EPZSDistortion[list + list_offset][blocktype - 1];
  short *motion=NULL;
  int   dist_method = F_PEL + 3 * apply_weights;

  short invalid_refs = 0;
  byte  checkMedian = FALSE;
  EPZSStructure *searchPatternF = searchPattern;
  EPZSBlkCount ++;

  ref_pic_sub.luma = ref_picture->curr_imgY_sub;

  img_width  = ref_picture->size_x;
  img_height = ref_picture->size_y;
  width_pad  = ref_picture->size_x_pad;
  height_pad = ref_picture->size_y_pad;

  if (apply_weights)
  {
    weight_luma = wp_weight[list + list_offset][ref][0];
    offset_luma = wp_offset[list + list_offset][ref][0];
  }

  if ( ChromaMEEnable)
  {
    ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
    ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
    width_pad_cr  = ref_picture->size_x_cr_pad;
    height_pad_cr = ref_picture->size_y_cr_pad;

    if (apply_weights)
    {
      weight_cr[0] = wp_weight[list + list_offset][ref][1];
      weight_cr[1] = wp_weight[list + list_offset][ref][2];
      offset_cr[0] = wp_offset[list + list_offset][ref][1];
      offset_cr[1] = wp_offset[list + list_offset][ref][2];
    }
  }
  pic_pix_x = (pic_pix_x << (2 - mv_rescale));
  pic_pix_y = (pic_pix_y << (2 - mv_rescale));

  if (input->EPZSSpatialMem)
  {
#if EPZSREF
    motion = EPZSMotion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2];
#else
    motion = EPZSMotion[list + list_offset][blocktype - 1][block_y][pic_pix_x2];
#endif
  }

  //===== set function for getting reference picture lines =====
  ref_access_method = CHECK_RANGE ? FAST_ACCESS : UMV_ACCESS;

  // Clear EPZSMap
  // memset(EPZSMap[0],FALSE,searcharray*searcharray);
  // Check median candidate;
  EPZSMap[search_range][search_range] = EPZSBlkCount;

  //--- initialize motion cost (cost for motion vector) and check ---
  min_mcost = MV_COST_SMP (lambda_factor, cand_x, cand_y, pred_x, pred_y);

  //--- add residual cost to motion cost ---
  min_mcost += computeUniPred[dist_method](cur_pic, blocksize_y, blocksize_x,
    INT_MAX, cand_x + IMG_PAD_SIZE_TIMES4, cand_y + IMG_PAD_SIZE_TIMES4);

  // Additional threshold for ref>0
  if ((ref>0 && img->structure == FRAME)
    && (prevSad[pic_pix_x2] < medthres[blocktype])
    && (prevSad[pic_pix_x2] < min_mcost))
  {
#if EPZSREF
    if (input->EPZSSpatialMem)
#else
    if (input->EPZSSpatialMem && ref == 0)
#endif
    {
      motion[0]  = tempmv[0];
      motion[1]  = tempmv[1];
    }

    return min_mcost;
  }

  //  if ((center_x > search_range) && (center_x < img_width  - search_range - blocksize_x) &&
  //(center_y > search_range) && (center_y < img_height - search_range - blocksize_y)   )
  if ( (center_x > search_range) && (center_x < ((img_width  - blocksize_x) << (input->EPZSSubPelGrid * 2)) - search_range)
    && (center_y > search_range) && (center_y < ((img_height - blocksize_y) << (input->EPZSSubPelGrid * 2)) - search_range))
  {
    ref_access_method = FAST_ACCESS;
  }
  else
  {
    ref_access_method = UMV_ACCESS;
  }

  //! If medthres satisfied, then terminate, otherwise generate Predictors
  //! Condition could be strengthened by consideration distortion of adjacent partitions.
  if (min_mcost > stopCriterion)
  {
    int mb_available_right   = (img->mb_x < (img_width  >> 4) - 1);
    int mb_available_below   = (img->mb_y < (img_height >> 4) - 1);

    int sadA, sadB, sadC;
    int block_available_right;
    int block_available_below;
    int prednum = 5;
    int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
    int totalCheckPts = 0, motionDirection = 0;
    int conditionEPZS;
    int tmv[2];
    int pos, mcost;
    PixelPos block_a, block_b, block_c, block_d;

    getLuma4x4Neighbour (img->current_mb_nr, mb_x - 1, mb_y, &block_a);
    getLuma4x4Neighbour (img->current_mb_nr, mb_x, mb_y - 1, &block_b);
    getLuma4x4Neighbour (img->current_mb_nr, mb_x + blocksize_x, mb_y -1, &block_c);
    getLuma4x4Neighbour (img->current_mb_nr, mb_x - 1, mb_y -1, &block_d);

    if (mb_y > 0)
    {
      if (mb_x < 8)   // first column of 8x8 blocks
      {
        if (mb_y == 8)
        {
          block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
          if (blocksize_x == MB_BLOCK_SIZE)
            block_c.available = 0;
        }
        else
        {
          block_available_righ

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -