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

📄 mv-search.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
      spiral_search_y[k] = -l;
      spiral_hpel_search_x[k] =  i<<1;
      spiral_hpel_search_y[k++] = -l<<1;
      spiral_search_x[k] =  i;
      spiral_search_y[k] =  l;
      spiral_hpel_search_x[k] =  i<<1;
      spiral_hpel_search_y[k++] =  l<<1;
    }
    for (i=-l;   i<=l; i++)
    {
      spiral_search_x[k] = -l;
      spiral_search_y[k] =  i;
      spiral_hpel_search_x[k] = -l<<1;
      spiral_hpel_search_y[k++] = i<<1;
      spiral_search_x[k] =  l;
      spiral_search_y[k] =  i;
      spiral_hpel_search_x[k] =  l<<1;
      spiral_hpel_search_y[k++] = i<<1;
    }
  }

  // set global variable prior to ME
  start_me_refinement_hp = (input->ChromaMEEnable == 1 || input->MEErrorMetric[F_PEL] != input->MEErrorMetric[H_PEL] ) ? 0 : 1;
  start_me_refinement_qp = (input->ChromaMEEnable == 1 || input->MEErrorMetric[H_PEL] != input->MEErrorMetric[Q_PEL] ) ? 0 : 1;

  // Setup Distortion Metrics depending on refinement level
  for (i=0; i<3; i++)
  {
    switch(input->MEErrorMetric[i])
    {
    case ERROR_SAD:
      computeUniPred[i] = computeSAD;
      computeUniPred[i + 3] = computeSADWP;
      computeBiPred1[i] = computeBiPredSAD1;
      computeBiPred2[i] = computeBiPredSAD2;
      break;
    case ERROR_SSE:
      computeUniPred[i] = computeSSE;
      computeUniPred[i + 3] = computeSSEWP;
      computeBiPred1[i] = computeBiPredSSE1;
      computeBiPred2[i] = computeBiPredSSE2;
      break;
    case ERROR_SATD :
    default:
      computeUniPred[i] = computeSATD;
      computeUniPred[i + 3] = computeSATDWP;
      computeBiPred1[i] = computeBiPredSATD1;
      computeBiPred2[i] = computeBiPredSATD2;
      break;
    }
  }
  // Setup buffer access methods
  get_line[0] = FastLine4X;
  get_line[1] = UMVLine4X;
  get_crline[0] = FastLine8X_chroma;
  get_crline[1] = UMVLine8X_chroma;

  if(input->SearchMode == FAST_FULL_SEARCH)
    InitializeFastFullIntegerSearch ();
}


/*!
 ************************************************************************
 * \brief
 *    Free memory used by motion search
 ************************************************************************
 */
void
Clear_Motion_Search_Module ()
{
  //--- correct array offset ---
  mvbits   -= max_mvd;
  byte_abs -= byte_abs_range/2;

  //--- delete arrays ---
  free (spiral_search_x);
  free (spiral_search_y);
  free (spiral_hpel_search_x);
  free (spiral_hpel_search_y);
  free (mvbits);
  free (refbits);
  free (byte_abs);
					
  if (motion_cost)
    free_mem4Dint (motion_cost, 8, 2);

  if(input->SearchMode == FAST_FULL_SEARCH)
    ClearFastFullIntegerSearch ();
}

/*!
 ***********************************************************************
 * \brief
 *    Motion Cost for Bidirectional modes
 ***********************************************************************
 */
