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

📄 epzs.c

📁 H264视频编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        predictor->point[*prednum].y = (mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][1] + 2048) >> 12;
        *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
      }
      if (block_available_below)
      {
        predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][0] + 2048) >> 12;
        predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][1] + 2048) >> 12;
        *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));
      }
    }
    
    if (block_available_below)
    {
      predictor->point[*prednum].x = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][0] + 2048) >> 12;
      predictor->point[*prednum].y = (mvScale * col_mv[o_block_y + blockshape_y][o_block_x][1] + 2048) >> 12;
      *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 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];
  
  
  if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
  {
    predictor->point[*prednum].x = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][0] + 512) >> 10;
    predictor->point[*prednum].y = (mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][1] + 512) >> 10;
    *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));    
    
    predictor->point[*prednum].x = (mv_scale[list][ref][0] * all_mv[0][blocktype][0] + 512) >> 10;
    predictor->point[*prednum].y = (mv_scale[list][ref][0] * all_mv[0][blocktype][1] + 512) >> 10;
    *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));        
  }
  
  predictor->point[*prednum].x = (all_mv[ref][blk_parent[blocktype]][0] + 2) >> 2;
  predictor->point[*prednum].y = (all_mv[ref][blk_parent[blocktype]][1] + 2) >> 2;
  *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));    
  
  if (blocktype != 1)
  {
    predictor->point[*prednum].x = (all_mv[ref][1][0] + 2) >> 2;
    predictor->point[*prednum].y = (all_mv[ref][1][1] + 2) >> 2;
    *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));        
  }  
  
  if (blocktype != 4)
  {
    predictor->point[*prednum].x = (all_mv[ref][4][0] + 2) >> 2;
    predictor->point[*prednum].y = (all_mv[ref][4][1] + 2) >> 2;
    *prednum += ((predictor->point[*prednum].x != 0) || (predictor->point[*prednum].y != 0));    
  }
}

/*!
************************************************************************
* \brief
*    EPZS Window Based Predictors 
************************************************************************
*/
static void EPZSWindowPredictors (int mv_x, int mv_y, 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)  ].x = mv_x + windowPred->point[pos].x;
    predictor->point[(*prednum)++].y = mv_y + windowPred->point[pos].y;
  }
}

/*!
************************************************************************
* \brief
*    SAD computation 
************************************************************************
*/
static int computeSad(pel_t** cur_pic,
               int blocksize_y,
               int blocksize_x, 
               int blockshape_x,
               int mcost,
               int min_mcost,
               int cand_x,
               int cand_y)
{
  int y,x4;
  
  pel_t *cur_line, *ref_line;
  for (y=0; y<blocksize_y; y++)
  {
    ref_line  = get_ref_line (blocksize_x, ref_pic, cand_y + y, cand_x, img_height, img_width);
    cur_line = cur_pic [y];
    
    for (x4 = 0; x4 < blockshape_x; x4++)
    {
      mcost += byte_abs[ *cur_line++ - *ref_line++ ];
      mcost += byte_abs[ *cur_line++ - *ref_line++ ];
      mcost += byte_abs[ *cur_line++ - *ref_line++ ];
      mcost += byte_abs[ *cur_line++ - *ref_line++ ];
      //mcost += abs( *cur_line++ - *ref_line++ );
      //mcost += abs( *cur_line++ - *ref_line++ );
      //mcost += abs( *cur_line++ - *ref_line++ );
      //mcost += abs( *cur_line++ - *ref_line++ );
    }    
    if (mcost >= min_mcost) break;
  }
  return mcost;
}

/*!
************************************************************************
* \brief
*    BiPred SAD computation (no weights)
************************************************************************
*/
static int computeBiPredSad1(pel_t** cur_pic,
                             int blocksize_y,
                             int blocksize_x, 
                             int blockshape_x,
                             int mcost,
                             int min_mcost,
                             int cand_x1, int cand_y1, 
                             int cand_x2, int cand_y2)
{
  pel_t *cur_line, *ref1_line, *ref2_line;
  int bi_diff; 
  int y,x4;  
  
  for (y = 0; y < blocksize_y; y++)
  {
    ref2_line = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
    ref1_line = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
    cur_line = cur_pic [y];
    
    for (x4 = 0; x4 < blockshape_x; x4++)
    {         
      bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
      mcost += byte_abs[bi_diff];
      bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
      mcost += byte_abs[bi_diff];
      bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
      mcost += byte_abs[bi_diff];
      bi_diff = (*cur_line++) - ((*ref1_line++ + *ref2_line++)>>1);
      mcost += byte_abs[bi_diff];
    }        
    
    if (mcost >= min_mcost) break;
  }
  return mcost;
}


