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

📄 me_epzs.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 5 页
字号:
        ? img->mb_data[block_b.mb_addr].mb_field
        ? (int) refPic[block_b.pos_y][block_b.pos_x] >> 1
        : (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
      refC = block_c.available
        ? img->mb_data[block_c.mb_addr].mb_field
        ? (int) refPic[block_c.pos_y][block_c.pos_x] >> 1
        : (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
      refD = block_d.available
        ? img->mb_data[block_d.mb_addr].mb_field
        ? (int) refPic[block_d.pos_y][block_d.pos_x] >> 1
        : (int) refPic[block_d.pos_y][block_d.pos_x] : -1;

      // Left Predictor
      predictor->point[1].motion.mv_x = (block_a.available)
        ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0]), sp_shift_mv) : fixed_mv;
      predictor->point[1].motion.mv_y = (block_a.available)
        ? img->mb_data[block_a.mb_addr].mb_field
        ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv - 1)
        : rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv) : 0;

      // Up predictor
      predictor->point[2].motion.mv_x = (block_b.available)
        ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0]), sp_shift_mv) : 0;
      predictor->point[2].motion.mv_y = (block_b.available)
        ? img->mb_data[block_b.mb_addr].mb_field
        ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv - 1)
        : rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv) :  fixed_mv;

      // Up-Right predictor
      predictor->point[3].motion.mv_x = (block_c.available)
        ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0]), sp_shift_mv) : -fixed_mv;
      predictor->point[3].motion.mv_y = (block_c.available)
        ? img->mb_data[block_c.mb_addr].mb_field
        ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv - 1)
        : rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv) : 0;

      //Up-Left predictor
      predictor->point[4].motion.mv_x = (block_d.available)
        ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0]), sp_shift_mv) : 0;
      predictor->point[4].motion.mv_y = (block_d.available)
        ? img->mb_data[block_d.mb_addr].mb_field
        ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv - 1)
        : rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv) : -fixed_mv;
    }
  }

  return ((refA == -1) + (refB == -1) + (refC == -1 && refD == -1));
}

/*!
***********************************************************************
* \brief
*    Spatial Predictors
*    AMT/HYC
***********************************************************************
*/

static void EPZSSpatialMemPredictors (int list,
                                      short ref,
                                      int blocktype,
                                      int pic_x,
                                      int bs_x,
                                      int bs_y,
                                      int by,
                                      int *prednum,
                                      int img_width,
                                      EPZSStructure * predictor)
{
#if EPZSREF
  short ***mv = EPZSMotion[list][ref][blocktype];
  //MotionVector ***prd_mv = &EPZS_Motion[list][ref][blocktype];
  MotionVector *cur_mv = &predictor->point[*prednum].motion;

  // Left Predictor
  if (pic_x > 0)
  {
    cur_mv->mv_x = mv[by][pic_x - bs_x][0];
    cur_mv->mv_y = mv[by][pic_x - bs_x][1];
    *prednum += (*((int*) cur_mv) != 0);
    cur_mv = &predictor->point[*prednum].motion;
  }
  
  by = (by > 0) ? by - bs_y: 4 - bs_y;
  // Up predictor  
  cur_mv->mv_x = mv[by][pic_x][0];
  cur_mv->mv_y = mv[by][pic_x][1];
  *prednum += (*((int*) cur_mv) != 0);

  // Up-Right predictor
  if (pic_x + bs_x < img_width)
  {
    cur_mv = &predictor->point[*prednum].motion;
    cur_mv->mv_x = mv[by][pic_x + bs_x][0];
    cur_mv->mv_y = mv[by][pic_x + bs_x][1];
    *prednum += (*((int*) cur_mv) != 0);
  }

#else
  int mot_scale = mv_scale[list][ref][0];
  short **mv = EPZSMotion[list][blocktype];
  MotionVector **predictor = &EPZS_Motion[list][blocktype];

  // Left Predictor
  predictor->point[*prednum].motion.mv_x = (pic_x > 0)
    ? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][0]), 8)
    : 0;
  predictor->point[*prednum].motion.mv_y = (pic_x > 0)
    ? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][1]), 8)
    : 0;
  *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));

  // Up predictor
  predictor->point[*prednum].motion.mv_x = (by > 0)
    ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][0]), 8)
    : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x][0]), 8);
  predictor->point[*prednum].motion.mv_y = (by > 0)
    ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][1]), 8)
    : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x][1]), 8);
  *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));

  // Up-Right predictor
  predictor->point[*prednum].motion.mv_x = (pic_x + bs_x < img_width)
    ? (by > 0)
    ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][0]), 8)
    : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x + bs_x][0]), 8)
    : 0;
  predictor->point[*prednum].motion.mv_y = (pic_x + bs_x < img_width)
    ? (by > 0)
    ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][1]), 8)
    : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x + bs_x][1]), 8)
    : 0;
  *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