int BPredPartitionCost (int   blocktype,
                        int   block8x8,
                        short ref_l0,
                        short ref_l1,
                        int   lambda_factor,
                        int   list)
{
  static int  bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
  static int  by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
  
  int   curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; // ABT pred.error buffer
  int   bsx       = imin(input->blc_size[blocktype][0],8);
  int   bsy       = imin(input->blc_size[blocktype][1],8);

  int   pic_pix_x, pic_pix_y, block_x, block_y;
  int   v, h, mcost, i, j, k;
  int   mvd_bits  = 0;
  int   parttype  = (blocktype<4?blocktype:4);
  int   step_h0   = (input->part_size[ parttype][0]);
  int   step_v0   = (input->part_size[ parttype][1]);
  int   step_h    = (input->part_size[blocktype][0]);
  int   step_v    = (input->part_size[blocktype][1]);
  int   bxx, byy;                               // indexing curr_blk

  short   ******all_mv = list ? img->bipred_mv1 : img->bipred_mv2;
  short   ******  p_mv = img->pred_mv;

  for (v=by0[parttype][block8x8]; v<by0[parttype][block8x8]+step_v0; v+=step_v)
  {
    for (h=bx0[parttype][block8x8]; h<bx0[parttype][block8x8]+step_h0; h+=step_h)
    {
      mvd_bits += mvbits[ all_mv [v][h][LIST_0][ref_l0][blocktype][0] - p_mv[v][h][LIST_0][ref_l0][blocktype][0] ];
      mvd_bits += mvbits[ all_mv [v][h][LIST_0][ref_l0][blocktype][1] - p_mv[v][h][LIST_0][ref_l0][blocktype][1] ];

      mvd_bits += mvbits[ all_mv [v][h][LIST_1][ref_l1][blocktype][0] - p_mv[v][h][LIST_1][ref_l1][blocktype][0] ];
      mvd_bits += mvbits[ all_mv [v][h][LIST_1][ref_l1][blocktype][1] - p_mv[v][h][LIST_1][ref_l1][blocktype][1] ];
    }
  }
    mcost = WEIGHTED_COST (lambda_factor, mvd_bits);

    //----- cost of residual signal -----
    for (byy=0, v=by0[parttype][block8x8]; v<by0[parttype][block8x8]+step_v0; byy+=4, v++)
    {

      pic_pix_y = img->opix_y + (block_y = (v<<2));
      for (bxx=0, h=bx0[parttype][block8x8]; h<bx0[parttype][block8x8]+step_h0; bxx+=4, h++)
      {
        pic_pix_x = img->opix_x + (block_x = (h<<2));
        LumaPrediction4x4Bi (block_x, block_y, blocktype, blocktype, ref_l0, ref_l1, list);

        for (k=j=0; j<4; j++)
        {
          for (  i=0; i<4; i++)
            diff64[k++] = curr_blk[byy+j][bxx+i] =
            imgY_org[pic_pix_y+j][pic_pix_x+i] - img->mpr[j+block_y][i+block_x];
        }
        if ((!input->Transform8x8Mode) || (blocktype>4))
        {
          mcost += distortion4x4 (diff64);
        }
      }
    }
    if (input->Transform8x8Mode && (blocktype<=4))  // tchen 4-29-04
    {
      for (byy=0; byy < input->blc_size[parttype][1]; byy+=bsy)
        for (bxx=0; bxx<input->blc_size[parttype][0]; bxx+=bsx)
        {
          for (k=0, j=byy;j<byy + 8;j++, k += 8)
            memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));

          mcost += distortion8x8(diff64);
        }
    }
    return mcost;
}


/*!
 ***********************************************************************
 * \brief
 *    Block motion search
 ***********************************************************************
 */
