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

Audio

开发平台:

Visual C++

  1. /*!
  2. *************************************************************************************
  3. * file me_fullsearch.c
  4. *
  5. * brief
  6. *    Motion Estimation using Fullsearch
  7. *
  8. * author
  9. *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10. *      - Alexis Michael Tourapis <alexismt@ieee.org>
  11. *      - Athanasios Leontaris    <aleon@dolby.com>
  12. *
  13. *************************************************************************************
  14. */
  15. // Includes
  16. #include "contributors.h"
  17. #include <limits.h>
  18. #include "global.h"
  19. #include "image.h"
  20. #include "memalloc.h"
  21. #include "mb_access.h"
  22. #include "refbuf.h"
  23. #include "me_distortion.h"
  24. #include "me_fullsearch.h"
  25. #include "mv-search.h"
  26. // Define Global Parameters
  27. extern short*  spiral_search_x;
  28. extern short*  spiral_search_y;
  29. extern short*  spiral_hpel_search_x;
  30. extern short*  spiral_hpel_search_y;
  31. // Functions
  32. /*!
  33.  ***********************************************************************
  34.  * brief
  35.  *    Full pixel block motion search
  36.  ***********************************************************************
  37.  */
  38. int                                                //  ==> minimum motion cost after search
  39. FullPelBlockMotionSearch (Macroblock *currMB ,     // <--  current Macroblock
  40.                           imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  41.                           short     ref,           // <--  reference frame (0... or -1 (backward))
  42.                           int       list,          // <--  current list
  43.                           int       list_offset,   // <--  MBAFF list offset
  44.                           char   ***refPic,        // <--  reference array
  45.                           short ****tmp_mv,        // <--  mv array
  46.                           int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  47.                           int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  48.                           int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  49.                           short     pred_mv[2],    // <--  motion vector predictor (x) in sub-pel units
  50.                           short     mv[2],         // <--> in: search center (x) / out: motion vector (x) - in pel units
  51.                           int       search_range,  // <--  1-d search range in pel units
  52.                           int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  53.                           int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  54.                           int       apply_weights) // <--  use weight based ME
  55. {
  56.   int   pos, cand_x, cand_y, mcost;
  57.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  58.   int   best_pos      = 0;                                        // position with minimum motion cost
  59.   int   max_pos       = (2*search_range+1)*(2*search_range+1);    // number of search positions
  60.   int   blocksize_y   = params->blc_size[blocktype][1];            // vertical block size
  61.   int   blocksize_x   = params->blc_size[blocktype][0];            // horizontal block size
  62.   int   pred_x        = (pic_pix_x << 2) + pred_mv[0];       // predicted position x (in sub-pel units)
  63.   int   pred_y        = (pic_pix_y << 2) + pred_mv[1];       // predicted position y (in sub-pel units)
  64.   int   center_x      = pic_pix_x + mv[0];                        // center position x (in pel units)
  65.   int   center_y      = pic_pix_y + mv[1];                        // center position y (in pel units)
  66.   int   check_for_00  = (blocktype==1 && !params->rdopt && img->type!=B_SLICE && ref==0);
  67.   int   dist_method = F_PEL + 3 * apply_weights;
  68.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  69.   img_width  = ref_picture->size_x;
  70.   img_height = ref_picture->size_y;
  71.   width_pad  = ref_picture->size_x_pad;
  72.   height_pad = ref_picture->size_y_pad;
  73.   if (ChromaMEEnable)
  74.   {
  75.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  76.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  77.     width_pad_cr  = ref_picture->size_x_cr_pad;
  78.     height_pad_cr = ref_picture->size_y_cr_pad;
  79.   }
  80.   //===== set function for getting reference picture lines =====
  81.   if ((center_x > search_range) && (center_x < img_width -1-search_range-blocksize_x) &&
  82.     (center_y > search_range) && (center_y < img_height-1-search_range-blocksize_y)   )
  83.   {
  84.     ref_access_method = FAST_ACCESS;
  85.   }
  86.   else
  87.   {
  88.     ref_access_method = UMV_ACCESS;
  89.   }
  90.   //===== loop over all search positions =====
  91.   for (pos=0; pos<max_pos; pos++)
  92.   {
  93.     //--- set candidate position (absolute position in pel units) ---
  94.     cand_x = (center_x + spiral_search_x[pos])<<2;
  95.     cand_y = (center_y + spiral_search_y[pos])<<2;
  96.     //--- initialize motion cost (cost for motion vector) and check ---
  97.     mcost = MV_COST_SMP (lambda_factor, cand_x, cand_y, pred_x, pred_y);
  98.     if (check_for_00 && cand_x==pic_pix_x && cand_y==pic_pix_y)
  99.     {
  100.       mcost -= WEIGHTED_COST (lambda_factor, 16);
  101.     }
  102.     if (mcost >= min_mcost)   continue;
  103.     //--- add residual cost to motion cost ---
  104.     mcost += computeUniPred[dist_method](orig_pic, blocksize_y, blocksize_x,
  105.       min_mcost - mcost, cand_x + IMG_PAD_SIZE_TIMES4, cand_y + IMG_PAD_SIZE_TIMES4);
  106.     //--- check if motion cost is less than minimum cost ---
  107.     if (mcost < min_mcost)
  108.     {
  109.       best_pos  = pos;
  110.       min_mcost = mcost;
  111.     }
  112.   }
  113.   //===== set best motion vector and return minimum motion cost =====
  114.   if (best_pos)
  115.   {
  116.     mv[0] += spiral_search_x[best_pos];
  117.     mv[1] += spiral_search_y[best_pos];
  118.   }
  119.   return min_mcost;
  120. }
  121. /*!
  122.  ***********************************************************************
  123.  * brief
  124.  *    Full pixel block motion search
  125.  ***********************************************************************
  126.  */
  127. int                                                //  ==> minimum motion cost after search
  128. FullPelBlockMotionBiPred (Macroblock *currMB,      // <--  current Macroblock
  129.                           imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  130.                           short     ref,           // <--  reference frame (0... or -1 (backward))
  131.                           int       list,          // <--  reference list
  132.                           int       list_offset,   // <--  MBAFF list offset
  133.                           char   ***refPic,        // <--  reference array
  134.                           short ****tmp_mv,        // <--  mv array
  135.                           int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  136.                           int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  137.                           int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  138.                           short     pred_mv1[2],   // <--  motion vector predictor from first list (x|y) in sub-pel units
  139.                           short     pred_mv2[2],   // <--  motion vector predictor from second list (x|y) in sub-pel units
  140.                           short     mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  141.                           short     static_mv[2],       // <--> in: search center (x|y) 
  142.                           int       search_range,  // <--  1-d search range in pel units
  143.                           int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  144.                           int       iteration_no,  // <--  bi pred iteration number
  145.                           int       lambda_factor, // <--  lagrangian parameter for determining motion cost
  146.                           int       apply_weights  // <--  perform weight based ME
  147.                           ) 
  148. {
  149.   StorablePicture *ref_picture1 = listX[list       + list_offset][ref];
  150.   StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0];
  151.   short blocksize_y   = params->blc_size[blocktype][1];        // vertical block size
  152.   short blocksize_x   = params->blc_size[blocktype][0];        // horizontal block size
  153.   
  154.   int   pos, mcost;
  155.   int   best_pos      = 0;                                     // position with minimum motion cost
  156.   int   max_pos       = (2*search_range+1)*(2*search_range+1); // number of search positions
  157.   static MotionVector center1, center2, cand, pred1, pred2;
  158.   pred1.mv_x   = (pic_pix_x << 2) + pred_mv1[0]; // predicted position x (in sub-pel units)
  159.   pred1.mv_y   = (pic_pix_y << 2) + pred_mv1[1]; // predicted position y (in sub-pel units)
  160.   pred2.mv_x   = (pic_pix_x << 2) + pred_mv2[0]; // predicted position x (in sub-pel units)
  161.   pred2.mv_y   = (pic_pix_y << 2) + pred_mv2[1]; // predicted position y (in sub-pel units)
  162.   center1.mv_x = pic_pix_x + mv[0];              // center position x (in pel units)
  163.   center1.mv_y = pic_pix_y + mv[1];              // center position y (in pel units)
  164.   center2.mv_x = pic_pix_x + static_mv[0];       // center position x of static mv (in pel units)
  165.   center2.mv_y = pic_pix_y + static_mv[1];       // center position y of static mv (in pel units)
  166.   ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
  167.   ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
  168.   img_width  = ref_picture1->size_x;
  169.   img_height = ref_picture1->size_y;
  170.   width_pad  = ref_picture1->size_x_pad;
  171.   height_pad = ref_picture1->size_y_pad;
  172.   if (apply_weights)
  173.   {
  174.     computeBiPred = computeBiPred2[F_PEL];
  175.   }
  176.   else
  177.   {
  178.     computeBiPred = computeBiPred1[F_PEL];
  179.   }
  180.   if ( ChromaMEEnable )
  181.   {
  182.     ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
  183.     ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
  184.     ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
  185.     ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
  186.     width_pad_cr  = ref_picture1->size_x_cr_pad;
  187.     height_pad_cr = ref_picture1->size_y_cr_pad;
  188.   }
  189.   //===== set function for getting reference picture lines from reference 1 =====
  190.   if ((center1.mv_x > search_range) && (center1.mv_x < img_width -1-search_range-blocksize_x) &&
  191.     (center1.mv_y > search_range) && (center1.mv_y < img_height-1-search_range-blocksize_y)   )
  192.   {
  193.     bipred1_access_method = FAST_ACCESS;
  194.   }
  195.   else
  196.   {
  197.     bipred1_access_method = UMV_ACCESS;
  198.   }
  199.   //===== set function for getting reference picture lines from reference 2 =====
  200.   if ((center2.mv_x > search_range) && (center2.mv_x < img_width -1-search_range-blocksize_x) &&
  201.     (center2.mv_y > search_range) && (center2.mv_y < img_height-1-search_range-blocksize_y)   )
  202.   {
  203.     bipred2_access_method = FAST_ACCESS;
  204.   }
  205.   else
  206.   {
  207.     bipred2_access_method = UMV_ACCESS;
  208.   }
  209.   //===== loop over all search positions =====
  210.   for (pos=0; pos<max_pos; pos++)
  211.   {
  212.     //--- set candidate position (absolute position in pel units) ---
  213.     cand.mv_x = (center1.mv_x + spiral_search_x[pos])<<2;
  214.     cand.mv_y = (center1.mv_y + spiral_search_y[pos])<<2;
  215.     //--- initialize motion cost (cost for motion vector) and check ---
  216.     mcost  = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred1.mv_x, pred1.mv_y);
  217.     mcost += MV_COST_SMP (lambda_factor, (center2.mv_x << 2), (center2.mv_y<<2), pred2.mv_x, pred2.mv_y);
  218.     if (mcost >= min_mcost)   continue;
  219.     //--- add residual cost to motion cost ---
  220.     mcost += computeBiPred(orig_pic,
  221.       blocksize_y, blocksize_x, min_mcost - mcost,
  222.       cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4,
  223.       (center2.mv_x << 2) + IMG_PAD_SIZE_TIMES4,
  224.       (center2.mv_y << 2) + IMG_PAD_SIZE_TIMES4);
  225.     //--- check if motion cost is less than minimum cost ---
  226.     if (mcost < min_mcost)
  227.     {
  228.       best_pos  = pos;
  229.       min_mcost = mcost;
  230.     }
  231.   }
  232.   //===== set best motion vector and return minimum motion cost =====
  233.   if (best_pos)
  234.   {
  235.     mv[0] += spiral_search_x[best_pos];
  236.     mv[1] += spiral_search_y[best_pos];
  237.   }
  238.   return min_mcost;
  239. }
  240. /*!
  241.  ***********************************************************************
  242.  * brief
  243.  *    Sub pixel block motion search
  244.  ***********************************************************************
  245.  */
  246. int                                               //  ==> minimum motion cost after search
  247. SubPelBlockMotionSearch (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  248.                          short     ref,           // <--  reference frame (0... or -1 (backward))
  249.                          int       list,          // <--  reference picture list
  250.                          int       list_offset,   // <--  MBAFF list offset
  251.                          int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  252.                          int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  253.                          int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  254.                          short     pred_mv[2],    // <--  motion vector predictor in sub-pel units
  255.                          short     mv[2],         // <--> in: search center / out: motion vector - in pel units
  256.                          int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  257.                          int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  258.                          int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  259.                          int*      lambda,        // <--  lagrangian parameter for determining motion cost
  260.                          int       apply_weights  // <--  use weight based ME
  261.                          )
  262. {
  263.   int   pos, best_pos, mcost;
  264.   int   cand_mv_x, cand_mv_y;
  265.   int   check_position0 = (!params->rdopt && img->type!=B_SLICE && ref==0 && blocktype==1 && mv[0] == 0 && mv[1] ==0);
  266.   int   blocksize_x     = params->blc_size[blocktype][0];
  267.   int   blocksize_y     = params->blc_size[blocktype][1];
  268.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
  269.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
  270.   int   max_pos2        = ( !start_me_refinement_hp ? imax(1,search_pos2) : search_pos2);  
  271.   int   cmv_x, cmv_y;
  272.   int dist_method = H_PEL + 3 * apply_weights;
  273.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  274.   int max_pos_x4 = ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  275.   int max_pos_y4 = ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  276.   int lambda_factor = lambda[H_PEL];
  277.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  278.   width_pad  = ref_picture->size_x_pad;
  279.   height_pad = ref_picture->size_y_pad;
  280.   if (ChromaMEEnable)
  281.   {
  282.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  283.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  284.     width_pad_cr  = ref_picture->size_x_cr_pad;
  285.     height_pad_cr = ref_picture->size_y_cr_pad;
  286.   }
  287.   /*********************************
  288.    *****                       *****
  289.    *****  HALF-PEL REFINEMENT  *****
  290.    *****                       *****
  291.    *********************************/
  292.   //===== set function for getting pixel values =====
  293.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  294.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1)   )
  295.   {
  296.     ref_access_method = FAST_ACCESS;
  297.   }
  298.   else
  299.   {
  300.     ref_access_method = UMV_ACCESS;
  301.   }
  302.   //===== loop over search positions =====
  303.   for (best_pos = 0, pos = start_me_refinement_hp; pos < max_pos2; pos++)
  304.   {
  305.     cand_mv_x = mv[0] + (spiral_hpel_search_x[pos]);    // quarter-pel units
  306.     cand_mv_y = mv[1] + (spiral_hpel_search_y[pos]);    // quarter-pel units
  307.     //----- set motion vector cost -----
  308.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  309.     if (mcost >= min_mcost) continue;
  310.     cmv_x = cand_mv_x + pic4_pix_x;
  311.     cmv_y = cand_mv_y + pic4_pix_y;
  312.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
  313.     if (pos==0 && check_position0)
  314.     {
  315.       mcost -= WEIGHTED_COST (lambda_factor, 16);
  316.     }
  317.     if (mcost < min_mcost)
  318.     {
  319.       min_mcost = mcost;
  320.       best_pos  = pos;
  321.     }
  322.   }
  323.   if (best_pos)
  324.   {
  325.     mv[0] += (spiral_hpel_search_x [best_pos]);
  326.     mv[1] += (spiral_hpel_search_y [best_pos]);
  327.   }
  328.   if ( !start_me_refinement_qp )
  329.     min_mcost = INT_MAX;
  330.   /************************************
  331.   *****                          *****
  332.   *****  QUARTER-PEL REFINEMENT  *****
  333.   *****                          *****
  334.   ************************************/
  335.   //===== set function for getting pixel values =====
  336.   if ((pic4_pix_x + mv[0] > 0) && (pic4_pix_x + mv[0] < max_pos_x4) &&
  337.     (pic4_pix_y + mv[1] > 0) && (pic4_pix_y + mv[1] < max_pos_y4)   )
  338.   {
  339.     ref_access_method = FAST_ACCESS;
  340.   }
  341.   else
  342.   {
  343.     ref_access_method = UMV_ACCESS;
  344.   }
  345.   dist_method = Q_PEL + 3 * apply_weights;
  346.   lambda_factor = lambda[Q_PEL];
  347.   //===== loop over search positions =====
  348.   for (best_pos = 0, pos = start_me_refinement_qp; pos < search_pos4; pos++)
  349.   {
  350.     cand_mv_x = mv[0] + spiral_search_x[pos];    // quarter-pel units
  351.     cand_mv_y = mv[1] + spiral_search_y[pos];    // quarter-pel units
  352.     //----- set motion vector cost -----
  353.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  354.     if (mcost >= min_mcost) continue;
  355.     cmv_x = cand_mv_x + pic4_pix_x;
  356.     cmv_y = cand_mv_y + pic4_pix_y;
  357.     mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
  358.     if (mcost < min_mcost)
  359.     {
  360.       min_mcost = mcost;
  361.       best_pos  = pos;
  362.     }
  363.   }
  364.   if (best_pos)
  365.   {
  366.     mv[0] += spiral_search_x [best_pos];
  367.     mv[1] += spiral_search_y [best_pos];
  368.   }
  369.   //===== return minimum motion cost =====
  370.   return min_mcost;
  371. }
  372. /*!
  373. ***********************************************************************
  374. * brief
  375. *    Bipred Sub pixel block motion search
  376. ***********************************************************************
  377. */
  378. int                                               //  ==> minimum motion cost after search
  379. SubPelBlockSearchBiPred (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  380.                          short     ref,           // <--  reference frame (0... or -1 (backward))
  381.                          int       list,          // <--  reference picture list
  382.                          int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  383.                          int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  384.                          int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  385.                          short     pred_mv1[2],   // <--  motion vector predictor (x) in sub-pel units
  386.                          short     pred_mv2[2],   // <--  motion vector predictor (x) in sub-pel units
  387.                          short     mv[2],         // <--> in: search center (x) / out: motion vector (x) - in pel units
  388.                          short     static_mv[2],  // <--> in: search center (x) / out: motion vector (x) - 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,        // <--  lagrangian parameter for determining motion cost
  393.                          int       apply_weights  // <--  perform weight based ME
  394.                          )
  395. {
  396.   int   list_offset   = img->mb_data[img->current_mb_nr].list_offset;
  397.   int   pos, best_pos, mcost;
  398.   int   cand_mv_x, cand_mv_y;
  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.   int   smv_x = static_mv[0] + pic4_pix_x;
  406.   int   smv_y = static_mv[1] + pic4_pix_y;
  407.   StorablePicture *ref_picture1 = listX[list       + list_offset][ref];
  408.   StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0];
  409.   int max_pos_x4 = ((ref_picture1->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  410.   int max_pos_y4 = ((ref_picture1->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  411.   int lambda_factor = lambda[H_PEL];
  412.   ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
  413.   ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
  414.   img_width    = ref_picture1->size_x;
  415.   img_height   = ref_picture1->size_y;
  416.   width_pad    = ref_picture1->size_x_pad;
  417.   height_pad   = ref_picture1->size_y_pad;
  418.   if (apply_weights)
  419.   {
  420.     computeBiPred = computeBiPred2[H_PEL];
  421.   }
  422.   else
  423.   {
  424.     computeBiPred = computeBiPred1[H_PEL];
  425.   }
  426.   if ( ChromaMEEnable )
  427.   {
  428.     ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
  429.     ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
  430.     ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
  431.     ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
  432.     width_pad_cr  = ref_picture1->size_x_cr_pad;
  433.     height_pad_cr = ref_picture1->size_y_cr_pad;
  434.   }
  435.   /*********************************
  436.    *****                       *****
  437.    *****  HALF-PEL REFINEMENT  *****
  438.    *****                       *****
  439.    *********************************/
  440.   //===== set function for getting pixel values =====
  441.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  442.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1))
  443.   {
  444.     bipred1_access_method = FAST_ACCESS;
  445.   }
  446.   else
  447.   {
  448.     bipred1_access_method = UMV_ACCESS;
  449.   }
  450.   if ((pic4_pix_x + static_mv[0] > 1) && (pic4_pix_x + static_mv[0] < max_pos_x4 - 1) &&
  451.     (pic4_pix_y + static_mv[1] > 1) && (pic4_pix_y + static_mv[1] < max_pos_y4 - 1))
  452.   {
  453.     bipred2_access_method = FAST_ACCESS;
  454.   }
  455.   else
  456.   {
  457.     bipred2_access_method = UMV_ACCESS;
  458.   }
  459.   //===== loop over search positions =====
  460.   for (best_pos = 0, pos = start_me_refinement_hp; pos < max_pos2; pos++)
  461.   {
  462.     cand_mv_x = mv[0] + (spiral_hpel_search_x[pos]);    // quarter-pel units
  463.     cand_mv_y = mv[1] + (spiral_hpel_search_y[pos]);    // quarter-pel units
  464.     //----- set motion vector cost -----
  465.     mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  466.     mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  467.     if (mcost >= min_mcost) continue;
  468.     cmv_x = cand_mv_x + pic4_pix_x;
  469.     cmv_y = cand_mv_y + pic4_pix_y;
  470.     mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x,
  471.       min_mcost - mcost, cmv_x, cmv_y, smv_x, smv_y);
  472.     if (mcost < min_mcost)
  473.     {
  474.       min_mcost = mcost;
  475.       best_pos  = pos;
  476.     }
  477.   }
  478.   if (best_pos)
  479.   {
  480.     mv[0] += (spiral_hpel_search_x [best_pos]);
  481.     mv[1] += (spiral_hpel_search_y [best_pos]);
  482.   }
  483.   computeBiPred = apply_weights? computeBiPred2[Q_PEL] : computeBiPred1[Q_PEL];
  484.   /************************************
  485.   *****                          *****
  486.   *****  QUARTER-PEL REFINEMENT  *****
  487.   *****                          *****
  488.   ************************************/
  489.   //===== set function for getting pixel values =====
  490.   if ((pic4_pix_x + mv[0] > 0) && (pic4_pix_x + mv[0] < max_pos_x4) &&
  491.     (pic4_pix_y + mv[1] > 0) && (pic4_pix_y + mv[1] < max_pos_y4))
  492.   {
  493.     bipred1_access_method = FAST_ACCESS;
  494.   }
  495.   else
  496.   {
  497.     bipred1_access_method = UMV_ACCESS;
  498.   }
  499.   if ((pic4_pix_x + static_mv[0] > 0) && (pic4_pix_x + static_mv[0] < max_pos_x4) &&
  500.     (pic4_pix_y + static_mv[1] > 0) && (pic4_pix_y + static_mv[1] < max_pos_y4))
  501.   {
  502.     bipred2_access_method = FAST_ACCESS;
  503.   }
  504.   else
  505.   {
  506.     bipred2_access_method = UMV_ACCESS;
  507.   }
  508.   if ( !start_me_refinement_qp )
  509.     min_mcost = INT_MAX;
  510.   lambda_factor = lambda[Q_PEL];
  511.   //===== loop over search positions =====
  512.   for (best_pos = 0, pos = start_me_refinement_qp; pos < search_pos4; pos++)
  513.   {
  514.     cand_mv_x = mv[0] + spiral_search_x[pos];    // quarter-pel units
  515.     cand_mv_y = mv[1] + spiral_search_y[pos];    // quarter-pel units
  516.     //----- set motion vector cost -----
  517.     mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  518.     mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  519.     if (mcost >= min_mcost) continue;
  520.     cmv_x = cand_mv_x + pic4_pix_x;
  521.     cmv_y = cand_mv_y + pic4_pix_y;
  522.     mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x,
  523.       min_mcost - mcost, cmv_x, cmv_y, smv_x, smv_y);
  524.     if (mcost < min_mcost)
  525.     {
  526.       min_mcost = mcost;
  527.       best_pos  = pos;
  528.     }
  529.   }
  530.   if (best_pos)
  531.   {
  532.     mv[0] += spiral_search_x [best_pos];
  533.     mv[1] += spiral_search_y [best_pos];
  534.   }
  535.   //===== return minimum motion cost =====
  536.   return min_mcost;
  537. }