#endif
}


/*!
***********************************************************************
* \brief
*    Temporal Predictors
*    AMT/HYC
***********************************************************************
*/
static void
EPZSTemporalPredictors (int list,         // <--  current list
                        int list_offset,  // <--  list offset for MBAFF
                        short ref,        // <--  current reference frame
                        int o_block_x,    // <--  absolute x-coordinate of regarded AxB block
                        int o_block_y,    // <--  absolute y-coordinate of regarded AxB block
                        EPZSStructure * predictor,
                        int *prednum,
                        int block_available_left,
                        int block_available_up,
                        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];
  MotionVector **col_mv = (list_offset == 0) ? EPZSCo_located->frame[list]  
    : (list_offset == 2) ? EPZSCo_located->top[list] : EPZSCo_located->bot[list];
  short temp_shift_mv = 8 + mv_rescale; // 16 - invmv_precision + mv_rescale
  MotionVector *cur_mv = &predictor->point[*prednum].motion;

  *prednum += add_predictor(cur_mv, col_mv[o_block_y][o_block_x], mvScale, temp_shift_mv);

  if (min_mcost > stopCriterion && ref < 2)
  {
    if (block_available_left)
    {
      *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, temp_shift_mv);

      //Up_Left
      if (block_available_up)
      {
        *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, temp_shift_mv);
      }
      //Down_Left
      if (block_available_below)
      {
        *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, temp_shift_mv);
      }
    }
    // Up
    if (block_available_up)
    {
      *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, temp_shift_mv);
    }

    // Up - Right
    if (block_available_right)
    {
      *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);

      if (block_available_up)
      {
        *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, temp_shift_mv);
      }
      if (block_available_below)
      {
        *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
      }
    }

    if (block_available_below)
    {
      *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, temp_shift_mv);
    }
  }
}

/*!
************************************************************************
* \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[list];
  short block_shift_mv = 8 + mv_rescale;
  MotionVector *cur_mv = &predictor->point[*prednum].motion;

  cur_mv->mv_x = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][0]), mv_rescale);
  cur_mv->mv_y = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][1]), mv_rescale);
  //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  *prednum += (*((int*) cur_mv) != 0);

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


    cur_mv = &predictor->point[*prednum].motion;
    cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][0]), block_shift_mv );
    cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][1]), block_shift_mv );
    //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
    *prednum += (*((int*) cur_mv) != 0);
  }

  if (blocktype != 1)
  {
    cur_mv = &predictor->point[*prednum].motion;
    cur_mv->mv_x = rshift_rnd((all_mv[ref][1][block_y][block_x][0]), mv_rescale);
    cur_mv->mv_y = rshift_rnd((all_mv[ref][1][block_y][block_x][1]), mv_rescale);
    //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
    *prednum += (*((int*) cur_mv) != 0);
  }

  if (blocktype != 4)
  {
    cur_mv = &predictor->point[*prednum].motion;
    cur_mv->mv_x = rshift_rnd((all_mv[ref][4][block_y][block_x][0]), mv_rescale);
    cur_mv->mv_y = rshift_rnd((all_mv[ref][4][block_y][block_x][1]), mv_rescale);
    //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
    *prednum += (*((int*) cur_mv) != 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;
  SPoint *wPoint = &windowPred->point[0];
  SPoint *pPoint = &predictor->point[(*prednum)];

  for (pos = 0; pos < windowPred->searchPoints; pos++)
  {
    (pPoint  )->motion.mv_x = mv[0] + (wPoint  )->motion.mv_x;
    (pPoint++)->motion.mv_y = mv[1] + (wPoint++)->motion.mv_y;    
  }
  *prednum += windowPred->searchPoints;
}

/*!
***********************************************************************
* \brief
*    FAST Motion Estimation using EPZS
*    AMT/HYC
***********************************************************************
*/
int                                           //  ==> minimum motion cost after search
EPZSPelBlockMotionSearch (Macroblock *currMB, // <--  current Macroblock
                          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 in sub-pel units
                          short mv[2],        // <--> in: search center (x|y) / out: motion vector (x|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
                          int apply_weights)  // <--  perform weight based ME
{
  StorablePicture *ref_picture = listX[list+list_offset][ref];
  short blocksize_y = params->blc_size[blocktype][1];  // vertical block size
  short blocksize_x = params->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->opi

⌨️ 快捷键说明

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