int                                         //!< minimum motion cost after search
BlockMotionSearch (short     ref,           //!< reference idx
                   int       list,          //!< reference pciture list
                   int       mb_x,          //!< x-coordinate inside macroblock
                   int       mb_y,          //!< y-coordinate inside macroblock
                   int       blocktype,     //!< block type (1-16x16 ... 7-4x4)
                   int       search_range,  //!< 1-d search range for integer-position search
                   int*      lambda_factor) //!< lagrangian parameter for determining motion cost
{
  // each 48-pel line stores the 16 luma pels (at 0) followed by 8 or 16 crcb[0] (at 16) and crcb[1] (at 32) pels
  // depending on the type of chroma subsampling used: YUV 4:4:4, 4:2:2, and 4:2:0
  imgpel *orig_pic_tmp = orig_pic;

  short     mv[2];
  int       i, j;

  int       max_value = INT_MAX;
  int       min_mcost = max_value;

  int       block_x   = (mb_x>>2);
  int       block_y   = (mb_y>>2);

  int       bsx       = input->blc_size[blocktype][0];
  int       bsy       = input->blc_size[blocktype][1];

  int       pic_pix_x = img->opix_x + mb_x;
  int       pic_pix_y = img->opix_y + mb_y;

  int pic_pix_x_c = pic_pix_x >> (chroma_shift_x - 2);
  int pic_pix_y_c = pic_pix_y >> (chroma_shift_y - 2);
  int bsx_c = bsx >> (chroma_shift_x - 2);
  int bsy_c = bsy >> (chroma_shift_y - 2);

  short*    pred_mv = img->pred_mv[block_y][block_x][list][ref][blocktype];
  short****** all_mv    = img->all_mv;
  int list_offset = ((img->MbaffFrameFlag) && (img->mb_data[img->current_mb_nr].mb_field)) ? img->current_mb_nr % 2 ? 4 : 2 : 0;
  int *prevSad = (input->SearchMode == EPZS)? EPZSDistortion[list + list_offset][blocktype - 1]: NULL;

#if GET_METIME
  static struct TIMEB tstruct1;
  static struct TIMEB tstruct2;
  time_t me_tmp_time;

  ftime( &tstruct1 );    // start time ms
#endif
  //==================================
  //=====   GET ORIGINAL BLOCK   =====
  //==================================
  for (j = 0; j < bsy; j++)
  {
    memcpy(orig_pic_tmp,&imgY_org[pic_pix_y+j][pic_pix_x], bsx *sizeof(imgpel));
    orig_pic_tmp += bsx;
  }
  ChromaMEEnable = input->ChromaMEEnable;

  if ( ChromaMEEnable )
  {
    // copy the original cmp1 and cmp2 data to the orig_pic matrix
    orig_pic_tmp = orig_pic + 256;
    for (j = 0; j < bsy_c; j++)
    {
      memcpy(orig_pic_tmp, &(imgUV_org[0][pic_pix_y_c+j][pic_pix_x_c]), bsx_c *sizeof(imgpel));
      orig_pic_tmp += bsx_c;
    }
    orig_pic_tmp = orig_pic + 512;
    for (j = 0; j < bsy_c; j++)
    {
      memcpy(orig_pic_tmp, &(imgUV_org[1][pic_pix_y_c+j][pic_pix_x_c]), bsx_c *sizeof(imgpel));
      orig_pic_tmp += bsx_c;
    }
  }


  if(input->SearchMode == UM_HEX)
  {
    UMHEX_blocktype = blocktype;
    bipred_flag = 0;
  }
  else if (input->SearchMode == UM_HEX_SIMPLE)
  {
    smpUMHEX_setup(ref, list, block_y, block_x, blocktype, all_mv );
  }

  // Set if 8x8 transform will be used if SATD is used
  test8x8transform = input->Transform8x8Mode && blocktype <= 4;

  //===========================================
  //=====   GET MOTION VECTOR PREDICTOR   =====
  //===========================================

  if (input->SearchMode == UM_HEX)
    UMHEXSetMotionVectorPredictor(pred_mv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, block_x, block_y, bsx, bsy, &search_range);
  else
    SetMotionVectorPredictor (pred_mv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, block_x, block_y, bsx, bsy);

  //==================================
  //=====   INTEGER-PEL SEARCH   =====
  //==================================

  if (input->SearchMode == UM_HEX)
  {
    mv[0] = pred_mv[0] / 4;
    mv[1] = pred_mv[1] / 4;

    if (!input->rdopt)
    {
      //--- adjust search center so that the (0,0)-vector is inside ---
      mv[0] = iClip3(-search_range, search_range, mv[0]);
      mv[1] = iClip3(-search_range, search_range, mv[1]);
    }

    mv[0] = iClip3(-2047 + search_range, 2047 - search_range, mv[0]);
    mv[1] = iClip3(LEVELMVLIMIT[img->LevelIndex][0] + search_range, LEVELMVLIMIT[img->LevelIndex][1]  - search_range, mv[1]);

    min_mcost = UMHEXIntegerPelBlockMotionSearch(orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
      pred_mv[0], pred_mv[1], &mv[0], &mv[1], search_range,
      min_mcost, lambda_factor[F_PEL]);
  }
  else if (input->SearchMode == UM_HEX_SIMPLE)
  {
    mv[0] = pred_mv[0] / 4;
    mv[1] = pred_mv[1] / 4;

    if (!input->rdopt)
    {
      //--- adjust search center so that the (0,0)-vector is inside ---
      mv[0] = iClip3(-search_range, search_range, mv[0]);
      mv[1] = iClip3(-search_range, search_range, mv[1]);
    }

    mv[0] = iClip3(-2047 + search_range, 2047 - search_range, mv[0]);
    mv[1] = iClip3(LEVELMVLIMIT[img->LevelIndex][0] + search_range, LEVELMVLIMIT[img->LevelIndex][1]  - search_range, mv[1]);


    min_mcost = smpUMHEXIntegerPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
                                                 pred_mv[0], pred_mv[1], &mv[0], &mv[1], search_range,
                                                 min_mcost, lambda_factor[F_PEL]);
    for (i=0; i < (bsx>>2); i++)
    {
      for (j=0; j < (bsy>>2); j++)
      {
        if(list == 0)
        {
         smpUMHEX_l0_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
        }
        else
        {
          smpUMHEX_l1_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
        }
      }
    }
  }
  //--- perform motion search using EPZS schemes---
  else if (input->SearchMode == EPZS)
  {
    //--- set search center ---
    // This has to be modified in the future
    if (input->EPZSSubPelGrid)
    {
      mv[0] = pred_mv[0];
      mv[1] = pred_mv[1];
    }
    else
    {
      mv[0] = (pred_mv[0] + 2)>> 2;
      mv[1] = (pred_mv[1] + 2)>> 2;
    }

    if (!input->rdopt)
    {
      //--- adjust search center so that the (0,0)-vector is inside ---
      mv[0] = iClip3 (-search_range<<(input->EPZSSubPelGrid * 2), search_range<<(input->EPZSSubPelGrid * 2), mv[0]);
      mv[1] = iClip3 (-search_range<<(input->EPZSSubPelGrid * 2), search_range<<(input->EPZSSubPelGrid * 2), mv[1]);
    }

    // valid search range limits could be precomputed once during the initialization process
    mv[0] = iClip3((-2047 + search_range)<<(input->EPZSSubPelGrid * 2), (2047 - search_range)<<(input->EPZSSubPelGrid * 2), mv[0]);
    mv[1] = iClip3((LEVELMVLIMIT[img->LevelIndex][0] + search_range)<<(input->EPZSSubPelGrid * 2),
      (LEVELMVLIMIT[img->LevelIndex][1]  - search_range)<<(input->EPZSSubPelGrid * 2), mv[1]);

    min_mcost = EPZSPelBlockMotionSearch (orig_pic, ref, list, list_offset,
      enc_picture->ref_idx, enc_picture->mv, pic_pix_x, pic_pix_y, blocktype,
      pred_mv, mv, search_range<<(input->EPZSSubPelGrid * 2), min_mcost, lambda_factor[F_PEL]);

  }
  else if (input->SearchMode == FAST_FULL_SEARCH)
  {
    // comments:   - orig_pic is not used  -> be careful
    //             - search center is automatically determined
    min_mcost = FastFullPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
      pred_mv[0], pred_mv[1], &mv[0], &mv[1], search_range,

⌨️ 快捷键说明

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