万圣节杀人狂百度云:PartitionMotionSearch函数分析 - 二手流氓的专栏 - CSDN博客

来源:百度文库 编辑:偶看新闻 时间:2024/04/25 17:14:49
这两个函数位于文件mv_search.c中,在分析这两个函数前,先看一下文件开头定义的两个数组:static const short bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static const short by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};这里,每一行的五个一维数组分别代表了Skip,16×16,16×8,8×16,8×8五种分块方式下,每个子分块左上角像素的坐标值(这个坐标以4×4的分块为单位)。/*!
 ************************************************************************
 * \brief
 *    Motion search for a macroblock partition
 ************************************************************************
 */
void PartitionMotionSearch (Macroblock *currMB,   /*指向当前宏块*/
                            int    blocktype,     /* 块类型,Skip,16×16,16×8,8×16,8×8 */
                            int    block8x8,      /* 8×8分块标识 */
                            int    *lambda_factor)/* 拉格朗日参数 */
{
  VideoParameters *p_Vid = currMB->p_Vid;
  Slice *currSlice = currMB->p_Slice;#if GET_METIME
  TIME_T me_time_start;
  TIME_T me_time_end;
  int64 me_tmp_time;
  gettime( &me_time_start );    // start time ms
#endif  if (currSlice->rdoq_motion_copy == 1)
  {
    PicMotionParams **motion = p_Vid->enc_picture->mv_info;
    short by = by0[blocktype][block8x8]; /* 含义见文章开头 */
    short bx = bx0[blocktype][block8x8];
    short step_h = (part_size[blocktype][0]); /*  */
    short step_v = (part_size[blocktype][1]); /*  */    short pic_block_y = currMB->block_y + by;
    short pic_block_x = currMB->block_x + bx;
    int   list_offset = currMB->list_offset;  /* ???? */
    int   numlists    = (currSlice->slice_type == B_SLICE) ? 2 : 1;
    distblk *m_cost;
  
    short list = LIST_0;
    short ref = 0;           //===== LOOP OVER REFERENCE FRAMES =====
    for (list = 0; list < numlists; list++)
    {
      for (ref=0; ref < currSlice->listXsize[list+list_offset]; ref++)
      {
        m_cost = &p_Vid->motion_cost[blocktype][list][ref][block8x8];        //===== LOOP OVER SUB MACRO BLOCK partitions
        updateMV_mp(currMB, m_cost, ref, list, bx, by, blocktype, block8x8);
        set_me_parameters(motion, &currSlice->all_mv[list][ref][blocktype][by][bx], list, (char) ref, step_h, step_v, pic_block_y, pic_block_x);
      }
    }
  }
  else
  {
    InputParameters *p_Inp = currMB->p_Inp;
    short by = by0[blocktype][block8x8]; /* 当前块在宏块内y方向的偏移,以4×4为单位 */
    short bx = bx0[blocktype][block8x8]; /* 当前块在宏块内x方向的偏移,以4×4为单位 */
    short step_h    = (part_size[blocktype][0]);
    short step_v    = (part_size[blocktype][1]);    short pic_block_y = currMB->block_y + by;/* 当前块的位置,y方向 */
    short pic_block_x = currMB->block_x + bx;/* 当前块的位置,x方向 */
    int   list_offset = currMB->list_offset;
    int   numlists  = (currSlice->slice_type == B_SLICE) ? 2 : 1; /* 使用的参考图像列表数目 */
    short list = LIST_0;/* 参考图像列表 */
    short ref = 0;      /* 参考图像索引值 */
    MEBlock  mv_block;  /* 运动矢量 */
    distblk *m_cost;   
    PicMotionParams **motion = p_Vid->enc_picture->mv_info;      // Set flag for 8x8 Hadamard consideration for SATD (only used when 8x8 integer transform is used for encoding)
    mv_block.test8x8 = p_Inp->Transform8x8Mode;    /* 初始化结构体,主要是这支参考图像列表及索引值,块类型等 */    init_mv_block(currMB, &mv_block, (short) blocktype, list, (char) ref, bx, by);    if (p_Inp->SearchMode == EPZS)
    {
      if (p_Inp->EPZSSubPelGrid)
        currMB->IntPelME = EPZSIntPelBlockMotionSearch;
      else
        currMB->IntPelME = EPZSPelBlockMotionSearch;
    }    /* 获取图像原像素值 */
    get_original_block(p_Vid, &mv_block);    //--- motion search for block ---  
    {
      //===== LOOP OVER REFERENCE FRAMES =====
      for (list = 0; list < numlists; list++)
      {
        //----- set arrays -----
        mv_block.list = (char) list;
        for (ref=0; ref < currSlice->listXsize[list+list_offset]; ref++)
        {
            mv_block.ref_idx = (char) ref; //设定参考图像索引值
            m_cost = &p_Vid->motion_cost[blocktype][list][ref][block8x8];            {
              //----- set search range ---
              get_search_range(&mv_block, p_Inp, ref, blocktype);              //===== LOOP OVER MACROBLOCK partitions       
              *m_cost = BlockMotionSearch (currMB, &mv_block, bx<<2, by<<2, lambda_factor);    
            }
            //--- set motion vectors and reference frame ---             set_me_parameters(motion, &currSlice->all_mv[list][ref][blocktype][by][bx], list, (char) ref, step_h, step_v, pic_block_y, pic_block_x);
        }
      }
    }    free_mv_block(&mv_block);
  }#if GET_METIME
  gettime(&me_time_end);   // end time ms
  me_tmp_time = timediff (&me_time_start, &me_time_end);
  p_Vid->me_tot_time += me_tmp_time;
  p_Vid->me_time += me_tmp_time;
#endif
} 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/underway2010/archive/2010/12/12/6071374.aspx