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

Audio

开发平台:

Visual C++

  1. /*!
  2.  ************************************************************************
  3.  *
  4.  * file me_umhex.c
  5.  *
  6.  * brief
  7.  *   Fast integer pel motion estimation and fractional pel motion estimation
  8.  *   algorithms are described in this file.
  9.  *   1. UMHEX_get_mem() and UMHEX_free_mem() are functions for allocation and release
  10.  *      of memories about motion estimation
  11.  *   2. UMHEX_BlockMotionSearch() is the function for fast integer pel motion
  12.  *      estimation and fractional pel motion estimation
  13.  *   3. UMHEX_DefineThreshold() defined thresholds for early termination
  14.  * author
  15.  *    Main contributors: (see contributors.h for copyright, address and affiliation details)
  16.  *    - Zhibo Chen         <chenzhibo@tsinghua.org.cn>
  17.  *    - JianFeng Xu        <fenax@video.mdc.tsinghua.edu.cn>
  18.  *    - Wenfang Fu         <fwf@video.mdc.tsinghua.edu.cn>
  19.  *    - Xiaozhong Xu       <xxz@video.mdc.tsinghua.edu.cn>
  20.  * date
  21.  *    2006.1
  22.  ************************************************************************
  23.  */
  24. #include <limits.h>
  25. #include "global.h"
  26. #include "memalloc.h"
  27. #include "me_umhex.h"
  28. #include "refbuf.h"
  29. #include "mb_access.h"
  30. #include "image.h"
  31. #include "enc_statistics.h"
  32. #include "me_distortion.h"
  33. #include "mv-search.h"
  34. #define Q_BITS          15
  35. #define MIN_IMG_WIDTH   176
  36. extern  int*   byte_abs;
  37. extern  short*   spiral_search_x;
  38. extern  short*   spiral_search_y;
  39. static const int Diamond_x[4] = {-1, 0, 1, 0};
  40. static const int Diamond_y[4] = {0, 1, 0, -1};
  41. static const int Hexagon_x[6] = {2, 1, -1, -2, -1, 1};
  42. static const int Hexagon_y[6] = {0, -2, -2, 0,  2, 2};
  43. static const int Big_Hexagon_x[16] = {0,-2, -4,-4,-4, -4, -4, -2,  0,  2,  4,  4, 4, 4, 4, 2};
  44. static const int Big_Hexagon_y[16] = {4, 3, 2,  1, 0, -1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3};
  45. // for bipred mode
  46. static int pred_MV_ref_flag;
  47. static int dist_method;
  48. static StorablePicture *ref_pic_ptr;
  49. static const int   Multi_Ref_Thd[8]    = {0,  300,  120,  120,  60,  30,   30,  15};
  50. static const int   Big_Hexagon_Thd[8]  = {0, 3000, 1500, 1500, 800, 400,  400, 200};
  51. static const int   Median_Pred_Thd[8]  = {0,  750,  350,  350, 170,  80,   80,  40};
  52. static const int   Threshold_DSR[8]    = {0, 2200, 1000, 1000, 500, 250,  250, 120};
  53. static int BlockType_LUT[4][4];
  54. static int Median_Pred_Thd_MB[8];
  55. static int Big_Hexagon_Thd_MB[8];
  56. static int Multi_Ref_Thd_MB[8];
  57. extern const int quant_coef[6][4][4];
  58. void UMHEX_DefineThreshold()
  59. {
  60.   AlphaFourth_1[1] = 0.01f;
  61.   AlphaFourth_1[2] = 0.01f;
  62.   AlphaFourth_1[3] = 0.01f;
  63.   AlphaFourth_1[4] = 0.02f;
  64.   AlphaFourth_1[5] = 0.03f;
  65.   AlphaFourth_1[6] = 0.03f;
  66.   AlphaFourth_1[7] = 0.04f;
  67.   AlphaFourth_2[1] = 0.06f;
  68.   AlphaFourth_2[2] = 0.07f;
  69.   AlphaFourth_2[3] = 0.07f;
  70.   AlphaFourth_2[4] = 0.08f;
  71.   AlphaFourth_2[5] = 0.12f;
  72.   AlphaFourth_2[6] = 0.11f;
  73.   AlphaFourth_2[7] = 0.15f;
  74.   UMHEX_DefineThresholdMB();
  75.   BlockType_LUT[0][0] = 7; // 4x4
  76.   BlockType_LUT[0][1] = 6; // 4x8
  77.   BlockType_LUT[1][0] = 5; // 8x4
  78.   BlockType_LUT[1][1] = 4; // 8x8
  79.   BlockType_LUT[1][3] = 3; // 8x16
  80.   BlockType_LUT[3][1] = 2; // 16x8
  81.   BlockType_LUT[3][3] = 1; // 16x16
  82.   return;
  83. }
  84. /*!
  85.  ************************************************************************
  86.  * brief
  87.  *    Set MB thresholds for fast motion estimation
  88.  *    Those thresholds may be adjusted to trade off rate-distortion
  89.  *    performance and UMHEX speed
  90.  ************************************************************************
  91.  */
  92. void UMHEX_DefineThresholdMB()
  93. {
  94.   int gb_qp_per    = (params->qpN)/6;
  95.   int gb_qp_rem    = (params->qpN)%6;
  96.   int gb_q_bits    = Q_BITS+gb_qp_per;
  97.   int gb_qp_const,Thresh4x4;
  98.   float Quantize_step;
  99.   int i;
  100. // scale factor: defined for different image sizes
  101.   float scale_factor = (float)((1-params->UMHexScale*0.1)+params->UMHexScale*0.1*(img->width/MIN_IMG_WIDTH));
  102. // QP factor: defined for different quantization steps
  103.   float QP_factor = (float)((1.0-0.90*(params->qpN/51.0f)));
  104.   gb_qp_const=(1<<gb_q_bits)/6;
  105.   Thresh4x4 =   ((1<<gb_q_bits) - gb_qp_const)/quant_coef[gb_qp_rem][0][0];
  106.   Quantize_step = Thresh4x4/(4*5.61f)*2.0f*scale_factor;
  107.   Bsize[7]=(16*16)*Quantize_step;
  108.   Bsize[6]=Bsize[7]*4;
  109.   Bsize[5]=Bsize[7]*4;
  110.   Bsize[4]=Bsize[5]*4;
  111.   Bsize[3]=Bsize[4]*4;
  112.   Bsize[2]=Bsize[4]*4;
  113.   Bsize[1]=Bsize[2]*4;
  114.   for(i=1;i<8;i++)
  115.   {
  116.     //ET_Thd1: early termination after median prediction
  117.     Median_Pred_Thd_MB[i]  = (int) (Median_Pred_Thd[i]* scale_factor*QP_factor);
  118.     //ET_thd2: early termination after every circle of 16 points Big-Hex Search
  119.     Big_Hexagon_Thd_MB[i]  = (int) (Big_Hexagon_Thd[i]* scale_factor*QP_factor);
  120.     //threshold for multi ref case
  121.     Multi_Ref_Thd_MB[i]    = (int) (Multi_Ref_Thd[i]  * scale_factor*QP_factor);
  122.     //threshold for usage of DSR technique. DSR ref to JVT-R088
  123.     Threshold_DSR_MB[i]    = (int) (Threshold_DSR[i]  * scale_factor*QP_factor);
  124.   }
  125. }
  126. /*!
  127.  ************************************************************************
  128.  * brief
  129.  *    Allocation of space for fast motion estimation
  130.  ************************************************************************
  131.  */
  132. int UMHEX_get_mem()
  133. {
  134.   int memory_size = 0;
  135.   if (NULL==(flag_intra = calloc ((img->width>>4)+1,sizeof(byte)))) no_mem_exit("UMHEX_get_mem: flag_intra"); //fwf 20050330
  136.   memory_size += get_mem2D(&McostState, 2*params->search_range+1, 2*params->search_range+1);
  137.   memory_size += get_mem4Dint(&(fastme_ref_cost), img->max_num_references, 9, 4, 4);
  138.   memory_size += get_mem3Dint(&(fastme_l0_cost), 9, img->height/4, img->width/4);
  139.   memory_size += get_mem3Dint(&(fastme_l1_cost), 9, img->height/4, img->width/4);
  140.   memory_size += get_mem2D(&SearchState,7,7);
  141.   memory_size += get_mem2Dint(&(fastme_best_cost), 7, img->width/4);
  142.   if(params->BiPredMotionEstimation == 1)//memory allocation for bipred mode
  143.   {
  144.     memory_size += get_mem3Dint(&(fastme_l0_cost_bipred), 9, img->height/4, img->width/4);//for bipred
  145.     memory_size += get_mem3Dint(&(fastme_l1_cost_bipred), 9, img->height/4, img->width/4);//for bipred
  146.   }
  147.   return memory_size;
  148. }
  149. /*!
  150.  ************************************************************************
  151.  * brief
  152.  *    Free space for fast motion estimation
  153.  ************************************************************************
  154.  */
  155. void UMHEX_free_mem()
  156. {
  157.   free_mem2D(McostState);
  158.   free_mem4Dint(fastme_ref_cost);
  159.   free_mem3Dint(fastme_l0_cost );
  160.   free_mem3Dint(fastme_l1_cost);
  161.   free_mem2D(SearchState);
  162.   free_mem2Dint(fastme_best_cost);
  163.   free (flag_intra);
  164.   if(params->BiPredMotionEstimation == 1)
  165.   {
  166.     free_mem3Dint(fastme_l0_cost_bipred);//for bipred
  167.     free_mem3Dint(fastme_l1_cost_bipred);//for bipred
  168.   }
  169. }
  170. /*!
  171.  ************************************************************************
  172.  * brief
  173.  *    UMHEXIntegerPelBlockMotionSearch: fast pixel block motion search
  174.  *    this algorithm is called UMHexagonS(see JVT-D016),which includes
  175.  *    four steps with different kinds of search patterns
  176.  * par Input:
  177.  * imgpel*   orig_pic,     // <--  original picture
  178.  * int       ref,          // <--  reference frame (0... or -1 (backward))
  179.  * int       pic_pix_x,    // <--  absolute x-coordinate of regarded AxB block
  180.  * int       pic_pix_y,    // <--  absolute y-coordinate of regarded AxB block
  181.  * int       blocktype,    // <--  block type (1-16x16 ... 7-4x4)
  182.  * int       pred_mv[2],   // <--  motion vector predictor (x|y) in sub-pel units
  183.  * int       mv[2],        //  --> motion vector (x|y) - in pel units
  184.  * int       search_range, // <--  1-d search range in pel units
  185.  * int       min_mcost,    // <--  minimum motion cost (cost for center or huge value)
  186.  * int       lambda_factor // <--  lagrangian parameter for determining motion cost
  187.  * par
  188.  * Two macro definitions defined in this program:
  189.  * 1. EARLY_TERMINATION: early termination algrithm, refer to JVT-D016.doc
  190.  * 2. SEARCH_ONE_PIXEL: search one pixel in search range
  191.  * author
  192.  *   Main contributors: (see contributors.h for copyright, address and affiliation details)
  193.  *   - Zhibo Chen         <chenzhibo@tsinghua.org.cn>
  194.  *   - JianFeng Xu        <fenax@video.mdc.tsinghua.edu.cn>
  195.  *   - Xiaozhong Xu       <xxz@video.mdc.tsinghua.edu.cn>
  196.  * date   :
  197.  *   2006.1
  198.  ************************************************************************
  199.  */
  200. int                                     //  ==> minimum motion cost after search
  201. UMHEXIntegerPelBlockMotionSearch  (Macroblock *currMB,     // <--  current Macroblock
  202.                                   imgpel   *orig_pic,      // < <--  not used
  203.                                   short     ref,           // < <--  reference frame (0... or -1 (backward))
  204.                                   int       list,          // < <--  reference picture list
  205.                                   int       list_offset,   // < <--  MBAFF list offset
  206.                                   char   ***refPic,        // <--  reference array
  207.                                   short ****tmp_mv,        // <--  mv array
  208.                                   int       pic_pix_x,     // < <--  absolute x-coordinate of regarded AxB block
  209.                                   int       pic_pix_y,     // < <--  absolute y-coordinate of regarded AxB block
  210.                                   int       blocktype,     // < <--  block type (1-16x16 ... 7-4x4)
  211.                                   short     pred_mv[2],    // < <--  motion vector predictor (x|y) in sub-pel units
  212.                                   short     mv[2],         // < --> motion vector (x|y) - in pel units
  213.                                   int       search_range,  // < <--  1-d search range in pel units
  214.                                   int       min_mcost,     // < <--  minimum motion cost (cost for center or huge value)
  215.                                   int       lambda_factor, // < <--  lagrangian parameter for determining motion cost
  216.                                   int       apply_weights
  217.                                   )
  218. {
  219.   int   mvshift       = 2;                                        //!< motion vector shift for getting sub-pel units
  220.   int   blocksize_y   = params->blc_size[blocktype][1];            //!< vertical block size
  221.   int   blocksize_x   = params->blc_size[blocktype][0];            //!< horizontal block size
  222.   int   pred_x        = (pic_pix_x << mvshift) + pred_mv[0];       //!< predicted position x (in sub-pel units)
  223.   int   pred_y        = (pic_pix_y << mvshift) + pred_mv[1];       //!< predicted position y (in sub-pel units)
  224.   int   center_x      = pic_pix_x + mv[0];                        //!< center position x (in pel units)
  225.   int   center_y      = pic_pix_y + mv[1];                        //!< center position y (in pel units)
  226.   int   best_x        = 0, best_y = 0;
  227.   int   search_step, iYMinNow, iXMinNow;
  228.   int   pos, cand_x, cand_y,  mcost;
  229.   int   i,m,j;
  230.   float betaFourth_1,betaFourth_2;
  231.   int  temp_Big_Hexagon_x[16];//  temp for Big_Hexagon_x;
  232.   int  temp_Big_Hexagon_y[16];//  temp for Big_Hexagon_y;
  233.   short mb_x = pic_pix_x - img->opix_x;
  234.   short mb_y = pic_pix_y - img->opix_y;
  235.   short pic_pix_x2 = pic_pix_x >> 2;
  236.   short block_x = (mb_x >> 2);
  237.   short block_y = (mb_y >> 2);
  238.   int ET_Thred = Median_Pred_Thd_MB[blocktype];//ET threshold in use
  239.   int   *SAD_prediction = fastme_best_cost[blocktype-1];//multi ref SAD prediction
  240.   //===== Use weighted Reference for ME ====
  241.   dist_method = F_PEL + 3 * apply_weights;
  242.   ref_pic_ptr = listX[list+list_offset][ref];
  243.   // Note that following seem to be universal for all functions and could be moved to a separate, clean public function in me_distortion.c
  244.   
  245.   ref_pic_sub.luma = ref_pic_ptr->p_curr_img_sub;
  246.   img_width  = ref_pic_ptr->size_x;
  247.   img_height = ref_pic_ptr->size_y;
  248.   width_pad  = ref_pic_ptr->size_x_pad;
  249.   height_pad = ref_pic_ptr->size_y_pad;
  250.   if (apply_weights)
  251.   {
  252.     weight_luma = wp_weight[list + list_offset][ref][0];
  253.     offset_luma = wp_offset[list + list_offset][ref][0];
  254.   }
  255.   if (ChromaMEEnable)
  256.   {
  257.     ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
  258.     ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
  259.     width_pad_cr  = ref_pic_ptr->size_x_cr_pad;
  260.     height_pad_cr = ref_pic_ptr->size_y_cr_pad;
  261.     if (apply_weights)
  262.     {
  263.       weight_cr[0] = wp_weight[list + list_offset][ref][1];
  264.       weight_cr[1] = wp_weight[list + list_offset][ref][2];
  265.       offset_cr[0] = wp_offset[list + list_offset][ref][1];
  266.       offset_cr[1] = wp_offset[list + list_offset][ref][2];
  267.     }
  268.   }
  269.   //===== set function for getting reference picture lines =====
  270.   if ((center_x > search_range) && (center_x < img_width - 1 - search_range - blocksize_x) &&
  271.     (center_y > search_range) && (center_y < img_height - 1 - search_range - blocksize_y))
  272.   {
  273.     ref_access_method = FAST_ACCESS;
  274.   }
  275.   else
  276.   {
  277.     ref_access_method = UMV_ACCESS;
  278.   }
  279.   //////allocate memory for search state//////////////////////////
  280.   memset(McostState[0],0,(2*params->search_range+1)*(2*params->search_range+1));
  281.   //check the center median predictor
  282.   cand_x = center_x ;
  283.   cand_y = center_y ;
  284.   mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
  285.   mcost += computeUniPred[dist_method](orig_pic, blocksize_y,blocksize_x, min_mcost - mcost,
  286.     (cand_x << 2) + IMG_PAD_SIZE_TIMES4, (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
  287.   McostState[search_range][search_range] = 1;
  288.   if (mcost < min_mcost)
  289.   {
  290.     min_mcost = mcost;
  291.     best_x    = cand_x;
  292.     best_y    = cand_y;
  293.   }
  294.   iXMinNow = best_x;
  295.   iYMinNow = best_y;
  296.   for (m = 0; m < 4; m++)
  297.   {
  298.     cand_x = iXMinNow + Diamond_x[m];
  299.     cand_y = iYMinNow + Diamond_y[m];
  300.     SEARCH_ONE_PIXEL
  301.   }
  302.   if(center_x != pic_pix_x || center_y != pic_pix_y)
  303.   {
  304.     cand_x = pic_pix_x ;
  305.     cand_y = pic_pix_y ;
  306.     SEARCH_ONE_PIXEL
  307.     iXMinNow = best_x;
  308.     iYMinNow = best_y;
  309.     for (m = 0; m < 4; m++)
  310.     {
  311.       cand_x = iXMinNow + Diamond_x[m];
  312.       cand_y = iYMinNow + Diamond_y[m];
  313.       SEARCH_ONE_PIXEL
  314.     }
  315.   }
  316.   /***********************************init process*************************/
  317.   //for multi ref
  318.   if(ref>0 && img->structure == FRAME  && min_mcost > ET_Thred && SAD_prediction[pic_pix_x2]<Multi_Ref_Thd_MB[blocktype])
  319.     goto terminate_step;
  320.   //ET_Thd1: early termination for low motion case
  321.   if( min_mcost < ET_Thred)
  322.   {
  323.     goto terminate_step;
  324.   }
  325.   else // hybrid search for main search loop
  326.   {
  327.     /****************************(MV and SAD prediction)********************************/
  328.     UMHEX_setup(ref, list, block_y, block_x, blocktype, img->all_mv );
  329.     ET_Thred = Big_Hexagon_Thd_MB[blocktype];  // ET_Thd2: early termination Threshold for strong motion
  330.     // Threshold defined for EARLY_TERMINATION
  331.     if (pred_SAD == 0)
  332.     {
  333.       betaFourth_1=0;
  334.       betaFourth_2=0;
  335.     }
  336.     else
  337.     {
  338.       betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
  339.       betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
  340.     }
  341.     /*********************************************end of init ***********************************************/
  342.   }
  343.   // first_step: initial start point prediction
  344.   if(blocktype>1)
  345.   {
  346.     cand_x = pic_pix_x + (pred_MV_uplayer[0]/4);
  347.     cand_y = pic_pix_y + (pred_MV_uplayer[1]/4);
  348.     SEARCH_ONE_PIXEL
  349.   }
  350.   //prediction using mV of last ref moiton vector
  351.   if(pred_MV_ref_flag == 1)      //Notes: for interlace case, ref==1 should be added
  352.   {
  353.     cand_x = pic_pix_x + (pred_MV_ref[0]/4);
  354.     cand_y = pic_pix_y + (pred_MV_ref[1]/4);
  355.     SEARCH_ONE_PIXEL
  356.   }
  357.   //small local search
  358.   iXMinNow = best_x;
  359.   iYMinNow = best_y;
  360.   for (m = 0; m < 4; m++)
  361.   {
  362.     cand_x = iXMinNow + Diamond_x[m];
  363.     cand_y = iYMinNow + Diamond_y[m];
  364.     SEARCH_ONE_PIXEL
  365.   }
  366.   //early termination algorithm, refer to JVT-G016
  367.   EARLY_TERMINATION
  368.   if(blocktype>6)
  369.     goto fourth_1_step;
  370.   else
  371.     goto sec_step;
  372. sec_step: //Unsymmetrical-cross search
  373.   iXMinNow = best_x;
  374.   iYMinNow = best_y;
  375.   for(i = 1; i < search_range; i+=2)
  376.   {
  377.     search_step = i;
  378.     cand_x = iXMinNow + search_step;
  379.     cand_y = iYMinNow ;
  380.     SEARCH_ONE_PIXEL
  381.     cand_x = iXMinNow - search_step;
  382.     cand_y = iYMinNow ;
  383.     SEARCH_ONE_PIXEL
  384.   }
  385.   for(i = 1; i < (search_range/2);i+=2)
  386.   {
  387.     search_step = i;
  388.     cand_x = iXMinNow ;
  389.     cand_y = iYMinNow + search_step;
  390.     SEARCH_ONE_PIXEL
  391.     cand_x = iXMinNow ;
  392.     cand_y = iYMinNow - search_step;
  393.     SEARCH_ONE_PIXEL
  394.   }
  395.   //early termination alogrithm, refer to JVT-G016
  396.   EARLY_TERMINATION
  397.   iXMinNow = best_x;
  398.   iYMinNow = best_y;
  399.   //third_step:    // Uneven Multi-Hexagon-grid Search
  400.   //sub step 1: 5x5 squre search
  401.   for(pos=1;pos<25;pos++)
  402.   {
  403.     cand_x = iXMinNow + spiral_search_x[pos];
  404.     cand_y = iYMinNow + spiral_search_y[pos];
  405.     SEARCH_ONE_PIXEL
  406.   }
  407.   //early termination alogrithm, refer to JVT-G016
  408.   EARLY_TERMINATION
  409.   //sub step 2:  Multi-Hexagon-grid search
  410.   memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
  411.   memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
  412.   for(i=1;i<=(search_range/4); i++)
  413.   {
  414.     for (m = 0; m < 16; m++)
  415.     {
  416.       cand_x = iXMinNow + temp_Big_Hexagon_x[m];
  417.       cand_y = iYMinNow + temp_Big_Hexagon_y[m];
  418.       temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
  419.       temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];
  420.       SEARCH_ONE_PIXEL
  421.     }
  422.     // ET_Thd2: early termination Threshold for strong motion
  423.     if(min_mcost < ET_Thred)
  424.     {
  425.       goto terminate_step;
  426.     }
  427.   }
  428.   //fourth_step:  //Extended Hexagon-based Search
  429.   // the fourth step with a small search pattern
  430. fourth_1_step:  //sub step 1: small Hexagon search
  431.   for(i = 0; i < search_range; i++)
  432.   {
  433.     iXMinNow = best_x;
  434.     iYMinNow = best_y;
  435.     for (m = 0; m < 6; m++)
  436.     {
  437.       cand_x = iXMinNow + Hexagon_x[m];
  438.       cand_y = iYMinNow + Hexagon_y[m];
  439.       SEARCH_ONE_PIXEL
  440.     }
  441.     if (best_x == iXMinNow && best_y == iYMinNow)
  442.     {
  443.       break;
  444.     }
  445.   }
  446. fourth_2_step: //sub step 2: small Diamond search
  447.   for(i = 0; i < search_range; i++)
  448.   {
  449.     iXMinNow = best_x;
  450.     iYMinNow = best_y;
  451.     for (m = 0; m < 4; m++)
  452.     {
  453.       cand_x = iXMinNow + Diamond_x[m];
  454.       cand_y = iYMinNow + Diamond_y[m];
  455.       SEARCH_ONE_PIXEL
  456.     }
  457.     if(best_x == iXMinNow && best_y == iYMinNow)
  458.       break;
  459.   }
  460. terminate_step:
  461.   // store SAD infomation for prediction
  462.   //FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  463.   for (i=0; i < (blocksize_x>>2); i++)
  464.   {
  465.     for (j=0; j < (blocksize_y>>2); j++)
  466.     {
  467.       if(list == 0)
  468.       {
  469.         fastme_ref_cost[ref][blocktype][block_y+j][block_x+i] = min_mcost;
  470.         if (ref==0)
  471.           fastme_l0_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
  472.       }
  473.       else
  474.       {
  475.         fastme_l1_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
  476.       }
  477.     }
  478.   }
  479.   //for multi ref SAD prediction
  480.   if ((ref==0) || (SAD_prediction[pic_pix_x2] > min_mcost))
  481.     SAD_prediction[pic_pix_x2] = min_mcost;
  482.   mv[0] = (short) (best_x - pic_pix_x);
  483.   mv[1] = (short) (best_y - pic_pix_y);
  484.   return min_mcost;
  485. }
  486. int                                                   //  ==> minimum motion cost after search
  487. UMHEXSubPelBlockMotionSearch (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  488.                              short     ref,           // <--  reference frame (0... or -1 (backward))
  489.                              int       list,
  490.                              int       list_offset,
  491.                              int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  492.                              int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  493.                              int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  494.                              short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  495.                              short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in sub-pel units
  496.                              int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  497.                              int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  498.                              int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  499.                              int       lambda_factor,
  500.                              int       apply_weights
  501.                              )
  502. {
  503.   static int Diamond_x[4] = {-1, 0, 1, 0};
  504.   static int Diamond_y[4] = {0, 1, 0, -1};
  505.   int   mcost;
  506.   int   cand_mv_x, cand_mv_y;
  507.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  508.   int   mv_shift        = 0;
  509.   int   blocksize_x     = params->blc_size[blocktype][0];
  510.   int   blocksize_y     = params->blc_size[blocktype][1];
  511.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
  512.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
  513.   short max_pos_x4      = ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  514.   short max_pos_y4      = ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  515.   int   search_range_dynamic,iXMinNow,iYMinNow,i;
  516.   int   m,currmv_x = 0,currmv_y = 0;
  517.   int   pred_frac_mv_x,pred_frac_mv_y,abort_search;
  518.   int   pred_frac_up_mv_x, pred_frac_up_mv_y;
  519.   dist_method = Q_PEL + 3 * apply_weights;
  520.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  521.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1)   )
  522.   {
  523.     ref_access_method = FAST_ACCESS;
  524.   }
  525.   else
  526.   {
  527.     ref_access_method = UMV_ACCESS;
  528.   }
  529.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  530.   img_width  = ref_picture->size_x;
  531.   img_height = ref_picture->size_y;
  532.   width_pad  = ref_picture->size_x_pad;
  533.   height_pad = ref_picture->size_y_pad;
  534.   if (apply_weights)
  535.   {
  536.     weight_luma = wp_weight[list + list_offset][ref][0];
  537.     offset_luma = wp_offset[list + list_offset][ref][0];
  538.   }
  539.   if (ChromaMEEnable )
  540.   {
  541.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  542.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  543.     width_pad_cr  = ref_picture->size_x_cr_pad;
  544.     height_pad_cr = ref_picture->size_y_cr_pad;
  545.     if (apply_weights)
  546.     {
  547.       weight_cr[0] = wp_weight[list + list_offset][ref][1];
  548.       weight_cr[1] = wp_weight[list + list_offset][ref][2];
  549.       offset_cr[0] = wp_offset[list + list_offset][ref][1];
  550.       offset_cr[1] = wp_offset[list + list_offset][ref][2];
  551.     }
  552.   }
  553.   search_range_dynamic = 3;
  554.   pred_frac_mv_x = (pred_mv[0] - mv[0])%4;
  555.   pred_frac_mv_y = (pred_mv[1] - mv[1])%4;
  556.   pred_frac_up_mv_x = (pred_MV_uplayer[0] - mv[0])%4;
  557.   pred_frac_up_mv_y = (pred_MV_uplayer[1] - mv[1])%4;
  558.   memset(SearchState[0],0,(2*search_range_dynamic+1)*(2*search_range_dynamic+1));
  559.   if( !start_me_refinement_hp )
  560.   {
  561.     cand_mv_x = mv[0];
  562.     cand_mv_y = mv[1];
  563.     mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  564.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  565.       min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  566.     SearchState[search_range_dynamic][search_range_dynamic] = 1;
  567.     if (mcost < min_mcost)
  568.     {
  569.       min_mcost = mcost;
  570.       currmv_x = cand_mv_x;
  571.       currmv_y = cand_mv_y;
  572.     }
  573.   }
  574.   else
  575.   {
  576.     SearchState[search_range_dynamic][search_range_dynamic] = 1;
  577.     currmv_x = mv[0];
  578.     currmv_y = mv[1];
  579.   }
  580.   if(pred_frac_mv_x!=0 || pred_frac_mv_y!=0)
  581.   {
  582.     cand_mv_x = mv[0] + pred_frac_mv_x;
  583.     cand_mv_y = mv[1] + pred_frac_mv_y;
  584.     mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  585.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  586.       min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  587.     SearchState[cand_mv_y -mv[1] + search_range_dynamic][cand_mv_x - mv[0] + search_range_dynamic] = 1;
  588.     if (mcost < min_mcost)
  589.     {
  590.       min_mcost = mcost;
  591.       currmv_x = cand_mv_x;
  592.       currmv_y = cand_mv_y;
  593.     }
  594.   }
  595.   iXMinNow = currmv_x;
  596.   iYMinNow = currmv_y;
  597.   for(i=0;i<search_range_dynamic;i++)
  598.   {
  599.     abort_search=1;
  600.     for (m = 0; m < 4; m++)
  601.     {
  602.       cand_mv_x = iXMinNow + Diamond_x[m];
  603.       cand_mv_y = iYMinNow + Diamond_y[m];
  604.       if(iabs(cand_mv_x - mv[0]) <=search_range_dynamic && iabs(cand_mv_y - mv[1])<= search_range_dynamic)
  605.       {
  606.         if(!SearchState[cand_mv_y -mv[1]+ search_range_dynamic][cand_mv_x -mv[0]+ search_range_dynamic])
  607.         {
  608.           mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  609.           mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
  610.             min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  611.           SearchState[cand_mv_y - mv[1] + search_range_dynamic][cand_mv_x - mv[0] + search_range_dynamic] = 1;
  612.           if (mcost < min_mcost)
  613.           {
  614.             min_mcost = mcost;
  615.             currmv_x = cand_mv_x;
  616.             currmv_y = cand_mv_y;
  617.             abort_search = 0;
  618.           }
  619.         }
  620.       }
  621.     }
  622.     iXMinNow = currmv_x;
  623.     iYMinNow = currmv_y;
  624.     if(abort_search)
  625.       break;
  626.   }
  627.   mv[0] = currmv_x;
  628.   mv[1] = currmv_y;
  629.   //===== return minimum motion cost =====
  630.   return min_mcost;
  631. }
  632. int                                                   //  ==> minimum motion cost after search
  633. UMHEXSubPelBlockME (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  634.                     short     ref,           // <--  reference frame (0... or -1 (backward))
  635.                     int       list,
  636.                     int       list_offset,   // <--  MBAFF list offset
  637.                     int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  638.                     int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  639.                     int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  640.                     short     pred_mv[2],    // <--  motion vector predictor (x|y) in sub-pel units
  641.                     short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in sub-pel units
  642.                     int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  643.                     int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  644.                     int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  645.                     int*      lambda,
  646.                     int       apply_weights
  647.                     )
  648. {  
  649.   if(blocktype >3)
  650.   {
  651.     min_mcost =  UMHEXSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y, blocktype,
  652.       pred_mv, mv, 9, 9, min_mcost, lambda[Q_PEL], apply_weights);
  653.   }
  654.   else
  655.   {
  656.     min_mcost =  SubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y, blocktype,
  657.       pred_mv, mv,  9, 9, min_mcost, lambda, apply_weights);
  658.   }
  659.  
  660.   return min_mcost;
  661. }
  662. /*!
  663.  ************************************************************************
  664.  * brief
  665.  * Functions for SAD prediction of intra block cases.
  666.  * 1. void UMHEX_decide_intrabk_SAD() judges the block coding type(intra/inter)
  667.  *    of neibouring blocks
  668.  * 2. void UMHEX_skip_intrabk_SAD() set the SAD to zero if neigouring block coding
  669.  *    type is intra
  670.  * date
  671.  *    2003.4
  672.  ************************************************************************
  673.  */
  674. void UMHEX_decide_intrabk_SAD()
  675. {
  676.   if (img->type != I_SLICE)
  677.   {
  678.     if (img->pix_x == 0 && img->pix_y == 0)
  679.     {
  680.       flag_intra_SAD = 0;
  681.     }
  682.     else if (img->pix_x == 0)
  683.     {
  684.       flag_intra_SAD = flag_intra[(img->pix_x)>>4];
  685.     }
  686.     else if (img->pix_y == 0)
  687.     {
  688.       flag_intra_SAD = flag_intra[((img->pix_x)>>4)-1];
  689.     }
  690.     else
  691.     {
  692.       flag_intra_SAD = ((flag_intra[(img->pix_x)>>4])||(flag_intra[((img->pix_x)>>4)-1])||(flag_intra[((img->pix_x)>>4)+1])) ;
  693.     }
  694.   }
  695.   return;
  696. }
  697. void UMHEX_skip_intrabk_SAD(int best_mode, int ref_max)
  698. {
  699.   int i,j,k, ref;
  700.   if (img->number > 0)
  701.     flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1:0;
  702.   if (img->type != I_SLICE  && (best_mode == 9 || best_mode == 10))
  703.   {
  704.     for (i=0; i < 4; i++)
  705.     {
  706.       for (j=0; j < 4; j++)
  707.       {
  708.         for (k=0; k < 9;k++)
  709.         {
  710.           fastme_l0_cost[k][j][i] = 0;
  711.           fastme_l1_cost[k][j][i] = 0;
  712.           for (ref=0; ref<ref_max;ref++)
  713.           {
  714.             fastme_ref_cost[ref][k][j][i] = 0;
  715.           }
  716.         }
  717.       }
  718.     }
  719.   }
  720.   return;
  721. }
  722. void UMHEX_setup(short ref, int list, int block_y, int block_x, int blocktype, short   ******all_mv)
  723. {
  724.   int  N_Bframe=0;
  725.   int n_Bframe=0;
  726.   int temp_blocktype = 0;
  727.   int indication_blocktype[8]={0,0,1,1,2,4,4,5};
  728.   N_Bframe = params->successive_Bframe;
  729.   n_Bframe =(N_Bframe) ? (stats->frame_ctr[B_SLICE]%(N_Bframe+1)): 0;
  730.   /**************************** MV prediction **********************/
  731.   //MV uplayer prediction
  732.   if (blocktype>1)
  733.   {
  734.     temp_blocktype = indication_blocktype[blocktype];
  735.     pred_MV_uplayer[0] = all_mv[list][ref][temp_blocktype][block_y][block_x][0];
  736.     pred_MV_uplayer[1] = all_mv[list][ref][temp_blocktype][block_y][block_x][1];
  737.   }
  738.   //MV ref-frame prediction
  739.   pred_MV_ref_flag = 0;
  740.   if(list==0)
  741.   {
  742.     if (img->field_picture)
  743.     {
  744.       if ( ref > 1)
  745.       {
  746.         pred_MV_ref[0] = all_mv[0][ref-2][blocktype][block_y][block_x][0];
  747.         pred_MV_ref[0] = (int)(pred_MV_ref[0]*((ref>>1)+1)/(float)((ref>>1)));
  748.         pred_MV_ref[1] = all_mv[0][ref-2][blocktype][block_y][block_x][1];
  749.         pred_MV_ref[1] = (int)(pred_MV_ref[1]*((ref>>1)+1)/(float)((ref>>1)));
  750.         pred_MV_ref_flag = 1;
  751.       }
  752.       if (img->type == B_SLICE &&  (ref==0 || ref==1) )
  753.       {
  754.         pred_MV_ref[0] =(int) (all_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  755.         pred_MV_ref[1] =(int) (all_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  756.         pred_MV_ref_flag = 1;
  757.       }
  758.     }
  759.     else //frame case
  760.     {
  761.       if ( ref > 0)
  762.       {
  763.         pred_MV_ref[0] = all_mv[0][ref-1][blocktype][block_y][block_x][0];
  764.         pred_MV_ref[0] = (int)(pred_MV_ref[0]*(ref+1)/(float)(ref));
  765.         pred_MV_ref[1] = all_mv[0][ref-1][blocktype][block_y][block_x][1];
  766.         pred_MV_ref[1] = (int)(pred_MV_ref[1]*(ref+1)/(float)(ref));
  767.         pred_MV_ref_flag = 1;
  768.       }
  769.       if (img->type == B_SLICE && (ref==0)) //B frame forward prediction, first ref
  770.       {
  771.         pred_MV_ref[0] =(int) (all_mv[1][0][blocktype][block_y][block_x][0] * (-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  772.         pred_MV_ref[1] =(int) (all_mv[1][0][blocktype][block_y][block_x][1] * (-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  773.         pred_MV_ref_flag = 1;
  774.       }
  775.     }
  776.   }
  777.   /******************************SAD prediction**********************************/
  778.   if (list==0 && ref>0)  //pred_SAD_ref
  779.   {
  780.     if (flag_intra_SAD) //add this for irregular motion
  781.     {
  782.       pred_SAD = 0;
  783.     }
  784.     else
  785.     {
  786.       if (img->field_picture)
  787.       {
  788.         if (ref > 1)
  789.         {
  790.           pred_SAD = fastme_ref_cost[ref-2][blocktype][block_y][block_x];
  791.         }
  792.         else
  793.         {
  794.           pred_SAD = fastme_ref_cost[0][blocktype][block_y][block_x];
  795.         }
  796.       }
  797.       else
  798.       {
  799.         pred_SAD = fastme_ref_cost[ref-1][blocktype][block_y][block_x];
  800.       }
  801.     }
  802.   }
  803.   else if (blocktype>1)  // pred_SAD_uplayer
  804.   {
  805.     if (flag_intra_SAD)
  806.     {
  807.       pred_SAD = 0;
  808.     }
  809.     else
  810.     {
  811.       pred_SAD = (list==1) ? (fastme_l1_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
  812.       pred_SAD /= 2;
  813.     }
  814.   }
  815.   else pred_SAD = 0 ;  // pred_SAD_space
  816. }
  817. /*!
  818.  ************************************************************************
  819.  * brief
  820.  *    UMHEXBipredIntegerPelBlockMotionSearch: fast pixel block motion search for bipred mode
  821.  *    this algrithm is called UMHexagonS(see JVT-D016),which includes
  822.  *    four steps with different kinds of search patterns
  823.  * author
  824.  *   Main contributors: (see contributors.h for copyright, address and affiliation details)
  825.  *   - Zhibo Chen         <chenzhibo@tsinghua.org.cn>
  826.  *   - JianFeng Xu        <fenax@video.mdc.tsinghua.edu.cn>
  827.  *   - Xiaozhong Xu       <xxz@video.mdc.tsinghua.edu.cn>
  828.  * date   :
  829.  *   2006.1
  830.  ************************************************************************
  831.  */
  832. int                                                //  ==> minimum motion cost after search
  833. UMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB,      // <--  current Macroblock
  834.                                         imgpel*   cur_pic,       // <--  original pixel values for the AxB block
  835.                                         short     ref,           // <--  reference frame (0... or -1 (backward))
  836.                                         int       list,          // <--  current reference list
  837.                                         int       list_offset,   // <--  MBAFF list offset
  838.                                         char   ***refPic,        // <--  reference array
  839.                                         short ****tmp_mv,        // <--  mv array
  840.                                         int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  841.                                         int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  842.                                         int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  843.                                         short     pred_mv1[2],   // <--  motion vector predictor (x|y) in sub-pel units
  844.                                         short     pred_mv2[2],   // <--  motion vector predictor (x|y) in sub-pel units
  845.                                         short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  846.                                         short     s_mv[2],       // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  847.                                         int       search_range,  // <--  1-d search range in pel units
  848.                                         int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  849.                                         int       iteration_no,  // <--  bi pred iteration number
  850.                                         int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  851.                                         int       apply_weights
  852.                                         )
  853. {
  854.   int   temp_Big_Hexagon_x[16];// = Big_Hexagon_x;
  855.   int   temp_Big_Hexagon_y[16];// = Big_Hexagon_y;
  856.   int   mvshift       = 2;                  // motion vector shift for getting sub-pel units
  857.   int   search_step,iYMinNow, iXMinNow;
  858.   int   i,m,j;
  859.   float betaFourth_1,betaFourth_2;
  860.   int   pos, cand_x, cand_y,mcost;
  861.   int   blocksize_y   = params->blc_size[blocktype][1];            // vertical block size
  862.   int   blocksize_x   = params->blc_size[blocktype][0];            // horizontal block size
  863.   int   pred_x1        = (pic_pix_x << 2) + pred_mv1[0];       // predicted position x (in sub-pel units)
  864.   int   pred_y1        = (pic_pix_y << 2) + pred_mv1[1];       // predicted position y (in sub-pel units)
  865.   int   pred_x2        = (pic_pix_x << 2) + pred_mv2[0];       // predicted position x (in sub-pel units)
  866.   int   pred_y2        = (pic_pix_y << 2) + pred_mv2[1];       // predicted position y (in sub-pel units)
  867.   short center2_x      = pic_pix_x + mv[0];                      // center position x (in pel units)
  868.   short center2_y      = pic_pix_y + mv[1];                      // center position y (in pel units)
  869.   short center1_x      = pic_pix_x + s_mv[0];                      // mvx of second pred (in pel units)
  870.   short center1_y      = pic_pix_y + s_mv[1];                      // mvy of second pred (in pel units)
  871.   short mb_x = pic_pix_x - img->opix_x;
  872.   short mb_y = pic_pix_y - img->opix_y;
  873.   short block_x = (mb_x >> 2);
  874.   short block_y = (mb_y >> 2);
  875.   int   best_x = center2_x;
  876.   int   best_y = center2_y;
  877.   int   ET_Thred = Median_Pred_Thd_MB[blocktype];
  878.   short offset1 = (apply_weights ? (list == 0?  wp_offset[list_offset    ][ref][0]:  wp_offset[list_offset + 1][0  ][ref]) : 0);
  879.   short offset2 = (apply_weights ? (list == 0?  wp_offset[list_offset + 1][ref][0]:  wp_offset[list_offset    ][0  ][ref]) : 0);
  880.   ref_pic1_sub.luma = listX[list + list_offset][ref]->p_curr_img_sub;
  881.   ref_pic2_sub.luma = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->p_curr_img_sub;
  882.   img_width  = listX[list + list_offset][ref]->size_x;
  883.   img_height = listX[list + list_offset][ref]->size_y;
  884.   width_pad  = listX[list + list_offset][ref]->size_x_pad;
  885.   height_pad = listX[list + list_offset][ref]->size_y_pad;
  886.   if (apply_weights)
  887.   {
  888.     weight1 = list == 0 ? wbp_weight[list_offset         ][ref][0][0] : wbp_weight[list_offset + LIST_1][0  ][ref][0];
  889.     weight2 = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][0] : wbp_weight[list_offset         ][0  ][ref][0];
  890.     offsetBi=(offset1 + offset2 + 1)>>1;
  891.     computeBiPred = computeBiPredSAD2; //ME only supports SAD computations
  892.   }
  893.   else
  894.   {
  895.     weight1 = 1<<luma_log_weight_denom;
  896.     weight2 = 1<<luma_log_weight_denom;
  897.     offsetBi = 0;
  898.     computeBiPred = computeBiPredSAD1; //ME only supports SAD computations
  899.   }
  900.   if (ChromaMEEnable )
  901.   {
  902.     ref_pic1_sub.crcb[0] = listX[list + list_offset][ref]->imgUV_sub[0];
  903.     ref_pic1_sub.crcb[1] = listX[list + list_offset][ref]->imgUV_sub[1];
  904.     ref_pic2_sub.crcb[0] = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgUV_sub[0];
  905.     ref_pic2_sub.crcb[1] = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgUV_sub[1];
  906.     width_pad_cr  = listX[list + list_offset][ref]->size_x_cr_pad;
  907.     height_pad_cr = listX[list + list_offset][ref]->size_y_cr_pad;
  908.     if (apply_weights)
  909.     {
  910.       weight1_cr[0] = list == 0 ? wbp_weight[list_offset         ][ref][0][1] : wbp_weight[list_offset + LIST_1][0  ][ref][1];
  911.       weight1_cr[1] = list == 0 ? wbp_weight[list_offset         ][ref][0][2] : wbp_weight[list_offset + LIST_1][0  ][ref][2];
  912.       weight2_cr[0] = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][1] : wbp_weight[list_offset         ][0  ][ref][1];
  913.       weight2_cr[1] = list == 0 ? wbp_weight[list_offset + LIST_1][ref][0][2] : wbp_weight[list_offset         ][0  ][ref][2];
  914.       offsetBi_cr[0] = (list == 0)
  915.         ? (wp_offset[list_offset         ][ref][1] + wp_offset[list_offset + LIST_1][ref][1] + 1) >> 1
  916.         : (wp_offset[list_offset + LIST_1][0  ][1] + wp_offset[list_offset         ][0  ][1] + 1) >> 1;
  917.       offsetBi_cr[1] = (list == 0)
  918.         ? (wp_offset[list_offset         ][ref][2] + wp_offset[list_offset + LIST_1][ref][2] + 1) >> 1
  919.         : (wp_offset[list_offset + LIST_1][0  ][2] + wp_offset[list_offset         ][0  ][2] + 1) >> 1;
  920.     }
  921.     else
  922.     {
  923.       weight1_cr[0] = 1<<chroma_log_weight_denom;
  924.       weight1_cr[1] = 1<<chroma_log_weight_denom;
  925.       weight2_cr[0] = 1<<chroma_log_weight_denom;
  926.       weight2_cr[1] = 1<<chroma_log_weight_denom;
  927.       offsetBi_cr[0] = 0;
  928.       offsetBi_cr[1] = 0;
  929.     }
  930.   }
  931.   //===== set function for getting reference picture lines =====
  932.   if ((center2_x > search_range) && (center2_x < img_width -1-search_range-blocksize_x) &&
  933.     (center2_y > search_range) && (center2_y < img_height-1-search_range-blocksize_y)   )
  934.   {
  935.     bipred2_access_method = FAST_ACCESS;
  936.   }
  937.   else
  938.   {
  939.     bipred2_access_method = UMV_ACCESS;
  940.   }
  941.   //===== set function for getting reference picture lines =====
  942.   if ((center1_y > search_range) && (center1_y < img_height-1-search_range-blocksize_y)   )
  943.   {
  944.     bipred1_access_method = FAST_ACCESS;
  945.   }
  946.   else
  947.   {
  948.     bipred1_access_method = UMV_ACCESS;
  949.   }
  950.   //////////////////////////////////////////////////////////////////////////
  951.   //////allocate memory for search state//////////////////////////
  952.   memset(McostState[0],0,(2*search_range+1)*(2*search_range+1));
  953.   //check the center median predictor
  954.   cand_x = center2_x ;
  955.   cand_y = center2_y ;
  956.   mcost  = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
  957.   mcost += MV_COST (lambda_factor, mvshift, cand_x,    cand_y,    pred_x2, pred_y2);
  958.   mcost += computeBiPred( cur_pic,
  959.                          blocksize_y, blocksize_x, INT_MAX,
  960.                          (center1_x << 2) + IMG_PAD_SIZE_TIMES4,
  961.                          (center1_y << 2) + IMG_PAD_SIZE_TIMES4,
  962.                          (cand_x << 2) + IMG_PAD_SIZE_TIMES4,
  963.                          (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
  964.   McostState[search_range][search_range] = 1;
  965.   if (mcost < min_mcost)
  966.   {
  967.     min_mcost = mcost;
  968.     best_x = cand_x;
  969.     best_y = cand_y;
  970.   }
  971.   iXMinNow = best_x;
  972.   iYMinNow = best_y;
  973.   for (m = 0; m < 4; m++)
  974.   {
  975.     cand_x = iXMinNow + Diamond_x[m];
  976.     cand_y = iYMinNow + Diamond_y[m];
  977.     SEARCH_ONE_PIXEL_BIPRED;
  978.   }
  979.   if(center2_x != pic_pix_x || center2_y != pic_pix_y)
  980.   {
  981.     cand_x = pic_pix_x ;
  982.     cand_y = pic_pix_y ;
  983.     SEARCH_ONE_PIXEL_BIPRED;
  984.     iXMinNow = best_x;
  985.     iYMinNow = best_y;
  986.     for (m = 0; m < 4; m++)
  987.     {
  988.       cand_x = iXMinNow + Diamond_x[m];
  989.       cand_y = iYMinNow + Diamond_y[m];
  990.       SEARCH_ONE_PIXEL_BIPRED;
  991.     }
  992.   }
  993.   /***********************************init process*************************/
  994.   if( min_mcost < ET_Thred)
  995.   {
  996.     goto terminate_step;
  997.   }
  998.   else
  999.   {
  1000.     int  N_Bframe=0;
  1001.     int  n_Bframe=0;
  1002.     short****** bipred_mv = img->bipred_mv[list];
  1003.     N_Bframe = params->successive_Bframe;
  1004.     n_Bframe = stats->frame_ctr[B_SLICE]%(N_Bframe+1);
  1005.     /**************************** MV prediction **********************/
  1006.     //MV uplayer prediction
  1007.     // non for bipred mode
  1008.     //MV ref-frame prediction
  1009.     if(list==0)
  1010.     {
  1011.       if (img->field_picture)
  1012.       {
  1013.         pred_MV_ref[0] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  1014.         pred_MV_ref[1] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  1015.       }
  1016.       else //frame case
  1017.       {
  1018.         pred_MV_ref[0] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  1019.         pred_MV_ref[1] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
  1020.       }
  1021.     }
  1022.     /******************************SAD prediction**********************************/
  1023.     pred_SAD =imin(imin(SAD_a,SAD_b),SAD_c);  // pred_SAD_space
  1024.     ET_Thred = Big_Hexagon_Thd_MB[blocktype];
  1025.     ///////Threshold defined for early termination///////////////////
  1026.     if (pred_SAD == 0)
  1027.     {
  1028.       betaFourth_1=0;
  1029.       betaFourth_2=0;
  1030.     }
  1031.     else
  1032.     {
  1033.       betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
  1034.       betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
  1035.     }
  1036.   }
  1037.   /***********************************end of init *************************/
  1038.   // first_step: initial start point prediction
  1039.   //prediction using mV of last ref moiton vector
  1040.   if(list == 0)
  1041.   {
  1042.     cand_x = pic_pix_x + (pred_MV_ref[0]/4);
  1043.     cand_y = pic_pix_y + (pred_MV_ref[1]/4);
  1044.     SEARCH_ONE_PIXEL_BIPRED;
  1045.   }
  1046.   //small local search
  1047.   iXMinNow = best_x;
  1048.   iYMinNow = best_y;
  1049.   for (m = 0; m < 4; m++)
  1050.   {
  1051.     cand_x = iXMinNow + Diamond_x[m];
  1052.     cand_y = iYMinNow + Diamond_y[m];
  1053.     SEARCH_ONE_PIXEL_BIPRED;
  1054.   }
  1055.   //early termination alogrithm, refer to JVT-G016
  1056.   EARLY_TERMINATION;
  1057.   //sec_step: //Unsymmetrical-cross search
  1058.   iXMinNow = best_x;
  1059.   iYMinNow = best_y;
  1060.   for(i = 1; i < search_range; i+=2)
  1061.   {
  1062.     search_step = i;
  1063.     cand_x = iXMinNow + search_step;
  1064.     cand_y = iYMinNow ;
  1065.     SEARCH_ONE_PIXEL_BIPRED;
  1066.     cand_x = iXMinNow - search_step;
  1067.     cand_y = iYMinNow ;
  1068.     SEARCH_ONE_PIXEL_BIPRED;
  1069.   }
  1070.   for(i = 1; i < (search_range/2);i+=2)
  1071.   {
  1072.     search_step = i;
  1073.     cand_x = iXMinNow ;
  1074.     cand_y = iYMinNow + search_step;
  1075.     SEARCH_ONE_PIXEL_BIPRED;
  1076.     cand_x = iXMinNow ;
  1077.     cand_y = iYMinNow - search_step;
  1078.     SEARCH_ONE_PIXEL_BIPRED;
  1079.   }
  1080.   //early termination alogrithm, refer to JVT-G016
  1081.   EARLY_TERMINATION;
  1082.   //third_step:     // Uneven Multi-Hexagon-grid Search
  1083.   iXMinNow = best_x;
  1084.   iYMinNow = best_y;
  1085.   //sub step1: 5x5 square search
  1086.   for(pos=1;pos<25;pos++)
  1087.   {
  1088.     cand_x = iXMinNow + spiral_search_x[pos];
  1089.     cand_y = iYMinNow + spiral_search_y[pos];
  1090.     SEARCH_ONE_PIXEL_BIPRED;
  1091.   }
  1092.   //early termination alogrithm, refer to JVT-G016
  1093.   EARLY_TERMINATION;      //added back by xxz
  1094.   //sub step2: multi-grid-hexagon-search
  1095.   memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
  1096.   memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
  1097.   for(i=1;i<=(params->search_range>>2); i++)
  1098.   {
  1099.     for (m = 0; m < 16; m++)
  1100.     {
  1101.       cand_x = iXMinNow + temp_Big_Hexagon_x[m];
  1102.       cand_y = iYMinNow + temp_Big_Hexagon_y[m];
  1103.       temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
  1104.       temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];
  1105.       SEARCH_ONE_PIXEL_BIPRED;
  1106.     }
  1107.     if(min_mcost < ET_Thred)
  1108.     {
  1109.       goto terminate_step;
  1110.     }
  1111.   }
  1112.   //fourth step: Local Refinement: Extended Hexagon-based Search
  1113. fourth_1_step:
  1114.   for(i=0; i < search_range; i++)
  1115.   {
  1116.     iXMinNow = best_x;
  1117.     iYMinNow = best_y;
  1118.     for (m = 0; m < 6; m++)
  1119.     {
  1120.       cand_x = iXMinNow + Hexagon_x[m];
  1121.       cand_y = iYMinNow + Hexagon_y[m];
  1122.       SEARCH_ONE_PIXEL_BIPRED;
  1123.     }
  1124.     if(best_x == iXMinNow && best_y == iYMinNow)
  1125.       break;
  1126.   }
  1127. fourth_2_step:
  1128.   for(i = 0; i < search_range; i++)
  1129.   {
  1130.     iXMinNow = best_x;
  1131.     iYMinNow = best_y;
  1132.     for (m = 0; m < 4; m++)
  1133.     {
  1134.       cand_x = iXMinNow + Diamond_x[m];
  1135.       cand_y = iYMinNow + Diamond_y[m];
  1136.       SEARCH_ONE_PIXEL_BIPRED;
  1137.     }
  1138.     if(best_x == iXMinNow && best_y == iYMinNow)
  1139.       break;
  1140.   }
  1141. terminate_step:
  1142.   for (i=0; i < (blocksize_x>>2); i++)
  1143.   {
  1144.     for (j=0; j < (blocksize_y>>2); j++)
  1145.     {
  1146.       if(list == 0)
  1147.       {
  1148.         fastme_l0_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
  1149.       }
  1150.       else
  1151.       {
  1152.         fastme_l1_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
  1153.       }
  1154.     }
  1155.   }
  1156.   mv[0] = best_x - pic_pix_x;
  1157.   mv[1] = best_y - pic_pix_y;
  1158.   return min_mcost;
  1159. }
  1160. /*!
  1161.  ************************************************************************
  1162.  * brief
  1163.  *    Set motion vector predictor
  1164.  ************************************************************************
  1165.  */
  1166. void UMHEXSetMotionVectorPredictor (Macroblock *currMB, 
  1167.                                     short  pmv[2],
  1168.                                     char   **refPic,
  1169.                                     short  ***tmp_mv,
  1170.                                     short  ref_frame,
  1171.                                     int    list,
  1172.                                     int    mb_x,
  1173.                                     int    mb_y,
  1174.                                     int    blockshape_x,
  1175.                                     int    blockshape_y,
  1176.                                     int    *search_range)
  1177. {
  1178.   int mv_a, mv_b, mv_c, pred_vec=0;
  1179.   int mvPredType, rFrameL, rFrameU, rFrameUR;
  1180.   int hv;
  1181.   PixelPos block_a, block_b, block_c, block_d;
  1182.   // added for bipred mode
  1183.   int *** fastme_l0_cost_flag = (bipred_flag ? fastme_l0_cost_bipred:fastme_l0_cost);
  1184.   int *** fastme_l1_cost_flag = (bipred_flag ? fastme_l1_cost_bipred:fastme_l1_cost);
  1185.   //Dynamic Search Range
  1186.   int dsr_temp_search_range[2];
  1187.   int dsr_mv_avail, dsr_mv_max, dsr_mv_sum, dsr_small_search_range;
  1188.   int *mb_size = img->mb_size[IS_LUMA];
  1189.   // neighborhood SAD init
  1190.   SAD_a=0;
  1191.   SAD_b=0;
  1192.   SAD_c=0;
  1193.   SAD_d=0;
  1194.   get4x4Neighbour(currMB, mb_x - 1           , mb_y    , mb_size, &block_a);
  1195.   get4x4Neighbour(currMB, mb_x               , mb_y - 1, mb_size, &block_b);
  1196.   get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, &block_c);
  1197.   get4x4Neighbour(currMB, mb_x - 1           , mb_y - 1, mb_size, &block_d);
  1198.   if (mb_y > 0)
  1199.   {
  1200.     if (mb_x < 8)  // first column of 8x8 blocks
  1201.     {
  1202.       if (mb_y==8)
  1203.       {
  1204.         if (blockshape_x == 16)      block_c.available  = 0;
  1205.       }
  1206.       else
  1207.       {
  1208.         if (mb_x+blockshape_x == 8)  block_c.available = 0;
  1209.       }
  1210.     }
  1211.     else
  1212.     {
  1213.       if (mb_x+blockshape_x == 16)   block_c.available = 0;
  1214.     }
  1215.   }
  1216.   if (!block_c.available)
  1217.   {
  1218.     block_c=block_d;
  1219.   }
  1220.   mvPredType = MVPRED_MEDIAN;
  1221.   if (!img->MbaffFrameFlag)
  1222.   {
  1223.     rFrameL    = block_a.available    ? refPic[block_a.pos_y][block_a.pos_x] : -1;
  1224.     rFrameU    = block_b.available    ? refPic[block_b.pos_y][block_b.pos_x] : -1;
  1225.     rFrameUR   = block_c.available    ? refPic[block_c.pos_y][block_c.pos_x] : -1;
  1226.   }
  1227.   else
  1228.   {
  1229.     if (img->mb_data[img->current_mb_nr].mb_field)
  1230.     {
  1231.       rFrameL  = block_a.available
  1232.         ? (img->mb_data[block_a.mb_addr].mb_field
  1233.         ? refPic[block_a.pos_y][block_a.pos_x]
  1234.         : refPic[block_a.pos_y][block_a.pos_x] * 2) : -1;
  1235.       rFrameU  = block_b.available
  1236.         ? (img->mb_data[block_b.mb_addr].mb_field
  1237.         ? refPic[block_b.pos_y][block_b.pos_x]
  1238.         : refPic[block_b.pos_y][block_b.pos_x] * 2) : -1;
  1239.       rFrameUR = block_c.available
  1240.         ? (img->mb_data[block_c.mb_addr].mb_field
  1241.         ? refPic[block_c.pos_y][block_c.pos_x]
  1242.         : refPic[block_c.pos_y][block_c.pos_x] * 2) : -1;
  1243.     }
  1244.     else
  1245.       {
  1246.       rFrameL = block_a.available
  1247.         ? (img->mb_data[block_a.mb_addr].mb_field
  1248.         ? refPic[block_a.pos_y][block_a.pos_x] >>1
  1249.         : refPic[block_a.pos_y][block_a.pos_x]) : -1;
  1250.       rFrameU    = block_b.available    ?
  1251.         img->mb_data[block_b.mb_addr].mb_field ?
  1252.         refPic[block_b.pos_y][block_b.pos_x] >>1:
  1253.       refPic[block_b.pos_y][block_b.pos_x] :
  1254.       -1;
  1255.       rFrameUR    = block_c.available    ?
  1256.         img->mb_data[block_c.mb_addr].mb_field ?
  1257.         refPic[block_c.pos_y][block_c.pos_x] >>1:
  1258.       refPic[block_c.pos_y][block_c.pos_x] :
  1259.       -1;
  1260.     }
  1261.   }
  1262.   /* Prediction if only one of the neighbors uses the reference frame
  1263.   * we are checking
  1264.   */
  1265.   if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)       mvPredType = MVPRED_L;
  1266.   else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)  mvPredType = MVPRED_U;
  1267.   else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)  mvPredType = MVPRED_UR;
  1268.   // Directional predictions
  1269.   if(blockshape_x == 8 && blockshape_y == 16)
  1270.   {
  1271.     if(mb_x == 0)
  1272.     {
  1273.       if(rFrameL == ref_frame)
  1274.         mvPredType = MVPRED_L;
  1275.     }
  1276.     else
  1277.     {
  1278.       if( rFrameUR == ref_frame)
  1279.         mvPredType = MVPRED_UR;
  1280.     }
  1281.   }
  1282.   else if(blockshape_x == 16 && blockshape_y == 8)
  1283.   {
  1284.     if(mb_y == 0)
  1285.     {
  1286.       if(rFrameU == ref_frame)
  1287.         mvPredType = MVPRED_U;
  1288.     }
  1289.     else
  1290.     {
  1291.       if(rFrameL == ref_frame)
  1292.         mvPredType = MVPRED_L;
  1293.     }
  1294.   }
  1295.   // neighborhood SAD prediction
  1296.   if((params->UMHexDSR == 1 || params->BiPredMotionEstimation == 1))
  1297.   {
  1298.     SAD_a = block_a.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x])) : 0;
  1299.     SAD_b = block_b.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x])) : 0;
  1300.     SAD_d = block_d.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x])) : 0;
  1301.     SAD_c = block_c.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x])) : SAD_d;
  1302.   }
  1303.   for (hv=0; hv < 2; hv++)
  1304.   {
  1305.     if (!img->MbaffFrameFlag || hv==0)
  1306.     {
  1307.       mv_a = block_a.available  ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] : 0;
  1308.       mv_b = block_b.available  ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] : 0;
  1309.       mv_c = block_c.available  ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] : 0;
  1310.     }
  1311.     else
  1312.     {
  1313.       if (img->mb_data[img->current_mb_nr].mb_field)
  1314.       {
  1315.         mv_a = block_a.available  ? img->mb_data[block_a.mb_addr].mb_field
  1316.           ? tmp_mv[block_a.pos_y][block_a.pos_x][hv]
  1317.           : tmp_mv[block_a.pos_y][block_a.pos_x][hv] / 2
  1318.           : 0;
  1319.         mv_b = block_b.available  ? img->mb_data[block_b.mb_addr].mb_field
  1320.           ? tmp_mv[block_b.pos_y][block_b.pos_x][hv]
  1321.           : tmp_mv[block_b.pos_y][block_b.pos_x][hv] / 2
  1322.           : 0;
  1323.         mv_c = block_c.available  ? img->mb_data[block_c.mb_addr].mb_field
  1324.           ? tmp_mv[block_c.pos_y][block_c.pos_x][hv]
  1325.           : tmp_mv[block_c.pos_y][block_c.pos_x][hv] / 2
  1326.           : 0;
  1327.       }
  1328.       else
  1329.       {
  1330.         mv_a = block_a.available  ? img->mb_data[block_a.mb_addr].mb_field
  1331.           ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] * 2
  1332.           : tmp_mv[block_a.pos_y][block_a.pos_x][hv]
  1333.           : 0;
  1334.         mv_b = block_b.available  ? img->mb_data[block_b.mb_addr].mb_field
  1335.           ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] * 2
  1336.           : tmp_mv[block_b.pos_y][block_b.pos_x][hv]
  1337.           : 0;
  1338.         mv_c = block_c.available  ? img->mb_data[block_c.mb_addr].mb_field
  1339.           ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] * 2
  1340.           : tmp_mv[block_c.pos_y][block_c.pos_x][hv]
  1341.           : 0;
  1342.       }
  1343.     }
  1344.     switch (mvPredType)
  1345.     {
  1346.     case MVPRED_MEDIAN:
  1347.       if(!(block_b.available || block_c.available))
  1348.       {
  1349.         pred_vec = mv_a;
  1350.       }
  1351.       else
  1352.       {
  1353.         pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
  1354.       }
  1355.       break;
  1356.     case MVPRED_L:
  1357.       pred_vec = mv_a;
  1358.       break;
  1359.     case MVPRED_U:
  1360.       pred_vec = mv_b;
  1361.       break;
  1362.     case MVPRED_UR:
  1363.       pred_vec = mv_c;
  1364.       break;
  1365.     default:
  1366.       break;
  1367.     }
  1368.     pmv[hv] = pred_vec;
  1369.     //Dynamic Search Range
  1370.     if (params->UMHexDSR)
  1371.     {
  1372.       dsr_mv_avail=block_a.available+block_b.available+block_c.available;
  1373.       if(dsr_mv_avail < 2)
  1374.       {
  1375.         dsr_temp_search_range[hv] = params->search_range;
  1376.       }
  1377.       else
  1378.       {
  1379.         dsr_mv_max = imax(iabs(mv_a),imax(iabs(mv_b),iabs(mv_c)));
  1380.         dsr_mv_sum = (iabs(mv_a)+iabs(mv_b)+iabs(mv_c));
  1381.         if(dsr_mv_sum == 0) dsr_small_search_range = (params->search_range + 4) >> 3;
  1382.         else if(dsr_mv_sum > 3 ) dsr_small_search_range = (params->search_range + 2) >>2;
  1383.         else dsr_small_search_range = (3*params->search_range + 8) >> 4;
  1384.         dsr_temp_search_range[hv]=imin(params->search_range,imax(dsr_small_search_range,dsr_mv_max<<1));
  1385.         if(imax(SAD_a,imax(SAD_b,SAD_c)) > Threshold_DSR_MB[UMHEX_blocktype])
  1386.           dsr_temp_search_range[hv] = params->search_range;
  1387.       }
  1388.     }
  1389.   }
  1390.   //Dynamic Search Range
  1391.   if (params->UMHexDSR) 
  1392.   {
  1393.     dsr_new_search_range = imax(dsr_temp_search_range[0],dsr_temp_search_range[1]);
  1394.     if      (params->full_search == 2) 
  1395.       *search_range = dsr_new_search_range;
  1396.     else if (params->full_search == 1) 
  1397.       *search_range = dsr_new_search_range /  (imin(ref_frame,1)+1);
  1398.     else                              
  1399.       *search_range = dsr_new_search_range / ((imin(ref_frame,1)+1) * imin(2,BlockType_LUT[(blockshape_y >> 2) - 1][(blockshape_x >> 2) - 1]));
  1400.   }
  1401. }