me_umhexsmp.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:48k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  *
  4.  * file me_umhexsmp.c
  5.  *
  6.  * brief
  7.  *   Fast integer pixel and sub pixel motion estimation
  8.  *   Improved and simplified from the original UMHexagonS algorithms
  9.  *   See JVT-P021 for details
  10.  *
  11.  * author
  12.  *    Main contributors: (see contributors.h for copyright, address and affiliation details)
  13.  *    - Zhibo Chen                      <chenzhibo@tsinghua.org.cn>
  14.  *    - JianFeng Xu                     <fenax@video.mdc.tsinghua.edu.cn>
  15.  *    - Wenfang Fu                      <fwf@video.mdc.tsinghua.edu.cn>
  16.  *
  17.  *    - Xiaoquan Yi                     <xyi@engr.scu.edu>
  18.  *    - Jun Zhang                       <jzhang2@engr.scu.edu>
  19.  *
  20.  * date
  21.  *    6. Nov. 2006
  22.  *************************************************************************************
  23.  */
  24. #include <limits.h>
  25. #include "global.h"
  26. #include "memalloc.h"
  27. #include "me_umhexsmp.h"
  28. #include "refbuf.h"
  29. #include "me_distortion.h"
  30. #include "mv-search.h"
  31. static const short Diamond_X[4]      = {-1, 1, 0, 0};
  32. static const short Diamond_Y[4]      = { 0, 0,-1, 1};
  33. static const short Hexagon_X[6]      = {-2, 2,-1, 1,-1, 1};
  34. static const short Hexagon_Y[6]      = { 0, 0,-2, 2, 2,-2};
  35. static const short Big_Hexagon_X[16] = {-4, 4, 0, 0,-4, 4,-4, 4,-4, 4,-4, 4,-2, 2,-2, 2};
  36. static const short Big_Hexagon_Y[16] = { 0, 0,-4, 4,-1, 1, 1,-1,-2, 2, 2,-2,-3, 3, 3,-3};
  37. const short block_type_shift_factor[8] = {0, 0, 1, 1, 2, 3, 3, 1}; // last one relaxed to 1 instead 4
  38. static StorablePicture *ref_pic_ptr;
  39. static int dist_method;
  40. extern short*  spiral_hpel_search_x;
  41. extern short*  spiral_hpel_search_y;
  42. extern short*  spiral_search_x;
  43. extern short*  spiral_search_y;
  44. // Macro for motion estimation cost computation per match
  45. #define SEARCH_ONE_PIXEL_HELPER                                                           
  46.   if(iabs(cand_x - center_x) <= search_range && iabs(cand_y - center_y) <= search_range)  
  47.   {                                                                                       
  48.     mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);             
  49.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,             
  50.           min_mcost - mcost, (cand_x + IMG_PAD_SIZE) << 2, (cand_y + IMG_PAD_SIZE) << 2); 
  51.     if (mcost < min_mcost)                                                                
  52.     {                                                                                     
  53.       best_x    = cand_x;                                                                 
  54.       best_y    = cand_y;                                                                 
  55.       min_mcost = mcost;                                                                  
  56.     }                                                                                     
  57. }
  58. #define SEARCH_ONE_PIXEL_BIPRED_HELPER                                                    
  59. if (iabs(cand_x - center2_x) <= search_range && iabs(cand_y - center2_y) <= search_range) 
  60. {                                                                                         
  61.   mcost  = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);      
  62.   mcost += MV_COST (lambda_factor, mvshift, cand_x,    cand_y,    pred_x2, pred_y2);      
  63.   if (mcost < min_mcost)                                                                  
  64.   {                                                                                       
  65.     mcost  += computeBiPred(cur_pic, blocksize_y, blocksize_x,                            
  66.                            min_mcost - mcost,                                             
  67.                            (center1_x << 2) + IMG_PAD_SIZE_TIMES4,                        
  68.                            (center1_y << 2) + IMG_PAD_SIZE_TIMES4,                        
  69.                            (cand_x << 2) + IMG_PAD_SIZE_TIMES4,                           
  70.                            (cand_y << 2) + IMG_PAD_SIZE_TIMES4);                          
  71.     if (mcost < min_mcost)                                                                
  72.     {                                                                                     
  73.       best_x = cand_x;                                                                    
  74.       best_y = cand_y;                                                                    
  75.       min_mcost = mcost;                                                                  
  76.     }                                                                                     
  77.   }                                                                                       
  78. }
  79. /*!
  80.  ************************************************************************
  81.  * brief
  82.  *    Set thresholds for fast motion estimation
  83.  *    Those thresholds may be adjusted to trade off rate-distortion
  84.  *    performance and simplified UMHEX speed
  85.  ************************************************************************
  86.  */
  87. void smpUMHEX_init()
  88. {
  89.   SymmetricalCrossSearchThreshold1 =  800;
  90.   SymmetricalCrossSearchThreshold2 = 7000;
  91.   ConvergeThreshold                = 1000;
  92.   SubPelThreshold1                 = 1000;
  93.   SubPelThreshold3                 =  400;
  94. }
  95. /*!
  96.  ************************************************************************
  97.  * brief
  98.  *    Allocation of space for fast motion estimation
  99.  ************************************************************************
  100.  */
  101. int smpUMHEX_get_mem()
  102. {
  103.   int memory_size = 0;
  104.   if (NULL==(smpUMHEX_flag_intra = calloc((img->width>>4)+1, sizeof(byte))))
  105.     no_mem_exit("smpUMHEX_get_mem: smpUMHEX_flag_intra");
  106.   memory_size += get_mem3Dint(&smpUMHEX_l0_cost, 9, img->height/4, img->width/4);
  107.   memory_size += get_mem3Dint(&smpUMHEX_l1_cost, 9, img->height/4, img->width/4);
  108.   memory_size += get_mem2D(&smpUMHEX_SearchState, 7, 7);
  109.   return memory_size;
  110. }
  111. /*!
  112.  ************************************************************************
  113.  * brief
  114.  *    Free space for fast motion estimation
  115.  ************************************************************************
  116.  */
  117. void smpUMHEX_free_mem()
  118. {
  119.   free_mem3Dint(smpUMHEX_l0_cost );
  120.   free_mem3Dint(smpUMHEX_l1_cost );
  121.   free_mem2D(smpUMHEX_SearchState);
  122.   free (smpUMHEX_flag_intra);
  123. }
  124. /*!
  125. ************************************************************************
  126. * brief
  127. *    Fast integer pixel block motion estimation
  128. ************************************************************************
  129. */
  130. int                                     //  ==> minimum motion cost after search
  131. smpUMHEXIntegerPelBlockMotionSearch (Macroblock *currMB,      // <--  current Macroblock
  132.                                      imgpel   *orig_pic,      // <--  not used
  133.                                      short     ref,           // <--  reference frame (0... or -1 (backward))
  134.                                      int       list,          // <--  reference picture list
  135.                                      int       list_offset,   // <--  MBAFF list offset
  136.                                      char   ***refPic,        // <--  reference array
  137.                                      short ****tmp_mv,        // <--  mv array
  138.                                      int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  139.                                      int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  140.                                      int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  141.                                      short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  142.                                      short     mv[2],         //  --> motion vector (x|y) - in pel units
  143.                                      int       search_range,  // <--  1-d search range in pel units
  144.                                      int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  145.                                      int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  146.                                      int       apply_weights
  147.                                      )
  148. {
  149.   int   mvshift       = 2;                                        // motion vector shift for getting sub-pel units
  150.   int   blocksize_y   = params->blc_size[blocktype][1];            // vertical block size
  151.   int   blocksize_x   = params->blc_size[blocktype][0];            // horizontal block size
  152.   int   pred_x        = (pic_pix_x << mvshift) + pred_mv[0];       // predicted position x (in sub-pel units)
  153.   int   pred_y        = (pic_pix_y << mvshift) + pred_mv[1];       // predicted position y (in sub-pel units)
  154.   int   center_x      = pic_pix_x + mv[0];                        // center position x (in pel units)
  155.   int   center_y      = pic_pix_y + mv[1];                        // center position y (in pel units)
  156.   int   best_x        = 0, best_y = 0;
  157.   int   search_step, iYMinNow, iXMinNow;
  158.   int   cand_x, cand_y, mcost;
  159.   unsigned short  i, j, m;
  160.   //===== Use weighted Reference for ME ====
  161.   dist_method = F_PEL + 3 * apply_weights;
  162.   ref_pic_ptr = listX[list+list_offset][ref];
  163.   // Note that following seem to be universal for all functions and could be moved to a separate, clean public function in me_distortion.c
  164.   ref_pic_sub.luma = ref_pic_ptr->p_curr_img_sub;
  165.   img_width  = ref_pic_ptr->size_x;
  166.   img_height = ref_pic_ptr->size_y;
  167.   width_pad  = ref_pic_ptr->size_x_pad;
  168.   height_pad = ref_pic_ptr->size_y_pad;
  169.   if (apply_weights)
  170.   {
  171.     weight_luma = wp_weight[list + list_offset][ref][0];
  172.     offset_luma = wp_offset[list + list_offset][ref][0];
  173.   }
  174.   if (ChromaMEEnable)
  175.   {
  176.     ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
  177.     ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
  178.     width_pad_cr  = ref_pic_ptr->size_x_cr_pad;
  179.     height_pad_cr = ref_pic_ptr->size_y_cr_pad;
  180.     if (apply_weights)
  181.     {
  182.       weight_cr[0] = wp_weight[list + list_offset][ref][1];
  183.       weight_cr[1] = wp_weight[list + list_offset][ref][2];
  184.       offset_cr[0] = wp_offset[list + list_offset][ref][1];
  185.       offset_cr[1] = wp_offset[list + list_offset][ref][2];
  186.     }
  187.   }
  188.   //===== set function for getting reference picture lines =====
  189.   if ((center_x > search_range) && (center_x < img_width - 1 - search_range - blocksize_x) &&
  190.     (center_y > search_range) && (center_y < img_height - 1 - search_range - blocksize_y))
  191.   {
  192.     ref_access_method = FAST_ACCESS;
  193.   }
  194.   else
  195.   {
  196.     ref_access_method = UMV_ACCESS;
  197.   }
  198.   //check the center median predictor
  199.   cand_x = center_x ;
  200.   cand_y = center_y ;
  201.   mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
  202.   mcost += computeUniPred[dist_method](orig_pic, blocksize_y,blocksize_x, min_mcost - mcost,
  203.     (cand_x << 2) + IMG_PAD_SIZE_TIMES4,  (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
  204.   if (mcost < min_mcost)
  205.   {
  206.     min_mcost = mcost;
  207.     best_x    = cand_x;
  208.     best_y    = cand_y;
  209.   }
  210.   iXMinNow = best_x;
  211.   iYMinNow = best_y;
  212.   if ((0 != pred_mv[0]) || (0 != pred_mv[1]))
  213.   {
  214.     cand_x = pic_pix_x;
  215.     cand_y = pic_pix_y;
  216.     SEARCH_ONE_PIXEL_HELPER
  217.   }
  218.   // If the min_mcost is small enough, do a local search then terminate
  219.   // Ihis is good for stationary or quasi-stationary areas
  220.   if (min_mcost < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
  221.   {
  222.     for (m = 0; m < 4; m++)
  223.     {
  224.       cand_x = iXMinNow + Diamond_X[m];
  225.       cand_y = iYMinNow + Diamond_Y[m];
  226.       SEARCH_ONE_PIXEL_HELPER
  227.     }
  228.     mv[0] = (short) (best_x - pic_pix_x);
  229.     mv[1] = (short) (best_y - pic_pix_y);
  230.     return min_mcost;
  231.   }
  232.   // Small local search
  233.   for (m = 0; m < 4; m++)
  234.   {
  235.     cand_x = iXMinNow + Diamond_X[m];
  236.     cand_y = iYMinNow + Diamond_Y[m];
  237.     SEARCH_ONE_PIXEL_HELPER
  238.   }
  239.   // First_step: Symmetrical-cross search
  240.   // If distortion is large, use large shapes. Otherwise, compact shapes are faster
  241.   if ( (blocktype == 1 &&
  242.     min_mcost > (SymmetricalCrossSearchThreshold1>>block_type_shift_factor[blocktype])) ||
  243.     (min_mcost > (SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])) )
  244.   {
  245.     iXMinNow = best_x;
  246.     iYMinNow = best_y;
  247.     for(i = 1; i <= search_range/2; i++)
  248.     {
  249.       search_step = (i<<1) - 1;
  250.       cand_x = iXMinNow + search_step;
  251.       cand_y = iYMinNow;
  252.       SEARCH_ONE_PIXEL_HELPER
  253.         cand_x = iXMinNow - search_step;
  254.       SEARCH_ONE_PIXEL_HELPER
  255.         cand_x = iXMinNow;
  256.       cand_y = iYMinNow + search_step;
  257.       SEARCH_ONE_PIXEL_HELPER
  258.         cand_y = iYMinNow - search_step;
  259.       SEARCH_ONE_PIXEL_HELPER
  260.     }
  261.     // Hexagon Search
  262.     iXMinNow = best_x;
  263.     iYMinNow = best_y;
  264.     for (m = 0; m < 6; m++)
  265.     {
  266.       cand_x = iXMinNow + Hexagon_X[m];
  267.       cand_y = iYMinNow + Hexagon_Y[m];
  268.       SEARCH_ONE_PIXEL_HELPER
  269.     }
  270.     // Multi Big Hexagon Search
  271.     iXMinNow = best_x;
  272.     iYMinNow = best_y;
  273.     for(i = 1; i <= search_range/4; i++)
  274.     {
  275.       for (m = 0; m < 16; m++)
  276.       {
  277.         cand_x = iXMinNow + Big_Hexagon_X[m]*i;
  278.         cand_y = iYMinNow + Big_Hexagon_Y[m]*i;
  279.         SEARCH_ONE_PIXEL_HELPER
  280.       }
  281.     }
  282.   }
  283.   // Search up_layer predictor for non 16x16 blocks
  284.   if (blocktype > 1)
  285.   {
  286.     cand_x = pic_pix_x + (smpUMHEX_pred_MV_uplayer_X/4);
  287.     cand_y = pic_pix_y + (smpUMHEX_pred_MV_uplayer_Y/4);
  288.     SEARCH_ONE_PIXEL_HELPER
  289.   }
  290.   if(center_x != pic_pix_x || center_y != pic_pix_y)
  291.   {
  292.     cand_x = pic_pix_x;
  293.     cand_y = pic_pix_y;
  294.     SEARCH_ONE_PIXEL_HELPER
  295.       iXMinNow = best_x;
  296.     iYMinNow = best_y;
  297.     // Local diamond search
  298.     for (m = 0; m < 4; m++)
  299.     {
  300.       cand_x = iXMinNow + Diamond_X[m];
  301.       cand_y = iYMinNow + Diamond_Y[m];
  302.       SEARCH_ONE_PIXEL_HELPER
  303.     }
  304.   }
  305.   // If the minimum cost is small enough, do a local search
  306.   // and finish the search here
  307.   if (min_mcost < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
  308.   {
  309.     iXMinNow = best_x;
  310.     iYMinNow = best_y;
  311.     for (m = 0; m < 4; m++)
  312.     {
  313.       cand_x = iXMinNow + Diamond_X[m];
  314.       cand_y = iYMinNow + Diamond_Y[m];
  315.       SEARCH_ONE_PIXEL_HELPER
  316.     }
  317.     mv[0] = (short) (best_x - pic_pix_x);
  318.     mv[1] = (short) (best_y - pic_pix_y);
  319.     return min_mcost;
  320.   }
  321.   //second_step:  Extended Hexagon-based Search
  322.   for(i = 0; i < search_range; i++)
  323.   {
  324.     iXMinNow = best_x;
  325.     iYMinNow = best_y;
  326.     for (m = 0; m < 6; m++)
  327.     {
  328.       cand_x = iXMinNow + Hexagon_X[m];
  329.       cand_y = iYMinNow + Hexagon_Y[m];
  330.       SEARCH_ONE_PIXEL_HELPER
  331.     }
  332.     // The minimum cost point happens in the center
  333.     if (best_x == iXMinNow && best_y == iYMinNow)
  334.     {
  335.       break;
  336.     }
  337.   }
  338.   //third_step: Small diamond search
  339.   for(i = 0; i < search_range; i++)
  340.   {
  341.     iXMinNow = best_x;
  342.     iYMinNow = best_y;
  343.     for (m = 0; m < 4; m++)
  344.     {
  345.       cand_x = iXMinNow + Diamond_X[m];
  346.       cand_y = iYMinNow + Diamond_Y[m];
  347.       SEARCH_ONE_PIXEL_HELPER
  348.     }
  349.     // The minimum cost point happens in the center
  350.     if (best_x == iXMinNow && best_y == iYMinNow)
  351.     {
  352.       break;
  353.     }
  354.   }
  355.   mv[0] = (short) (best_x - pic_pix_x);
  356.   mv[1] = (short) (best_y - pic_pix_y);
  357.   for (j=(pic_pix_y>>2); j < (pic_pix_y>>2) + (blocksize_y>>2); j++)
  358.   {
  359.     for (i=(pic_pix_x>>2); i < (pic_pix_x>>2) + (blocksize_x>>2); i++)    
  360.     {
  361.       if(list == 0)
  362.       {
  363.         smpUMHEX_l0_cost[blocktype][j][i] = min_mcost;
  364.       }
  365.       else
  366.       {
  367.         smpUMHEX_l1_cost[blocktype][j][i] = min_mcost;
  368.       }
  369.     }
  370.   }
  371.   return min_mcost;
  372. }
  373. /*!
  374.  ***********************************************************************
  375.  * brief
  376.  *    Sub pixel block motion search enhanced
  377.  ***********************************************************************
  378.  */
  379. int                                               //  ==> minimum motion cost after search
  380. smpUMHEXFullSubPelBlockMotionSearch (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  381.                                      short     ref,           // <--  reference frame (0... or -1 (backward))
  382.                                      int       list,          // <--  reference picture list
  383.                                      int       list_offset,
  384.                                      int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  385.                                      int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  386.                                      int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  387.                                      short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  388.                                      short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  389.                                      int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  390.                                      int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  391.                                      int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  392.                                      int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  393.                                      int       apply_weights
  394.                                      )
  395. {
  396.   int   pos, best_pos, mcost;
  397.   int   cand_mv_x, cand_mv_y;
  398.   int   check_position0 = (!params->rdopt && img->type!=B_SLICE && ref==0 && blocktype==1 && mv[0]==0 && mv[1]==0);
  399.   int   blocksize_x     = params->blc_size[blocktype][0];
  400.   int   blocksize_y     = params->blc_size[blocktype][1];
  401.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
  402.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
  403.   int   max_pos2        = ( !start_me_refinement_hp ? imax(1,search_pos2) : search_pos2);
  404.   int   cmv_x, cmv_y;
  405.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  406.   int max_pos_x4 = ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  407.   int max_pos_y4 = ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  408.   dist_method = Q_PEL + 3 * apply_weights;
  409.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  410.   img_width  = ref_picture->size_x;
  411.   img_height = ref_picture->size_y;
  412.   width_pad  = ref_picture->size_x_pad;
  413.   height_pad = ref_picture->size_y_pad;
  414.   if (apply_weights)
  415.   {
  416.     weight_luma = wp_weight[list + list_offset][ref][0];
  417.     offset_luma = wp_offset[list + list_offset][ref][0];
  418.   }
  419.   if (ChromaMEEnable)
  420.   {
  421.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  422.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  423.     width_pad_cr  = ref_picture->size_x_cr_pad;
  424.     height_pad_cr = ref_picture->size_y_cr_pad;
  425.     if (apply_weights)
  426.     {
  427.       weight_cr[0] = wp_weight[list + list_offset][ref][1];
  428.       weight_cr[1] = wp_weight[list + list_offset][ref][2];
  429.       offset_cr[0] = wp_offset[list + list_offset][ref][1];
  430.       offset_cr[1] = wp_offset[list + list_offset][ref][2];
  431.     }
  432.   }
  433.   /*********************************
  434.    *****                       *****
  435.    *****  HALF-PEL REFINEMENT  *****
  436.    *****                       *****
  437.    *********************************/
  438.   //===== set function for getting pixel values =====
  439.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  440.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1)   )
  441.   {
  442.     ref_access_method = FAST_ACCESS;
  443.   }
  444.   else
  445.   {
  446.     ref_access_method = UMV_ACCESS;
  447.   }
  448.   //===== loop over search positions =====
  449.   for (best_pos = 0, pos = start_me_refinement_hp; pos < max_pos2; pos++)
  450.   {
  451.     cand_mv_x = mv[0] + (spiral_hpel_search_x[pos]);    // quarter-pel units
  452.     cand_mv_y = mv[1] + (spiral_hpel_search_y[pos]);    // quarter-pel units
  453.     //----- set motion vector cost -----
  454.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  455.     if (mcost >= min_mcost) continue;
  456.     cmv_x = cand_mv_x + pic4_pix_x;
  457.     cmv_y = cand_mv_y + pic4_pix_y;
  458.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
  459.     if (pos==0 && check_position0)
  460.     {
  461.       mcost -= WEIGHTED_COST (lambda_factor, 16);
  462.     }
  463.     if (mcost < min_mcost)
  464.     {
  465.       min_mcost = mcost;
  466.       best_pos  = pos;
  467.     }
  468.     if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
  469.     {
  470.       break;
  471.     }
  472.   }
  473.   if (best_pos)
  474.   {
  475.     mv[0] += (spiral_hpel_search_x [best_pos]);
  476.     mv[1] += (spiral_hpel_search_y [best_pos]);
  477.   }
  478.   if ((mv[0] == 0) && (mv[1] == 0) && (pred_mv[0] == 0 && pred_mv[1] == 0) &&
  479.     (min_mcost < (SubPelThreshold1>>block_type_shift_factor[blocktype])) )
  480.   {
  481.     best_pos = 0;
  482.     return min_mcost;
  483.   }
  484.   if ( !start_me_refinement_qp )
  485.     min_mcost = INT_MAX;
  486.   /************************************
  487.    *****                          *****
  488.    *****  QUARTER-PEL REFINEMENT  *****
  489.    *****                          *****
  490.    ************************************/
  491.   //===== set function for getting pixel values =====
  492.   if ((pic4_pix_x + mv[0] > 0) && (pic4_pix_x + mv[0] < max_pos_x4) &&
  493.     (pic4_pix_y + mv[1] > 0) && (pic4_pix_y + mv[1] < max_pos_y4)   )
  494.   {
  495.     ref_access_method = FAST_ACCESS;
  496.   }
  497.   else
  498.   {
  499.     ref_access_method = UMV_ACCESS;
  500.   }
  501.   //===== loop over search positions =====
  502.   for (best_pos = 0, pos = start_me_refinement_qp; pos < search_pos4; pos++)
  503.   {
  504.     cand_mv_x = mv[0] + spiral_search_x[pos];    // quarter-pel units
  505.     cand_mv_y = mv[1] + spiral_search_y[pos];    // quarter-pel units
  506.     //----- set motion vector cost -----
  507.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  508.     if (mcost >= min_mcost) continue;
  509.     cmv_x = cand_mv_x + pic4_pix_x;
  510.     cmv_y = cand_mv_y + pic4_pix_y;
  511.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
  512.     if (mcost < min_mcost)
  513.     {
  514.       min_mcost = mcost;
  515.       best_pos  = pos;
  516.     }
  517.     if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
  518.     {
  519.       break;
  520.     }
  521.   }
  522.   if (best_pos)
  523.   {
  524.     mv[0] += spiral_search_x [best_pos];
  525.     mv[1] += spiral_search_y [best_pos];
  526.   }
  527.   //===== return minimum motion cost =====
  528.   return min_mcost;
  529. }
  530. /*!
  531.  ************************************************************************
  532.  * brief
  533.  *    Fast sub pixel block motion estimation
  534.  ************************************************************************
  535.  */
  536. int                                     //  ==> minimum motion cost after search
  537. smpUMHEXSubPelBlockMotionSearch  (
  538.                                   imgpel* orig_pic,        // <--  original pixel values for the AxB block
  539.                                   short     ref,           // <--  reference frame (0... or -1 (backward))
  540.                                   int       list,          // <--  reference picture list
  541.                                   int       list_offset,   // <--  MBAFF list offset
  542.                                   int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  543.                                   int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  544.                                   int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  545.                                   short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  546.                                   short     mv[2],         // <--> in: search center (x|y) / out: MV (x|y) - in pel units
  547.                                   int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  548.                                   int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  549.                                   int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  550.                                   int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  551.                                   int       apply_weights
  552.                                   )
  553. {
  554.   int   mcost;
  555.   int   cand_mv_x, cand_mv_y;
  556.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  557.   short mv_shift        = 0;
  558.   short blocksize_x     = (short) params->blc_size[blocktype][0];
  559.   short blocksize_y     = (short) params->blc_size[blocktype][1];
  560.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<<2);
  561.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<<2);
  562.   short max_pos_x4      = (short) ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  563.   short max_pos_y4      = (short) ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  564.   int   iXMinNow, iYMinNow;
  565.   short dynamic_search_range, i, m;
  566.   int   currmv_x = 0, currmv_y = 0;
  567.   int   pred_frac_mv_x,pred_frac_mv_y,abort_search;
  568.   int   pred_frac_up_mv_x, pred_frac_up_mv_y;
  569.   dist_method = Q_PEL + 3 * apply_weights;
  570.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  571.   img_width  = ref_pic_ptr->size_x;
  572.   img_height = ref_pic_ptr->size_y;
  573.   width_pad  = ref_pic_ptr->size_x_pad;
  574.   height_pad = ref_pic_ptr->size_y_pad;
  575.   if (apply_weights)
  576.   {
  577.     weight_luma = wp_weight[list + list_offset][ref][0];
  578.     offset_luma = wp_offset[list + list_offset][ref][0];
  579.   }
  580.   if (ChromaMEEnable)
  581.   {
  582.     ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
  583.     ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
  584.     width_pad_cr  = ref_pic_ptr->size_x_cr_pad;
  585.     height_pad_cr = ref_pic_ptr->size_y_cr_pad;
  586.     if (apply_weights)
  587.     {
  588.       weight_cr[0] = wp_weight[list + list_offset][ref][1];
  589.       weight_cr[1] = wp_weight[list + list_offset][ref][2];
  590.       offset_cr[0] = wp_offset[list + list_offset][ref][1];
  591.       offset_cr[1] = wp_offset[list + list_offset][ref][2];
  592.     }
  593.   }
  594.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  595.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1))
  596.   {
  597.     ref_access_method = FAST_ACCESS;
  598.   }
  599.   else
  600.   {
  601.     ref_access_method = UMV_ACCESS;
  602.   }
  603.   dynamic_search_range = 3;
  604.   pred_frac_mv_x = (pred_mv[0] - mv[0]) % 4;
  605.   pred_frac_mv_y = (pred_mv[1] - mv[1]) % 4;
  606.   pred_frac_up_mv_x = (smpUMHEX_pred_MV_uplayer_X - mv[0]) % 4;
  607.   pred_frac_up_mv_y = (smpUMHEX_pred_MV_uplayer_Y - mv[1]) % 4;
  608.   memset(smpUMHEX_SearchState[0], 0,
  609.     (2*dynamic_search_range+1)*(2*dynamic_search_range+1));
  610.   smpUMHEX_SearchState[dynamic_search_range][dynamic_search_range] = 1;
  611.   if( !start_me_refinement_hp )
  612.   {
  613.     cand_mv_x = mv[0];
  614.     cand_mv_y = mv[1];
  615.     mcost   = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  616.     mcost   += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  617.       min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  618.     if (mcost < min_mcost)
  619.     {
  620.       min_mcost = mcost;
  621.       currmv_x  = cand_mv_x;
  622.       currmv_y  = cand_mv_y;
  623.     }
  624.   }
  625.   else
  626.   {
  627.     currmv_x = mv[0];
  628.     currmv_y = mv[1];
  629.   }
  630.   // If the min_mcost is small enough and other statistics are positive,
  631.   // better to stop the search now
  632.   if ( ((mv[0]) == 0) && ((mv[1]) == 0) &&
  633.     (pred_frac_mv_x == 0 && pred_frac_up_mv_x == 0) &&
  634.     (pred_frac_mv_y == 0 && pred_frac_up_mv_y == 0) &&
  635.     (min_mcost < (SubPelThreshold1>>block_type_shift_factor[blocktype])) )
  636.   {
  637.     mv[0] = (short) currmv_x;
  638.     mv[1] = (short) currmv_y;
  639.     return min_mcost;
  640.   }
  641.   if(pred_frac_mv_x || pred_frac_mv_y)
  642.   {
  643.     cand_mv_x = mv[0] + pred_frac_mv_x;
  644.     cand_mv_y = mv[1] + pred_frac_mv_y;
  645.     mcost   = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  646.     mcost   += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  647.       min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  648.     smpUMHEX_SearchState[cand_mv_y -mv[1] + dynamic_search_range][cand_mv_x - mv[0] + dynamic_search_range] = 1;
  649.     if (mcost < min_mcost)
  650.     {
  651.       min_mcost = mcost;
  652.       currmv_x  = cand_mv_x;
  653.       currmv_y  = cand_mv_y;
  654.     }
  655.   }
  656.   // Multiple small diamond search
  657.   for(i = 0; i < dynamic_search_range; i++)
  658.   {
  659.     abort_search = 1;
  660.     iXMinNow = currmv_x;
  661.     iYMinNow = currmv_y;
  662.     for (m = 0; m < 4; m++)
  663.     {
  664.       cand_mv_x = iXMinNow + Diamond_X[m];
  665.       cand_mv_y = iYMinNow + Diamond_Y[m];
  666.       if(iabs(cand_mv_x - mv[0]) <= dynamic_search_range && iabs(cand_mv_y - mv[1]) <= dynamic_search_range)
  667.       {
  668.         if(!smpUMHEX_SearchState[cand_mv_y - mv[1] + dynamic_search_range][cand_mv_x - mv[0] + dynamic_search_range])
  669.         {
  670.           mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  671.           mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  672.             min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  673.           smpUMHEX_SearchState[cand_mv_y - mv[1] + dynamic_search_range][cand_mv_x - mv[0] + dynamic_search_range] = 1;
  674.           if (mcost < min_mcost)
  675.           {
  676.             min_mcost    = mcost;
  677.             currmv_x     = cand_mv_x;
  678.             currmv_y     = cand_mv_y;
  679.             abort_search = 0;
  680.           }
  681.           if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
  682.           {
  683.             mv[0] = (short) currmv_x;
  684.             mv[1] = (short) currmv_y;
  685.             return min_mcost;
  686.           }
  687.         }
  688.       }
  689.     }
  690.     // If the minimum cost point is in the center, break out the loop
  691.     if (abort_search)
  692.     {
  693.       break;
  694.     }
  695.   }
  696.   mv[0] = (short) currmv_x;
  697.   mv[1] = (short) currmv_y;
  698.   return min_mcost;
  699. }
  700. int                                                   //  ==> minimum motion cost after search
  701. smpUMHEXSubPelBlockME (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  702.                     short     ref,           // <--  reference frame (0... or -1 (backward))
  703.                     int       list,
  704.                     int       list_offset,   // <--  MBAFF list offset
  705.                     int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  706.                     int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  707.                     int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  708.                     short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  709.                     short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in sub-pel units
  710.                     int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  711.                     int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  712.                     int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  713.                     int*      lambda_factor,
  714.                     int       apply_weights
  715.                     )
  716. {  
  717.   if(blocktype > 1)
  718.   {
  719.     min_mcost =  smpUMHEXSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y,
  720.       blocktype, pred_mv, mv, 9, 9, min_mcost, lambda_factor[Q_PEL], apply_weights);
  721.   }
  722.   else
  723.   {
  724.     min_mcost =  smpUMHEXFullSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y,
  725.       blocktype, pred_mv, mv, 9, 9, min_mcost, lambda_factor[Q_PEL], apply_weights);
  726.   }
  727.   return min_mcost;
  728. }
  729. /*!
  730.  ************************************************************************
  731.  * brief
  732.  *    smpUMHEXBipredIntegerPelBlockMotionSearch: fast pixel block motion search for bipred mode
  733.  *
  734.  ************************************************************************
  735.  */
  736. int                                                           //  ==> minimum motion cost after search
  737. smpUMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <--  current Macroblock
  738.                                            imgpel* cur_pic,   // <--  original pixel values for the AxB block
  739.                                            short     ref,           // <--  reference frame (0... or -1 (backward))
  740.                                            int       list,          // <--  Current reference list
  741.                                            int       list_offset,   // <--  MBAFF list offset
  742.                                            char   ***refPic,        // <--  reference array
  743.                                            short ****tmp_mv,        // <--  mv array
  744.                                            int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  745.                                            int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  746.                                            int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  747.                                            short     pred_mv1[2],   // <--  motion vector predictor (x|y) in sub-pel units
  748.                                            short     pred_mv2[2],   // <--  motion vector predictor (x|y) in sub-pel units
  749.                                            short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  750.                                            short     s_mv[2],       // <--> in: search center (x|y) 
  751.                                            int       search_range,  // <--  1-d search range in pel units
  752.                                            int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  753.                                            int       iteration_no,  // <--  bi pred iteration number
  754.                                            int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  755.                                            int       apply_weights
  756.                                            )
  757. {
  758.   int   mvshift       = 2;                              // motion vector shift for getting sub-pel units
  759.   int   search_step, iYMinNow, iXMinNow;
  760.   int   i, m;
  761.   int   cand_x, cand_y, mcost;
  762.   int   blocksize_y   = params->blc_size[blocktype][1];  // vertical block size
  763.   int   blocksize_x   = params->blc_size[blocktype][0];  // horizontal block size
  764.   int   pred_x1       = (pic_pix_x << 2) + pred_mv1[0];  // predicted position x (in sub-pel units)
  765.   int   pred_y1       = (pic_pix_y << 2) + pred_mv1[1];  // predicted position y (in sub-pel units)
  766.   int   pred_x2       = (pic_pix_x << 2) + pred_mv2[0];  // predicted position x (in sub-pel units)
  767.   int   pred_y2       = (pic_pix_y << 2) + pred_mv2[1];  // predicted position y (in sub-pel units)
  768.   short center2_x     = pic_pix_x + mv[0];               // center position x (in pel units)
  769.   short center2_y     = pic_pix_y + mv[1];               // center position y (in pel units)
  770.   short center1_x     = pic_pix_x + s_mv[0];             // mvx of second pred (in pel units)
  771.   short center1_y     = pic_pix_y + s_mv[1];             // mvy of second pred (in pel units)
  772.   int   best_x        = center2_x;
  773.   int   best_y        = center2_y;
  774.   short offset1 = (apply_weights ? (list == 0?  wp_offset[list_offset    ][ref][0]:  wp_offset[list_offset + 1][0  ][ref]) : 0);
  775.   short offset2 = (apply_weights ? (list == 0?  wp_offset[list_offset + 1][ref][0]:  wp_offset[list_offset    ][0  ][ref]) : 0);
  776.   ref_pic1_sub.luma = listX[list + list_offset][ref]->p_curr_img_sub;
  777.   ref_pic2_sub.luma = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->p_curr_img_sub;
  778.   img_width  = listX[list + list_offset][ref]->size_x;
  779.   img_height = listX[list + list_offset][ref]->size_y;
  780.   width_pad  = listX[list + list_offset][ref]->size_x_pad;
  781.   height_pad = listX[list + list_offset][ref]->size_y_pad;
  782.   if (apply_weights)
  783.   {
  784.     weight1 = list == 0 ? wbp_weight[list_offset         ][ref][0][0] : wbp_weight[list_offset + LIST_1][0  ][ref][0];
  785.     weight2 = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][0] : wbp_weight[list_offset         ][0  ][ref][0];
  786.     offsetBi=(offset1 + offset2 + 1)>>1;
  787.     computeBiPred = computeBiPredSAD2; //ME only supports SAD computations
  788.   }
  789.   else
  790.   {
  791.     weight1 = 1<<luma_log_weight_denom;
  792.     weight2 = 1<<luma_log_weight_denom;
  793.     offsetBi = 0;
  794.     computeBiPred = computeBiPredSAD1; //ME only supports SAD computations
  795.   }
  796.   if (ChromaMEEnable )
  797.   {
  798.     ref_pic1_sub.crcb[0] = listX[list + list_offset][ref]->imgUV_sub[0];
  799.     ref_pic1_sub.crcb[1] = listX[list + list_offset][ref]->imgUV_sub[1];
  800.     ref_pic2_sub.crcb[0] = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgUV_sub[0];
  801.     ref_pic2_sub.crcb[1] = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgUV_sub[1];
  802.     width_pad_cr  = listX[list + list_offset][ref]->size_x_cr_pad;
  803.     height_pad_cr = listX[list + list_offset][ref]->size_y_cr_pad;
  804.     if (apply_weights)
  805.     {
  806.       weight1_cr[0] = list == 0 ? wbp_weight[list_offset         ][ref][0][1] : wbp_weight[list_offset + LIST_1][0  ][ref][1];
  807.       weight1_cr[1] = list == 0 ? wbp_weight[list_offset         ][ref][0][2] : wbp_weight[list_offset + LIST_1][0  ][ref][2];
  808.       weight2_cr[0] = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][1] : wbp_weight[list_offset         ][0  ][ref][1];
  809.       weight2_cr[1] = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][2] : wbp_weight[list_offset         ][0  ][ref][2];
  810.       offsetBi_cr[0] = (list == 0)
  811.         ? (wp_offset[list_offset         ][ref][1] + wp_offset[list_offset + LIST_1][ref][1] + 1) >> 1
  812.         : (wp_offset[list_offset + LIST_1][0  ][1] + wp_offset[list_offset         ][0  ][1] + 1) >> 1;
  813.       offsetBi_cr[1] = (list == 0)
  814.         ? (wp_offset[list_offset         ][ref][2] + wp_offset[list_offset + LIST_1][ref][2] + 1) >> 1
  815.         : (wp_offset[list_offset + LIST_1][0  ][2] + wp_offset[list_offset         ][0  ][2] + 1) >> 1;
  816.     }
  817.     else
  818.     {
  819.       weight1_cr[0] = 1<<chroma_log_weight_denom;
  820.       weight1_cr[1] = 1<<chroma_log_weight_denom;
  821.       weight2_cr[0] = 1<<chroma_log_weight_denom;
  822.       weight2_cr[1] = 1<<chroma_log_weight_denom;
  823.       offsetBi_cr[0] = 0;
  824.       offsetBi_cr[1] = 0;
  825.     }
  826.   }
  827.   // Set function for getting reference picture lines
  828.   if ((center2_x > search_range) && (center2_x < img_width -1-search_range-blocksize_x) &&
  829.       (center2_y > search_range) && (center2_y < img_height-1-search_range-blocksize_y))
  830.   {
  831.     bipred2_access_method = FAST_ACCESS;
  832.   }
  833.   else
  834.   {
  835.     bipred2_access_method = UMV_ACCESS;
  836.   }
  837.   // Set function for getting reference picture lines
  838.   if ((center1_y > search_range) && (center1_y < img_height-1-search_range-blocksize_y))
  839.   {
  840.     bipred1_access_method = FAST_ACCESS;
  841.   }
  842.   else
  843.   {
  844.     bipred1_access_method = UMV_ACCESS;
  845.   }
  846.   // Check the center median predictor
  847.   cand_x = center2_x ;
  848.   cand_y = center2_y ;
  849.   mcost  = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
  850.   mcost += MV_COST (lambda_factor, mvshift, cand_x,    cand_y,    pred_x2, pred_y2);
  851.   mcost += computeBiPred(cur_pic,
  852.                         blocksize_y, blocksize_x, INT_MAX,
  853.                         (center1_x << 2) + IMG_PAD_SIZE_TIMES4,
  854.                         (center1_y << 2) + IMG_PAD_SIZE_TIMES4,
  855.                         (cand_x << 2) + IMG_PAD_SIZE_TIMES4,
  856.                         (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
  857.   if (mcost < min_mcost)
  858.   {
  859.     min_mcost = mcost;
  860.     best_x = cand_x;
  861.     best_y = cand_y;
  862.   }
  863.   iXMinNow = best_x;
  864.   iYMinNow = best_y;
  865.   if (0 != pred_mv1[0] || 0 != pred_mv1[1] || 0 != pred_mv2[0] || 0 != pred_mv2[1])
  866.   {
  867.     cand_x = pic_pix_x;
  868.     cand_y = pic_pix_y;
  869.     SEARCH_ONE_PIXEL_BIPRED_HELPER;
  870.   }
  871.   // If the min_mcost is small enough, do a local search then terminate
  872.   // This is good for stationary or quasi-stationary areas
  873.   if ((min_mcost<<3) < (ConvergeThreshold>>(block_type_shift_factor[blocktype])))
  874.   {
  875.     for (m = 0; m < 4; m++)
  876.     {
  877.       cand_x = iXMinNow + Diamond_X[m];
  878.       cand_y = iYMinNow + Diamond_Y[m];
  879.       SEARCH_ONE_PIXEL_BIPRED_HELPER;
  880.     }
  881.     mv[0] = best_x - pic_pix_x;
  882.     mv[1] = best_y - pic_pix_y;
  883.     return min_mcost;
  884.   }
  885.   // Small local search
  886.   for (m = 0; m < 4; m++)
  887.   {
  888.     cand_x = iXMinNow + Diamond_X[m];
  889.     cand_y = iYMinNow + Diamond_Y[m];
  890.     SEARCH_ONE_PIXEL_BIPRED_HELPER;
  891.   }
  892.   // First_step: Symmetrical-cross search
  893.   // If distortion is large, use large shapes. Otherwise, compact shapes are faster
  894.   if ((blocktype == 1 &&
  895.     (min_mcost<<2) > (SymmetricalCrossSearchThreshold1>>block_type_shift_factor[blocktype])) ||
  896.     ((min_mcost<<2) > (SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])))
  897.   {
  898.     iXMinNow = best_x;
  899.     iYMinNow = best_y;
  900.     for (i = 1; i <= search_range / 2; i++)
  901.     {
  902.       search_step = (i<<1) - 1;
  903.       cand_x = iXMinNow + search_step;
  904.       cand_y = iYMinNow;
  905.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  906.       cand_x = iXMinNow - search_step;
  907.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  908.       cand_x = iXMinNow;
  909.       cand_y = iYMinNow + search_step;
  910.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  911.       cand_y = iYMinNow - search_step;
  912.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  913.     }
  914.     // Hexagon Search
  915.     iXMinNow = best_x;
  916.     iYMinNow = best_y;
  917.     for (m = 0; m < 6; m++)
  918.     {
  919.       cand_x = iXMinNow + Hexagon_X[m];
  920.       cand_y = iYMinNow + Hexagon_Y[m];
  921.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  922.     }
  923.     // Multi Big Hexagon Search
  924.     iXMinNow = best_x;
  925.     iYMinNow = best_y;
  926.     for(i = 1; i <= search_range / 4; i++)
  927.     {
  928.       for (m = 0; m < 16; m++)
  929.       {
  930.         cand_x = iXMinNow + Big_Hexagon_X[m] * i;
  931.         cand_y = iYMinNow + Big_Hexagon_Y[m] * i;
  932.         SEARCH_ONE_PIXEL_BIPRED_HELPER
  933.       }
  934.     }
  935.   }
  936.   // Search up_layer predictor for non 16x16 blocks
  937.   if (blocktype > 1)
  938.   {
  939.     cand_x = pic_pix_x + (smpUMHEX_pred_MV_uplayer_X / 4);
  940.     cand_y = pic_pix_y + (smpUMHEX_pred_MV_uplayer_Y / 4);
  941.     SEARCH_ONE_PIXEL_BIPRED_HELPER
  942.   }
  943.   if(center2_x != pic_pix_x || center2_y != pic_pix_y)
  944.   {
  945.     cand_x = pic_pix_x;
  946.     cand_y = pic_pix_y;
  947.     SEARCH_ONE_PIXEL_BIPRED_HELPER
  948.     iXMinNow = best_x;
  949.     iYMinNow = best_y;
  950.     // Local diamond search
  951.     for (m = 0; m < 4; m++)
  952.     {
  953.       cand_x = iXMinNow + Diamond_X[m];
  954.       cand_y = iYMinNow + Diamond_Y[m];
  955.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  956.     }
  957.   }
  958.   // If the minimum cost is small enough, do a local search
  959.   // and finish the search here
  960.   if ((min_mcost<<2) < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
  961.   {
  962.     iXMinNow = best_x;
  963.     iYMinNow = best_y;
  964.     for (m = 0; m < 4; m++)
  965.     {
  966.       cand_x = iXMinNow + Diamond_X[m];
  967.       cand_y = iYMinNow + Diamond_Y[m];
  968.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  969.     }
  970.     mv[0] = (short) (best_x - pic_pix_x);
  971.     mv[1] = (short) (best_y - pic_pix_y);
  972.     return min_mcost;
  973.   }
  974.   // Second_step:  Extended Hexagon-based Search
  975.   for (i = 0; i < search_range; i++)
  976.   {
  977.     iXMinNow = best_x;
  978.     iYMinNow = best_y;
  979.     for (m = 0; m < 6; m++)
  980.     {
  981.       cand_x = iXMinNow + Hexagon_X[m];
  982.       cand_y = iYMinNow + Hexagon_Y[m];
  983.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  984.     }
  985.     // The minimum cost point happens in the center
  986.     if (best_x == iXMinNow && best_y == iYMinNow)
  987.     {
  988.       break;
  989.     }
  990.   }
  991.   // Third_step: Small diamond search
  992.   for (i = 0; i < search_range; i++)
  993.   {
  994.     iXMinNow = best_x;
  995.     iYMinNow = best_y;
  996.     for (m = 0; m < 4; m++)
  997.     {
  998.       cand_x = iXMinNow + Diamond_X[m];
  999.       cand_y = iYMinNow + Diamond_Y[m];
  1000.       SEARCH_ONE_PIXEL_BIPRED_HELPER
  1001.     }
  1002.     // The minimum cost point happens in the center
  1003.     if (best_x == iXMinNow && best_y == iYMinNow)
  1004.     {
  1005.       break;
  1006.     }
  1007.   }
  1008.   mv[0] = (short) (best_x - pic_pix_x);
  1009.   mv[1] = (short) (best_y - pic_pix_y);
  1010.   return min_mcost;
  1011. }
  1012. /*!
  1013.  ************************************************************************
  1014.  * brief
  1015.  *    Set neighbouring block mode (intra/inter)
  1016.  *    used for fast motion estimation
  1017.  ************************************************************************
  1018.  */
  1019. void smpUMHEX_decide_intrabk_SAD()
  1020. {
  1021.   if (img->type != I_SLICE)
  1022.   {
  1023.     if (img->pix_x == 0 && img->pix_y == 0)
  1024.     {
  1025.       smpUMHEX_flag_intra_SAD = 0;
  1026.     }
  1027.     else if (img->pix_x == 0)
  1028.     {
  1029.       smpUMHEX_flag_intra_SAD = smpUMHEX_flag_intra[(img->pix_x)>>4];
  1030.     }
  1031.     else if (img->pix_y == 0)
  1032.     {
  1033.       smpUMHEX_flag_intra_SAD = smpUMHEX_flag_intra[((img->pix_x)>>4)-1];
  1034.     }
  1035.     else
  1036.     {
  1037.       smpUMHEX_flag_intra_SAD = ((smpUMHEX_flag_intra[(img->pix_x)>>4])||
  1038.         (smpUMHEX_flag_intra[((img->pix_x)>>4)-1])||
  1039.         (smpUMHEX_flag_intra[((img->pix_x)>>4)+1])) ;
  1040.     }
  1041.   }
  1042.   return;
  1043. }
  1044. /*!
  1045.  ************************************************************************
  1046.  * brief
  1047.  *    Set cost to zero if neighbouring block is intra
  1048.  *    used for fast motion estimation
  1049.  ************************************************************************
  1050.  */
  1051. void smpUMHEX_skip_intrabk_SAD(int best_mode, int ref_max)
  1052. {
  1053.   short i, j, k;
  1054.   if (img->number > 0)
  1055.   {
  1056.     smpUMHEX_flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1 : 0;
  1057.   }
  1058.   if (img->type != I_SLICE  && (best_mode == 9 || best_mode == 10))
  1059.   {
  1060.     for (i=0; i < 4; i++)
  1061.     {
  1062.       for (j=0; j < 4; j++)
  1063.       {
  1064.         for (k=0; k < 9;k++)
  1065.         {
  1066.           smpUMHEX_l0_cost[k][j][i] = 0;
  1067.           smpUMHEX_l1_cost[k][j][i] = 0;
  1068.         }
  1069.       }
  1070.     }
  1071.   }
  1072.   return;
  1073. }
  1074. /*!
  1075.  ************************************************************************
  1076.  * brief
  1077.  *    Set up prediction MV and prediction up layer cost
  1078.  *    used for fast motion estimation
  1079.  ************************************************************************
  1080.  */
  1081. void smpUMHEX_setup(short ref,
  1082.                           int list,
  1083.                           int block_y,
  1084.                           int block_x,
  1085.                           int blocktype,
  1086.                           short ******all_mv)
  1087. {
  1088.   if (blocktype > 6)
  1089.   {
  1090.     smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][5][block_y][block_x][0];
  1091.     smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][5][block_y][block_x][1];
  1092.   }
  1093.   else if (blocktype > 4)
  1094.   {
  1095.     smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][4][block_y][block_x][0];
  1096.     smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][4][block_y][block_x][1];
  1097.   }
  1098.   else if (blocktype == 4)
  1099.   {
  1100.     smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][2][block_y][block_x][0];
  1101.     smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][2][block_y][block_x][1];
  1102.   }
  1103.   else if (blocktype > 1)
  1104.   {
  1105.     smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][1][block_y][block_x][0];
  1106.     smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][1][block_y][block_x][1];
  1107.   }
  1108.   if (blocktype > 1)
  1109.   {
  1110.     if (blocktype > 6)
  1111.     {
  1112.       smpUMHEX_pred_SAD_uplayer = (list==1) ?
  1113.         (smpUMHEX_l1_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
  1114.         : (smpUMHEX_l0_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
  1115.       smpUMHEX_pred_SAD_uplayer /= 2;
  1116.     }
  1117.     else if (blocktype > 4)
  1118.     {
  1119.       smpUMHEX_pred_SAD_uplayer = (list==1) ?
  1120.         (smpUMHEX_l1_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
  1121.         : (smpUMHEX_l0_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
  1122.       smpUMHEX_pred_SAD_uplayer /= 2;
  1123.     }
  1124.     else if (blocktype == 4)
  1125.     {
  1126.       smpUMHEX_pred_SAD_uplayer = (list==1) ?
  1127.         (smpUMHEX_l1_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
  1128.         : (smpUMHEX_l0_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
  1129.       smpUMHEX_pred_SAD_uplayer /= 2;
  1130.     }
  1131.     else
  1132.     {
  1133.       smpUMHEX_pred_SAD_uplayer = (list==1) ?
  1134.         (smpUMHEX_l1_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
  1135.         : (smpUMHEX_l0_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
  1136.       smpUMHEX_pred_SAD_uplayer /= 2;
  1137.     }
  1138.     smpUMHEX_pred_SAD_uplayer = smpUMHEX_flag_intra_SAD ? 0 : smpUMHEX_pred_SAD_uplayer;
  1139.   }
  1140. }