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

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file mv-search.c
  4.  *
  5.  * brief
  6.  *    Motion Vector Search, unified for B and P Pictures
  7.  *
  8.  * author
  9.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10.  *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  11.  *      - Inge Lille-Langoy               <inge.lille-langoy@telenor.com>
  12.  *      - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
  13.  *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  14.  *      - Jani Lainema                    <jani.lainema@nokia.com>
  15.  *      - Detlev Marpe                    <marpe@hhi.de>
  16.  *      - Thomas Wedi                     <wedi@tnt.uni-hannover.de>
  17.  *      - Heiko Schwarz                   <hschwarz@hhi.de>
  18.  *      - Alexis Michael Tourapis         <alexismt@ieee.org>
  19.  *
  20.  *************************************************************************************
  21. */
  22. #include "contributors.h"
  23. #include <math.h>
  24. #include <limits.h>
  25. #include <time.h>
  26. #include <sys/timeb.h>
  27. #include "global.h"
  28. #include "image.h"
  29. #include "mv-search.h"
  30. #include "refbuf.h"
  31. #include "memalloc.h"
  32. #include "mb_access.h"
  33. #include "macroblock.h"
  34. #include "mc_prediction.h"
  35. #include "conformance.h"
  36. // Motion estimation distortion header file
  37. #include "me_distortion.h"
  38. // Motion estimation search algorithms
  39. #include "me_epzs.h"
  40. #include "me_fullfast.h"
  41. #include "me_fullsearch.h"
  42. #include "me_umhex.h"
  43. #include "me_umhexsmp.h"
  44. #include "rdoq.h"
  45. // Statistics, temporary
  46. int     max_mvd;
  47. short*  spiral_search_x;
  48. short*  spiral_search_y;
  49. short*  spiral_hpel_search_x;
  50. short*  spiral_hpel_search_y;
  51. int*    mvbits;
  52. int*    refbits;
  53. int*    byte_abs;
  54. int**** motion_cost;
  55. int     byte_abs_range;
  56. static int diff  [16];
  57. static int diff64[64];
  58. static imgpel orig_pic [768];
  59. int (*IntPelME)       (Macroblock *, imgpel *, short, int, int, char ***, short ****,
  60.                        int, int, int, short[2], short[2], int, int, int, int);
  61. int (*BiPredME)       (Macroblock *, imgpel *, short, int, int, char  ***, short  ****,
  62.                        int, int, int, short[2], short[2], short[2], short[2], int, int, int, int, int);
  63. int (*SubPelBiPredME) (imgpel* orig_pic, short ref, int list, int pic_pix_x, int pic_pix_y,
  64.                        int blocktype, short pred_mv1[2], short pred_mv2[2], short mv1[2], short mv2[2], 
  65.                        int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights);
  66. int (*SubPelME)       (imgpel* orig_pic, short ref, int list, int list_offset, int pic_pix_x, int pic_pix_y, 
  67.                        int blocktype, short pred_mv[2], short mv[2], 
  68.                        int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights);
  69. int BlockMotionSearch (Macroblock *currMB, short,int,int,int,int,int, int*);
  70. int BiPredBlockMotionSearch(Macroblock *currMB, short[2], short*, short, int, int, int, int , int, int, int*);
  71. int GetSkipCostMB     (Macroblock *currMB);
  72. extern ColocatedParams *Co_located;
  73. extern const short block_type_shift_factor[8];
  74. /*!
  75.  ************************************************************************
  76.  * brief
  77.  *    Initialize ME engine
  78.  ************************************************************************
  79.  */
  80. void init_ME_engine(int SearchMode)
  81. {
  82.   switch (SearchMode)
  83.   {
  84.    case EPZS:
  85.      IntPelME       = EPZSPelBlockMotionSearch;
  86.      BiPredME       = EPZSBiPredBlockMotionSearch;
  87.      SubPelBiPredME = (params->EPZSSubPelMEBiPred) ? EPZSSubPelBlockSearchBiPred : SubPelBlockSearchBiPred;
  88.      SubPelME       = (params->EPZSSubPelME) ? EPZSSubPelBlockMotionSearch : SubPelBlockMotionSearch;
  89.      break;
  90.    case UM_HEX:
  91.      IntPelME       = UMHEXIntegerPelBlockMotionSearch;
  92.      BiPredME       = UMHEXBipredIntegerPelBlockMotionSearch;
  93.      SubPelBiPredME = SubPelBlockSearchBiPred;
  94.      SubPelME       = UMHEXSubPelBlockME;
  95.      break;
  96.    case UM_HEX_SIMPLE:
  97.      IntPelME       = smpUMHEXIntegerPelBlockMotionSearch;
  98.      BiPredME       = smpUMHEXBipredIntegerPelBlockMotionSearch;
  99.      SubPelBiPredME = SubPelBlockSearchBiPred;
  100.      SubPelME       = smpUMHEXSubPelBlockME;
  101.      break;
  102.    case FULL_SEARCH:
  103.      IntPelME       = FullPelBlockMotionSearch;
  104.      BiPredME       = FullPelBlockMotionBiPred;
  105.      SubPelBiPredME = SubPelBlockSearchBiPred;
  106.      SubPelME       = SubPelBlockMotionSearch;
  107.      break;
  108.    case FAST_FULL_SEARCH:
  109.    default:
  110.      IntPelME       = FastFullPelBlockMotionSearch;
  111.      BiPredME       = FullPelBlockMotionBiPred;
  112.      SubPelBiPredME = SubPelBlockSearchBiPred;
  113.      SubPelME       = SubPelBlockMotionSearch;
  114.      break;
  115.   }
  116. }
  117. /*!
  118.  ************************************************************************
  119.  * brief
  120.  *    Prepare Motion Estimation parameters for single list ME
  121.  ************************************************************************
  122.  */
  123. void PrepareMEParams(int apply_weights, int ChromaMEEnable, int list, int ref)
  124. {
  125.   if (apply_weights)
  126.   {
  127.     weight_luma = wp_weight[list][ref][0];
  128.     offset_luma = wp_offset[list][ref][0];
  129.     if ( ChromaMEEnable)
  130.     {
  131.       weight_cr[0] = wp_weight[list][ref][1];
  132.       weight_cr[1] = wp_weight[list][ref][2];
  133.       offset_cr[0] = wp_offset[list][ref][1];
  134.       offset_cr[1] = wp_offset[list][ref][2];
  135.     }
  136.   }
  137. }
  138. /*!
  139.  ************************************************************************
  140.  * brief
  141.  *    Prepare Motion Estimation parameters for bipred list ME
  142.  ************************************************************************
  143.  */
  144. void PrepareBiPredMEParams(int apply_weights, int ChromaMEEnable, int list, int list_offset, int ref)
  145. {
  146.   if (apply_weights)
  147.   {
  148.     if (list == LIST_0)
  149.     {
  150.       weight1  = wbp_weight[list_offset         ][ref][0][0];
  151.       weight2  = wbp_weight[list_offset + LIST_1][ref][0][0];
  152.       offsetBi = (wp_offset[list_offset         ][ref][0] + wp_offset[list_offset + LIST_1][ref][0] + 1)>>1;
  153.       if ( ChromaMEEnable)
  154.       {
  155.         weight1_cr[0] = wbp_weight[list_offset         ][ref][0][1];
  156.         weight1_cr[1] = wbp_weight[list_offset         ][ref][0][2];
  157.         weight2_cr[0] = wbp_weight[list_offset + LIST_1][ref][0][1];
  158.         weight2_cr[1] = wbp_weight[list_offset + LIST_1][ref][0][2];
  159.    
  160.         offsetBi_cr[0] = (wp_offset[list_offset        ][ref][1] + wp_offset[list_offset + LIST_1][ref][1] + 1) >> 1;
  161.         offsetBi_cr[1] = (wp_offset[list_offset        ][ref][2] + wp_offset[list_offset + LIST_1][ref][2] + 1) >> 1;
  162.       }
  163.     }
  164.     else
  165.     {
  166.       weight1  = wbp_weight[list_offset + LIST_1][0  ][ref][0];
  167.       weight2  = wbp_weight[list_offset         ][0  ][ref][0];
  168.       offsetBi = (wp_offset[list_offset + LIST_1][0][0] + wp_offset[list_offset][0][0] + 1)>>1;
  169.       if ( ChromaMEEnable)
  170.       {
  171.         weight1_cr[0] = wbp_weight[list_offset + LIST_1][0  ][ref][1];
  172.         weight1_cr[1] = wbp_weight[list_offset + LIST_1][0  ][ref][2];
  173.         weight2_cr[0] = wbp_weight[list_offset         ][0  ][ref][1];
  174.         weight2_cr[1] = wbp_weight[list_offset         ][0  ][ref][2];
  175.         offsetBi_cr[0] = (wp_offset[list_offset + LIST_1][0  ][1] + wp_offset[list_offset         ][0  ][1] + 1) >> 1;
  176.         offsetBi_cr[1] = (wp_offset[list_offset + LIST_1][0  ][2] + wp_offset[list_offset         ][0  ][2] + 1) >> 1;
  177.       }
  178.     }
  179.   }
  180.   else
  181.   {
  182.     weight1 = 1<<luma_log_weight_denom;
  183.     weight2 = 1<<luma_log_weight_denom;
  184.     offsetBi = 0;
  185.     if ( ChromaMEEnable)
  186.     {
  187.       weight1_cr[0] = 1<<chroma_log_weight_denom;
  188.       weight1_cr[1] = 1<<chroma_log_weight_denom;
  189.       weight2_cr[0] = 1<<chroma_log_weight_denom;
  190.       weight2_cr[1] = 1<<chroma_log_weight_denom;
  191.       offsetBi_cr[0] = 0;
  192.       offsetBi_cr[1] = 0;
  193.     }
  194.   }
  195. }
  196. /*!
  197.  ************************************************************************
  198.  * brief
  199.  *    Set motion vector predictor
  200.  ************************************************************************
  201.  */
  202. void SetMotionVectorPredictor (Macroblock *currMB, 
  203.                                short  pmv[2],
  204.                                char   **refPic,
  205.                                short  ***tmp_mv,
  206.                                short  ref_frame,
  207.                                int    list,
  208.                                int    mb_x,
  209.                                int    mb_y,
  210.                                int    blockshape_x,
  211.                                int    blockshape_y)
  212. {
  213.   int mv_a, mv_b, mv_c, pred_vec=0;
  214.   int mvPredType, rFrameL, rFrameU, rFrameUR;
  215.   int hv;
  216.   PixelPos block_a, block_b, block_c, block_d;
  217.   int *mb_size = img->mb_size[IS_LUMA];
  218.   get4x4Neighbour(currMB, mb_x - 1,            mb_y    , mb_size, &block_a);
  219.   get4x4Neighbour(currMB, mb_x,                mb_y - 1, mb_size, &block_b);
  220.   get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, &block_c);
  221.   get4x4Neighbour(currMB, mb_x - 1,            mb_y - 1, mb_size, &block_d);
  222.   if (mb_y > 0)
  223.   {
  224.     if (mb_x < 8)  // first column of 8x8 blocks
  225.     {
  226.       if (mb_y == 8 )
  227.       {
  228.         if (blockshape_x == 16)      block_c.available  = 0;
  229.       }
  230.       else if (mb_x+blockshape_x == 8)
  231.       {
  232.           block_c.available = 0;
  233.       }
  234.     }
  235.     else if (mb_x+blockshape_x == 16)
  236.     {
  237.       block_c.available = 0;
  238.     }
  239.   }
  240.   if (!block_c.available)
  241.   {
  242.     block_c = block_d;
  243.   }
  244.   mvPredType = MVPRED_MEDIAN;
  245.   if (!img->MbaffFrameFlag)
  246.   {
  247.     rFrameL    = block_a.available ? refPic[block_a.pos_y][block_a.pos_x] : -1;
  248.     rFrameU    = block_b.available ? refPic[block_b.pos_y][block_b.pos_x] : -1;
  249.     rFrameUR   = block_c.available ? refPic[block_c.pos_y][block_c.pos_x] : -1;
  250.   }
  251.   else
  252.   {
  253.     if (currMB->mb_field)
  254.     {
  255.       rFrameL  = block_a.available
  256.         ? (img->mb_data[block_a.mb_addr].mb_field
  257.         ? refPic[block_a.pos_y][block_a.pos_x]
  258.         : refPic[block_a.pos_y][block_a.pos_x] * 2) : -1;
  259.       rFrameU  = block_b.available
  260.         ? (img->mb_data[block_b.mb_addr].mb_field
  261.         ? refPic[block_b.pos_y][block_b.pos_x]
  262.         : refPic[block_b.pos_y][block_b.pos_x] * 2) : -1;
  263.       rFrameUR = block_c.available
  264.         ? (img->mb_data[block_c.mb_addr].mb_field
  265.         ? refPic[block_c.pos_y][block_c.pos_x]
  266.         : refPic[block_c.pos_y][block_c.pos_x] * 2) : -1;
  267.     }
  268.     else
  269.     {
  270.       rFrameL = block_a.available
  271.         ? (img->mb_data[block_a.mb_addr].mb_field
  272.         ? refPic[block_a.pos_y][block_a.pos_x] >>1
  273.         : refPic[block_a.pos_y][block_a.pos_x]) : -1;
  274.       rFrameU  = block_b.available
  275.         ? (img->mb_data[block_b.mb_addr].mb_field
  276.         ? refPic[block_b.pos_y][block_b.pos_x] >>1
  277.         : refPic[block_b.pos_y][block_b.pos_x]) : -1;
  278.       rFrameUR = block_c.available
  279.         ? (img->mb_data[block_c.mb_addr].mb_field
  280.         ? refPic[block_c.pos_y][block_c.pos_x] >>1
  281.         : refPic[block_c.pos_y][block_c.pos_x]) : -1;
  282.     }
  283.   }
  284.   /* Prediction if only one of the neighbors uses the reference frame
  285.   *  we are checking
  286.   */
  287.   if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)       
  288.     mvPredType = MVPRED_L;
  289.   else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)  
  290.     mvPredType = MVPRED_U;
  291.   else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)  
  292.     mvPredType = MVPRED_UR;
  293.   // Directional predictions
  294.   if(blockshape_x == 8 && blockshape_y == 16)
  295.   {
  296.     if(mb_x == 0)
  297.     {
  298.       if(rFrameL == ref_frame)
  299.         mvPredType = MVPRED_L;
  300.     }
  301.     else
  302.     {
  303.       if( rFrameUR == ref_frame)
  304.         mvPredType = MVPRED_UR;
  305.     }
  306.   }
  307.   else if(blockshape_x == 16 && blockshape_y == 8)
  308.   {
  309.     if(mb_y == 0)
  310.     {
  311.       if(rFrameU == ref_frame)
  312.         mvPredType = MVPRED_U;
  313.     }
  314.     else
  315.     {
  316.       if(rFrameL == ref_frame)
  317.         mvPredType = MVPRED_L;
  318.     }
  319.   }
  320.   for (hv=0; hv < 2; hv++)
  321.   {
  322.     if (!img->MbaffFrameFlag || hv==0)
  323.     {
  324.       mv_a = block_a.available ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] : 0;
  325.       mv_b = block_b.available ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] : 0;
  326.       mv_c = block_c.available ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] : 0;
  327.     }
  328.     else
  329.     {
  330.       if (currMB->mb_field)
  331.       {
  332.         mv_a = block_a.available  ? img->mb_data[block_a.mb_addr].mb_field
  333.           ? tmp_mv[block_a.pos_y][block_a.pos_x][hv]
  334.           : tmp_mv[block_a.pos_y][block_a.pos_x][hv] / 2
  335.           : 0;
  336.         mv_b = block_b.available  ? img->mb_data[block_b.mb_addr].mb_field
  337.           ? tmp_mv[block_b.pos_y][block_b.pos_x][hv]
  338.           : tmp_mv[block_b.pos_y][block_b.pos_x][hv] / 2
  339.           : 0;
  340.         mv_c = block_c.available  ? img->mb_data[block_c.mb_addr].mb_field
  341.           ? tmp_mv[block_c.pos_y][block_c.pos_x][hv]
  342.           : tmp_mv[block_c.pos_y][block_c.pos_x][hv] / 2
  343.           : 0;
  344.       }
  345.       else
  346.       {
  347.         mv_a = block_a.available  ? img->mb_data[block_a.mb_addr].mb_field
  348.           ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] * 2
  349.           : tmp_mv[block_a.pos_y][block_a.pos_x][hv]
  350.           : 0;
  351.         mv_b = block_b.available  ? img->mb_data[block_b.mb_addr].mb_field
  352.           ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] * 2
  353.           : tmp_mv[block_b.pos_y][block_b.pos_x][hv]
  354.           : 0;
  355.         mv_c = block_c.available  ? img->mb_data[block_c.mb_addr].mb_field
  356.           ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] * 2
  357.           : tmp_mv[block_c.pos_y][block_c.pos_x][hv]
  358.           : 0;
  359.       }
  360.     }
  361.     switch (mvPredType)
  362.     {
  363.     case MVPRED_MEDIAN:
  364.       if(!(block_b.available || block_c.available))
  365.       {
  366.         pred_vec = mv_a;
  367.       }
  368.       else
  369.       {
  370.         pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
  371.       }
  372.       break;
  373.     case MVPRED_L:
  374.       pred_vec = mv_a;
  375.       break;
  376.     case MVPRED_U:
  377.       pred_vec = mv_b;
  378.       break;
  379.     case MVPRED_UR:
  380.       pred_vec = mv_c;
  381.       break;
  382.     default:
  383.       break;
  384.     }
  385.     pmv[hv] = pred_vec;
  386.   }
  387. }
  388. /*!
  389. ************************************************************************
  390. * brief
  391. *    Initialize the motion search
  392. ************************************************************************
  393. */
  394. void Init_Motion_Search_Module (void)
  395. {
  396.   int bits, i_min, i_max, k;
  397.   int i, l;
  398.   int search_range               = params->search_range;
  399.   int max_search_points          = imax(9, (2*search_range+1)*(2*search_range+1));
  400.   int max_ref_bits               = 1 + 2 * (int)floor(log(imax(16, img->max_num_references + 1)) / log(2) + 1e-10);
  401.   int max_ref                    = (1<<((max_ref_bits>>1)+1))-1;
  402.   int number_of_subpel_positions = 4 * (2*search_range+3);
  403.   int max_mv_bits                = 3 + 2 * (int)ceil (log(number_of_subpel_positions+1) / log(2) + 1e-10);
  404.   max_mvd                        = (1<<( max_mv_bits >>1)   )-1;
  405.   byte_abs_range                 = (imax(img->max_imgpel_value_comp[0],img->max_imgpel_value_comp[1]) + 1) * 64;
  406.   //=====   CREATE ARRAYS   =====
  407.   //-----------------------------
  408.   if ((spiral_search_x = (short*)calloc(max_search_points, sizeof(short))) == NULL)
  409.     no_mem_exit("Init_Motion_Search_Module: spiral_search_x");
  410.   if ((spiral_search_y = (short*)calloc(max_search_points, sizeof(short))) == NULL)
  411.     no_mem_exit("Init_Motion_Search_Module: spiral_search_y");
  412.   if ((spiral_hpel_search_x = (short*)calloc(max_search_points, sizeof(short))) == NULL)
  413.     no_mem_exit("Init_Motion_Search_Module: spiral_hpel_search_x");
  414.   if ((spiral_hpel_search_y = (short*)calloc(max_search_points, sizeof(short))) == NULL)
  415.     no_mem_exit("Init_Motion_Search_Module: spiral_hpel_search_y");
  416.   if ((mvbits = (int*)calloc(2 * max_mvd + 1, sizeof(int))) == NULL)
  417.     no_mem_exit("Init_Motion_Search_Module: mvbits");
  418.   if ((refbits = (int*)calloc(max_ref, sizeof(int))) == NULL)
  419.     no_mem_exit("Init_Motion_Search_Module: refbits");
  420.   if ((byte_abs = (int*)calloc(byte_abs_range, sizeof(int))) == NULL)
  421.     no_mem_exit("Init_Motion_Search_Module: byte_abs");
  422.   if (img->max_num_references)
  423.     get_mem4Dint (&motion_cost, 8, 2, img->max_num_references, 4);
  424.   //--- set array offsets ---
  425.   mvbits   += max_mvd;
  426.   byte_abs += byte_abs_range/2;
  427.   //=====   INIT ARRAYS   =====
  428.   //---------------------------
  429.   //--- init array: motion vector bits ---
  430.   mvbits[0] = 1;
  431.   for (bits=3; bits<=max_mv_bits; bits+=2)
  432.   {
  433.     i_max = 1    << (bits >> 1);
  434.     i_min = i_max >> 1;
  435.     for (i = i_min; i < i_max; i++)
  436.       mvbits[-i] = mvbits[i] = bits;
  437.   }
  438.   //--- init array: reference frame bits ---
  439.   refbits[0] = 1;
  440.   for (bits=3; bits<=max_ref_bits; bits+=2)
  441.   {
  442.     i_max = (1   << ((bits >> 1) + 1)) - 1;
  443.     i_min = i_max >> 1;
  444.     for (i = i_min; i < i_max; i++)
  445.       refbits[i] = bits;
  446.   }
  447.   //--- init array: absolute value ---
  448.   byte_abs[0] = 0;
  449.   // Set scaler for integer/subpel motion refinement.
  450.   // Currently only EPZS supports subpel positions
  451.   for (i=1; i<byte_abs_range/2; i++)
  452.   {
  453.     byte_abs[i] = byte_abs[-i] = i;
  454.   }
  455.   //--- init array: search pattern ---
  456.   spiral_search_x[0] = spiral_search_y[0] = 0;
  457.   spiral_hpel_search_x[0] = spiral_hpel_search_y[0] = 0;
  458.   for (k=1, l=1; l <= imax(1,search_range); l++)
  459.   {
  460.     for (i=-l+1; i< l; i++)
  461.     {
  462.       spiral_search_x[k] =  i;
  463.       spiral_search_y[k] = -l;
  464.       spiral_hpel_search_x[k] =  i<<1;
  465.       spiral_hpel_search_y[k++] = -l<<1;
  466.       spiral_search_x[k] =  i;
  467.       spiral_search_y[k] =  l;
  468.       spiral_hpel_search_x[k] =  i<<1;
  469.       spiral_hpel_search_y[k++] =  l<<1;
  470.     }
  471.     for (i=-l;   i<=l; i++)
  472.     {
  473.       spiral_search_x[k] = -l;
  474.       spiral_search_y[k] =  i;
  475.       spiral_hpel_search_x[k] = -l<<1;
  476.       spiral_hpel_search_y[k++] = i<<1;
  477.       spiral_search_x[k] =  l;
  478.       spiral_search_y[k] =  i;
  479.       spiral_hpel_search_x[k] =  l<<1;
  480.       spiral_hpel_search_y[k++] = i<<1;
  481.     }
  482.   }
  483.   // set global variable prior to ME
  484.   start_me_refinement_hp = (params->ChromaMEEnable == 1 || params->MEErrorMetric[F_PEL] != params->MEErrorMetric[H_PEL] ) ? 0 : 1;
  485.   start_me_refinement_qp = (params->ChromaMEEnable == 1 || params->MEErrorMetric[H_PEL] != params->MEErrorMetric[Q_PEL] ) ? 0 : 1;
  486.   // Setup Distortion Metrics depending on refinement level
  487.   for (i=0; i<3; i++)
  488.   {
  489.     switch(params->MEErrorMetric[i])
  490.     {
  491.     case ERROR_SAD:
  492.       computeUniPred[i] = computeSAD;
  493.       computeUniPred[i + 3] = computeSADWP;
  494.       computeBiPred1[i] = computeBiPredSAD1;
  495.       computeBiPred2[i] = computeBiPredSAD2;
  496.       break;
  497.     case ERROR_SSE:
  498.       computeUniPred[i] = computeSSE;
  499.       computeUniPred[i + 3] = computeSSEWP;
  500.       computeBiPred1[i] = computeBiPredSSE1;
  501.       computeBiPred2[i] = computeBiPredSSE2;
  502.       break;
  503.     case ERROR_SATD :
  504.     default:
  505.       computeUniPred[i] = computeSATD;
  506.       computeUniPred[i + 3] = computeSATDWP;
  507.       computeBiPred1[i] = computeBiPredSATD1;
  508.       computeBiPred2[i] = computeBiPredSATD2;
  509.       break;
  510.     }
  511.   }
  512.   // Setup buffer access methods
  513.   get_line[0] = FastLine4X;
  514.   get_line[1] = UMVLine4X;
  515.   get_crline[0] = FastLine8X_chroma;
  516.   get_crline[1] = UMVLine8X_chroma;
  517.   if (!params->IntraProfile)
  518.   {
  519.     if(params->SearchMode == FAST_FULL_SEARCH)
  520.       InitializeFastFullIntegerSearch ();
  521.     init_ME_engine(params->SearchMode);
  522.     if (params->SearchMode == UM_HEX)
  523.       UMHEX_DefineThreshold();
  524.   }
  525. }
  526. /*!
  527.  ************************************************************************
  528.  * brief
  529.  *    Free memory used by motion search
  530.  ************************************************************************
  531.  */
  532. void
  533. Clear_Motion_Search_Module ()
  534. {
  535.   //--- correct array offset ---
  536.   mvbits   -= max_mvd;
  537.   byte_abs -= byte_abs_range/2;
  538.   //--- delete arrays ---
  539.   free (spiral_search_x);
  540.   free (spiral_search_y);
  541.   free (spiral_hpel_search_x);
  542.   free (spiral_hpel_search_y);
  543.   free (mvbits);
  544.   free (refbits);
  545.   free (byte_abs);
  546.   if (motion_cost)
  547.     free_mem4Dint (motion_cost);
  548.   if ((params->SearchMode == FAST_FULL_SEARCH) && (!params->IntraProfile) )
  549.     ClearFastFullIntegerSearch ();
  550. }
  551. static inline int mv_bits_cost(short ***all_mv, short ***p_mv, int by, int bx, int step_v0, int step_v, int step_h0, int step_h, int mvd_bits)
  552. {
  553.   int v, h;
  554.   for (v=by; v<by + step_v0; v+=step_v)
  555.   {
  556.     for (h=bx; h<bx + step_h0; h+=step_h)
  557.     {
  558.       mvd_bits += mvbits[ all_mv[v][h][0] - p_mv[v][h][0] ];
  559.       mvd_bits += mvbits[ all_mv[v][h][1] - p_mv[v][h][1] ];
  560.     }
  561.   }
  562.   return mvd_bits;
  563. }
  564. /*!
  565.  ***********************************************************************
  566.  * brief
  567.  *    Motion Cost for Bidirectional modes
  568.  ***********************************************************************
  569.  */
  570. int BPredPartitionCost (Macroblock *currMB,
  571.                         int   blocktype,
  572.                         int   block8x8,
  573.                         short ref_l0,
  574.                         short ref_l1,
  575.                         int   lambda_factor,
  576.                         int   list)
  577. {
  578.   static int  bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
  579.   static int  by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
  580.   int   curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; // ABT pred.error buffer
  581.   int   bsx       = imin(params->blc_size[blocktype][0], 8);
  582.   int   bsy       = imin(params->blc_size[blocktype][1], 8);
  583.   int   pic_pix_x, pic_pix_y, block_x, block_y;
  584.   int   v, h, mcost, i, j, k;
  585.   int   mvd_bits  = 0;
  586.   int   parttype  = (blocktype < 4 ? blocktype : 4);
  587.   int   step_h0   = (params->part_size[ parttype][0]);
  588.   int   step_v0   = (params->part_size[ parttype][1]);
  589.   int   step_h    = (params->part_size[blocktype][0]);
  590.   int   step_v    = (params->part_size[blocktype][1]);
  591.   int   bxx, byy;                               // indexing curr_blk
  592.   int   by0_part = by0[parttype][block8x8];
  593.   int   bx0_part = bx0[parttype][block8x8];
  594.   short   ***all_mv_l0 = img->bipred_mv[list][LIST_0][ref_l0][blocktype]; 
  595.   short   ***all_mv_l1 = img->bipred_mv[list][LIST_1][ref_l1][blocktype]; 
  596.   short   ***p_mv_l0   = img->pred_mv[LIST_0][ref_l0][blocktype];
  597.   short   ***p_mv_l1   = img->pred_mv[LIST_1][ref_l1][blocktype];
  598.   imgpel  (*mb_pred)[16] = img->mb_pred[0];
  599.   // List0 
  600.   mvd_bits = mv_bits_cost(all_mv_l0, p_mv_l0, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits);
  601.   // List1
  602.   mvd_bits = mv_bits_cost(all_mv_l1, p_mv_l1, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits);
  603.   mcost = WEIGHTED_COST (lambda_factor, mvd_bits);
  604.   //----- cost of residual signal -----
  605.   for (byy=0, v=by0_part; v < by0_part + step_v0; byy += 4, v++)
  606.   {
  607.     pic_pix_y = img->opix_y + (block_y = (v<<2));
  608.     for (bxx=0, h = bx0_part; h < bx0_part + step_h0; bxx += 4, h++)
  609.     {
  610.       pic_pix_x = img->opix_x + (block_x = (h<<2));
  611.       LumaPredictionBi (currMB, block_x, block_y, 4, 4, blocktype, blocktype, ref_l0, ref_l1, list);
  612.       for (k = j = 0; j < 4; j++)
  613.       {
  614.         for (i = 0; i < 4; i++)
  615.           diff64[k++] = curr_blk[byy+j][bxx+i] =
  616.           pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
  617.       }
  618.       if ((!params->Transform8x8Mode) || (blocktype>4))
  619.       {
  620.         mcost += distortion4x4 (diff64);
  621.       }
  622.     }
  623.   }
  624.   if (params->Transform8x8Mode && (blocktype<=4))  // tchen 4-29-04
  625.   {
  626.     for (byy=0; byy < params->blc_size[parttype][1]; byy += bsy)
  627.       for (bxx=0; bxx < params->blc_size[parttype][0]; bxx += bsx)
  628.       {
  629.         for (k=0, j = byy; j < byy + 8; j++, k += 8)
  630.           memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));
  631.         mcost += distortion8x8(diff64);
  632.       }
  633.   }
  634.   return mcost;
  635. }
  636. /*!
  637.  ***********************************************************************
  638.  * brief
  639.  *    Block motion search
  640.  ***********************************************************************
  641.  */
  642. int                                         //!< minimum motion cost after search
  643. BlockMotionSearch (Macroblock *currMB,      //!< Current Macroblock
  644.                    short     ref,           //!< reference idx
  645.                    int       list,          //!< reference picture list
  646.                    int       mb_x,          //!< x-coordinate inside macroblock
  647.                    int       mb_y,          //!< y-coordinate inside macroblock
  648.                    int       blocktype,     //!< block type (1-16x16 ... 7-4x4)
  649.                    int       search_range,  //!< 1-d search range for integer-position search
  650.                    int*      lambda_factor) //!< lagrangian parameter for determining motion cost
  651. {
  652.   // each 48-pel line stores the 16 luma pels (at 0) followed by 8 or 16 crcb[0] (at 16) and crcb[1] (at 32) pels
  653.   // depending on the type of chroma subsampling used: YUV 4:4:4, 4:2:2, and 4:2:0
  654.   imgpel *orig_pic_tmp = orig_pic;
  655.   int   apply_bi_weights = params->UseWeightedReferenceME && ((img->type == B_SLICE) && active_pps->weighted_bipred_idc != 0);
  656.   int   apply_weights    = params->UseWeightedReferenceME &&
  657.                            ((active_pps->weighted_pred_flag  && (img->type == P_SLICE || img->type == SP_SLICE)) || apply_bi_weights);
  658.   short     mv[2];
  659.   int       i, j;
  660.   int       max_value = INT_MAX;
  661.   int       min_mcost = max_value;
  662.   int       block_x   = (mb_x>>2);
  663.   int       block_y   = (mb_y>>2);
  664.   int       bsx       = params->blc_size[blocktype][0];
  665.   int       bsy       = params->blc_size[blocktype][1];
  666.   int       pic_pix_x = img->opix_x + mb_x;
  667.   int       pic_pix_y = img->opix_y + mb_y;
  668.   int pic_pix_x_c = pic_pix_x >> (shift_cr_x);
  669.   int pic_pix_y_c = pic_pix_y >> (shift_cr_y);
  670.   int bsx_c = bsx >> (shift_cr_x);
  671.   int bsy_c = bsy >> (shift_cr_y);
  672.   short*    pred_mv = img->pred_mv[list][ref][blocktype][block_y][block_x];
  673.   short***   all_mv = &img->all_mv[list][ref][blocktype][block_y];
  674.   int list_offset = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? img->current_mb_nr % 2 ? 4 : 2 : 0;
  675.   int *prevSad = (params->SearchMode == EPZS)? EPZSDistortion[list + list_offset][blocktype - 1]: NULL;
  676. #if GET_METIME
  677.   static TIME_T me_time_start;
  678.   static TIME_T me_time_end;
  679.   time_t me_tmp_time;
  680.   gettime( &me_time_start );    // start time ms
  681. #endif
  682.   PrepareMEParams(apply_weights, params->ChromaMEEnable, list + list_offset, ref);
  683.   //==================================
  684.   //=====   GET ORIGINAL BLOCK   =====
  685.   //==================================
  686.   for (j = pic_pix_y; j < pic_pix_y + bsy; j++)
  687.   {
  688.     memcpy(orig_pic_tmp,&pCurImg[j][pic_pix_x], bsx *sizeof(imgpel));
  689.     orig_pic_tmp += bsx;
  690.   }
  691.   ChromaMEEnable = params->ChromaMEEnable;
  692.   if ( ChromaMEEnable )
  693.   {
  694.     // copy the original cmp1 and cmp2 data to the orig_pic matrix
  695.     for ( i = 1; i<=2; i++)
  696.     {
  697.       orig_pic_tmp = orig_pic + (256 << (i - 1));
  698.       for (j = pic_pix_y_c; j < pic_pix_y_c + bsy_c; j++)
  699.       {
  700.         memcpy(orig_pic_tmp, &(pImgOrg[i][j][pic_pix_x_c]), bsx_c * sizeof(imgpel));
  701.         orig_pic_tmp += bsx_c;
  702.       }
  703.     }
  704.   }
  705.   if (params->SearchMode == UM_HEX)
  706.   {
  707.     UMHEX_blocktype = blocktype;
  708.     bipred_flag = 0;
  709.   }
  710.   else if (params->SearchMode == UM_HEX_SIMPLE)
  711.   {
  712.     smpUMHEX_setup(ref, list, block_y, block_x, blocktype, img->all_mv );
  713.   }
  714.   // Set if 8x8 transform will be used if SATD is used
  715.   test8x8transform = params->Transform8x8Mode && blocktype <= 4;
  716.   //===========================================
  717.   //=====   GET MOTION VECTOR PREDICTOR   =====
  718.   //===========================================
  719.   if (params->SearchMode == UM_HEX)
  720.     UMHEXSetMotionVectorPredictor(currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, mb_x, mb_y, bsx, bsy, &search_range);
  721.   else
  722.     SetMotionVectorPredictor (currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, mb_x, mb_y, bsx, bsy);
  723.   //==================================
  724.   //=====   INTEGER-PEL SEARCH   =====
  725.   //==================================
  726.   if (params->EPZSSubPelGrid)
  727.   {
  728.     mv[0] = pred_mv[0];
  729.     mv[1] = pred_mv[1];
  730.   }
  731.   else
  732.   {
  733.     mv[0] = (pred_mv[0] + 2)>> 2;
  734.     mv[1] = (pred_mv[1] + 2)>> 2;
  735.   }
  736.   if (!params->rdopt)
  737.   {
  738.     //--- adjust search center so that the (0,0)-vector is inside ---
  739.     mv[0] = iClip3 (-search_range<<(params->EPZSGrid), search_range<<(params->EPZSGrid), mv[0]);
  740.     mv[1] = iClip3 (-search_range<<(params->EPZSGrid), search_range<<(params->EPZSGrid), mv[1]);
  741.   }
  742.   // valid search range limits could be precomputed once during the initialization process
  743.   clip_mv_range(img, search_range, mv, params->EPZSGrid);
  744.   //--- perform motion search ---
  745.     min_mcost = IntPelME (currMB, orig_pic, ref, list, list_offset,
  746.     enc_picture->motion.ref_idx, enc_picture->motion.mv, pic_pix_x, pic_pix_y, blocktype,
  747.     pred_mv, mv, search_range<<(params->EPZSGrid), min_mcost, lambda_factor[F_PEL], apply_weights);
  748.   //===== convert search center to quarter-pel units =====
  749.   if (params->EPZSSubPelGrid == 0 || params->SearchMode != EPZS)
  750.   {
  751.     mv[0] <<= 2;
  752.     mv[1] <<= 2;
  753.   }
  754.   //==============================
  755.   //=====   SUB-PEL SEARCH   =====
  756.   //============================== 
  757.   ChromaMEEnable = (params->ChromaMEEnable == ME_YUV_FP_SP ) ? 1 : 0; // set it externally
  758.   if (!params->DisableSubpelME)
  759.   {
  760.     if (params->SearchMode != EPZS || (ref == 0 || img->structure != FRAME || (ref > 0 && min_mcost < 3.5 * prevSad[pic_pix_x >> 2])))
  761.     {
  762.       if ( !start_me_refinement_hp )
  763.       {
  764.         min_mcost = max_value;
  765.       }
  766.       min_mcost =  SubPelME (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y, blocktype,
  767.         pred_mv, mv, 9, 9, min_mcost, lambda_factor, apply_weights);
  768.     }
  769.   }
  770.   if (!params->rdopt)
  771.   {
  772.     // Get the skip mode cost
  773.     if (blocktype == 1 && (img->type == P_SLICE||img->type == SP_SLICE))
  774.     {
  775.       int cost;
  776.       FindSkipModeMotionVector (currMB);
  777.       cost  = GetSkipCostMB (currMB);
  778.       cost -= ((lambda_factor[Q_PEL] + 4096) >> 13);
  779.       if (cost < min_mcost)
  780.       {
  781.         min_mcost = cost;
  782.         mv[0]      = img->all_mv [0][0][0][0][0][0];
  783.         mv[1]      = img->all_mv [0][0][0][0][0][1];
  784.       }
  785.     } 
  786.   }
  787.   //===============================================
  788.   //=====   SET MV'S AND RETURN MOTION COST   =====
  789.   //===============================================
  790.   // Set first line
  791.   for (i=block_x; i < block_x + (bsx>>2); i++)
  792.   {
  793.     all_mv[0][i][0] = mv[0];
  794.     all_mv[0][i][1] = mv[1];
  795.   }
  796.   // set all other lines
  797.   for (j=1; j < (bsy>>2); j++)
  798.   {
  799.     memcpy(all_mv[j][block_x], all_mv[0][block_x], (bsx>>2) * 2 * sizeof(short));
  800.   }
  801.   // Bipred ME consideration: returns minimum bipred cost
  802.   if (img->type == B_SLICE && is_bipred_enabled(blocktype) && (ref == 0)) 
  803.   {
  804.     BiPredBlockMotionSearch(currMB, mv, pred_mv, ref, list, mb_x, mb_y, blocktype, search_range, apply_bi_weights, lambda_factor);
  805.   }
  806. #if GET_METIME
  807.   gettime(&me_time_end);   // end time ms
  808.   me_tmp_time = timediff (&me_time_start, &me_time_end);
  809.   me_tot_time += me_tmp_time;
  810.   me_time += me_tmp_time;
  811. #endif
  812.   return min_mcost;
  813. }
  814. /*!
  815.  ***********************************************************************
  816.  * brief
  817.  *    Block bi-prediction motion search
  818.  ***********************************************************************
  819.  */
  820. int BiPredBlockMotionSearch(Macroblock *currMB,      //!< Current Macroblock
  821.                    short     mv[2],           //!< current list motion vector
  822.                    short*    pred_mv,         //!< current list motion vector predictor
  823.                    short     ref,             //!< reference idx
  824.                    int       list,            //!< reference picture list
  825.                    int       mb_x,            //!< x-coordinate inside macroblock
  826.                    int       mb_y,            //!< y-coordinate inside macroblock
  827.                    int       blocktype,       //!< block type (1-16x16 ... 7-4x4)
  828.                    int       search_range,    //!< 1-d search range for integer-position search
  829.                    int       apply_bi_weights, //!< apply bipred weights
  830.                    int*      lambda_factor)   //!< lagrangian parameter for determining motion cost
  831. {
  832.   int         iteration_no, i, j;
  833.   short       bipred_type = list ? 0 : 1;
  834.   short****** bipred_mv = img->bipred_mv[bipred_type];
  835.   int         min_mcostbi = INT_MAX;
  836.   short       bimv[2] = {0, 0}, tempmv[2] = {0, 0};
  837.   short*      pred_mv1 = NULL;
  838.   short*      pred_mv2 = NULL;
  839.   short*      bi_mv1 = NULL, *bi_mv2 = NULL;
  840.   short       iterlist=list;
  841.   short       pred_mv_bi[2];
  842.   int         block_x   = (mb_x>>2);
  843.   int         block_y   = (mb_y>>2);
  844.   int         bsx       = params->blc_size[blocktype][0];
  845.   int         bsy       = params->blc_size[blocktype][1];
  846.   int         pic_pix_x = img->opix_x + mb_x;
  847.   int         pic_pix_y = img->opix_y + mb_y;
  848.   int         list_offset = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? img->current_mb_nr % 2 ? 4 : 2 : 0;
  849.   if (params->SearchMode == UM_HEX)
  850.   {
  851.     bipred_flag = 1;
  852.     UMHEXSetMotionVectorPredictor(currMB, pred_mv_bi, enc_picture->motion.ref_idx[list ^ 1], enc_picture->motion.mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy, &search_range);
  853.   }
  854.   else
  855.     SetMotionVectorPredictor     (currMB, pred_mv_bi, enc_picture->motion.ref_idx[list ^ 1], enc_picture->motion.mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy);
  856.   if ((params->SearchMode != EPZS) || (params->EPZSSubPelGrid == 0))
  857.   {
  858.     mv[0] = (mv[0] + 2) >> 2;
  859.     mv[1] = (mv[1] + 2) >> 2;
  860.     bimv[0] = (pred_mv_bi[0] + 2)>>2;
  861.     bimv[1] = (pred_mv_bi[1] + 2)>>2;
  862.   }
  863.   else
  864.   {
  865.     bimv[0] = pred_mv_bi[0];
  866.     bimv[1] = pred_mv_bi[1];
  867.   }
  868.   //Bi-predictive motion Refinements
  869.   for (iteration_no = 0; iteration_no <= params->BiPredMERefinements; iteration_no++)
  870.   {
  871.     if (iteration_no & 0x01)
  872.     {
  873.       pred_mv1  = pred_mv;
  874.       pred_mv2  = pred_mv_bi;
  875.       bi_mv1    = mv;
  876.       bi_mv2    = bimv;
  877.       iterlist  = list;
  878.     }
  879.     else
  880.     {
  881.       pred_mv1  = pred_mv_bi;
  882.       pred_mv2  = pred_mv;
  883.       bi_mv1    = bimv;
  884.       bi_mv2    = mv;
  885.       iterlist = list ^ 1;
  886.     }
  887.     tempmv[0] = bi_mv1[0];
  888.     tempmv[1] = bi_mv1[1];
  889.     PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, list_offset, ref);
  890.     // Get bipred mvs for list iterlist given previously computed mvs from other list
  891.     min_mcostbi = BiPredME (currMB, orig_pic, ref, iterlist, list_offset, enc_picture->motion.ref_idx, enc_picture->motion.mv,
  892.       pic_pix_x, pic_pix_y, blocktype, pred_mv1, pred_mv2, bi_mv1, bi_mv2,
  893.       (params->BiPredMESearchRange <<(params->EPZSGrid))>>iteration_no, min_mcostbi, iteration_no, lambda_factor[F_PEL], apply_bi_weights);
  894.     if (iteration_no > 0 && (tempmv[0] == bi_mv1[0]) && (tempmv[1] == bi_mv1[1]))
  895.     {
  896.       break;
  897.     }
  898.   }
  899.   if ((params->SearchMode != EPZS) || (params->EPZSSubPelGrid == 0))
  900.   {
  901.     bi_mv2[0] = (bi_mv2[0] << 2);
  902.     bi_mv2[1] = (bi_mv2[1] << 2);
  903.     bi_mv1[0] = (bi_mv1[0] << 2);
  904.     bi_mv1[1] = (bi_mv1[1] << 2);
  905.   }
  906.   if (!params->DisableSubpelME)
  907.   {
  908.     if (params->BiPredMESubPel)
  909.     {
  910.       min_mcostbi = INT_MAX;
  911.       PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, list_offset, ref);
  912.       min_mcostbi =  SubPelBiPredME (orig_pic, ref, iterlist, pic_pix_x, pic_pix_y, blocktype,
  913.         pred_mv1, pred_mv2, bi_mv1, bi_mv2, 9, 9, min_mcostbi, lambda_factor, apply_bi_weights);
  914.     }
  915.     if (params->BiPredMESubPel==2)
  916.     {
  917.       min_mcostbi = INT_MAX;
  918.       PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist ^ 1, list_offset, ref);
  919.       min_mcostbi =  SubPelBiPredME (orig_pic, ref, iterlist ^ 1, pic_pix_x, pic_pix_y, blocktype,
  920.         pred_mv2, pred_mv1, bi_mv2, bi_mv1, 9, 9, min_mcostbi, lambda_factor, apply_bi_weights);
  921.     }
  922.   }
  923.   for (j=block_y; j < block_y + (bsy>>2); j++)
  924.   {
  925.     for (i=block_x ; i < block_x + (bsx>>2); i++)
  926.     {
  927.       bipred_mv[iterlist    ][ref][blocktype][j][i][0] = bi_mv1[0];
  928.       bipred_mv[iterlist    ][ref][blocktype][j][i][1] = bi_mv1[1];
  929.       bipred_mv[iterlist ^ 1][ref][blocktype][j][i][0] = bi_mv2[0];
  930.       bipred_mv[iterlist ^ 1][ref][blocktype][j][i][1] = bi_mv2[1];
  931.     }
  932.   }
  933.   return min_mcostbi;
  934. }
  935. /*!
  936.  ***********************************************************************
  937.  * brief
  938.  *    Motion Cost for Bidirectional modes
  939.  ***********************************************************************
  940.  */
  941. int BIDPartitionCost (Macroblock *currMB, 
  942.                       int   blocktype,
  943.                       int   block8x8,
  944.                       char  cur_ref[2],
  945.                       int   lambda_factor)
  946. {
  947.   static int  bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
  948.   static int  by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
  949.   int   curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; // ABT pred.error buffer
  950.   int   bsx       = imin(params->blc_size[blocktype][0],8);
  951.   int   bsy       = imin(params->blc_size[blocktype][1],8);
  952.   int   pic_pix_x, pic_pix_y, block_x, block_y;
  953.   int   v, h, mcost, i, j, k;
  954.   int   mvd_bits  = 0;
  955.   int   parttype  = (blocktype<4?blocktype:4);
  956.   int   step_h0   = (params->part_size[ parttype][0]);
  957.   int   step_v0   = (params->part_size[ parttype][1]);
  958.   int   step_h    = (params->part_size[blocktype][0]);
  959.   int   step_v    = (params->part_size[blocktype][1]);
  960.   int   bxx, byy;                               // indexing curr_blk
  961.   int   bx = bx0[parttype][block8x8];
  962.   int   by = by0[parttype][block8x8];
  963.   short   ***   p_mv_l0 = img->pred_mv[LIST_0][(int) cur_ref[LIST_0]][blocktype];
  964.   short   ***   p_mv_l1 = img->pred_mv[LIST_1][(int) cur_ref[LIST_1]][blocktype];
  965.   short   *** all_mv_l0 = img->all_mv [LIST_0][(int) cur_ref[LIST_0]][blocktype];
  966.   short   *** all_mv_l1 = img->all_mv [LIST_1][(int) cur_ref[LIST_1]][blocktype];
  967.   short bipred_me =  0; //no bipred for this case 
  968.   imgpel  (*mb_pred)[16] = img->mb_pred[0];
  969.   //----- cost for motion vector bits -----
  970.   // Should write a separate, small function to do this processing
  971.   // List0 
  972.   mvd_bits = mv_bits_cost(all_mv_l0, p_mv_l0, by, bx, step_v0, step_v, step_h0, step_h, mvd_bits);
  973.   // List1
  974.   mvd_bits = mv_bits_cost(all_mv_l1, p_mv_l1, by, bx, step_v0, step_v, step_h0, step_h, mvd_bits);
  975.   mcost = WEIGHTED_COST (lambda_factor, mvd_bits);
  976.   //----- cost of residual signal -----
  977.   for (byy=0, v=by; v<by + step_v0; byy+=4, v++)
  978.   {
  979.     pic_pix_y = img->opix_y + (block_y = (v<<2));
  980.     for (bxx=0, h=bx; h<bx + step_h0; bxx+=4, h++)
  981.     {
  982.       pic_pix_x = img->opix_x + (block_x = (h<<2));
  983.       LumaPrediction (currMB, block_x, block_y, 4, 4, 2, blocktype, blocktype, (short) cur_ref[0], (short) cur_ref[1], bipred_me);
  984.       for (k=j=0; j<4; j++)
  985.       {
  986.         for (  i=0; i<4; i++)
  987.           diff64[k++] = curr_blk[byy+j][bxx+i] =
  988.           pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
  989.       }
  990.       if ((!params->Transform8x8Mode) || (blocktype>4))
  991.         mcost += distortion4x4 (diff64);
  992.     }
  993.   }
  994.   if (params->Transform8x8Mode && (blocktype<=4))  // tchen 4-29-04
  995.   {
  996.     for (byy=0; byy < params->blc_size[parttype][1]; byy+=bsy)
  997.     {
  998.       for (bxx=0; bxx<params->blc_size[parttype][0]; bxx+=bsx)
  999.       {
  1000.         for (k=0, j=byy;j<byy + 8;j++, k += 8)
  1001.           memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));
  1002.         mcost += distortion8x8(diff64);
  1003.       }
  1004.     }
  1005.   }
  1006.   return mcost;
  1007. }
  1008. /*!
  1009.  ************************************************************************
  1010.  * brief
  1011.  *    Get cost for skip mode for an macroblock
  1012.  ************************************************************************
  1013.  */
  1014. int GetSkipCostMB (Macroblock *currMB)
  1015. {
  1016.   int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
  1017.   int cost = 0;
  1018.   int curr_diff[8][8];
  1019.   int mb_x, mb_y;
  1020.   int block;
  1021.   imgpel  (*mb_pred)[16] = img->mb_pred[0];
  1022.   for(block = 0;block < 4;block++)
  1023.   {
  1024.     mb_y    = (block >>   1)<<3;
  1025.     mb_x    = (block & 0x01)<<3;
  1026.     for (block_y = mb_y; block_y < mb_y+8; block_y += 4)
  1027.     {
  1028.       pic_pix_y = img->opix_y + block_y;
  1029.       for (block_x = mb_x; block_x < mb_x + 8; block_x += 4)
  1030.       {
  1031.         pic_pix_x = img->opix_x + block_x;
  1032.         //===== prediction of 4x4 block =====
  1033.         LumaPrediction (currMB, block_x, block_y, 4, 4, 0, 0, 0, 0, 0, 0);
  1034.         //===== get displaced frame difference ======
  1035.         for (k = j = 0; j < 4; j++)
  1036.         {
  1037.           for (i = 0; i < 4; i++, k++)
  1038.           {
  1039.             diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
  1040.           }
  1041.         }
  1042.         if(!((params->rdopt==0) && (params->Transform8x8Mode)))
  1043.           cost += distortion4x4 (diff);
  1044.       }
  1045.     }
  1046.     if((params->rdopt == 0) && (params->Transform8x8Mode))
  1047.     {
  1048.       for(k=j=0; j<8; j++, k+=8)
  1049.         memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));
  1050.       cost += distortion8x8 (diff64);
  1051.     }
  1052.   }
  1053.   return cost;
  1054. }
  1055. /*!
  1056.  ************************************************************************
  1057.  * brief
  1058.  *    Find motion vector for the Skip mode
  1059.  ************************************************************************
  1060.  */
  1061. void FindSkipModeMotionVector (Macroblock *currMB)
  1062. {
  1063.   int   bx, by;
  1064.   short ***all_mv = img->all_mv[0][0][0];
  1065.   short pmv[2];
  1066.   int zeroMotionAbove;
  1067.   int zeroMotionLeft;
  1068.   PixelPos mb_a, mb_b;
  1069.   int      a_mv_y = 0;
  1070.   int      a_ref_idx = 0;
  1071.   int      b_mv_y = 0;
  1072.   int      b_ref_idx = 0;
  1073.   short    ***mv = enc_picture->motion.mv[LIST_0];
  1074.   int *mb_size = img->mb_size[IS_LUMA];
  1075.   get4x4Neighbour(currMB,-1, 0, mb_size, &mb_a);
  1076.   get4x4Neighbour(currMB, 0,-1, mb_size, &mb_b);
  1077.   if (mb_a.available)
  1078.   {
  1079.     a_mv_y    = mv[mb_a.pos_y][mb_a.pos_x][1];
  1080.     a_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
  1081.     if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
  1082.     {
  1083.       a_mv_y    /=2;
  1084.       a_ref_idx *=2;
  1085.     }
  1086.     if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
  1087.     {
  1088.       a_mv_y    *= 2;
  1089.       a_ref_idx >>=1;
  1090.     }
  1091.   }
  1092.   if (mb_b.available)
  1093.   {
  1094.     b_mv_y    = mv[mb_b.pos_y][mb_b.pos_x][1];
  1095.     b_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
  1096.     if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
  1097.     {
  1098.       b_mv_y    /=2;
  1099.       b_ref_idx *=2;
  1100.     }
  1101.     if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
  1102.     {
  1103.       b_mv_y    *=2;
  1104.       b_ref_idx >>=1;
  1105.     }
  1106.   }
  1107.   zeroMotionLeft  = !mb_a.available ? 1 : a_ref_idx==0 && mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
  1108.   zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
  1109.   if (zeroMotionAbove || zeroMotionLeft)
  1110.   {
  1111.     memset(all_mv [0][0], 0, 4 * 4 * 2* sizeof(short));
  1112.   }
  1113.   else
  1114.   {
  1115.     SetMotionVectorPredictor (currMB, pmv, enc_picture->motion.ref_idx[LIST_0], mv, 0, LIST_0, 0, 0, 16, 16);
  1116.     for (bx = 0;bx < 4;bx++)
  1117.     {
  1118.       memcpy(all_mv [0][bx], pmv, 2* sizeof(short));
  1119.     }
  1120.     for (by = 1;by < 4;by++)
  1121.       memcpy(all_mv [by][0], all_mv [0][0], 4 * 2* sizeof(short));
  1122.   }
  1123. }
  1124. /*!
  1125.  ************************************************************************
  1126.  * brief
  1127.  *    Get cost for direct mode for an 8x8 block
  1128.  ************************************************************************
  1129.  */
  1130. int GetDirectCost8x8 (Macroblock *currMB, int block, int *cost8x8)
  1131. {
  1132.   int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
  1133.   int curr_diff[8][8];
  1134.   int cost  = 0;
  1135.   int mb_y  = (block/2)<<3;
  1136.   int mb_x  = (block%2)<<3;
  1137.   short bipred_me  = 0;
  1138.   imgpel  (*mb_pred)[16] = img->mb_pred[0];
  1139.   for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
  1140.   {
  1141.     pic_pix_y = img->opix_y + block_y;
  1142.     for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
  1143.     {
  1144.       pic_pix_x = img->opix_x + block_x;
  1145.       if (direct_pdir[pic_pix_y>>2][pic_pix_x>>2]<0)
  1146.       {
  1147.         *cost8x8=INT_MAX;
  1148.         return INT_MAX; //mode not allowed
  1149.       }
  1150.       //===== prediction of 4x4 block =====
  1151.       LumaPrediction (currMB, block_x, block_y, 4, 4,
  1152.         direct_pdir[pic_pix_y>>2][pic_pix_x>>2], 0, 0,
  1153.         direct_ref_idx[LIST_0][pic_pix_y>>2][pic_pix_x>>2],
  1154.         direct_ref_idx[LIST_1][pic_pix_y>>2][pic_pix_x>>2], bipred_me);
  1155.       //===== get displaced frame difference ======
  1156.       for (k=j=0; j<4; j++)
  1157.         for (i=0; i<4; i++, k++)
  1158.         {
  1159.           diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] =
  1160.             pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
  1161.         }
  1162.         cost += distortion4x4 (diff);
  1163.     }
  1164.   }
  1165.   if((params->rdopt == 0) && (params->Transform8x8Mode))
  1166.   {
  1167.     k=0;
  1168.     for(j=0; j<8; j++, k+=8)
  1169.       memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));          
  1170.     *cost8x8 += distortion8x8 (diff64);
  1171.   }
  1172.   return cost;
  1173. }
  1174. /*!
  1175.  ************************************************************************
  1176.  * brief
  1177.  *    Get cost for direct mode for an macroblock
  1178.  ************************************************************************
  1179.  */
  1180. int GetDirectCostMB (Macroblock *currMB, int bslice)
  1181. {
  1182.   int i;
  1183.   int cost = 0;
  1184.   int cost8x8 = 0;
  1185.   for (i=0; i<4; i++)
  1186.   {
  1187.     cost += GetDirectCost8x8 (currMB, i, &cost8x8);
  1188.     if (cost8x8 == INT_MAX) return INT_MAX;
  1189.   }
  1190.   switch(params->Transform8x8Mode)
  1191.   {
  1192.   case 1: // Mixture of 8x8 & 4x4 transform
  1193.     if((cost8x8 < cost)||
  1194.       !(params->InterSearch[bslice][5] &&
  1195.       params->InterSearch[bslice][6] &&
  1196.       params->InterSearch[bslice][7])
  1197.       )
  1198.     {
  1199.       cost = cost8x8; //return 8x8 cost
  1200.     }
  1201.     break;
  1202.   case 2: // 8x8 Transform only
  1203.     cost = cost8x8;
  1204.     break;
  1205.   default: // 4x4 Transform only
  1206.     break;
  1207.   }
  1208.   return cost;
  1209.   // T.Nishi(MEI ACC) 04-28-2004 end
  1210. }
  1211. /*!
  1212.  ************************************************************************
  1213.  * brief
  1214.  *    Motion search for a partition
  1215.  ************************************************************************
  1216.  */
  1217. void
  1218. PartitionMotionSearch (Macroblock *currMB,
  1219.                        int    blocktype,
  1220.                        int    block8x8,
  1221.                        int    *lambda_factor)
  1222. {
  1223.   static int  bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
  1224.   static int  by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
  1225.   char  **ref_array;
  1226.   short ***mv_array;
  1227.   short *all_mv;
  1228.   short ref;
  1229.   int   v, h, mcost, search_range, i, j;
  1230.   int   pic_block_x, pic_block_y;
  1231.   int   bslice    = (img->type==B_SLICE);
  1232.   int   parttype  = (blocktype < 4 ? blocktype : 4);
  1233.   int   step_h0   = (params->part_size[ parttype][0]);
  1234.   int   step_v0   = (params->part_size[ parttype][1]);
  1235.   int   step_h    = (params->part_size[blocktype][0]);
  1236.   int   step_v    = (params->part_size[blocktype][1]);
  1237.   int   list;
  1238.   int   numlists  = bslice ? 2 : 1;
  1239.   int   list_offset = currMB->list_offset;
  1240.   int   *m_cost;
  1241.   int   by = by0[parttype][block8x8];
  1242.   int   bx = bx0[parttype][block8x8];
  1243.   //===== LOOP OVER REFERENCE FRAMES =====
  1244.   for (list=0; list<numlists;list++)
  1245.   {
  1246.     for (ref=0; ref < listXsize[list+list_offset]; ref++)
  1247.     {
  1248.       m_cost = &motion_cost[blocktype][list][ref][block8x8];
  1249.       //----- set search range ---
  1250.       if      (params->full_search == 2)
  1251.         search_range = params->search_range;
  1252.       else if (params->full_search == 1)
  1253.         search_range = params->search_range /  (imin(ref,1)+1);
  1254.       else
  1255.         search_range = params->search_range / ((imin(ref,1)+1) * imin(2,blocktype));
  1256.       //----- set arrays -----
  1257.       ref_array = enc_picture->motion.ref_idx[list];
  1258.       mv_array  = enc_picture->motion.mv[list];
  1259.       //----- init motion cost -----
  1260.       //motion_cost[blocktype][list][ref][block8x8] = 0;
  1261.       if (Motion_Selected != 1)
  1262.         *m_cost = 0;
  1263.       //===== LOOP OVER SUB MACRO BLOCK partitions
  1264.       for (v=by; v<by + step_v0; v += step_v)
  1265.       {
  1266.         pic_block_y = img->block_y + v;
  1267.         for (h=bx; h<bx+step_h0; h+=step_h)
  1268.         {
  1269.           all_mv = img->all_mv[list][ref][blocktype][v][h];
  1270.           pic_block_x = img->block_x + h;
  1271.           //--- motion search for block ---          
  1272.           if (Motion_Selected != 1)
  1273.           {
  1274.             mcost = BlockMotionSearch     (currMB, ref, list, h<<2, v<<2, blocktype, search_range, lambda_factor);
  1275.             *m_cost += mcost;
  1276.             if ( (params->Transform8x8Mode == 1) && params->RDOQ_CP_MV && (blocktype == 4) && currMB->luma_transform_size_8x8_flag)
  1277.             {
  1278.               tmp_mv8[list][ref][v][h][0] = all_mv[0];
  1279.               tmp_mv8[list][ref][v][h][1] = all_mv[1];
  1280.               tmp_pmv8[list][ref][v][h][0] = img->pred_mv[list][ref][blocktype][v][h][0];
  1281.               tmp_pmv8[list][ref][v][h][1] = img->pred_mv[list][ref][blocktype][v][h][1];
  1282.               motion_cost8[list][ref][block8x8] = mcost;
  1283.             }
  1284.           }
  1285.           else
  1286.             updateMV_mp(m_cost, ref, list, h, v, blocktype, lambda_factor, block8x8);
  1287.           //--- set motion vectors and reference frame (for motion vector prediction) ---
  1288.           for (j=pic_block_y; j<pic_block_y + step_v; j++)
  1289.           {
  1290.             memset(&ref_array [j][pic_block_x], ref, step_h * sizeof(char));
  1291.             for (i=pic_block_x; i<pic_block_x + step_h; i++)
  1292.             {
  1293.               memcpy(mv_array  [j][i], all_mv, 2* sizeof(short));
  1294.             }
  1295.           }
  1296.         }
  1297.       }
  1298.     }
  1299.   }
  1300. }
  1301. /*!
  1302.  ************************************************************************
  1303.  * brief
  1304.  *    Calculate Direct Motion Vectors  *****
  1305.  ************************************************************************
  1306.  */
  1307. void Get_Direct_Motion_Vectors (Macroblock *currMB)
  1308. {
  1309.   int   block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
  1310.   short ******all_mvs;
  1311.   int   mv_scale;
  1312.   int refList;
  1313.   int ref_idx;
  1314.   MotionParams *colocated;
  1315.   char  **     ref_pic_l0 = enc_picture->motion.ref_idx[LIST_0];
  1316.   char  **     ref_pic_l1 = enc_picture->motion.ref_idx[LIST_1];
  1317.   if (currMB->list_offset)
  1318.   {
  1319.     if(img->current_mb_nr%2)
  1320.     {
  1321.       colocated = &Co_located->bottom;
  1322.     }
  1323.     else
  1324.     {
  1325.       colocated = &Co_located->top;
  1326.     }
  1327.   }
  1328.   else
  1329.   {
  1330.     colocated = &Co_located->frame;
  1331.   }
  1332.   if (img->direct_spatial_mv_pred_flag)  //spatial direct mode copy from decoder
  1333.   {
  1334.     short l0_refA, l0_refB, l0_refD, l0_refC;
  1335.     short l1_refA, l1_refB, l1_refD, l1_refC;
  1336.     short l0_refX,l1_refX;
  1337.     short pmvfw[2]={0,0},pmvbw[2]={0,0};
  1338.     PixelPos mb_a, mb_b, mb_d, mb_c;
  1339.     int *mb_size = img->mb_size[IS_LUMA];
  1340.     get4x4Neighbour(currMB, -1,  0, mb_size, &mb_a);
  1341.     get4x4Neighbour(currMB,  0, -1, mb_size, &mb_b);
  1342.     get4x4Neighbour(currMB, 16, -1, mb_size, &mb_c);
  1343.     get4x4Neighbour(currMB, -1, -1, mb_size, &mb_d);
  1344.     if (!img->MbaffFrameFlag)
  1345.     {
  1346.       l0_refA = mb_a.available ? ref_pic_l0[mb_a.pos_y][mb_a.pos_x] : -1;
  1347.       l0_refB = mb_b.available ? ref_pic_l0[mb_b.pos_y][mb_b.pos_x] : -1;
  1348.       l0_refD = mb_d.available ? ref_pic_l0[mb_d.pos_y][mb_d.pos_x] : -1;
  1349.       l0_refC = mb_c.available ? ref_pic_l0[mb_c.pos_y][mb_c.pos_x] : l0_refD;
  1350.       l1_refA = mb_a.available ? ref_pic_l1[mb_a.pos_y][mb_a.pos_x] : -1;
  1351.       l1_refB = mb_b.available ? ref_pic_l1[mb_b.pos_y][mb_b.pos_x] : -1;
  1352.       l1_refD = mb_d.available ? ref_pic_l1[mb_d.pos_y][mb_d.pos_x] : -1;
  1353.       l1_refC = mb_c.available ? ref_pic_l1[mb_c.pos_y][mb_c.pos_x] : l1_refD;
  1354.     }
  1355.     else
  1356.     {
  1357.       if (currMB->mb_field)
  1358.       {
  1359.         l0_refA = mb_a.available
  1360.           ? (img->mb_data[mb_a.mb_addr].mb_field  || ref_pic_l0[mb_a.pos_y][mb_a.pos_x] < 0
  1361.           ?  ref_pic_l0[mb_a.pos_y][mb_a.pos_x]
  1362.           :  ref_pic_l0[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
  1363.         l0_refB = mb_b.available
  1364.           ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
  1365.           ?  ref_pic_l0[mb_b.pos_y][mb_b.pos_x]
  1366.           :  ref_pic_l0[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
  1367.         l0_refD = mb_d.available
  1368.           ? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l0[mb_d.pos_y][mb_d.pos_x] < 0
  1369.           ?  ref_pic_l0[mb_d.pos_y][mb_d.pos_x]
  1370.           :  ref_pic_l0[mb_d.pos_y][mb_d.pos_x] * 2) : -1;
  1371.         l0_refC = mb_c.available
  1372.           ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
  1373.           ?  ref_pic_l0[mb_c.pos_y][mb_c.pos_x]
  1374.           :  ref_pic_l0[mb_c.pos_y][mb_c.pos_x] * 2) : l0_refD;
  1375.         l1_refA = mb_a.available
  1376.           ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
  1377.           ?  ref_pic_l1[mb_a.pos_y][mb_a.pos_x]
  1378.           :  ref_pic_l1[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
  1379.         l1_refB = mb_b.available
  1380.           ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
  1381.           ?  ref_pic_l1[mb_b.pos_y][mb_b.pos_x]
  1382.           :  ref_pic_l1[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
  1383.         l1_refD = mb_d.available
  1384.           ? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l1[mb_d.pos_y][mb_d.pos_x] < 0
  1385.           ?  ref_pic_l1[mb_d.pos_y][mb_d.pos_x]
  1386.           :  ref_pic_l1[mb_d.pos_y][mb_d.pos_x] * 2) : -1;
  1387.         l1_refC = mb_c.available
  1388.           ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
  1389.           ?  ref_pic_l1[mb_c.pos_y][mb_c.pos_x]
  1390.           :  ref_pic_l1[mb_c.pos_y][mb_c.pos_x] * 2) : l1_refD;
  1391.       }
  1392.       else
  1393.       {
  1394.         l0_refA = mb_a.available
  1395.           ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l0[mb_a.pos_y][mb_a.pos_x]  < 0
  1396.           ?  ref_pic_l0[mb_a.pos_y][mb_a.pos_x] >> 1
  1397.           :  ref_pic_l0[mb_a.pos_y][mb_a.pos_x]) : -1;
  1398.         l0_refB = mb_b.available
  1399.           ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
  1400.           ?  ref_pic_l0[mb_b.pos_y][mb_b.pos_x] >> 1
  1401.           :  ref_pic_l0[mb_b.pos_y][mb_b.pos_x]) : -1;
  1402.         l0_refD = mb_d.available
  1403.           ? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l0[mb_d.pos_y][mb_d.pos_x] < 0
  1404.           ?  ref_pic_l0[mb_d.pos_y][mb_d.pos_x] >> 1
  1405.           :  ref_pic_l0[mb_d.pos_y][mb_d.pos_x]) : -1;
  1406.         l0_refC = mb_c.available
  1407.           ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
  1408.           ?  ref_pic_l0[mb_c.pos_y][mb_c.pos_x] >> 1
  1409.           :  ref_pic_l0[mb_c.pos_y][mb_c.pos_x]) : l0_refD;
  1410.         l1_refA = mb_a.available
  1411.           ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
  1412.           ?  ref_pic_l1[mb_a.pos_y][mb_a.pos_x] >> 1
  1413.           :  ref_pic_l1[mb_a.pos_y][mb_a.pos_x]) : -1;
  1414.         l1_refB = mb_b.available
  1415.           ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
  1416.           ?  ref_pic_l1[mb_b.pos_y][mb_b.pos_x] >> 1
  1417.           :  ref_pic_l1[mb_b.pos_y][mb_b.pos_x]) : -1;
  1418.         l1_refD = mb_d.available
  1419.           ? (img->mb_data[mb_d.mb_addr].mb_field || ref_pic_l1[mb_d.pos_y][mb_d.pos_x] < 0
  1420.           ?  ref_pic_l1[mb_d.pos_y][mb_d.pos_x] >> 1
  1421.           :  ref_pic_l1[mb_d.pos_y][mb_d.pos_x]) : -1;
  1422.         l1_refC = mb_c.available
  1423.           ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
  1424.           ?  ref_pic_l1[mb_c.pos_y][mb_c.pos_x] >> 1
  1425.           :  ref_pic_l1[mb_c.pos_y][mb_c.pos_x]) : l1_refD;
  1426.       }
  1427.     }
  1428.     l0_refX = (l0_refA >= 0 && l0_refB >= 0) ? imin(l0_refA,l0_refB): imax(l0_refA,l0_refB);
  1429.     l0_refX = (l0_refX >= 0 && l0_refC >= 0) ? imin(l0_refX,l0_refC): imax(l0_refX,l0_refC);
  1430.     l1_refX = (l1_refA >= 0 && l1_refB >= 0) ? imin(l1_refA,l1_refB): imax(l1_refA,l1_refB);
  1431.     l1_refX = (l1_refX >= 0 && l1_refC >= 0) ? imin(l1_refX,l1_refC): imax(l1_refX,l1_refC);
  1432.     if (l0_refX >=0)
  1433.       SetMotionVectorPredictor (currMB, pmvfw, enc_picture->motion.ref_idx[LIST_0], enc_picture->motion.mv[LIST_0], l0_refX, LIST_0, 0, 0, 16, 16);
  1434.     if (l1_refX >=0)
  1435.       SetMotionVectorPredictor (currMB, pmvbw, enc_picture->motion.ref_idx[LIST_1], enc_picture->motion.mv[LIST_1], l1_refX, LIST_1, 0, 0, 16, 16);
  1436.     for (block_y=0; block_y<4; block_y++)
  1437.     {
  1438.       pic_block_y  = (img->pix_y  >> 2) + block_y;
  1439.       opic_block_y = (img->opix_y >> 2) + block_y;
  1440.       for (block_x=0; block_x<4; block_x++)
  1441.       {
  1442.         pic_block_x  = (img->pix_x  >> 2) + block_x;
  1443.         opic_block_x = (img->opix_x >> 2) + block_x;
  1444.         all_mvs = img->all_mv;
  1445.         if (l0_refX >=0)
  1446.         {
  1447.           if (!l0_refX  && !colocated->moving_block[opic_block_y][opic_block_x])
  1448.           {
  1449.             memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2 * sizeof(short));
  1450.             direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=0;
  1451.           }
  1452.           else
  1453.           {
  1454.             memcpy(all_mvs[LIST_0][l0_refX][0][block_y][block_x], pmvfw, 2 * sizeof(short));
  1455.             direct_ref_idx[LIST_0][pic_block_y][pic_block_x]= (char)l0_refX;
  1456.           }
  1457.         }
  1458.         else
  1459.         {
  1460.           memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2 * sizeof(short));
  1461.           direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=-1;
  1462.         }
  1463.         if (l1_refX >=0)
  1464.         {
  1465.           if(l1_refX==0 && !colocated->moving_block[opic_block_y][opic_block_x])
  1466.           {
  1467.             memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2 * sizeof(short));
  1468.             direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
  1469.           }
  1470.           else
  1471.           {
  1472.             memcpy(all_mvs[LIST_1][l1_refX][0][block_y][block_x], pmvbw, 2 * sizeof(short));
  1473.             direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
  1474.           }
  1475.         }
  1476.         else
  1477.         {
  1478.           memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2 * sizeof(short));
  1479.           direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1480.         }
  1481.         // Test Level Limits if satisfied.
  1482.         if (img->MbaffFrameFlag
  1483.           && (out_of_bounds_mvs(img, all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][block_y][block_x], Q_PEL)
  1484.           ||  out_of_bounds_mvs(img, all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][block_y][block_x], Q_PEL)))
  1485.         {
  1486.           direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
  1487.           direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1488.           direct_pdir           [pic_block_y][pic_block_x] = -1;
  1489.         }
  1490.         else
  1491.         {
  1492.           if (l0_refX < 0 && l1_refX < 0)
  1493.           {
  1494.             direct_ref_idx[LIST_0][pic_block_y][pic_block_x] =
  1495.               direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
  1496.             l0_refX = 0;
  1497.             l1_refX = 0;
  1498.           }
  1499.           if      (direct_ref_idx[LIST_1][pic_block_y][pic_block_x] == -1)
  1500.             direct_pdir[pic_block_y][pic_block_x] = 0;
  1501.           else if (direct_ref_idx[LIST_0][pic_block_y][pic_block_x] == -1)
  1502.             direct_pdir[pic_block_y][pic_block_x] = 1;
  1503.           else if (active_pps->weighted_bipred_idc == 1)
  1504.           {
  1505.             int weight_sum, i;
  1506.             Boolean invalid_wp = FALSE;
  1507.             for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
  1508.             {
  1509.               weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
  1510.               if (weight_sum < -128 ||  weight_sum > 127)
  1511.               {
  1512.                 invalid_wp = TRUE;
  1513.                 break;
  1514.               }
  1515.             }
  1516.             if (invalid_wp == FALSE)
  1517.               direct_pdir[pic_block_y][pic_block_x] = 2;
  1518.             else
  1519.             {
  1520.               direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
  1521.               direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1522.               direct_pdir           [pic_block_y][pic_block_x] = -1;
  1523.             }
  1524.           }
  1525.           else
  1526.             direct_pdir[pic_block_y][pic_block_x] = 2;
  1527.         }
  1528.       }
  1529.     }
  1530.   }
  1531.   else
  1532.   {
  1533.     int64 *refpic = enc_picture->ref_pic_num[LIST_0 +currMB->list_offset];
  1534.     //temporal direct mode copy from decoder
  1535.     for (block_y = 0; block_y < 4; block_y++)
  1536.     {
  1537.       pic_block_y  = (img->pix_y  >> 2) + block_y;
  1538.       opic_block_y = (img->opix_y >> 2) + block_y;
  1539.       for (block_x = 0; block_x < 4; block_x++)
  1540.       {
  1541.         pic_block_x  = (img->pix_x>>2) + block_x;
  1542.         opic_block_x = (img->opix_x>>2) + block_x;
  1543.         all_mvs = img->all_mv;
  1544.         refList = (colocated->ref_idx[LIST_0][opic_block_y][opic_block_x]== -1 ? LIST_1 : LIST_0);
  1545.         ref_idx = colocated->ref_idx[refList][opic_block_y][opic_block_x];
  1546.         // next P is intra mode
  1547.         if (ref_idx==-1)
  1548.         {
  1549.           memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2* sizeof(short));
  1550.           memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2* sizeof(short));
  1551.           direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = 0;
  1552.           direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
  1553.           direct_pdir[pic_block_y][pic_block_x] = 2;
  1554.         }
  1555.         // next P is skip or inter mode
  1556.         else
  1557.         {
  1558.           int mapped_idx=INVALIDINDEX;
  1559.           int iref;
  1560.           for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0+currMB->list_offset]);iref++)
  1561.           {
  1562.             if (refpic[iref]==colocated->ref_pic_id[refList ][opic_block_y][opic_block_x])
  1563.             {
  1564.               mapped_idx=iref;
  1565.               break;
  1566.             }
  1567.             else //! invalid index. Default to zero even though this case should not happen
  1568.             {
  1569.               mapped_idx=INVALIDINDEX;
  1570.             }
  1571.           }
  1572.           if (mapped_idx !=INVALIDINDEX)
  1573.           {
  1574.             mv_scale = img->mvscale[LIST_0+currMB->list_offset][mapped_idx];
  1575.             if (mv_scale==9999)
  1576.             {
  1577.               // forward
  1578.               memcpy(all_mvs[LIST_0][0][0][block_y][block_x], colocated->mv[refList][opic_block_y][opic_block_x], 2* sizeof(short));
  1579.               // backward
  1580.               memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2* sizeof(short));
  1581.             }
  1582.             else
  1583.             {
  1584.               // forward
  1585.               all_mvs[LIST_0][mapped_idx][0][block_y][block_x][0] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
  1586.               all_mvs[LIST_0][mapped_idx][0][block_y][block_x][1] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
  1587.               // backward
  1588.               all_mvs[LIST_1][         0][0][block_y][block_x][0] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
  1589.               all_mvs[LIST_1][         0][0][block_y][block_x][1] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
  1590.             }
  1591.             // Test Level Limits if satisfied.
  1592.             if ( out_of_bounds_mvs(img, all_mvs[LIST_0][mapped_idx][0][block_y][block_x], Q_PEL)|| out_of_bounds_mvs(img, all_mvs[LIST_1][0][0][block_y][block_x], Q_PEL))
  1593.             {
  1594.               direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
  1595.               direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1596.               direct_pdir[pic_block_y][pic_block_x] = -1;
  1597.             }
  1598.             else
  1599.             {
  1600.               direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = mapped_idx;
  1601.               direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
  1602.               direct_pdir[pic_block_y][pic_block_x] = 2;
  1603.             }
  1604.           }
  1605.           else
  1606.           {
  1607.             direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
  1608.             direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1609.             direct_pdir[pic_block_y][pic_block_x] = -1;
  1610.           }
  1611.         }
  1612.         if (active_pps->weighted_bipred_idc == 1 && direct_pdir[pic_block_y][pic_block_x] == 2)
  1613.         {
  1614.           int weight_sum, i;
  1615.           short l0_refX = direct_ref_idx[LIST_0][pic_block_y][pic_block_x];
  1616.           short l1_refX = direct_ref_idx[LIST_1][pic_block_y][pic_block_x];
  1617.           for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
  1618.           {
  1619.             weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
  1620.             if (weight_sum < -128 ||  weight_sum > 127)
  1621.             {
  1622.               direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
  1623.               direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
  1624.               direct_pdir           [pic_block_y][pic_block_x] = -1;
  1625.               break;
  1626.             }
  1627.           }
  1628.         }
  1629.       }
  1630.     }
  1631.   }
  1632. }