mv-search.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:56k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ***********************************************************************
  3. * COPYRIGHT AND WARRANTY INFORMATION
  4. *
  5. * Copyright 2001, International Telecommunications Union, Geneva
  6. *
  7. * DISCLAIMER OF WARRANTY
  8. *
  9. * These software programs are available to the user without any
  10. * license fee or royalty on an "as is" basis. The ITU disclaims
  11. * any and all warranties, whether express, implied, or
  12. * statutory, including any implied warranties of merchantability
  13. * or of fitness for a particular purpose.  In no event shall the
  14. * contributor or the ITU be liable for any incidental, punitive, or
  15. * consequential damages of any kind whatsoever arising from the
  16. * use of these programs.
  17. *
  18. * This disclaimer of warranty extends to the user of these programs
  19. * and user's customers, employees, agents, transferees, successors,
  20. * and assigns.
  21. *
  22. * The ITU does not represent or warrant that the programs furnished
  23. * hereunder are free of infringement of any third-party patents.
  24. * Commercial implementations of ITU-T Recommendations, including
  25. * shareware, may be subject to royalty fees to patent holders.
  26. * Information regarding the ITU-T patent policy is available from
  27. * the ITU Web site at http://www.itu.int.
  28. *
  29. * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
  30. ************************************************************************
  31. */
  32. /*!
  33.  *************************************************************************************
  34.  * file mv-search.c
  35.  *
  36.  * brief
  37.  *    Motion Vector Search, unified for B and P Pictures
  38.  *
  39.  * author
  40.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  41.  *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  42.  *      - Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
  43.  *      - Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
  44.  *      - Stephan Wenger                  <stewe@cs.tu-berlin.de>
  45.  *      - Jani Lainema                    <jani.lainema@nokia.com>
  46.  *      - Detlev Marpe                    <marpe@hhi.de>
  47.  *      - Thomas Wedi                     <wedi@tnt.uni-hannover.de>
  48.  *      - Heiko Schwarz                   <hschwarz@hhi.de>
  49.  *
  50.  *************************************************************************************
  51.  * todo
  52.  *   6. Unite the 1/2, 1/4 and1/8th pel search routines into a single routine       n
  53.  *   7. Clean up parameters, use sensemaking variable names                         n
  54.  *   9. Implement fast leaky search, such as UBCs Diamond search
  55.  *
  56.  *************************************************************************************
  57. */
  58. #include "contributors.h"
  59. #include <math.h>
  60. #include <stdlib.h>
  61. #include <assert.h>
  62. #include "global.h"
  63. #include "mv-search.h"
  64. #include "refbuf.h"
  65. // Local function declarations
  66. __inline int ByteAbs (int foo);
  67. // These procedure pointers are used by motion_search() and one_eigthpel()
  68. static pel_t (*PelY_18) (pel_t**, int, int);
  69. static pel_t (*PelY_14) (pel_t**, int, int);
  70. static pel_t *(*PelYline_11) (pel_t *, int, int);
  71. //! The Spiral for spiral search
  72. static int SpiralX[6561];
  73. static int SpiralY[6561];
  74. /*! The bit usage for MVs (currently lives in img-> mv_bituse and is used by
  75.     b_frame.c, but should move one day to a more appropriate place */
  76. static int *MVBitUse;
  77. // Statistics, temporary
  78. /*!
  79.  ***********************************************************************
  80.  * brief
  81.  *    MV Cost returns the initial penalty for the motion vector representation.
  82.  *    Used by the various MV search routines for MV RD optimization
  83.  *
  84.  * param ParameterResolution
  85.  *    the resolution of the vector parameter, 1, 2, 4, 8, eg 4 means 1/4 pel
  86.  * param BitstreamResolution
  87.  *    the resolyution in which the bitstream is coded
  88.  * param ParameterResolution
  89.  *    TargetResolution
  90.  * param pred_x, pred_y
  91.  *    Predicted vector in BitstreamResolution
  92.  * param Candidate_x, Candidate_y
  93.  *    Candidate vector in Parameter Resolution
  94.  ***********************************************************************
  95.  */
  96. static int MVCost (int ParameterResolution, int BitstreamResolution,
  97.                    int Blocktype, int qp,
  98.                    int Pred_x, int Pred_y,
  99.                    int Candidate_x, int Candidate_y)
  100. {
  101.   int Factor = BitstreamResolution/ParameterResolution;
  102.   int Penalty;
  103.   int len_x, len_y;
  104.   len_x = Candidate_x * Factor - Pred_x;
  105.   len_y = Candidate_y * Factor - Pred_y;
  106.   Penalty = (QP2QUANT[qp] * ( MVBitUse[absm (len_x)]+MVBitUse[absm(len_y)]) );
  107.   if (img->type != B_IMG && Blocktype == 1 && Candidate_x == 0 && Candidate_y == 0)   // 16x16 and no motion
  108.     Penalty -= QP2QUANT [qp] * 16;
  109.   return Penalty;
  110. }
  111. /*!
  112.  ***********************************************************************
  113.  * brief
  114.  *    motion vector cost for rate-distortion optimization
  115.  ***********************************************************************
  116.  */
  117. static int MVCostLambda (int shift, double lambda,
  118.        int pred_x, int pred_y, int cand_x, int cand_y)
  119. {
  120.   return (int)(lambda * (MVBitUse[absm((cand_x << shift) - pred_x)] +
  121.        MVBitUse[absm((cand_y << shift) - pred_y)]   ));
  122. }
  123. /*!
  124.  ***********************************************************************
  125.  * brief
  126.  *    setting the motion vector predictor
  127.  ***********************************************************************
  128.  */
  129. void
  130. SetMotionVectorPredictor (int pred[2], int **refFrArr, int ***tmp_mv,
  131.         int ref_frame, int mb_x, int mb_y, int blockshape_x, int blockshape_y)
  132. {
  133.   int block_x     = mb_x/BLOCK_SIZE;
  134.   int block_y = mb_y/BLOCK_SIZE;
  135.   int pic_block_x = img->block_x + block_x;
  136.   int pic_block_y = img->block_y + block_y;
  137.   int mb_nr = img->current_mb_nr;
  138.   int mb_width = img->width/16;
  139.   int mb_available_up      = (img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width]);
  140.   int mb_available_left    = (img->mb_x == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-1]);
  141.   int mb_available_upleft  = (img->mb_x == 0 || img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width-1]);
  142.   int mb_available_upright = (img->mb_x >= mb_width-1 || img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width+1]);
  143.   int block_available_up, block_available_left, block_available_upright, block_available_upleft;
  144.   int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
  145.   int mvPredType, rFrameL, rFrameU, rFrameUR;
  146.   int hv;
  147.   // D B C
  148.   // A X
  149.   // 1 A, B, D are set to 0 if unavailable
  150.   // 2 If C is not available it is replaced by D
  151.   block_available_up   = mb_available_up   || (mb_y > 0);
  152.   block_available_left = mb_available_left || (mb_x > 0);
  153.   if (mb_y > 0)
  154.     block_available_upright = mb_x+blockshape_x != MB_BLOCK_SIZE ? 1 : 0;
  155.   else if (mb_x+blockshape_x != MB_BLOCK_SIZE)
  156.     block_available_upright = block_available_up;
  157.   else
  158.     block_available_upright = mb_available_upright;
  159.   if (mb_x > 0)
  160.     block_available_upleft = mb_y > 0 ? 1 : block_available_up;
  161.   else if (mb_y > 0)
  162.     block_available_upleft = block_available_left;
  163.   else
  164.     block_available_upleft = mb_available_upleft;
  165.   mvPredType = MVPRED_MEDIAN;
  166.   rFrameL    = block_available_left    ? refFrArr[pic_block_y][pic_block_x-1]   : -1;
  167.   rFrameU    = block_available_up      ? refFrArr[pic_block_y-1][pic_block_x]   : -1;
  168.   rFrameUR   = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] :
  169.                block_available_upleft  ? refFrArr[pic_block_y-1][pic_block_x-1] : -1;
  170.   /* Prediction if only one of the neighbors uses the reference frame
  171.    * we are checking
  172.    */
  173.   if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
  174.     mvPredType = MVPRED_L;
  175.   else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
  176.     mvPredType = MVPRED_U;
  177.   else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
  178.     mvPredType = MVPRED_UR;
  179.   // Directional predictions
  180.   else if(blockshape_x == 8 && blockshape_y == 16)
  181.   {
  182.     if(mb_x == 0)
  183.     {
  184.       if(rFrameL == ref_frame)
  185.         mvPredType = MVPRED_L;
  186.     }
  187.     else
  188.     {
  189.       if(rFrameUR == ref_frame)
  190.         mvPredType = MVPRED_UR;
  191.     }
  192.   }
  193.   else if(blockshape_x == 16 && blockshape_y == 8)
  194.   {
  195.     if(mb_y == 0)
  196.     {
  197.       if(rFrameU == ref_frame)
  198.         mvPredType = MVPRED_U;
  199.     }
  200.     else
  201.     {
  202.       if(rFrameL == ref_frame)
  203.         mvPredType = MVPRED_L;
  204.     }
  205.   }
  206.   else if(blockshape_x == 8 && blockshape_y == 4 && mb_x == 8)
  207.     mvPredType = MVPRED_L;
  208.   else if(blockshape_x == 4 && blockshape_y == 8 && mb_y == 8)
  209.     mvPredType = MVPRED_U;
  210.   for (hv=0; hv < 2; hv++)
  211.   {
  212.     mv_a = block_available_left    ? tmp_mv[hv][pic_block_y][pic_block_x-1+4]   : 0;
  213.     mv_b = block_available_up      ? tmp_mv[hv][pic_block_y-1][pic_block_x+4]   : 0;
  214.     mv_d = block_available_upleft  ? tmp_mv[hv][pic_block_y-1][pic_block_x-1+4] : 0;
  215.     mv_c = block_available_upright ? tmp_mv[hv][pic_block_y-1][pic_block_x+blockshape_x/4+4] : mv_d;
  216.     switch (mvPredType)
  217.     {
  218.     case MVPRED_MEDIAN:
  219.       if(!(block_available_upleft || block_available_up || block_available_upright))
  220.         pred_vec = mv_a;
  221.       else
  222.         pred_vec = mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(mv_b,mv_c));
  223.       break;
  224.     case MVPRED_L:
  225.       pred_vec = mv_a;
  226.       break;
  227.     case MVPRED_U:
  228.       pred_vec = mv_b;
  229.       break;
  230.     case MVPRED_UR:
  231.       pred_vec = mv_c;
  232.       break;
  233.     default:
  234.       break;
  235.     }
  236.     pred[hv] = pred_vec;
  237.   }
  238. }
  239. #ifdef _FAST_FULL_ME_
  240. /*****
  241.  *****  static variables for fast integer motion estimation
  242.  *****
  243.  */
  244. static int  *search_setup_done;  //!< flag if all block SAD's have been calculated yet
  245. static int  *search_center_x;    //!< absolute search center for fast full motion search
  246. static int  *search_center_y;    //!< absolute search center for fast full motion search
  247. static int  *pos_00;             //!< position of (0,0) vector
  248. static int  ****BlockSAD;        //!< SAD for all blocksize, ref. frames and motion vectors
  249. /*!
  250.  ***********************************************************************
  251.  * brief
  252.  *    function creating arrays for fast integer motion estimation
  253.  ***********************************************************************
  254.  */
  255. void
  256. InitializeFastFullIntegerSearch (int search_range)
  257. {
  258.   int  i, j, k;
  259.   int  max_pos = (2*search_range+1) * (2*search_range+1);
  260.   if ((BlockSAD = (int****)malloc ((img->buf_cycle+1) * sizeof(int***))) == NULL)
  261.     no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
  262.   for (i = 0; i <= img->buf_cycle; i++)
  263.   {
  264.     if ((BlockSAD[i] = (int***)malloc (8 * sizeof(int**))) == NULL)
  265.       no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
  266.     for (j = 1; j < 8; j++)
  267.     {
  268.       if ((BlockSAD[i][j] = (int**)malloc (16 * sizeof(int*))) == NULL)
  269.         no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
  270.       for (k = 0; k < 16; k++)
  271.       {
  272.         if ((BlockSAD[i][j][k] = (int*)malloc (max_pos * sizeof(int))) == NULL)
  273.           no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
  274.       }
  275.     }
  276.   }
  277.   if ((search_setup_done = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
  278.     no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
  279.   if ((search_center_x = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
  280.     no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
  281.   if ((search_center_y = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
  282.     no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
  283.   if ((pos_00 = (int*)malloc ((img->buf_cycle+1)*sizeof(int)))==NULL)
  284.     no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
  285. }
  286. /*!
  287.  ***********************************************************************
  288.  * brief
  289.  *    function for deleting the arrays for fast integer motion estimation
  290.  ***********************************************************************
  291.  */
  292. void
  293. ClearFastFullIntegerSearch ()
  294. {
  295.   int  i, j, k;
  296.   for (i = 0; i <= img->buf_cycle; i++)
  297.   {
  298.     for (j = 1; j < 8; j++)
  299.     {
  300.       for (k = 0; k < 16; k++)
  301.       {
  302.         free (BlockSAD[i][j][k]);
  303.       }
  304.       free (BlockSAD[i][j]);
  305.     }
  306.     free (BlockSAD[i]);
  307.   }
  308.   free (BlockSAD);
  309.   free (search_setup_done);
  310.   free (search_center_x);
  311.   free (search_center_y);
  312.   free (pos_00);
  313. }
  314. /*!
  315.  ***********************************************************************
  316.  * brief
  317.  *    function resetting flags for fast integer motion estimation
  318.  *    (have to be called in start_macroblock())
  319.  ***********************************************************************
  320.  */
  321. void
  322. ResetFastFullIntegerSearch ()
  323. {
  324.   int i;
  325.   for (i = 0; i <= img->buf_cycle; i++)
  326.     search_setup_done [i] = 0;
  327. }
  328. /*!
  329.  ***********************************************************************
  330.  * brief
  331.  *    calculation of SAD for larger blocks on the basis of 4x4 blocks
  332.  ***********************************************************************
  333.  */
  334. void
  335. SetupLargerBlocks (int refindex, int max_pos)
  336. {
  337. #define ADD_UP_BLOCKS()   _o=*_bo; _i=*_bi; _j=*_bj; for(pos=0;pos<max_pos;pos++) *_o++ = *_i++ + *_j++;
  338. #define INCREMENT(inc)    _bo+=inc; _bi+=inc; _bj+=inc;
  339.   int    pos, **_bo, **_bi, **_bj;
  340.   register int *_o,   *_i,   *_j;
  341.   //--- blocktype 6 ---
  342.   _bo = BlockSAD[refindex][6];
  343.   _bi = BlockSAD[refindex][7];
  344.   _bj = _bi + 4;
  345.   ADD_UP_BLOCKS(); INCREMENT(1);
  346.   ADD_UP_BLOCKS(); INCREMENT(1);
  347.   ADD_UP_BLOCKS(); INCREMENT(1);
  348.   ADD_UP_BLOCKS(); INCREMENT(5);
  349.   ADD_UP_BLOCKS(); INCREMENT(1);
  350.   ADD_UP_BLOCKS(); INCREMENT(1);
  351.   ADD_UP_BLOCKS(); INCREMENT(1);
  352.   ADD_UP_BLOCKS();
  353.   //--- blocktype 5 ---
  354.   _bo = BlockSAD[refindex][5];
  355.   _bi = BlockSAD[refindex][7];
  356.   _bj = _bi + 1;
  357.   ADD_UP_BLOCKS(); INCREMENT(2);
  358.   ADD_UP_BLOCKS(); INCREMENT(2);
  359.   ADD_UP_BLOCKS(); INCREMENT(2);
  360.   ADD_UP_BLOCKS(); INCREMENT(2);
  361.   ADD_UP_BLOCKS(); INCREMENT(2);
  362.   ADD_UP_BLOCKS(); INCREMENT(2);
  363.   ADD_UP_BLOCKS(); INCREMENT(2);
  364.   ADD_UP_BLOCKS();
  365.   //--- blocktype 4 ---
  366.   _bo = BlockSAD[refindex][4];
  367.   _bi = BlockSAD[refindex][6];
  368.   _bj = _bi + 1;
  369.   ADD_UP_BLOCKS(); INCREMENT(2);
  370.   ADD_UP_BLOCKS(); INCREMENT(6);
  371.   ADD_UP_BLOCKS(); INCREMENT(2);
  372.   ADD_UP_BLOCKS();
  373.   //--- blocktype 3 ---
  374.   _bo = BlockSAD[refindex][3];
  375.   _bi = BlockSAD[refindex][4];
  376.   _bj = _bi + 8;
  377.   ADD_UP_BLOCKS(); INCREMENT(2);
  378.   ADD_UP_BLOCKS();
  379.   //--- blocktype 2 ---
  380.   _bo = BlockSAD[refindex][2];
  381.   _bi = BlockSAD[refindex][4];
  382.   _bj = _bi + 2;
  383.   ADD_UP_BLOCKS(); INCREMENT(8);
  384.   ADD_UP_BLOCKS();
  385.   //--- blocktype 1 ---
  386.   _bo = BlockSAD[refindex][1];
  387.   _bi = BlockSAD[refindex][3];
  388.   _bj = _bi + 2;
  389.   ADD_UP_BLOCKS();
  390. }
  391. /*!
  392.  ***********************************************************************
  393.  * brief
  394.  *    calculation of all SAD's (for all motion vectors and 4x4 blocks)
  395.  ***********************************************************************
  396.  */
  397. void
  398. SetupFastFullIntegerSearch (int      refframe,
  399.                             int    **refFrArr,
  400.                             int   ***tmp_mv,
  401.                             int *****img_mv,
  402.                             pel_t   *CurrRefPic,
  403.                             int      search_range,
  404.                             int      backward,
  405.                             int      rdopt)
  406. // Note: All Vectors in this function are full pel only.
  407. {
  408.   int     x, y, pos, blky, bindex;
  409.   int Absolute_X, Absolute_Y;
  410.   int LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
  411.   int     range_partly_outside, offset_x, offset_y, ref_x, ref_y;
  412.   int refindex     = backward ? img->buf_cycle : refframe;
  413.   int max_width    = img->width  - 17;
  414.   int max_height   = img->height - 17;
  415.   int max_pos      = (2*search_range+1) * (2*search_range+1);
  416.   int     mv_mul       = input->mv_res ? 2 : 1;
  417.   int   **block_sad    = BlockSAD[refindex][7];
  418.   pel_t   orig_blocks [256];
  419.   register pel_t  *orgptr = orig_blocks;
  420.   register pel_t  *refptr;
  421.   //===== get search center: predictor of 16x16 block =====
  422.   SetMotionVectorPredictor (img_mv[0][0][refframe][1], refFrArr, tmp_mv,
  423.           refframe, 0, 0, 16, 16);
  424.   search_center_x[refindex] = img_mv[0][0][refframe][1][0] / (mv_mul*4);
  425.   search_center_y[refindex] = img_mv[0][0][refframe][1][1] / (mv_mul*4);
  426.   if (!rdopt)
  427.   {
  428.     // correct center so that (0,0) vector is inside
  429.     search_center_x[refindex] = max(-search_range, min(search_range, search_center_x[refindex]));
  430.     search_center_y[refindex] = max(-search_range, min(search_range, search_center_y[refindex]));
  431.   }
  432.   search_center_x[refindex] += img->pix_x;
  433.   search_center_y[refindex] += img->pix_y;
  434.   offset_x = search_center_x[refindex];
  435.   offset_y = search_center_y[refindex];
  436.   //===== copy original block for fast access =====
  437.   for   (y = img->pix_y; y < img->pix_y+16; y++)
  438.     for (x = img->pix_x; x < img->pix_x+16; x++)
  439.       *orgptr++ = imgY_org [y][x];
  440.   //===== check if whole search range is inside image =====
  441.   if (offset_x >= search_range      &&
  442.       offset_y >= search_range      &&
  443.       offset_x <= max_width  - search_range &&
  444.       offset_y <= max_height - search_range)
  445.   {
  446.     range_partly_outside = 0; PelYline_11 = FastLine16Y_11;
  447.   }
  448.   else
  449.     range_partly_outside = 1;
  450.   //===== determine position of (0,0)-vector =====
  451.   if (!rdopt)
  452.   {
  453.     ref_x = img->pix_x - offset_x;
  454.     ref_y = img->pix_y - offset_y;
  455.     for (pos = 0; pos < max_pos; pos++)
  456.       if (ref_x == SpiralX[pos] &&
  457.           ref_y == SpiralY[pos])
  458.       {
  459.         pos_00[refindex] = pos;
  460.         break;
  461.       }
  462.   }
  463.   //===== loop over search range (spiral search): get blockwise SAD =====
  464.   for (pos = 0; pos < max_pos; pos++)
  465.   {
  466.     Absolute_Y = offset_y + SpiralY[pos];
  467.     Absolute_X = offset_x + SpiralX[pos];
  468.     if (range_partly_outside)
  469.     {
  470.       if (Absolute_Y >= 0 && Absolute_Y <= max_height &&
  471.           Absolute_X >= 0 && Absolute_X <= max_width    )
  472.         PelYline_11 = FastLine16Y_11;
  473.       else
  474.         PelYline_11 = UMVLine16Y_11;
  475.     }
  476.     orgptr = orig_blocks;
  477.     bindex = 0;
  478.     for (blky = 0; blky < 4; blky++)
  479.     {
  480.       LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
  481.       for (y = 0; y < 4; y++)
  482.       {
  483.         refptr = PelYline_11 (CurrRefPic, Absolute_Y++, Absolute_X);
  484.         LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
  485.         LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
  486.         LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
  487.         LineSadBlk0 += ByteAbs(*refptr++ - *orgptr++);
  488.         LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
  489.         LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
  490.         LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
  491.         LineSadBlk1 += ByteAbs(*refptr++ - *orgptr++);
  492.         LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
  493.         LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
  494.         LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
  495.         LineSadBlk2 += ByteAbs(*refptr++ - *orgptr++);
  496.         LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
  497.         LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
  498.         LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
  499.         LineSadBlk3 += ByteAbs(*refptr++ - *orgptr++);
  500.       }
  501.       block_sad[bindex++][pos] = LineSadBlk0;
  502.       block_sad[bindex++][pos] = LineSadBlk1;
  503.       block_sad[bindex++][pos] = LineSadBlk2;
  504.       block_sad[bindex++][pos] = LineSadBlk3;
  505.     }
  506.   }
  507.   //===== combine SAD's for larger block types =====
  508.   SetupLargerBlocks (refindex, max_pos);
  509.   //===== set flag marking that search setup have been done =====
  510.   search_setup_done[refindex] = 1;
  511. }
  512. /*!
  513.  ***********************************************************************
  514.  * brief
  515.  *    fast full integer search (SetupFastFullIntegerSearch have to be called before)
  516.  ***********************************************************************
  517.  */
  518. int
  519. FastFullIntegerSearch (int    mv_mul,
  520.                        int    predicted_x,
  521.                        int    predicted_y,
  522.                        int    search_range,
  523.                        int    refindex,
  524.                        int    blocktype,
  525.                        int    mb_x,
  526.                        int    mb_y,
  527.                        int    *center_h2,
  528.                        int    *center_v2,
  529.                        int    pic_pix_x,
  530.                        int    pic_pix_y,
  531.                        double lambda)
  532. {
  533. // Note: All Vectors in this function are full pel only.
  534.   int Candidate_X, Candidate_Y, current_inter_sad;
  535.   int mvres          = mv_mul==1 ? 4 : 8;
  536.   int mvres_l        = mv_mul==1 ? 2 : 3;
  537.   int Offset_X     = search_center_x[refindex] - img->pix_x;
  538.   int Offset_Y       = search_center_y[refindex] - img->pix_y;
  539.   int best_inter_sad = MAX_VALUE;
  540.   int bindex        = mb_y + (mb_x >> 2);
  541.   register int  pos;
  542.   register int  max_pos   = (2*search_range+1)*(2*search_range+1);
  543.   register int *block_sad = BlockSAD[refindex][blocktype][bindex];
  544.   //===== cost for (0,0)-vector: it is done before, because MVCost can be negative =====
  545.   if (!lambda)
  546.   {
  547.     *center_h2     = 0;
  548.     *center_v2     = 0;
  549.     best_inter_sad = block_sad[pos_00[refindex]] + MVCost(1, mvres, blocktype, img->qp, predicted_x, predicted_y, 0, 0);
  550.   }
  551.   //===== loop over search range (spiral search) =====
  552.   if (lambda)
  553.   {
  554.     for (pos = 0; pos < max_pos; pos++, block_sad++)
  555.       if (*block_sad < best_inter_sad)
  556.       {
  557.         Candidate_X        = Offset_X + SpiralX[pos];
  558.         Candidate_Y        = Offset_Y + SpiralY[pos];
  559.         current_inter_sad  = *block_sad;
  560.         current_inter_sad += MVCostLambda (mvres_l, lambda, predicted_x, predicted_y, Candidate_X, Candidate_Y);
  561.         if (current_inter_sad < best_inter_sad)
  562.         {
  563.           *center_h2     = Candidate_X;
  564.           *center_v2     = Candidate_Y;
  565.           best_inter_sad = current_inter_sad;
  566.         }
  567.       }
  568.   }
  569.   else
  570.   {
  571.     for (pos = 0; pos < max_pos; pos++, block_sad++)
  572.       if (*block_sad < best_inter_sad)
  573.       {
  574.         Candidate_X        = Offset_X + SpiralX[pos];
  575.         Candidate_Y        = Offset_Y + SpiralY[pos];
  576.         current_inter_sad  = *block_sad;
  577.         current_inter_sad += MVCost (1, mvres, blocktype, img->qp, predicted_x, predicted_y, Candidate_X, Candidate_Y);
  578.         if (current_inter_sad < best_inter_sad)
  579.         {
  580.           *center_h2     = Candidate_X;
  581.           *center_v2     = Candidate_Y;
  582.           best_inter_sad = current_inter_sad;
  583.         }
  584.       }
  585.   }
  586.   return best_inter_sad;
  587. }
  588. #endif // _FAST_FULL_ME_
  589. /*!
  590.  ***********************************************************************
  591.  * brief
  592.  *    Integer Spiral Search
  593.  * par Output:
  594.  *    best_inter_sad
  595.  * par Output (through Parameter pointers):
  596.  *    center_h2, center_v2 (if better MV was found)
  597.  ***********************************************************************
  598.  */
  599. int IntegerSpiralSearch ( int mv_mul, int center_x, int center_y,
  600.                           int predicted_x, int predicted_y,
  601.                           int blockshape_x, int blockshape_y,
  602.                           int curr_search_range, int blocktype,
  603.                           pel_t mo[16][16], pel_t *FullPelCurrRefPic,
  604.                           int *center_h2, int *center_v2,
  605.                           int pic_pix_x, int pic_pix_y,
  606.                           double lambda)
  607. {
  608. // Note: All Vectors in this function are full pel only.
  609.   int numc, lv;
  610.   int best_inter_sad = MAX_VALUE;
  611.   int abort_search;
  612.   int current_inter_sad;
  613.   int Candidate_X, Candidate_Y, Absolute_X, Absolute_Y;
  614.   int i, x, y;
  615.   int Difference;
  616.   pel_t SingleDimensionMo[16*16];
  617.   pel_t *check;
  618.   numc=(curr_search_range*2+1)*(curr_search_range*2+1);
  619.   // Setup a fast access field for the original
  620.   for (y=0, i=0; y<blockshape_y; y++)
  621.     for (x=0; x<blockshape_x; x++)
  622.       SingleDimensionMo[i++] = mo[y][x];
  623.   for (lv=0; lv < numc; lv++)
  624.   {
  625.     Candidate_X = center_x + SpiralX[lv];
  626.     Candidate_Y = center_y + SpiralY[lv];
  627.     Absolute_X = pic_pix_x + Candidate_X;
  628.     Absolute_Y = pic_pix_y + Candidate_Y;
  629.     if (lambda)
  630.       current_inter_sad = MVCostLambda (mv_mul==1?2:3, lambda, predicted_x, predicted_y, Candidate_X, Candidate_Y);
  631.     else
  632.       current_inter_sad = MVCost (1, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, Candidate_X,Candidate_Y);
  633.     abort_search=FALSE;
  634.     for (y=0, i=0; y < blockshape_y && !abort_search; y++)
  635.     {
  636.       check = PelYline_11 (FullPelCurrRefPic, Absolute_Y+y, Absolute_X);      // get pointer to line
  637.       for (x=0; x < blockshape_x ;x++)
  638.       {
  639.         Difference = SingleDimensionMo[i++]- *check++;
  640.         current_inter_sad += ByteAbs (Difference);
  641.       }
  642.       if (current_inter_sad >= best_inter_sad)
  643.       {
  644.         abort_search=TRUE;
  645.       }
  646.     }
  647.     if(!abort_search)
  648.     {
  649.       *center_h2=Candidate_X;
  650.       *center_v2=Candidate_Y;
  651.       best_inter_sad=current_inter_sad;
  652.     }
  653.   }
  654.   return best_inter_sad;
  655. }
  656. /*!
  657.  ***********************************************************************
  658.  * brief
  659.  *    Half Pel Search
  660.  ***********************************************************************
  661.  */
  662. int HalfPelSearch(int pic4_pix_x, int pic4_pix_y, int mv_mul, int blockshape_x, int blockshape_y,
  663.       int *s_pos_x1, int *s_pos_y1, int *s_pos_x2, int *s_pos_y2, int center_h2, int center_v2,
  664.       int predicted_x, int predicted_y, int blocktype, pel_t mo[16][16], pel_t **CurrRefPic, int ***tmp_mv,
  665.       int *****all_mv, int block_x, int block_y, int ref_frame, int pic_block_x, int pic_block_y,
  666.       double lambda)
  667. {
  668.   int best_inter_sad=MAX_VALUE;
  669.   int current_inter_sad;
  670.   int lv, iy0, jy0, vec1_x, vec1_y, vec2_x, vec2_y, i, i22, j;
  671.   int s_pos_x, s_pos_y;
  672.   int  m7[16][16];
  673.   for (lv=0; lv < 9; lv++)
  674.   {
  675.     s_pos_x=center_h2+SpiralX[lv]*2;
  676.     s_pos_y=center_v2+SpiralY[lv]*2;
  677.     iy0=pic4_pix_x+s_pos_x;
  678.     jy0=pic4_pix_y+s_pos_y;
  679.     if (lambda)
  680.       current_inter_sad = MVCostLambda (mv_mul==1?0:1, lambda,
  681.       predicted_x, predicted_y, s_pos_x, s_pos_y);
  682.     else
  683.       current_inter_sad = MVCost (4, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, s_pos_x, s_pos_y);
  684.     for (vec1_x=0; vec1_x < blockshape_x; vec1_x += 4)
  685.     {
  686.       for (vec1_y=0; vec1_y < blockshape_y; vec1_y += 4)
  687.       {
  688.         for (i=0; i < BLOCK_SIZE; i++)
  689.         {
  690.           vec2_x=i+vec1_x;
  691.           i22=iy0+vec2_x*4;
  692.           for (j=0; j < BLOCK_SIZE; j++)
  693.           {
  694.             vec2_y=j+vec1_y;
  695.             m7[i][j]=mo[vec2_y][vec2_x]-PelY_14 (CurrRefPic, jy0+vec2_y*4, i22);
  696.           }
  697.         }
  698.         current_inter_sad += find_sad(input->hadamard, m7);
  699.       }
  700.     }
  701.     if (current_inter_sad < best_inter_sad)
  702.     {
  703.       *s_pos_x1=s_pos_x;
  704.       *s_pos_y1=s_pos_y;
  705.       *s_pos_x2=s_pos_x;
  706.       *s_pos_y2=s_pos_y;
  707.       for (i=0; i < blockshape_x/BLOCK_SIZE; i++)
  708.       {
  709.         for (j=0; j < blockshape_y/BLOCK_SIZE; j++)
  710.         {
  711.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][0]=mv_mul**s_pos_x1;
  712.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][1]=mv_mul**s_pos_y1;
  713.           tmp_mv[0][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_x1;
  714.           tmp_mv[1][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_y1;
  715.         }
  716.       }
  717.       best_inter_sad=current_inter_sad;
  718.     }
  719.   }
  720.   return best_inter_sad;
  721. }
  722. /*!
  723.  ***********************************************************************
  724.  * brief
  725.  *    Quarter Pel Search
  726.  ***********************************************************************
  727.  */
  728. int QuarterPelSearch(int pic4_pix_x, int pic4_pix_y, int mv_mul, int blockshape_x, int blockshape_y,
  729.         int *s_pos_x1, int *s_pos_y1, int *s_pos_x2, int *s_pos_y2, int center_h2, int center_v2,
  730.         int predicted_x, int predicted_y, int blocktype, pel_t mo[16][16], pel_t **CurrRefPic, int ***tmp_mv,
  731.         int *****all_mv, int block_x, int block_y, int ref_frame,
  732.         int pic_block_x, int pic_block_y, int best_inter_sad,
  733.         double lambda
  734.         )
  735. {
  736.   int current_inter_sad;
  737.   int lv, s_pos_x, s_pos_y, iy0, jy0, vec1_x, vec1_y, vec2_x, vec2_y, i, i22, j;
  738.   int  m7[16][16];
  739.   for (lv=1; lv < 9; lv++)
  740.   {
  741.     s_pos_x=*s_pos_x2+SpiralX[lv];
  742.     s_pos_y=*s_pos_y2+SpiralY[lv];
  743.     iy0=pic4_pix_x+s_pos_x;
  744.     jy0=pic4_pix_y+s_pos_y;
  745.     if (lambda)
  746.       current_inter_sad = MVCostLambda (mv_mul==1?0:1, lambda,
  747.                                         predicted_x, predicted_y, s_pos_x, s_pos_y);
  748.     else
  749.       current_inter_sad = MVCost (4, (mv_mul==1)?4:8, blocktype, img->qp, predicted_x, predicted_y, s_pos_x, s_pos_y);
  750.     for (vec1_x=0; vec1_x < blockshape_x; vec1_x += 4)
  751.     {
  752.       for (vec1_y=0; vec1_y < blockshape_y; vec1_y += 4)
  753.       {
  754.         for (i=0; i < BLOCK_SIZE; i++)
  755.         {
  756.           vec2_x=i+vec1_x;
  757.           i22=iy0+vec2_x*4;
  758.           for (j=0; j < BLOCK_SIZE; j++)
  759.           {
  760.             vec2_y=j+vec1_y;
  761.             m7[i][j]=mo[vec2_y][vec2_x]-PelY_14 (CurrRefPic, jy0+vec2_y*4, i22);
  762.           }
  763.         }
  764.         current_inter_sad += find_sad(input->hadamard, m7);
  765.       }
  766.     }
  767.     if (current_inter_sad < best_inter_sad)
  768.     {
  769.       // Vectors are saved in all_mv[] to be able to assign correct vectors to each block after mode selection.
  770.       // tmp_mv[] is a 'temporary' assignment of vectors to be used to estimate 'bit cost' in vector prediction.
  771.       *s_pos_x1=s_pos_x;
  772.       *s_pos_y1=s_pos_y;
  773.       for (i=0; i < blockshape_x/BLOCK_SIZE; i++)
  774.       {
  775.         for (j=0; j < blockshape_y/BLOCK_SIZE; j++)
  776.         {
  777.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][0]=mv_mul**s_pos_x1;
  778.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][1]=mv_mul**s_pos_y1;
  779.           tmp_mv[0][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_x1;
  780.           tmp_mv[1][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=mv_mul**s_pos_y1;
  781.         }
  782.       }
  783.       best_inter_sad=current_inter_sad;
  784.     }
  785.   }
  786.   *s_pos_x2 = 2 * *s_pos_x1;
  787.   *s_pos_y2 = 2 * *s_pos_y1;
  788.   return best_inter_sad;
  789. }
  790. /*!
  791.  ***********************************************************************
  792.  * brief
  793.  *    Eighth Pel Search
  794.  ***********************************************************************
  795.  */
  796. int EighthPelSearch(int pic8_pix_x, int pic8_pix_y, int mv_mul, int blockshape_x, int blockshape_y,
  797.        int *s_pos_x1, int *s_pos_y1, int *s_pos_x2, int *s_pos_y2, int center_h2, int center_v2,
  798.        int predicted_x, int predicted_y, int blocktype, pel_t mo[16][16], pel_t **CurrRefPic, int ***tmp_mv,
  799.        int *****all_mv, int block_x, int block_y, int ref_frame,
  800.        int pic_block_x, int pic_block_y, int best_inter_sad,
  801.        double lambda
  802.        )
  803. {
  804.   int current_inter_sad;
  805.   int lv, s_pos_x, s_pos_y, iy0, jy0, vec1_x, vec1_y, vec2_x, vec2_y, i, i22, j;
  806.   int  m7[16][16];
  807.   for (lv=1; lv < 9; lv++)
  808.   {
  809.     s_pos_x=*s_pos_x2+SpiralX[lv];
  810.     s_pos_y=*s_pos_y2+SpiralY[lv];
  811.     iy0=pic8_pix_x+s_pos_x;
  812.     jy0=pic8_pix_y+s_pos_y;
  813.     if (lambda)
  814.       current_inter_sad = MVCostLambda (0, lambda,
  815.       predicted_x, predicted_y, s_pos_x, s_pos_y);
  816.     else
  817.       current_inter_sad = MVCost (8, 8, blocktype, img->qp, predicted_x, predicted_y, s_pos_x, s_pos_y);
  818.     for (vec1_x=0; vec1_x < blockshape_x; vec1_x += 4)
  819.     {
  820.       for (vec1_y=0; vec1_y < blockshape_y; vec1_y += 4)
  821.       {
  822.         for (i=0; i < BLOCK_SIZE; i++)
  823.         {
  824.           vec2_x=i+vec1_x;
  825.           i22=iy0+vec2_x*8;
  826.           for (j=0; j < BLOCK_SIZE; j++)
  827.           {
  828.             vec2_y=j+vec1_y;
  829.             m7[i][j]=mo[vec2_y][vec2_x]-PelY_18 (CurrRefPic, jy0+vec2_y*8, i22);
  830.           }
  831.         }
  832.         current_inter_sad += find_sad(input->hadamard, m7);
  833.       }
  834.     }
  835.     if (current_inter_sad < best_inter_sad)
  836.     {
  837.       // Vectors are saved in all_mv[] to be able to assign correct vectors to each block after mode selection.
  838.       // tmp_mv[] is a 'temporary' assignment of vectors to be used to estimate 'bit cost' in vector prediction.
  839.       *s_pos_x1=s_pos_x;
  840.       *s_pos_y1=s_pos_y;
  841.       for (i=0; i < blockshape_x/BLOCK_SIZE; i++)
  842.       {
  843.         for (j=0; j < blockshape_y/BLOCK_SIZE; j++)
  844.         {
  845.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][0]=*s_pos_x1;
  846.           all_mv[block_x+i][block_y+j][ref_frame][blocktype][1]=*s_pos_y1;
  847.           tmp_mv[0][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=*s_pos_x1;
  848.           tmp_mv[1][pic_block_y+j][pic_block_x+i+BLOCK_SIZE]=*s_pos_y1;
  849.         }
  850.       }
  851.       best_inter_sad=current_inter_sad;
  852.     }
  853.   }
  854.   return best_inter_sad;
  855. }
  856. #define PFRAME    0
  857. #define B_FORWARD 1
  858. #define B_BACKWARD  2
  859. /*!
  860.  ************************************************************************
  861.  * brief
  862.  *    In this routine motion search (integer pel+1/2 and 1/4 pel) and mode selection
  863.  *    is performed. Since we treat all 4x4 blocks before coding/decoding the
  864.  *    prediction may not be based on decoded pixels (except for some of the blocks).
  865.  *    This will result in too good prediction.  To compensate for this the SAD for
  866.  *    intra(tot_intra_sad) is given a 'handicap' depending on QP.
  867.  *                                                                                     par
  868.  *    Note that a couple of speed improvements were implemented by StW, which
  869.  *    slightly change the use of some variables.  In particular, the dimensions
  870.  *    of the img->m7 and mo[] variables were changed in order to allow better
  871.  *    cache access.
  872.  *                                                                                     par
  873.  *    Depending on the MV-resolution 1/4-pel or 1/8-pel motion vectors are estimated
  874.  *                                                                                     par
  875.  * par Input:
  876.  *    Best intra SAD value.
  877.  *
  878.  * par Output:
  879.  *    Reference image.
  880.  *
  881.  * par Side Effects:
  882.  *    writes refFrArr[ ][ ] to set reference frame ID for each block
  883.  *
  884.  *  par Bugs and Limitations:
  885.  *    currently the B-frame module does not support UMV in its residual coding.
  886.  *    Hence, the old search range limitation is implemented here for all B frames.
  887.  *    The if()s in question all start in column 1 of the file and are thus
  888.  *    easily idetifyable.
  889.  *
  890.  ************************************************************************
  891.  */
  892. int
  893. UnifiedMotionSearch (int tot_intra_sad, int **refFrArr, int ***tmp_mv,
  894.          int *****img_mv,
  895.          int *img_mb_mode, int *img_blc_size_h, int *img_blc_size_v,
  896.          int *img_multframe_no, int BFrame, int *min_inter_sad, int *****all_mv)
  897. {
  898.   int predframe_no=0;
  899.   int ref_frame,blocktype;
  900.   int tot_inter_sad;
  901.   int ref_inx;
  902.   *min_inter_sad = MAX_VALUE;
  903.   // Loop through all reference frames under consideration
  904.   // P-Frames, B-Forward: All reference frames
  905.   // P-Backward: use only the last reference frame, stored in mref_P
  906.   
  907. #ifdef _ADDITIONAL_REFERENCE_FRAME_
  908.   for (ref_frame=0; ref_frame < img->nb_references; ref_frame++)
  909.     if ((ref_frame <  input->no_multpred) || (ref_frame == input->add_ref_frame))
  910. #else
  911.   for (ref_frame=0; ref_frame < img->nb_references; ref_frame++)
  912. #endif
  913.   {
  914.     ref_inx = (img->number-ref_frame-1)%img->buf_cycle;
  915.     //  Looping through all the chosen block sizes:
  916.     blocktype=1;
  917.     while (input->blc_size[blocktype][0]==0 && blocktype<=7) // skip blocksizes not chosen
  918.       blocktype++;
  919.     for (;blocktype <= 7;)
  920.     {
  921.       tot_inter_sad  = QP2QUANT[img->qp] * min(ref_frame,1) * 2; // start 'handicap '
  922.       tot_inter_sad += SingleUnifiedMotionSearch (ref_frame, blocktype,
  923.         refFrArr, tmp_mv, img_mv,
  924.         BFrame, all_mv, 0.0);
  925.         /*
  926.         Here we update which is the best inter mode. At the end we have the best inter mode.
  927.         predframe_no:  which reference frame to use for prediction
  928.         img->multframe_no:  Index in the mref[] matrix used for prediction
  929.       */
  930.       if (tot_inter_sad <= *min_inter_sad)
  931.       {
  932.         if (BFrame==PFRAME)
  933.           *img_mb_mode=blocktype;
  934.         if (BFrame == B_FORWARD)
  935.         {
  936.           if (blocktype == 1)
  937.             *img_mb_mode = blocktype;
  938.           else
  939.             *img_mb_mode = blocktype * 2;
  940.         }
  941.         if (BFrame == B_BACKWARD)
  942.         {
  943.           if (blocktype == 1)
  944.             *img_mb_mode = blocktype+1;
  945.           else
  946.             *img_mb_mode = blocktype * 2+1;
  947.         }
  948.         *img_blc_size_h=input->blc_size[blocktype][0];
  949.         *img_blc_size_v=input->blc_size[blocktype][1];
  950.         predframe_no=ref_frame;
  951.         *img_multframe_no=ref_inx;
  952.         *min_inter_sad=tot_inter_sad;
  953.       }
  954.       while (input->blc_size[++blocktype][0]==0 && blocktype<=7); // only go through chosen blocksizes
  955.     }
  956.     if (BFrame == B_BACKWARD)
  957.       ref_frame = MAX_VALUE;    // jump out of the loop
  958.   }
  959.   return predframe_no;
  960. }
  961. /*!
  962.  ************************************************************************
  963.  * brief
  964.  *    unified motion search for a single combination of reference frame and blocksize
  965.  ************************************************************************
  966.  */
  967. int
  968. SingleUnifiedMotionSearch (int    ref_frame,
  969.                            int    blocktype,
  970.                            int  **refFrArr,
  971.                            int ***tmp_mv,
  972.                            int    *****img_mv,
  973.                            int    BFrame,
  974.                            int    *****all_mv,
  975.                            double lambda)
  976. {
  977.   int   j,i;
  978.   int   pic_block_x,pic_block_y,block_x,ref_inx,block_y,pic_pix_y;
  979.   int   pic4_pix_y,pic8_pix_y,pic_pix_x,pic4_pix_x,pic8_pix_x;
  980.   int   ip0,ip1;
  981.   int   center_h2,curr_search_range,center_v2;
  982.   int   s_pos_x1,s_pos_y1,s_pos_x2,s_pos_y2;
  983.   int   mb_y,mb_x;
  984.   int   best_inter_sad, tot_inter_sad = 0;
  985.   pel_t mo[16][16];
  986.   int   blockshape_x,blockshape_y;
  987.   int   mv_mul;
  988.   pel_t **CurrRefPic;
  989.   pel_t *CurrRefPic11;
  990. #ifdef _FAST_FULL_ME_
  991.   int  refindex, full_search_range;
  992. #else
  993.   int    center_x, center_y;
  994. #endif
  995.   /*  curr_search_range is the actual search range used depending on block size and reference frame.
  996.   It may be reduced by 1/2 or 1/4 for smaller blocks and prediction from older frames due to compexity
  997.   */
  998. #ifdef _FULL_SEARCH_RANGE_
  999.   if (input->full_search == 2) // no restrictions at all
  1000.   {
  1001.     curr_search_range = input->search_range;
  1002.   }
  1003.   else if (input->full_search == 1) // smaller search range for older reference frames
  1004.   {
  1005.     curr_search_range = input->search_range /  (min(ref_frame,1)+1);
  1006.   }
  1007.   else // smaller search range for older reference frames and smaller blocks
  1008. #endif
  1009.   {
  1010.     curr_search_range = input->search_range / ((min(ref_frame,1)+1) * min(2,blocktype));
  1011.   }
  1012. #ifdef _FAST_FULL_ME_
  1013. #ifdef _FULL_SEARCH_RANGE_
  1014.   if (input->full_search == 2)
  1015.     full_search_range   = input->search_range;
  1016.   else
  1017. #endif
  1018.     full_search_range   = input->search_range / (min(ref_frame,1)+1);
  1019. #endif
  1020.   // Motion vector scale-factor for 1/8-pel MV-resolution
  1021.   if(input->mv_res)
  1022.     mv_mul=2;
  1023.   else
  1024.     mv_mul=1;
  1025.   // set reference frame array
  1026.   for (j = 0;j < 4;j++)
  1027.   {
  1028.     for (i = 0;i < 4;i++)
  1029.     {
  1030.       refFrArr[img->block_y+j][img->block_x+i] = ref_frame;
  1031.     }
  1032.   }
  1033.   // find  reference image
  1034.   if (BFrame != B_BACKWARD)
  1035.   {
  1036.     ref_inx=(img->number-ref_frame-1)%img->buf_cycle;
  1037.     CurrRefPic   = mref[ref_inx];
  1038.     CurrRefPic11 = Refbuf11[ref_inx];
  1039.   }
  1040.   else
  1041.   {
  1042.     CurrRefPic   = mref_P;
  1043.     CurrRefPic11 = Refbuf11_P;
  1044.   }
  1045. #ifdef _FAST_FULL_ME_
  1046.   //===== setup fast full integer search: get SAD's for all motion vectors and 4x4 blocks =====
  1047.   //      (this is done just once for a macroblock)
  1048.   refindex = (BFrame != B_BACKWARD ? ref_frame : img->buf_cycle);
  1049.   if (!search_setup_done[refindex])
  1050.   {
  1051.     SetupFastFullIntegerSearch (ref_frame, refFrArr, tmp_mv, img_mv, CurrRefPic11,
  1052.       full_search_range, (BFrame==B_BACKWARD), (lambda != 0));
  1053.   }
  1054. #endif
  1055.   blockshape_x=input->blc_size[blocktype][0];// input->blc_size has information of the 7 blocksizes
  1056.   blockshape_y=input->blc_size[blocktype][1];// array iz stores offset inside one MB
  1057.   //  Loop through the whole MB with all block sizes
  1058.   for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += blockshape_y)
  1059.   {
  1060.     block_y=mb_y/BLOCK_SIZE;
  1061.     pic_block_y=img->block_y+block_y;
  1062.     pic_pix_y=img->pix_y+mb_y;
  1063.     pic4_pix_y=pic_pix_y*4;
  1064.     for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += blockshape_x)
  1065.     {
  1066.       block_x=mb_x/BLOCK_SIZE;
  1067.       pic_block_x=img->block_x+block_x;
  1068.       pic_pix_x=img->pix_x+mb_x;
  1069.       pic4_pix_x=pic_pix_x*4;
  1070.       SetMotionVectorPredictor (img_mv[block_x][block_y][ref_frame][blocktype], refFrArr, tmp_mv,
  1071.         ref_frame, mb_x, mb_y, blockshape_x, blockshape_y);
  1072.       ip0=img_mv[block_x][block_y][ref_frame][blocktype][0];
  1073.       ip1=img_mv[block_x][block_y][ref_frame][blocktype][1];
  1074.       //  mo[] is the the original block to be used in the search process
  1075.       // Note: dimensions changed to speed up access
  1076.       for (i=0; i < blockshape_x; i++)
  1077.         for (j=0; j < blockshape_y; j++)
  1078.           mo[j][i]=imgY_org[pic_pix_y+j][pic_pix_x+i];
  1079.       //  Integer pel search.  center_x,center_y is the 'search center'
  1080. #ifndef _FAST_FULL_ME_
  1081.       // Note that the predictor in mv[][][][][] is in 1/4 or 1/8th pel resolution
  1082.       // The following rounding enforces a "true" integer pel search.
  1083.       center_x=ip0/(mv_mul*4);
  1084.       center_y=ip1/(mv_mul*4);
  1085.       // Limitation of center_x,center_y so that the search wlevel ow contains the (0,0) vector
  1086.       center_x=max(-(input->search_range),min(input->search_range,center_x));
  1087.       center_y=max(-(input->search_range),min(input->search_range,center_y));
  1088.       // The following was deleted to support UMV.  See Remak regarding UMV performance for B
  1089.       // in the Readme File (to be provided)
  1090.       // Search center corrected to prevent vectors outside the frame, this is not permitted in this model.
  1091.       if ((pic_pix_x + center_x > curr_search_range) &&
  1092.           (pic_pix_y + center_y > curr_search_range) &&
  1093.           (pic_pix_x + center_x < img->width  - 1 - curr_search_range - blockshape_x) &&
  1094.           (pic_pix_y + center_y < img->height - 1 - curr_search_range - blockshape_y))
  1095.       {
  1096.         PelYline_11 = FastLine16Y_11;
  1097.       }
  1098.       else
  1099.       {
  1100.         PelYline_11 = UMVLine16Y_11;
  1101.       }
  1102.       best_inter_sad = IntegerSpiralSearch (mv_mul, center_x, center_y, ip0, ip1,
  1103.                                             blockshape_x, blockshape_y, curr_search_range,
  1104.                                             blocktype, mo, CurrRefPic11, &center_h2, &center_v2,
  1105.                                             pic_pix_x, pic_pix_y,
  1106.                                             lambda);
  1107. #else // _FAST_FULL_ME_
  1108.       best_inter_sad = FastFullIntegerSearch (mv_mul, ip0, ip1, curr_search_range,
  1109.                                               refindex, blocktype, mb_x, mb_y,
  1110.                                               &center_h2, &center_v2, pic_pix_x, pic_pix_y,
  1111.                                               lambda);
  1112. #endif // _FAST_FULL_ME_
  1113.       // Adjust center to 1/4 pel positions
  1114.       center_h2 *=4;
  1115.       center_v2 *=4;
  1116.       if ((pic4_pix_x + center_h2 > 1) &&
  1117.           (pic4_pix_y + center_v2 > 1) &&
  1118.           (pic4_pix_x + center_h2 < 4*(img->width  - blockshape_x + 1) - 2) &&
  1119.           (pic4_pix_y + center_v2 < 4*(img->height - blockshape_y + 1) - 2)   )
  1120.         PelY_14 = FastPelY_14;
  1121.       else
  1122.         PelY_14 = UMVPelY_14;
  1123.       //  1/2 pixel search.  In this version the search is over 9 vector positions.
  1124.       best_inter_sad = HalfPelSearch (pic4_pix_x, pic4_pix_y, mv_mul, blockshape_x, blockshape_y,
  1125.                                       &s_pos_x1, &s_pos_y1, &s_pos_x2, &s_pos_y2, center_h2, center_v2,
  1126.                                       ip0, ip1, blocktype, mo, CurrRefPic, tmp_mv, all_mv, block_x,
  1127.                                       block_y, ref_frame, pic_block_x, pic_block_y,
  1128.                                       lambda);
  1129.       //  1/4 pixel search.
  1130.       if ((pic4_pix_x + s_pos_x2 > 0) &&
  1131.           (pic4_pix_y + s_pos_y2 > 0) &&
  1132.           (pic4_pix_x + s_pos_x2 < 4*(img->width  - blockshape_x + 1) - 1) &&
  1133.           (pic4_pix_y + s_pos_y2 < 4*(img->height - blockshape_y + 1) - 1)   )
  1134.         PelY_14 = FastPelY_14;
  1135.       else
  1136.         PelY_14 = UMVPelY_14;
  1137.       best_inter_sad = QuarterPelSearch (pic4_pix_x, pic4_pix_y, mv_mul, blockshape_x, blockshape_y,
  1138.                                          &s_pos_x1, &s_pos_y1, &s_pos_x2, &s_pos_y2, center_h2, center_v2,
  1139.                                          ip0, ip1, blocktype, mo, CurrRefPic, tmp_mv, all_mv, block_x, block_y, ref_frame,
  1140.                                          pic_block_x, pic_block_y, best_inter_sad,
  1141.                                          lambda);
  1142.       //  1/8 pixel search.
  1143.       if(input->mv_res)
  1144.       {
  1145.         pic8_pix_x=2*pic4_pix_x;
  1146.         pic8_pix_y=2*pic4_pix_y;
  1147.         if ((pic8_pix_x + s_pos_x2 > 0) &&
  1148.             (pic8_pix_y + s_pos_y2 > 0) &&
  1149.             (pic8_pix_x + s_pos_x2 < 8*(img->width  - blockshape_x + 1) - 2) &&
  1150.             (pic8_pix_y + s_pos_y2 < 8*(img->height - blockshape_y + 1) - 2)   )
  1151.           PelY_18 = FastPelY_18;
  1152.         else
  1153.           PelY_18 = UMVPelY_18;
  1154.         best_inter_sad = EighthPelSearch(pic8_pix_x, pic8_pix_y, mv_mul, blockshape_x, blockshape_y,
  1155.                                         &s_pos_x1, &s_pos_y1, &s_pos_x2, &s_pos_y2, center_h2, center_v2,
  1156.                                         ip0, ip1, blocktype, mo, CurrRefPic, tmp_mv, all_mv, block_x, block_y, ref_frame,
  1157.                                         pic_block_x, pic_block_y, best_inter_sad,
  1158.                                         lambda);
  1159.       }
  1160.       tot_inter_sad += best_inter_sad;
  1161.     }
  1162.   }
  1163.   return tot_inter_sad;
  1164. }
  1165. /*!
  1166.  ************************************************************************
  1167.  * brief
  1168.  *    motion search for P-frames
  1169.  ************************************************************************
  1170.  */
  1171. int motion_search(int tot_intra_sad)
  1172. {
  1173.   int predframe_no, min_inter_sad, hv, i, j;
  1174.   predframe_no = UnifiedMotionSearch(tot_intra_sad, refFrArr, tmp_mv, img->mv, &img->mb_mode,
  1175.     &img->blc_size_h, &img->blc_size_v, &img->multframe_no, PFRAME, &min_inter_sad, img->all_mv);
  1176.   // tot_intra_sad is now the minimum SAD for intra.  min_inter_sad is the best (min) SAD for inter (see above).
  1177.   // Inter/intra is determined depending on which is smallest
  1178.   if (tot_intra_sad < min_inter_sad)
  1179.   {
  1180.     img->mb_mode=img->imod+8*img->type; // set intra mode in inter frame
  1181.     for (hv=0; hv < 2; hv++)
  1182.       for (i=0; i < 4; i++)
  1183.         for (j=0; j < 4; j++)
  1184.           tmp_mv[hv][img->block_y+j][img->block_x+i+4]=0;
  1185.   }
  1186.   else
  1187.   {
  1188.     img->mb_data[img->current_mb_nr].intraOrInter = INTER_MB;
  1189.     img->imod=INTRA_MB_INTER; // Set inter mode
  1190.     for (hv=0; hv < 2; hv++)
  1191.       for (i=0; i < 4; i++)
  1192.         for (j=0; j < 4; j++)
  1193.           tmp_mv[hv][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][predframe_no][img->mb_mode][hv];
  1194.   }
  1195.   return predframe_no;
  1196. };
  1197. /*!
  1198.  ************************************************************************
  1199.  * brief
  1200.  *    forward motion search for B-frames
  1201.  ************************************************************************
  1202.  */
  1203. int get_fwMV(int *min_fw_sad, int tot_intra_sad)
  1204. {
  1205.   int fw_predframe_no, hv, i, j;
  1206.   fw_predframe_no = UnifiedMotionSearch(tot_intra_sad, fw_refFrArr, tmp_fwMV,
  1207.                                         img->p_fwMV, &img->fw_mb_mode,
  1208.                                         &img->fw_blc_size_h, &img->fw_blc_size_v,
  1209.                                         &img->fw_multframe_no, B_FORWARD,
  1210.                                         min_fw_sad, img->all_mv);
  1211.   // save forward MV to tmp_fwMV
  1212.   for (hv=0; hv < 2; hv++)
  1213.     for (i=0; i < 4; i++)
  1214.       for (j=0; j < 4; j++)
  1215.       {
  1216.         if(img->fw_mb_mode==1)
  1217.           tmp_fwMV[hv][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][fw_predframe_no][1][hv];
  1218.         else
  1219.           tmp_fwMV[hv][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][fw_predframe_no][(img->fw_mb_mode)/2][hv];
  1220.       }
  1221.   return fw_predframe_no;
  1222. }
  1223. /*!
  1224.  ************************************************************************
  1225.  * brief
  1226.  *    backward motion search for B-frames
  1227.  ************************************************************************
  1228.  */
  1229. void get_bwMV(int *min_bw_sad)
  1230. {
  1231.   int bw_predframe_no, hv, i, j;
  1232.   bw_predframe_no = UnifiedMotionSearch(MAX_VALUE, bw_refFrArr, tmp_bwMV,
  1233.           img->p_bwMV, &img->bw_mb_mode,
  1234.           &img->bw_blc_size_h, &img->bw_blc_size_v,
  1235.           &img->bw_multframe_no, B_BACKWARD,
  1236.           min_bw_sad, img->all_mv);
  1237.   // save backward MV to tmp_bwMV
  1238.   for (hv=0; hv < 2; hv++)
  1239.     for (i=0; i < 4; i++)
  1240.       for (j=0; j < 4; j++)
  1241.       {
  1242.         if(img->bw_mb_mode==2)
  1243.           tmp_bwMV[hv][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][bw_predframe_no][1][hv];
  1244.         else
  1245.           tmp_bwMV[hv][img->block_y+j][img->block_x+i+4]=img->all_mv[i][j][bw_predframe_no][(img->bw_mb_mode-1)/2][hv];
  1246.       }
  1247. }
  1248. /*!
  1249.  ************************************************************************
  1250.  * brief
  1251.  *    Do hadamard transform or normal SAD calculation.
  1252.  *    If Hadamard=1 4x4 Hadamard transform is performed and SAD of transform
  1253.  *    levels is calculated
  1254.  *
  1255.  * par Input:
  1256.  *    hadamard=0 : normal SAD                                                  n
  1257.  *    hadamard=1 : 4x4 Hadamard transform is performed and SAD of transform
  1258.  *                 levels is calculated
  1259.  *
  1260.  * par Output:
  1261.  *    SAD/hadamard transform value
  1262.  *
  1263.  * note
  1264.  *    This function was optimized by manual loop unrolling and pointer arithmetic
  1265.  ************************************************************************
  1266.  */
  1267. int find_sad(int hadamard, int m7[16][16])
  1268. {
  1269.   int i, j,x, y, best_sad,current_sad;
  1270.   int m1[BLOCK_SIZE*BLOCK_SIZE], m[BLOCK_SIZE*BLOCK_SIZE], *mp;
  1271. #ifdef COMPLEXITY
  1272.     SadCalls++;
  1273. #endif
  1274.   current_sad=0;
  1275.   if (hadamard != 0)
  1276.   {
  1277.     best_sad=0;
  1278. // Copy img->m7[][] into local variable, to avoid costly address arithmetic and cache misses
  1279.     mp=m;
  1280.     for (y=0; y<BLOCK_SIZE; y++)
  1281.       for (x=0; x<BLOCK_SIZE; x++)
  1282.         *mp++= m7[y][x];
  1283.     m1[0] = m[0] + m[12];
  1284.     m1[4] = m[4] + m[8];
  1285.     m1[8] = m[4] - m[8];
  1286.     m1[12]= m[0] - m[12];
  1287.     m1[1] = m[1] + m[13];
  1288.     m1[5] = m[5] + m[9];
  1289.     m1[9] = m[5] - m[9];
  1290.     m1[13]= m[1] - m[13];
  1291.     m1[2] = m[2] + m[14];
  1292.     m1[6] = m[6] + m[10];
  1293.     m1[10]= m[6] - m[10];
  1294.     m1[14]= m[2] - m[14];
  1295.     m1[3] = m[3] + m[15];
  1296.     m1[7] = m[7] + m[11];
  1297.     m1[11]= m[7] - m[11];
  1298.     m1[15]= m[3] - m[15];
  1299.     m[0] = m1[0] + m1[4];
  1300.     m[8] = m1[0] - m1[4];
  1301.     m[4] = m1[8] + m1[12];
  1302.     m[12]= m1[12]- m1[8];
  1303.     m[1] = m1[1] + m1[5];
  1304.     m[9] = m1[1] - m1[5];
  1305.     m[5] = m1[9] + m1[13];
  1306.     m[13]= m1[13]- m1[9];
  1307.     m[2] = m1[2] + m1[6];
  1308.     m[10] = m1[2] - m1[6];
  1309.     m[6] = m1[10] + m1[14];
  1310.     m[14]= m1[14]- m1[10];
  1311.     m[3] = m1[3] + m1[7];
  1312.     m[11]= m1[3] - m1[7];
  1313.     m[7] = m1[11]+ m1[15];
  1314.     m[15]= m1[15]- m1[11];
  1315.     m1[0] = m[0] + m[3];
  1316.     m1[1] = m[1] + m[2];
  1317.     m1[2] = m[1] - m[2];
  1318.     m1[3] = m[0] - m[3];
  1319.     m1[4] = m[4] + m[7];
  1320.     m1[5] = m[5] + m[6];
  1321.     m1[6] = m[5] - m[6];
  1322.     m1[7] = m[4] - m[7];
  1323.     m1[8] = m[8] + m[11];
  1324.     m1[9] = m[9] + m[10];
  1325.     m1[10]= m[9] - m[10];
  1326.     m1[11]= m[8] - m[11];
  1327.     m1[12]= m[12]+ m[15];
  1328.     m1[13]= m[13]+ m[14];
  1329.     m1[14]= m[13]- m[14];
  1330.     m1[15]= m[12]- m[15];
  1331.     m[0] = m1[0] + m1[1];
  1332.     m[1] = m1[0] - m1[1];
  1333.     m[2] = m1[2] + m1[3];
  1334.     m[3] = m1[3] - m1[2];
  1335.     m[4] = m1[4] + m1[5];
  1336.     m[5] = m1[4] - m1[5];
  1337.     m[6] = m1[6] + m1[7];
  1338.     m[7] = m1[7] - m1[6];
  1339.     m[8] = m1[8] + m1[9];
  1340.     m[9] = m1[8] - m1[9];
  1341.     m[10]= m1[10]+ m1[11];
  1342.     m[11]= m1[11]- m1[10];
  1343.     m[12]= m1[12]+ m1[13];
  1344.     m[13]= m1[12]- m1[13];
  1345.     m[14]= m1[14]+ m1[15];
  1346.     m[15]= m1[15]- m1[14];
  1347.     // Note: we cannot use ByteAbs() here because the absolute values can be bigger
  1348.     // than +- 256.  WOuld either need to enhance ByteAbs to WordAbs (or something)
  1349.     // or leave it as is (use of absm*( macro)
  1350.     for (j=0; j< BLOCK_SIZE * BLOCK_SIZE; j++)
  1351.       best_sad += absm (m[j]);
  1352.       /*
  1353.     Calculation of normalized Hadamard transforms would require divison by 4 here.
  1354.     However,we flevel  that divison by 2 is better (assuming we give the same penalty for
  1355.     bituse for Hadamard=0 and 1)
  1356.     */
  1357.     current_sad += best_sad/2;
  1358.   }
  1359.   else
  1360.   {
  1361.     register int *p;
  1362.     {
  1363.       for (i=0;i<4;i++)
  1364.       {
  1365.         p = m7[i];
  1366.         for (j=0;j<4;j++)
  1367.           current_sad+=ByteAbs(*p++);
  1368.       }
  1369.     }
  1370.   }
  1371.   return current_sad;
  1372. }
  1373. /*!
  1374.  ************************************************************************
  1375.  * brief
  1376.  *    control the sign of a with b
  1377.  ************************************************************************
  1378.  */
  1379. int sign(int a,int b)
  1380. {
  1381.   int x;
  1382.   x=absm(a);
  1383.   if (b >= 0)
  1384.     return x;
  1385.   else
  1386.     return -x;
  1387. }
  1388. static int ByteAbsLookup[] = {
  1389.   255,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,
  1390.   239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,
  1391.   223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,
  1392.   207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,
  1393.   191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,
  1394.   175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,
  1395.   159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,
  1396.   143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,
  1397.   127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,
  1398.   111,110,109,108,107,106,105,104,103,102,101,100, 99, 98, 97, 96,
  1399.    95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
  1400.    79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64,
  1401.    63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
  1402.    47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32,
  1403.    31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
  1404.    15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,
  1405.     1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
  1406.    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
  1407.    33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  1408.    49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
  1409.    65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  1410.    81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
  1411.    97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,
  1412.   113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
  1413.   129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,
  1414.   145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,
  1415.   161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
  1416.   177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
  1417.   193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,
  1418.   209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
  1419.   225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
  1420.   241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 };
  1421. __inline int ByteAbs (int foo)
  1422. {
  1423.   return ByteAbsLookup [foo+255];
  1424. }
  1425. void InitMotionVectorSearchModule ()
  1426. {
  1427.   int i,j,k,l,l2;
  1428.   // Set up the static pointer for MV_bituse;
  1429.   MVBitUse = img->mv_bituse;
  1430.   // initialize Spiral Search statics
  1431.   k=1;
  1432.   for (l=1; l < 41; l++)
  1433.   {
  1434.     l2=l+l;
  1435.     for (i=-l+1; i < l; i++)
  1436.     {
  1437.       for (j=-l; j < l+1; j += l2)
  1438.       {
  1439.         SpiralX[k] = i;
  1440.         SpiralY[k] = j;
  1441.         k++;
  1442.       }
  1443.     }
  1444.     for (j=-l; j <= l; j++)
  1445.     {
  1446.       for (i=-l;i <= l; i += l2)
  1447.       {
  1448.         SpiralX[k] = i;
  1449.         SpiralY[k] = j;
  1450.         k++;
  1451.       }
  1452.     }
  1453.   }
  1454. }