/*!
************************************************************************
* \brief
*    BiPred SAD computation (with weights)
************************************************************************
*/
static int computeBiPredSad2(pel_t** cur_pic,
                             int blocksize_y,
                             int blocksize_x, 
                             int blockshape_x,
                             int mcost,
                             int min_mcost,
                             int cand_x1, int cand_y1, 
                             int cand_x2, int cand_y2)
{
  pel_t *cur_line, *ref1_line, *ref2_line;
  int bi_diff; 
  int denom = luma_log_weight_denom + 1;
  int lround = 2 * wp_luma_round;
  int y,x4;  
  int weightedpel, pixel1, pixel2;
  for (y=0; y<blocksize_y; y++)
  {
    ref2_line  = get_ref_line2 (blocksize_x, ref_pic2, cand_y2 + y, cand_x2, img_height, img_width);
    ref1_line  = get_ref_line1 (blocksize_x, ref_pic1, cand_y1 + y, cand_x1, img_height, img_width);
    cur_line = cur_pic [y];
    
    for (x4 = 0; x4 < blockshape_x; x4++)
    { 
      pixel1 = weight1 * (*ref1_line++);
      pixel2 = weight2 * (*ref2_line++);
      weightedpel =  Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
      bi_diff = (*cur_line++)  - weightedpel;
      mcost += byte_abs[bi_diff];
      
      pixel1 = weight1 * (*ref1_line++);
      pixel2 = weight2 * (*ref2_line++);
      weightedpel =  Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
      bi_diff = (*cur_line++)  - weightedpel;
      mcost += byte_abs[bi_diff];
      
      pixel1 = weight1 * (*ref1_line++);
      pixel2 = weight2 * (*ref2_line++);
      weightedpel =  Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);                     
      bi_diff = (*cur_line++)  - weightedpel;
      mcost += byte_abs[bi_diff];
      
      pixel1 = weight1 * (*ref1_line++);
      pixel2 = weight2 * (*ref2_line++);
      weightedpel =  Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
      bi_diff = (*cur_line++)  - weightedpel;
      mcost += byte_abs[bi_diff];
      if (mcost >= min_mcost) break;
    }    
    
    if (mcost >= min_mcost) break;
  }
  return mcost;
}

/*!
***********************************************************************
* \brief
*    FAST Motion Estimation using EPZS
*    AMT/HYC
***********************************************************************
*/
int				                                    //  ==> minimum motion cost after search
EPZSPelBlockMotionSearch (pel_t ** 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_x,	  // <--  motion vector predictor (x) in sub-pel units
                          short pred_mv_y,	  // <--  motion vector predictor (y) in sub-pel units
                          short *mv_x,	      // <--> in: search center (x) / out: motion vector (x) - in pel units
                          short *mv_y,	      // <--> in: search center (y) / out: motion vector (y) - 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_x;	// predicted position x (in sub-pel units)
  int   pred_y = (pic_pix_y << 2) + pred_mv_y;	// predicted position y (in sub-pel units)
  int   center_x = pic_pix_x + *mv_x;	// center position x (in pel units)
  int   center_y = pic_pix_y + *mv_y;	// center position y (in pel units)
  int   cand_x = center_x;
  int   cand_y = center_y;
  int   tempmv_x  = *mv_x, tempmv_y  = *mv_y;
  int   tempmv_x2 = 0, tempmv_y2 = 0;
  int   stopCriterion = medthres[blocktype];
  int   mapCenter_x = search_range - *mv_x;
  int   mapCenter_y = search_range - *mv_y;
  int   second_mcost = INT_MAX;
  short apply_weights = (active_pps->weighted_pred_flag > 0 || active_pps->weighted_bipred_idc == 1);
  int   *prevSad = EPZSDistortion[list + list_offset][blocktype - 1];
  short *motion=NULL;
  
  short invalid_refs = 0;
  byte  checkMedian = FALSE;  
  EPZSStructure *searchPatternF = searchPattern;
  ref_pic = (apply_weights && input->UseWeightedReferenceME) ? ref_picture->imgY_11_w : ref_picture->imgY_11;
  
  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
  }
  img_width  = ref_picture->size_x;
  img_height = ref_picture->size_y;  
  
  
  //===== set function for getting reference picture lines =====
  get_ref_line = CHECK_RANGE ? FastLineX : UMVLineX;
  
  // Clear EPZSMap
  memset(EPZSMap[0],FALSE,(2*search_range+1)*(2*search_range+1));
  // Check median candidate;  
  EPZSMap[search_range][search_range] = TRUE;
  
  //--- initialize motion cost (cost for motion vector) and check ---
  min_mcost = MV_COST (lambda_factor, 2, cand_x, cand_y, pred_x, pred_y);  
  
  //--- add residual cost to motion cost ---
  min_mcost = computeSad(cur_pic, blocksize_y,blocksize_x,
    blockshape_x,min_mcost, INT_MAX, cand_x,cand_y);
  // Additional threshold for ref>0  
  if ((ref>0 && img->structure == FRAME)  
    && (prevSad[pic_pix_x2] < medthres[blocktype]) 
    && (prevSad[pic_pix_x2] < min_mcost))
  {
    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)   )
    get_ref_line = FastLineX;
  else
    get_ref_line = UMVLineX;
  
  //! 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;
    int

⌨️ 快捷键说明

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