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

Audio

开发平台:

Visual C++

  1. /*!
  2. *************************************************************************************
  3. * file me_epzs.c
  4. *
  5. * brief
  6. *    Motion Estimation using EPZS
  7. *
  8. * author
  9. *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10. *      - Alexis Michael Tourapis <alexismt@ieee.org>
  11. *      - Athanasios Leontaris    <aleon@dolby.com>
  12. *
  13. *************************************************************************************
  14. */
  15. #include "contributors.h"
  16. #include <limits.h>
  17. #include "global.h"
  18. #include "image.h"
  19. #include "memalloc.h"
  20. #include "mb_access.h"
  21. #include "refbuf.h"
  22. #include "me_distortion.h"
  23. #include "me_epzs.h"
  24. #include "mv-search.h"
  25. #define EPZSREF 1
  26. // Define Global Parameters
  27. static const short blk_parent[8] = {1, 1, 1, 1, 2, 4, 4, 5}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
  28. //static const short blk_child[8]  = {1, 2, 4, 4, 5, 7, 7, 7}; //!< {skip, 16x16, 16x8, 8x16, 8x8, 8x4, 4x8, 4x4}
  29. static const int   minthres_base[8] = {0,  64,  32,  32,  16,  8,  8,  4};
  30. static const int   medthres_base[8] = {0, 256, 128, 128,  64, 32, 32, 16};
  31. static const int   maxthres_base[8] = {0, 768, 384, 384, 192, 96, 96, 48};
  32. static const short search_point_hp[10][2] = {{0,0},{-2,0}, {0,2}, {2,0},  {0,-2}, {-2,2},  {2,2},  {2,-2}, {-2,-2}, {-2,2}};
  33. static const short search_point_qp[10][2] = {{0,0},{-1,0}, {0,1}, {1,0},  {0,-1}, {-1,1},  {1,1},  {1,-1}, {-1,-1}, {-1,1}};
  34. //static const int   next_subpel_pos_start[5][5] = {};
  35. //static const int   next_subpel_pos_end  [5][5] = {};
  36. static int (*computePred)(imgpel* , int , int , int , int , int );
  37. static short EPZSBlkCount;
  38. static int   searcharray;
  39. static int   mv_rescale;
  40. //! Define EPZS Refinement patterns
  41. static int pattern_data[5][12][4] =
  42. {
  43.   { // Small Diamond pattern
  44.     {  0,  4,  3, 3 }, {  4,  0,  0, 3 }, {  0, -4,  1, 3 }, { -4,  0, 2, 3 }
  45.   },
  46.   { // Square pattern
  47.     {  0,  4,  7, 3 }, {  4,  4,  7, 5 }, {  4,  0,  1, 3 }, {  4, -4, 1, 5 },
  48.     {  0, -4,  3, 3 }, { -4, -4,  3, 5 }, { -4,  0,  5, 3 }, { -4,  4, 5, 5 }
  49.   },
  50.   { // Enhanced Diamond pattern
  51.     { -4,  4, 10, 5 }, {  0,  8, 10, 8 }, {  0,  4, 10, 7 }, {  4,  4, 1, 5 },
  52.     {  8,  0, 1,  8 }, {  4,  0,  1, 7 }, {  4, -4,  4, 5 }, {  0, -8, 4, 8 },
  53.     {  0, -4, 4,  7 }, { -4, -4, 7,  5 }, { -8,  0,  7, 8 }, { -4,  0, 7, 7 }
  54.   },
  55.   { // Large Diamond pattern
  56.     {  0,  8, 6,  5 }, {  4,  4, 0,  3 }, {  8,  0, 0,  5 }, {  4, -4, 2, 3 },
  57.     {  0, -8, 2,  5 }, { -4, -4, 4,  3 }, { -8,  0, 4,  5 }, { -4,  4, 6, 3 }
  58.   },
  59.   { // Extended Subpixel pattern
  60.     {  0,  8, 6, 12 }, {  4,  4, 0, 12 }, {  8,  0, 0, 12 }, {  4, -4, 2, 12 },
  61.     {  0, -8, 2, 12 }, { -4, -4, 4, 12 }, { -8,  0, 4, 12 }, { -4,  4, 6, 12 },
  62.     {  0,  2, 6, 12 }, {  2,  0, 0, 12 }, {  0, -2, 2, 12 }, { -2,  0, 4, 12 }
  63.   }
  64. };
  65. // Other definitions
  66. static const char c_EPZSPattern[6][20]     = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
  67. static const char c_EPZSDualPattern[7][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
  68. static const char c_EPZSFixed[3][20]       = { "Disabled","All P", "All P + B"};
  69. static const char c_EPZSOther[2][20]       = { "Disabled","Enabled"};
  70. static int medthres[8];
  71. static int maxthres[8];
  72. static int minthres[8];
  73. static int subthres[8];
  74. static int mv_scale[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES];
  75. static short **EPZSMap;  //!< Memory Map definition
  76. int ***EPZSDistortion;  //!< Array for storing SAD Values
  77. int ***EPZSBiDistortion;  //!< Array for storing SAD Values
  78. #if EPZSREF
  79. MotionVector *****EPZS_Motion;  //!< Array for storing Motion Vectors
  80. short ******EPZSMotion;  //!< Array for storing Motion Vectors
  81. #else
  82. MotionVector ****EPZS_Motion;  //!< Array for storing Motion Vectors
  83. short *****EPZSMotion;  //!< Array for storing Motion Vectors
  84. #endif
  85. //
  86. EPZSStructure *searchPattern,*searchPatternD, *predictor;
  87. EPZSStructure *window_predictor, *window_predictor_extended;
  88. EPZSStructure *sdiamond,*square,*ediamond,*ldiamond, *sbdiamond, *pmvfast;
  89. EPZSColocParams *EPZSCo_located;
  90. // Functions
  91. /*!
  92. *************************************************************************************
  93. * brief
  94. *    Determine stop criterion for EPZS
  95. *************************************************************************************
  96. */
  97. static int EPZSDetermineStopCriterion(int* prevSad, PixelPos *block_a, PixelPos *block_b, PixelPos *block_c, int pic_pix_x2, int blocktype, int blockshape_x)
  98. {
  99.   int sadA, sadB, sadC, stopCriterion;
  100.   sadA = block_a->available ? prevSad[pic_pix_x2 - blockshape_x] : INT_MAX;
  101.   sadB = block_b->available ? prevSad[pic_pix_x2] : INT_MAX;
  102.   sadC = block_c->available ? prevSad[pic_pix_x2 + blockshape_x] : INT_MAX;
  103.   stopCriterion = imin(sadA,imin(sadB,sadC));
  104.   stopCriterion = imax(stopCriterion,minthres[blocktype]);
  105.   stopCriterion = imin(stopCriterion,maxthres[blocktype]);
  106.   stopCriterion = (9 * imax (medthres[blocktype], stopCriterion) + 2 * medthres[blocktype]) >> 3;
  107.   return stopCriterion;
  108. }
  109. /*!
  110. ************************************************************************
  111. * brief
  112. *    Allocate co-located memory
  113. *
  114. * param size_x
  115. *    horizontal luma size
  116. * param size_y
  117. *    vertical luma size
  118. * param mb_adaptive_frame_field_flag
  119. *    flag that indicates macroblock adaptive frame/field coding
  120. *
  121. * return
  122. *    the allocated EPZSColocParams structure
  123. ************************************************************************
  124. */
  125. static EPZSColocParams* allocEPZScolocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
  126. {
  127.   EPZSColocParams *s;
  128.   s = calloc(1, sizeof(EPZSColocParams));
  129.   if (NULL == s)
  130.     no_mem_exit("alloc_EPZScolocated: s");
  131.   s->size_x = size_x;
  132.   s->size_y = size_y;
  133.   get_mem3Dmv(&(s->frame), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
  134.   if (mb_adaptive_frame_field_flag)
  135.   {
  136.     get_mem3Dmv(&(s->top), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
  137.     get_mem3Dmv(&(s->bot), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
  138.   }
  139.   s->mb_adaptive_frame_field_flag  = mb_adaptive_frame_field_flag;
  140.   return s;
  141. }
  142. /*!
  143. ************************************************************************
  144. * brief
  145. *    Free co-located memory.
  146. *
  147. * param p
  148. *    structure to be freed
  149. *
  150. ************************************************************************
  151. */
  152. static void freeEPZScolocated(EPZSColocParams* p)
  153. {
  154.   if (p)
  155.   {
  156.     free_mem3Dmv (p->frame);
  157.     if (p->mb_adaptive_frame_field_flag)
  158.     {
  159.       free_mem3Dmv (p->top);
  160.       free_mem3Dmv (p->bot);
  161.     }
  162.     free(p);
  163.     p=NULL;
  164.   }
  165. }
  166. /*!
  167. ************************************************************************
  168. * brief
  169. *    Allocate EPZS pattern memory
  170. *
  171. * param searchpoints
  172. *    number of searchpoints to allocate
  173. *
  174. * return
  175. *    the allocated EPZSStructure structure
  176. ************************************************************************
  177. */
  178. static EPZSStructure* allocEPZSpattern(int searchpoints)
  179. {
  180.   EPZSStructure *s;
  181.   s = calloc(1, sizeof(EPZSStructure));
  182.   if (NULL == s)
  183.     no_mem_exit("alloc_EPZSpattern: s");
  184.   s->searchPoints = searchpoints;
  185.   s->point = (SPoint*) calloc(searchpoints, sizeof(SPoint));
  186.   return s;
  187. }
  188. /*!
  189. ************************************************************************
  190. * brief
  191. *    Free EPZS pattern memory.
  192. *
  193. * param p
  194. *    structure to be freed
  195. *
  196. ************************************************************************
  197. */
  198. static void freeEPZSpattern(EPZSStructure* p)
  199. {
  200.   if (p)
  201.   {
  202.     free ( (SPoint*) p->point);
  203.     free(p);
  204.     p=NULL;
  205.   }
  206. }
  207. static void assignEPZSpattern(EPZSStructure *pattern,int type, int stopSearch, int nextLast, EPZSStructure *nextpattern)
  208. {
  209.   int i;
  210.   for (i = 0; i < pattern->searchPoints; i++)
  211.   {
  212.     pattern->point[i].motion.mv_x = pattern_data[type][i][0] >> mv_rescale;
  213.     pattern->point[i].motion.mv_y = pattern_data[type][i][1] >> mv_rescale;
  214.     pattern->point[i].start_nmbr  = pattern_data[type][i][2];
  215.     pattern->point[i].next_points = pattern_data[type][i][3];
  216.   }
  217.   pattern->stopSearch = stopSearch;
  218.   pattern->nextLast = nextLast;
  219.   pattern->nextpattern = nextpattern;
  220. }
  221. /*!
  222. ************************************************************************
  223. * brief
  224. *    calculate RoundLog2(uiVal)
  225. ************************************************************************
  226. */
  227. static int RoundLog2 (int iValue)
  228. {
  229.   int iRet = 0;
  230.   int iValue_square = iValue * iValue;
  231.   while ((1 << (iRet + 1)) <= iValue_square)
  232.     iRet++;
  233.   iRet = (iRet + 1) >> 1;
  234.   return iRet;
  235. }
  236. /*!
  237. ***********************************************************************
  238. * brief
  239. *    Add Predictor function
  240. *    
  241. ***********************************************************************
  242. */
  243. static inline int add_predictor(MotionVector *cur_mv, MotionVector prd_mv, int mvScale, int shift_mv)
  244. {
  245.   *cur_mv = prd_mv;
  246.   cur_mv->mv_x = rshift_rnd_sf((mvScale * cur_mv->mv_x), shift_mv);
  247.   cur_mv->mv_y = rshift_rnd_sf((mvScale * cur_mv->mv_y), shift_mv);
  248.   return (*((int*) cur_mv) != 0);
  249. }
  250. /*!
  251. ************************************************************************
  252. * brief
  253. *    EPZS Search Window Predictor Initialization
  254. ************************************************************************
  255. */
  256. static void EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
  257. {
  258.   int pos;
  259.   int searchpos, fieldsearchpos;
  260.   int prednum = 0;
  261.   int i;
  262.   int search_range_qpel = params->EPZSSubPelGrid ? 2 : 0;
  263.   if (mode == 0)
  264.   {
  265.     for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
  266.     {
  267.       searchpos = ((search_range << search_range_qpel)>> pos);
  268.       for (i=1; i>=-1; i-=2)
  269.       {
  270.         predictor->point[prednum  ].motion.mv_x =  i * searchpos;
  271.         predictor->point[prednum++].motion.mv_y =  0;
  272.         predictor->point[prednum  ].motion.mv_x =  i * searchpos;
  273.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  274.         predictor->point[prednum  ].motion.mv_x =  0;
  275.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  276.         predictor->point[prednum  ].motion.mv_x = -i * searchpos;
  277.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  278.       }
  279.     }
  280.   }
  281.   else // if (mode == 0)
  282.   {
  283.     for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
  284.     {
  285.       searchpos = ((search_range << search_range_qpel) >> pos);
  286.       fieldsearchpos = ((3 * searchpos + 1) << search_range_qpel) >> 1;
  287.       for (i=1; i>=-1; i-=2)
  288.       {
  289.         predictor->point[prednum  ].motion.mv_x =  i * searchpos;
  290.         predictor->point[prednum++].motion.mv_y =  0;
  291.         predictor->point[prednum  ].motion.mv_x =  i * searchpos;
  292.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  293.         predictor->point[prednum  ].motion.mv_x =  0;
  294.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  295.         predictor->point[prednum  ].motion.mv_x = -i * searchpos;
  296.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  297.       }
  298.       for (i=1; i>=-1; i-=2)
  299.       {
  300.         predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
  301.         predictor->point[prednum++].motion.mv_y = -i * searchpos;
  302.         predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
  303.         predictor->point[prednum++].motion.mv_y =  0;
  304.         predictor->point[prednum  ].motion.mv_x =  i * fieldsearchpos;
  305.         predictor->point[prednum++].motion.mv_y =  i * searchpos;
  306.         predictor->point[prednum  ].motion.mv_x =  i * searchpos;
  307.         predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
  308.         predictor->point[prednum  ].motion.mv_x =  0;
  309.         predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
  310.         predictor->point[prednum  ].motion.mv_x = -i * searchpos;
  311.         predictor->point[prednum++].motion.mv_y =  i * fieldsearchpos;
  312.       }
  313.     }
  314.   }
  315.   predictor->searchPoints = prednum;
  316. }
  317. /*!
  318. ************************************************************************
  319. * brief
  320. *    EPZS Global Initialization
  321. ************************************************************************
  322. */
  323. int EPZSInit (InputParameters *params, ImageParameters *img)
  324. {
  325.   int pel_error_me = 1 << (img->bitdepth_luma - 8);
  326.   int pel_error_me_cr = 1 << (img->bitdepth_chroma - 8);
  327.   int i, memory_size = 0;
  328.   double chroma_weight = params->ChromaMEEnable ? pel_error_me_cr * params->ChromaMEWeight * (double) (img->width_cr * img->height_cr) / (double) (img->width * img->height) : 0;
  329.   int searchlevels = RoundLog2 (params->search_range) - 1;
  330.   
  331.   searcharray = params->BiPredMotionEstimation? (2 * imax (params->search_range, params->BiPredMESearchRange) + 1) << (params->EPZSGrid) : (2 * params->search_range + 1)<< (params->EPZSGrid);
  332.   mv_rescale = params->EPZSSubPelGrid ? 0 : 2;
  333.   
  334.   //! In this implementation we keep threshold limits fixed.
  335.   //! However one could adapt these limits based on lagrangian
  336.   //! optimization considerations (i.e. qp), while also allow
  337.   //! adaptation of the limits themselves based on content or complexity.
  338.   for (i=0;i<8;i++)
  339.   {
  340.     medthres[i] = params->EPZSMedThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
  341.     maxthres[i] = params->EPZSMaxThresScale * (maxthres_base[i] * pel_error_me + (int) (maxthres_base[i] * chroma_weight + 0.5));
  342.     minthres[i] = params->EPZSMinThresScale * (minthres_base[i] * pel_error_me + (int) (minthres_base[i] * chroma_weight + 0.5));
  343.     subthres[i] = params->EPZSSubPelThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
  344.   }
  345.   //! Definition of pottential EPZS patterns.
  346.   //! It is possible to also define other patterns, or even use
  347.   //! resizing patterns (such as the PMVFAST scheme. These patterns
  348.   //! are only shown here as reference, while the same also holds
  349.   //! for this implementation (i.e. new conditions could be added
  350.   //! on adapting predictors, or thresholds etc. Note that search
  351.   //! could also be performed on subpel positions directly while
  352.   //! pattern needs not be restricted on integer positions only.
  353.   //! Allocate memory and assign search patterns
  354.   sdiamond = allocEPZSpattern(4);
  355.   assignEPZSpattern(sdiamond, SDIAMOND, TRUE, TRUE, sdiamond);
  356.   square = allocEPZSpattern(8);
  357.   assignEPZSpattern(square, SQUARE, TRUE, TRUE, square);
  358.   ediamond = allocEPZSpattern(12);
  359.   assignEPZSpattern(ediamond, EDIAMOND, TRUE, TRUE, ediamond);
  360.   ldiamond = allocEPZSpattern(8);
  361.   assignEPZSpattern(ldiamond, LDIAMOND, TRUE, TRUE, ldiamond);
  362.   sbdiamond = allocEPZSpattern(12);
  363.   assignEPZSpattern(sbdiamond, SBDIAMOND, FALSE, TRUE, sdiamond);
  364.   pmvfast = allocEPZSpattern(8);
  365.   assignEPZSpattern(pmvfast, LDIAMOND, FALSE, TRUE, sdiamond);
  366.   //! Allocate and assign window based predictors.
  367.   //! Other window types could also be used, while method could be
  368.   //! made a bit more adaptive (i.e. patterns could be assigned
  369.   //! based on neighborhood
  370.   window_predictor = allocEPZSpattern(searchlevels * 8);
  371.   window_predictor_extended = allocEPZSpattern(searchlevels * 20);
  372.   EPZSWindowPredictorInit ((short) params->search_range, window_predictor, 0);
  373.   EPZSWindowPredictorInit ((short) params->search_range, window_predictor_extended, 1);
  374.   //! Also assing search predictor memory
  375.   // maxwindow + spatial + blocktype + temporal + memspatial
  376.   predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (params->EPZSTemporal) + 3 * (params->EPZSSpatialMem));
  377.   //! Finally assign memory for all other elements
  378.   //! (distortion, EPZSMap, and temporal predictors)
  379.   //memory_size += get_offset_mem2Dshort(&EPZSMap, searcharray, searcharray, (searcharray>>1), (searcharray>>1));
  380.   memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
  381.   if (params->BiPredMotionEstimation)
  382.     memory_size += get_mem3Dint (&EPZSBiDistortion, 6, 7, img->width/BLOCK_SIZE);
  383.   memory_size += get_mem2Dshort (&EPZSMap, searcharray, searcharray );
  384.   if (params->EPZSSpatialMem)
  385.   {
  386. #if EPZSREF
  387.     memory_size += get_mem5Dmv (&EPZS_Motion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE);
  388.     memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2);
  389. #else
  390.     memory_size += get_mem4Dmv (&EPZS_Motion, 6, 7, 4, img->width/BLOCK_SIZE);
  391.     memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2);
  392. #endif
  393.   }
  394.   if (params->EPZSTemporal)
  395.     EPZSCo_located = allocEPZScolocated (img->width, img->height, active_sps->mb_adaptive_frame_field_flag);
  396.   switch (params->EPZSPattern)
  397.   {
  398.   case 5:
  399.     searchPattern = pmvfast;
  400.     break;
  401.   case 4:
  402.     searchPattern = sbdiamond;
  403.     break;
  404.   case 3:
  405.     searchPattern = ldiamond;
  406.     break;
  407.   case 2:
  408.     searchPattern = ediamond;
  409.     break;
  410.   case 1:
  411.     searchPattern = square;
  412.     break;
  413.   case 0:
  414.   default:
  415.     searchPattern = sdiamond;
  416.     break;
  417.   }
  418.   switch (params->EPZSDual)
  419.   {
  420.   case 6:
  421.     searchPatternD = pmvfast;
  422.     break;
  423.   case 5:
  424.     searchPatternD = sbdiamond;
  425.     break;
  426.   case 4:
  427.     searchPatternD = ldiamond;
  428.     break;
  429.   case 3:
  430.     searchPatternD = ediamond;
  431.     break;
  432.   case 2:
  433.     searchPatternD = square;
  434.     break;
  435.   case 1:
  436.   default:
  437.     searchPatternD = sdiamond;
  438.     break;
  439.   }
  440.   return memory_size;
  441. }
  442. /*!
  443. ************************************************************************
  444. * brief
  445. *    Delete EPZS Alocated memory
  446. ************************************************************************
  447. */
  448. void EPZSDelete (InputParameters *params)
  449. {
  450.   if (params->EPZSTemporal)
  451.     freeEPZScolocated (EPZSCo_located);
  452.   //free_offset_mem2Dshort(EPZSMap, searcharray, (searcharray>>1), (searcharray>>1));
  453.   free_mem2Dshort(EPZSMap);
  454.   free_mem3Dint  (EPZSDistortion);
  455.   if (params->BiPredMotionEstimation)
  456.     free_mem3Dint  (EPZSBiDistortion);
  457.   freeEPZSpattern(window_predictor_extended);
  458.   freeEPZSpattern(window_predictor);
  459.   freeEPZSpattern(predictor);
  460.   // Free search patterns
  461.   freeEPZSpattern(pmvfast);
  462.   freeEPZSpattern(sbdiamond);
  463.   freeEPZSpattern(ldiamond);
  464.   freeEPZSpattern(ediamond);
  465.   freeEPZSpattern(sdiamond);
  466.   freeEPZSpattern(square);
  467.   if (params->EPZSSpatialMem)
  468.   {
  469. #if EPZSREF
  470.     free_mem5Dmv (EPZS_Motion);
  471.     free_mem6Dshort (EPZSMotion);
  472. #else
  473.     free_mem4Dmv (EPZS_Motion);
  474.     free_mem5Dshort (EPZSMotion);
  475. #endif
  476.   }
  477. }
  478. //! For ME purposes restricting the co-located partition is not necessary.
  479. /*!
  480. ************************************************************************
  481. * brief
  482. *    EPZS Slice Level Initialization
  483. ************************************************************************
  484. */
  485. void EPZSSliceInit (InputParameters *params, ImageParameters *img, EPZSColocParams * p, StorablePicture ** listX[6])
  486. {
  487.   StorablePicture *fs, *fs_top, *fs_bottom;
  488.   StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
  489.   int i, j, k, jj, jdiv, loffset;
  490.   int prescale, iTRb, iTRp;
  491.   int list = img->type == B_SLICE ? LIST_1 : LIST_0;
  492.   int tempmv_scale[2];
  493.   int epzs_scale[2][6][MAX_LIST_SIZE];
  494.   int iref;
  495.   int invmv_precision = 8;
  496.   // Lets compute scaling factoes between all references in lists.
  497.   // Needed to scale spatial predictors.
  498.   for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
  499.   {
  500.     for (k = 0; k < listXsize[j]; k++)
  501.     {
  502.       for (i = 0; i < listXsize[j]; i++)
  503.       {
  504.         if ((j >> 1) == 0)
  505.         {
  506.           iTRb = iClip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
  507.           iTRp = iClip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
  508.         }
  509.         else if ((j >> 1) == 1)
  510.         {
  511.           iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
  512.           iTRp = iClip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
  513.         }
  514.         else
  515.         {
  516.           iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
  517.           iTRp = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
  518.         }
  519.         if (iTRp != 0)
  520.         {
  521.           prescale = (16384 + iabs (iTRp / 2)) / iTRp;
  522.           mv_scale[j][i][k] = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
  523.         }
  524.         else
  525.           mv_scale[j][i][k] = 256;
  526.       }
  527.     }
  528.   }
  529.   if (params->EPZSTemporal)
  530.   {
  531.     fs_top = fs_bottom = fs = listX[list][0];
  532.     if (listXsize[list]> 1)
  533.       fs_top1 = fs_bottom1 = fs1 = listX[list][1];
  534.     else
  535.       fs_top1 = fs_bottom1 = fs1 = listX[list][0];
  536.     for (j = 0; j < 6; j++)
  537.     {
  538.       for (i = 0; i < 6; i++)
  539.       {
  540.         epzs_scale[0][j][i] = 256;
  541.         epzs_scale[1][j][i] = 256;
  542.       }
  543.     }
  544.     for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
  545.     {
  546.       for (i = 0; i < listXsize[j]; i++)
  547.       {
  548.         if (j == 0)
  549.           iTRb = iClip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
  550.         else if (j == 2)
  551.           iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
  552.         else
  553.           iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
  554.         iTRp = iClip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
  555.         if (iTRp != 0)
  556.         {
  557.           prescale = (16384 + iabs (iTRp / 2)) / iTRp;
  558.           prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
  559.           //prescale = (iTRb * prescale + 32) >> 6;
  560.         }
  561.         else      // This could not happen but lets use it in case that reference is removed.
  562.           prescale = 256;
  563.         epzs_scale[0][j][i] = rshift_rnd_sf((mv_scale[j][0][i] * prescale), 8);
  564.         epzs_scale[0][j + 1][i] = prescale - 256;
  565.         
  566.         if (listXsize[list + j]>1)
  567.         {
  568.           iTRp = iClip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
  569.           if (iTRp != 0)
  570.           {
  571.             prescale = (16384 + iabs (iTRp / 2)) / iTRp;
  572.             prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
  573.             //prescale = (iTRb * prescale + 32) >> 6;
  574.           }
  575.           else      // This could not happen but lets use it for case that reference is removed.
  576.             prescale = 256;
  577.           epzs_scale[1][j][i] = rshift_rnd_sf((mv_scale[j][1][i] * prescale), 8);
  578.           epzs_scale[1][j + 1][i] = prescale - 256;
  579.         }
  580.         else
  581.         {
  582.           epzs_scale[1][j][i] = epzs_scale[0][j][i];
  583.           epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
  584.         }
  585.       }
  586.     }
  587.     if (img->MbaffFrameFlag)
  588.     {
  589.       fs_top = listX[list + 2][0];
  590.       fs_bottom = listX[list + 4][0];
  591.       if (listXsize[0]> 1)
  592.       {
  593.         fs_top1 = listX[list + 2][1];
  594.         fs_bottom = listX[list + 4][1];
  595.       }
  596.     }
  597.     else
  598.     {
  599.       if (img->structure != FRAME)
  600.       {
  601.         if ((img->structure != fs->structure) && (fs->coded_frame))
  602.         {
  603.           if (img->structure == TOP_FIELD)
  604.           {
  605.             fs_top = fs_bottom = fs = listX[list][0]->top_field;
  606.             fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
  607.           }
  608.           else
  609.           {
  610.             fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
  611.             fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
  612.           }
  613.         }
  614.       }
  615.     }
  616.     if (!active_sps->frame_mbs_only_flag)
  617.     {
  618.       if (img->MbaffFrameFlag)
  619.       {
  620.         for (j = 0; j < fs->size_y >> 2; j++)
  621.         {
  622.           jj = j >> 1;
  623.           jdiv = jj + 4 * (j >> 3);
  624.           for (i = 0; i < fs->size_x >> 2; i++)
  625.           {
  626.             if (fs->motion.field_frame[j][i])
  627.             {
  628.               //! Assign frame buffers for field MBs
  629.               //! Check whether we should use top or bottom field mvs.
  630.               //! Depending on the assigned poc values.
  631.               if (iabs (enc_picture->poc - fs_bottom->poc) > iabs (enc_picture->poc - fs_top->poc))
  632.               {
  633.                 tempmv_scale[LIST_0] = 256;
  634.                 tempmv_scale[LIST_1] = 0;
  635.                 if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
  636.                 {
  637.                   fsx = fs_top1;
  638.                   loffset = 1;
  639.                 }
  640.                 else
  641.                 {
  642.                   fsx = fs_top;
  643.                   loffset = 0;
  644.                 }
  645.                 if (fs->motion.ref_id [LIST_0][jdiv][i] != -1)
  646.                 {
  647.                   for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  648.                   {
  649.                     if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv][i])
  650.                     {
  651.                       tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  652.                       tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  653.                       break;
  654.                     }
  655.                   }
  656.                   p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  657.                   p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  658.                   p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  659.                   p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  660.                 }
  661.                 else
  662.                 {
  663.                   p->frame[LIST_0][j][i].mv_x = 0;
  664.                   p->frame[LIST_0][j][i].mv_y = 0;
  665.                   p->frame[LIST_1][j][i].mv_x = 0;
  666.                   p->frame[LIST_1][j][i].mv_y = 0;
  667.                 }
  668.               }
  669.               else
  670.               {
  671.                 tempmv_scale[LIST_0] = 256;
  672.                 tempmv_scale[LIST_1] = 0;
  673.                 if (fs->motion.ref_id [LIST_0][jdiv + 4][i] < 0 && listXsize[LIST_0] > 1)
  674.                 {
  675.                   fsx = fs_bottom1;
  676.                   loffset = 1;
  677.                 }
  678.                 else
  679.                 {
  680.                   fsx = fs_bottom;
  681.                   loffset = 0;
  682.                 }
  683.                 if (fs->motion.ref_id [LIST_0][jdiv + 4][i] != -1)
  684.                 {
  685.                   for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  686.                   {
  687.                     if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv + 4][i])
  688.                     {
  689.                       tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  690.                       tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  691.                       break;
  692.                     }
  693.                   }
  694.                   p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  695.                   p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  696.                   p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  697.                   p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  698.                 }
  699.                 else
  700.                 {
  701.                   p->frame[LIST_0][j][i].mv_x = 0;
  702.                   p->frame[LIST_0][j][i].mv_y = 0;
  703.                   p->frame[LIST_1][j][i].mv_x = 0;
  704.                   p->frame[LIST_1][j][i].mv_y = 0;
  705.                 }
  706.               }
  707.             }
  708.             else
  709.             {
  710.               tempmv_scale[LIST_0] = 256;
  711.               tempmv_scale[LIST_1] = 0;
  712.               if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  713.               {
  714.                 fsx = fs1;
  715.                 loffset = 1;
  716.               }
  717.               else
  718.               {
  719.                 fsx = fs;
  720.                 loffset = 0;
  721.               }
  722.               if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  723.               {
  724.                 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  725.                 {
  726.                   if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
  727.                   {
  728.                     tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  729.                     tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  730.                     break;
  731.                   }
  732.                 }
  733.                 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  734.                 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  735.                 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  736.                 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  737.               }
  738.               else
  739.               {
  740.                 p->frame[LIST_0][j][i].mv_x = 0;
  741.                 p->frame[LIST_0][j][i].mv_y = 0;
  742.                 p->frame[LIST_1][j][i].mv_x = 0;
  743.                 p->frame[LIST_1][j][i].mv_y = 0;
  744.               }
  745.             }
  746.           }
  747.         }
  748.       }
  749.       else
  750.       {
  751.         for (j = 0; j < fs->size_y >> 2; j++)
  752.         {
  753.           jj = j >> 1;
  754.           jdiv = jj + 4 * (j >> 3);
  755.           for (i = 0; i < fs->size_x >> 2; i++)
  756.           {
  757.             tempmv_scale[LIST_0] = 256;
  758.             tempmv_scale[LIST_1] = 0;
  759.             if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  760.             {
  761.               fsx = fs1;
  762.               loffset = 1;
  763.             }
  764.             else
  765.             {
  766.               fsx = fs;
  767.               loffset = 0;
  768.             }
  769.             if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  770.             {
  771.               for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  772.               {
  773.                 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
  774.                 {
  775.                   tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  776.                   tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  777.                   break;
  778.                 }
  779.               }
  780.               p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  781.               p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  782.               p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  783.               p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  784.             }
  785.             else
  786.             {
  787.               p->frame[LIST_0][j][i].mv_x = 0;
  788.               p->frame[LIST_0][j][i].mv_y = 0;
  789.               p->frame[LIST_1][j][i].mv_x = 0;
  790.               p->frame[LIST_1][j][i].mv_y = 0;
  791.             }
  792.           }
  793.         }
  794.       }
  795.       
  796.       //! Generate field MVs from Frame MVs
  797.       if (img->structure || img->MbaffFrameFlag)
  798.       {
  799.         for (j = 0; j < fs->size_y / 8; j++)
  800.         {
  801.           for (i = 0; i < fs->size_x / 4; i++)
  802.           {
  803.             if (!img->MbaffFrameFlag)
  804.             {
  805.               tempmv_scale[LIST_0] = 256;
  806.               tempmv_scale[LIST_1] = 0;
  807.               if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  808.               {
  809.                 fsx = fs1;
  810.                 loffset = 1;
  811.               }
  812.               else
  813.               {
  814.                 fsx = fs;
  815.                 loffset = 0;
  816.               }
  817.               if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  818.               {
  819.                 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  820.                 {
  821.                   if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
  822.                   {
  823.                     tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  824.                     tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  825.                     break;
  826.                   }
  827.                 }
  828.                 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  829.                 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  830.                 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  831.                 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  832.               }
  833.               else
  834.               {
  835.                 p->frame[LIST_0][j][i].mv_x = 0;
  836.                 p->frame[LIST_0][j][i].mv_y = 0;
  837.                 p->frame[LIST_1][j][i].mv_x = 0;
  838.                 p->frame[LIST_1][j][i].mv_y = 0;
  839.               }
  840.             }
  841.             else
  842.             {
  843.               tempmv_scale[LIST_0] = 256;
  844.               tempmv_scale[LIST_1] = 0;
  845.               if (fs_bottom->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  846.               {
  847.                 fsx = fs_bottom1;
  848.                 loffset = 1;
  849.               }
  850.               else
  851.               {
  852.                 fsx = fs_bottom;
  853.                 loffset = 0;
  854.               }
  855.               if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  856.               {
  857.                 for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 4]); iref++)
  858.                 {
  859.                   if (enc_picture->ref_pic_num[LIST_0 + 4][iref]==fsx->motion.ref_id [LIST_0][j][i])
  860.                   {
  861.                     tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref];
  862.                     tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref];
  863.                     break;
  864.                   }
  865.                 }
  866.                 p->bot[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  867.                 p->bot[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  868.                 p->bot[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  869.                 p->bot[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  870.               }
  871.               else
  872.               {
  873.                 p->bot[LIST_0][j][i].mv_x = 0;
  874.                 p->bot[LIST_0][j][i].mv_y = 0;
  875.                 p->bot[LIST_1][j][i].mv_x = 0;
  876.                 p->bot[LIST_1][j][i].mv_y = 0;
  877.               }
  878.               if (!fs->motion.field_frame[2 * j][i])
  879.               {
  880.                 p->bot[LIST_0][j][i].mv_y  = (p->bot[LIST_0][j][i].mv_y + 1) >> 1;
  881.                 p->bot[LIST_1][j][i].mv_y  = (p->bot[LIST_1][j][i].mv_y + 1) >> 1;
  882.               }
  883.               tempmv_scale[LIST_0] = 256;
  884.               tempmv_scale[LIST_1] = 0;
  885.               if (fs_top->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  886.               {
  887.                 fsx = fs_top1;
  888.                 loffset = 1;
  889.               }
  890.               else
  891.               {
  892.                 fsx = fs_top;
  893.                 loffset = 0;
  894.               }
  895.               if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  896.               {
  897.                 for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 2]); iref++)
  898.                 {
  899.                   if (enc_picture->ref_pic_num[LIST_0 + 2][iref]==fsx->motion.ref_id [LIST_0][j][i])
  900.                   {
  901.                     tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref];
  902.                     tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref];
  903.                     break;
  904.                   }
  905.                 }
  906.                 p->top[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  907.                 p->top[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  908.                 p->top[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  909.                 p->top[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  910.               }
  911.               else
  912.               {
  913.                 p->top[LIST_0][j][i].mv_x = 0;
  914.                 p->top[LIST_0][j][i].mv_y = 0;
  915.                 p->top[LIST_1][j][i].mv_x = 0;
  916.                 p->top[LIST_1][j][i].mv_y = 0;
  917.               }
  918.               if (!fs->motion.field_frame[2 * j][i])
  919.               {
  920.                 p->top[LIST_0][j][i].mv_y  = (p->top[LIST_0][j][i].mv_y + 1) >> 1;
  921.                 p->top[LIST_1][j][i].mv_y  = (p->top[LIST_1][j][i].mv_y + 1) >> 1;
  922.               }
  923.             }
  924.           }
  925.         }
  926.       }
  927.     }
  928.     //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
  929.     if (!active_sps->frame_mbs_only_flag )
  930.     {
  931.       //! Use inference flag to remap mvs/references
  932.       //! Frame with field co-located
  933.       if (!img->structure)
  934.       {
  935.         for (j = 0; j < fs->size_y >> 2; j++)
  936.         {
  937.           jj = j>>1;
  938.           jdiv = (j>>1) + ((j>>3) << 2);
  939.           for (i = 0; i < fs->size_x >> 2; i++)
  940.           {
  941.             if (fs->motion.field_frame[j][i])
  942.             {
  943.               tempmv_scale[LIST_0] = 256;
  944.               tempmv_scale[LIST_1] = 0;
  945.               if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
  946.               {
  947.                 fsx = fs1;
  948.                 loffset = 1;
  949.               }
  950.               else
  951.               {
  952.                 fsx = fs;
  953.                 loffset = 0;
  954.               }
  955.               if (fsx->motion.ref_id [LIST_0][jdiv][i] != -1)
  956.               {
  957.                 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  958.                 {
  959.                   if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][jdiv][i])
  960.                   {
  961.                     tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  962.                     tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  963.                     break;
  964.                   }
  965.                 }
  966.                 if (iabs (enc_picture->poc - fsx->bottom_field->poc) > iabs (enc_picture->poc - fsx->top_field->poc))
  967.                 {
  968.                   p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  969.                   p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  970.                   p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  971.                   p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  972.                 }
  973.                 else
  974.                 {
  975.                   p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  976.                   p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  977.                   p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
  978.                   p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
  979.                 }
  980.               }
  981.               else
  982.               {
  983.                 p->frame[LIST_0][j][i].mv_x = 0;
  984.                 p->frame[LIST_0][j][i].mv_y = 0;
  985.                 p->frame[LIST_1][j][i].mv_x = 0;
  986.                 p->frame[LIST_1][j][i].mv_y = 0;
  987.               }
  988.             }
  989.           }
  990.         }
  991.       }
  992.     }
  993.     if (active_sps->frame_mbs_only_flag)
  994.     {
  995.       for (j = 0; j < fs->size_y >> 2; j++)
  996.       {
  997.         for (i = 0; i < fs->size_x >> 2; i++)
  998.         {
  999.           tempmv_scale[LIST_0] = 256;
  1000.           tempmv_scale[LIST_1] = 0;
  1001.           if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
  1002.           {
  1003.             fsx = fs1;
  1004.             loffset = 1;
  1005.           }
  1006.           else
  1007.           {
  1008.             fsx = fs;
  1009.             loffset = 0;
  1010.           }
  1011.          
  1012.           if (fsx->motion.ref_id [LIST_0][j][i] != -1)
  1013.           {
  1014.             for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
  1015.             {
  1016.               if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
  1017.               {
  1018.                 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
  1019.                 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
  1020.                 break;
  1021.               }
  1022.             }
  1023.             p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  1024.             p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  1025.             p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
  1026.             p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
  1027.           }
  1028.           else
  1029.           {
  1030.             p->frame[LIST_0][j][i].mv_x = 0;
  1031.             p->frame[LIST_0][j][i].mv_y = 0;
  1032.             p->frame[LIST_1][j][i].mv_x = 0;
  1033.             p->frame[LIST_1][j][i].mv_y = 0;
  1034.           }
  1035.         }
  1036.       }
  1037.     }
  1038.     if (!active_sps->frame_mbs_only_flag)
  1039.     {
  1040.       for (j = 0; j < fs->size_y >> 2; j++)
  1041.       {
  1042.         for (i = 0; i < fs->size_x >> 2; i++)
  1043.         {
  1044.           if ((!img->MbaffFrameFlag && !img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i]))
  1045.           {
  1046.             p->frame[LIST_0][j][i].mv_y *= 2; 
  1047.             p->frame[LIST_1][j][i].mv_y *= 2;
  1048.           }
  1049.           else if (img->structure && !fs->motion.field_frame[j][i])
  1050.           {
  1051.             p->frame[LIST_0][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_0][j][i].mv_y, 1);
  1052.             p->frame[LIST_1][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_1][j][i].mv_y, 1);
  1053.           }
  1054.         }
  1055.       }
  1056.     }
  1057.   }
  1058. }
  1059. /*!
  1060. ***********************************************************************
  1061. * brief
  1062. *    Spatial Predictors
  1063. *    AMT/HYC
  1064. ***********************************************************************
  1065. */
  1066. static short EPZSSpatialPredictors (PixelPos block_a,
  1067.                                     PixelPos block_b,
  1068.                                     PixelPos block_c,
  1069.                                     PixelPos block_d,
  1070.                                     int list,
  1071.                                     int list_offset,
  1072.                                     short ref,
  1073.                                     char **refPic,
  1074.                                     short ***tmp_mv,
  1075.                                     EPZSStructure * predictor)
  1076. {
  1077.   int refA, refB, refC, refD;
  1078.   int *mot_scale = mv_scale[list + list_offset][ref];
  1079.   short sp_shift_mv = 8 + mv_rescale;
  1080.   int   fixed_mv = (12 >> mv_rescale);
  1081.   // zero predictor
  1082.   predictor->point[0].motion.mv_x = 0;
  1083.   predictor->point[0].motion.mv_y = 0;
  1084.   // Non MB-AFF mode
  1085.   if (!img->MbaffFrameFlag)
  1086.   {
  1087.     refA = block_a.available ? (int) refPic[block_a.pos_y][block_a.pos_x] : -1;
  1088.     refB = block_b.available ? (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
  1089.     refC = block_c.available ? (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
  1090.     refD = block_d.available ? (int) refPic[block_d.pos_y][block_d.pos_x] : -1;
  1091.     // Left Predictor
  1092.     if (block_a.available)
  1093.     {
  1094.       predictor->point[1].motion.mv_x = rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0]), sp_shift_mv);
  1095.       predictor->point[1].motion.mv_y = rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv);
  1096.     }
  1097.     else
  1098.     {
  1099.       predictor->point[1].motion.mv_x = fixed_mv;
  1100.       predictor->point[1].motion.mv_y = 0;
  1101.     }
  1102.     // Up predictor
  1103.     if (block_b.available)
  1104.     {
  1105.       predictor->point[2].motion.mv_x = rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0]), sp_shift_mv);
  1106.       predictor->point[2].motion.mv_y = rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv);
  1107.     }
  1108.     else
  1109.     {
  1110.       predictor->point[2].motion.mv_x = 0;
  1111.       predictor->point[2].motion.mv_y = fixed_mv;
  1112.     }
  1113.     // Up-Right predictor
  1114.     if (block_c.available)
  1115.     {
  1116.       predictor->point[3].motion.mv_x = rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0]), sp_shift_mv);
  1117.       predictor->point[3].motion.mv_y = rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv);
  1118.     }
  1119.     else
  1120.     {
  1121.       predictor->point[3].motion.mv_x = -fixed_mv;
  1122.       predictor->point[3].motion.mv_y = 0;
  1123.     }
  1124.     //Up-Left predictor
  1125.     if (block_d.available)
  1126.     {
  1127.       predictor->point[4].motion.mv_x = rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0]), sp_shift_mv);
  1128.       predictor->point[4].motion.mv_y = rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv);
  1129.     }
  1130.     else
  1131.     {
  1132.       predictor->point[4].motion.mv_x = 0;
  1133.       predictor->point[4].motion.mv_y = -fixed_mv;
  1134.     }
  1135.   }
  1136.   else  // MB-AFF mode
  1137.   {
  1138.     // Field Macroblock
  1139.     if (list_offset)
  1140.     {
  1141.       refA = block_a.available
  1142.         ? img->mb_data[block_a.mb_addr].mb_field
  1143.         ? (int) refPic[block_a.pos_y][block_a.pos_x]
  1144.         : (int) refPic[block_a.pos_y][block_a.pos_x] * 2 : -1;
  1145.       refB =block_b.available
  1146.         ? img->mb_data[block_b.mb_addr].mb_field
  1147.         ? (int) refPic[block_b.pos_y][block_b.pos_x]
  1148.         : (int) refPic[block_b.pos_y][block_b.pos_x] * 2 : -1;
  1149.       refC = block_c.available
  1150.         ? img->mb_data[block_c.mb_addr].mb_field
  1151.         ? (int) refPic[block_c.pos_y][block_c.pos_x]
  1152.         : (int) refPic[block_c.pos_y][block_c.pos_x] * 2 : -1;
  1153.       refD = block_d.available
  1154.         ? img->mb_data[block_d.mb_addr].mb_field
  1155.         ? (int) refPic[block_d.pos_y][block_d.pos_x]
  1156.         : (int) refPic[block_d.pos_y][block_d.pos_x] * 2 : -1;
  1157.       // Left Predictor
  1158.       predictor->point[1].motion.mv_x = (block_a.available)
  1159.         ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0]), sp_shift_mv) :  fixed_mv;
  1160.       predictor->point[1].motion.mv_y = (block_a.available)
  1161.         ? img->mb_data[block_a.mb_addr].mb_field
  1162.         ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv)
  1163.         : rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv + 1) :  0;
  1164.       // Up predictor
  1165.       predictor->point[2].motion.mv_x = (block_b.available)
  1166.         ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0]), sp_shift_mv) : 0;
  1167.       predictor->point[2].motion.mv_y = (block_b.available)
  1168.         ? img->mb_data[block_b.mb_addr].mb_field
  1169.         ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv)
  1170.         : rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv + 1) : fixed_mv;
  1171.       // Up-Right predictor
  1172.       predictor->point[3].motion.mv_x = (block_c.available)
  1173.         ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0]), sp_shift_mv) : -fixed_mv;
  1174.       predictor->point[3].motion.mv_y = (block_c.available)
  1175.         ? img->mb_data[block_c.mb_addr].mb_field
  1176.         ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv)
  1177.         : rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv + 1) : 0;
  1178.       //Up-Left predictor
  1179.       predictor->point[4].motion.mv_x = (block_d.available)
  1180.         ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0]), sp_shift_mv) : 0;
  1181.       predictor->point[4].motion.mv_y = (block_d.available)
  1182.         ? img->mb_data[block_d.mb_addr].mb_field
  1183.         ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv)
  1184.         : rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv + 1) : -fixed_mv;
  1185.     }
  1186.     else // Frame macroblock
  1187.     {
  1188.       refA = block_a.available
  1189.         ? img->mb_data[block_a.mb_addr].mb_field
  1190.         ? (int) refPic[block_a.pos_y][block_a.pos_x] >> 1
  1191.         : (int) refPic[block_a.pos_y][block_a.pos_x] : -1;
  1192.       refB = block_b.available
  1193.         ? img->mb_data[block_b.mb_addr].mb_field
  1194.         ? (int) refPic[block_b.pos_y][block_b.pos_x] >> 1
  1195.         : (int) refPic[block_b.pos_y][block_b.pos_x] : -1;
  1196.       refC = block_c.available
  1197.         ? img->mb_data[block_c.mb_addr].mb_field
  1198.         ? (int) refPic[block_c.pos_y][block_c.pos_x] >> 1
  1199.         : (int) refPic[block_c.pos_y][block_c.pos_x] : -1;
  1200.       refD = block_d.available
  1201.         ? img->mb_data[block_d.mb_addr].mb_field
  1202.         ? (int) refPic[block_d.pos_y][block_d.pos_x] >> 1
  1203.         : (int) refPic[block_d.pos_y][block_d.pos_x] : -1;
  1204.       // Left Predictor
  1205.       predictor->point[1].motion.mv_x = (block_a.available)
  1206.         ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][0]), sp_shift_mv) : fixed_mv;
  1207.       predictor->point[1].motion.mv_y = (block_a.available)
  1208.         ? img->mb_data[block_a.mb_addr].mb_field
  1209.         ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv - 1)
  1210.         : rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a.pos_y][block_a.pos_x][1]), sp_shift_mv) : 0;
  1211.       // Up predictor
  1212.       predictor->point[2].motion.mv_x = (block_b.available)
  1213.         ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][0]), sp_shift_mv) : 0;
  1214.       predictor->point[2].motion.mv_y = (block_b.available)
  1215.         ? img->mb_data[block_b.mb_addr].mb_field
  1216.         ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv - 1)
  1217.         : rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b.pos_y][block_b.pos_x][1]), sp_shift_mv) :  fixed_mv;
  1218.       // Up-Right predictor
  1219.       predictor->point[3].motion.mv_x = (block_c.available)
  1220.         ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][0]), sp_shift_mv) : -fixed_mv;
  1221.       predictor->point[3].motion.mv_y = (block_c.available)
  1222.         ? img->mb_data[block_c.mb_addr].mb_field
  1223.         ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv - 1)
  1224.         : rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c.pos_y][block_c.pos_x][1]), sp_shift_mv) : 0;
  1225.       //Up-Left predictor
  1226.       predictor->point[4].motion.mv_x = (block_d.available)
  1227.         ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][0]), sp_shift_mv) : 0;
  1228.       predictor->point[4].motion.mv_y = (block_d.available)
  1229.         ? img->mb_data[block_d.mb_addr].mb_field
  1230.         ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv - 1)
  1231.         : rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d.pos_y][block_d.pos_x][1]), sp_shift_mv) : -fixed_mv;
  1232.     }
  1233.   }
  1234.   return ((refA == -1) + (refB == -1) + (refC == -1 && refD == -1));
  1235. }
  1236. /*!
  1237. ***********************************************************************
  1238. * brief
  1239. *    Spatial Predictors
  1240. *    AMT/HYC
  1241. ***********************************************************************
  1242. */
  1243. static void EPZSSpatialMemPredictors (int list,
  1244.                                       short ref,
  1245.                                       int blocktype,
  1246.                                       int pic_x,
  1247.                                       int bs_x,
  1248.                                       int bs_y,
  1249.                                       int by,
  1250.                                       int *prednum,
  1251.                                       int img_width,
  1252.                                       EPZSStructure * predictor)
  1253. {
  1254. #if EPZSREF
  1255.   short ***mv = EPZSMotion[list][ref][blocktype];
  1256.   //MotionVector ***prd_mv = &EPZS_Motion[list][ref][blocktype];
  1257.   MotionVector *cur_mv = &predictor->point[*prednum].motion;
  1258.   // Left Predictor
  1259.   if (pic_x > 0)
  1260.   {
  1261.     cur_mv->mv_x = mv[by][pic_x - bs_x][0];
  1262.     cur_mv->mv_y = mv[by][pic_x - bs_x][1];
  1263.     *prednum += (*((int*) cur_mv) != 0);
  1264.     cur_mv = &predictor->point[*prednum].motion;
  1265.   }
  1266.   
  1267.   by = (by > 0) ? by - bs_y: 4 - bs_y;
  1268.   // Up predictor  
  1269.   cur_mv->mv_x = mv[by][pic_x][0];
  1270.   cur_mv->mv_y = mv[by][pic_x][1];
  1271.   *prednum += (*((int*) cur_mv) != 0);
  1272.   // Up-Right predictor
  1273.   if (pic_x + bs_x < img_width)
  1274.   {
  1275.     cur_mv = &predictor->point[*prednum].motion;
  1276.     cur_mv->mv_x = mv[by][pic_x + bs_x][0];
  1277.     cur_mv->mv_y = mv[by][pic_x + bs_x][1];
  1278.     *prednum += (*((int*) cur_mv) != 0);
  1279.   }
  1280. #else
  1281.   int mot_scale = mv_scale[list][ref][0];
  1282.   short **mv = EPZSMotion[list][blocktype];
  1283.   MotionVector **predictor = &EPZS_Motion[list][blocktype];
  1284.   // Left Predictor
  1285.   predictor->point[*prednum].motion.mv_x = (pic_x > 0)
  1286.     ? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][0]), 8)
  1287.     : 0;
  1288.   predictor->point[*prednum].motion.mv_y = (pic_x > 0)
  1289.     ? rshift_rnd_sf((mot_scale * mv[by][pic_x - bs_x][1]), 8)
  1290.     : 0;
  1291.   *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
  1292.   // Up predictor
  1293.   predictor->point[*prednum].motion.mv_x = (by > 0)
  1294.     ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][0]), 8)
  1295.     : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x][0]), 8);
  1296.   predictor->point[*prednum].motion.mv_y = (by > 0)
  1297.     ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x][1]), 8)
  1298.     : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x][1]), 8);
  1299.   *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
  1300.   // Up-Right predictor
  1301.   predictor->point[*prednum].motion.mv_x = (pic_x + bs_x < img_width)
  1302.     ? (by > 0)
  1303.     ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][0]), 8)
  1304.     : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x + bs_x][0]), 8)
  1305.     : 0;
  1306.   predictor->point[*prednum].motion.mv_y = (pic_x + bs_x < img_width)
  1307.     ? (by > 0)
  1308.     ? rshift_rnd_sf((mot_scale * mv[by - bs_y][pic_x + bs_x][1]), 8)
  1309.     : rshift_rnd_sf((mot_scale * mv[4  - bs_y][pic_x + bs_x][1]), 8)
  1310.     : 0;
  1311.   *prednum += ((predictor->point[*prednum].motion.mv_x != 0) || (predictor->point[*prednum].motion.mv_y != 0));
  1312. #endif
  1313. }
  1314. /*!
  1315. ***********************************************************************
  1316. * brief
  1317. *    Temporal Predictors
  1318. *    AMT/HYC
  1319. ***********************************************************************
  1320. */
  1321. static void
  1322. EPZSTemporalPredictors (int list,         // <--  current list
  1323.                         int list_offset,  // <--  list offset for MBAFF
  1324.                         short ref,        // <--  current reference frame
  1325.                         int o_block_x,    // <--  absolute x-coordinate of regarded AxB block
  1326.                         int o_block_y,    // <--  absolute y-coordinate of regarded AxB block
  1327.                         EPZSStructure * predictor,
  1328.                         int *prednum,
  1329.                         int block_available_left,
  1330.                         int block_available_up,
  1331.                         int block_available_right,
  1332.                         int block_available_below,
  1333.                         int blockshape_x,
  1334.                         int blockshape_y,
  1335.                         int stopCriterion,
  1336.                         int min_mcost)
  1337. {
  1338.   int mvScale = mv_scale[list + list_offset][ref][0];
  1339.   MotionVector **col_mv = (list_offset == 0) ? EPZSCo_located->frame[list]  
  1340.     : (list_offset == 2) ? EPZSCo_located->top[list] : EPZSCo_located->bot[list];
  1341.   short temp_shift_mv = 8 + mv_rescale; // 16 - invmv_precision + mv_rescale
  1342.   MotionVector *cur_mv = &predictor->point[*prednum].motion;
  1343.   *prednum += add_predictor(cur_mv, col_mv[o_block_y][o_block_x], mvScale, temp_shift_mv);
  1344.   if (min_mcost > stopCriterion && ref < 2)
  1345.   {
  1346.     if (block_available_left)
  1347.     {
  1348.       *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, temp_shift_mv);
  1349.       //Up_Left
  1350.       if (block_available_up)
  1351.       {
  1352.         *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, temp_shift_mv);
  1353.       }
  1354.       //Down_Left
  1355.       if (block_available_below)
  1356.       {
  1357.         *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, temp_shift_mv);
  1358.       }
  1359.     }
  1360.     // Up
  1361.     if (block_available_up)
  1362.     {
  1363.       *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, temp_shift_mv);
  1364.     }
  1365.     // Up - Right
  1366.     if (block_available_right)
  1367.     {
  1368.       *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
  1369.       if (block_available_up)
  1370.       {
  1371.         *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, temp_shift_mv);
  1372.       }
  1373.       if (block_available_below)
  1374.       {
  1375.         *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
  1376.       }
  1377.     }
  1378.     if (block_available_below)
  1379.     {
  1380.       *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, temp_shift_mv);
  1381.     }
  1382.   }
  1383. }
  1384. /*!
  1385. ************************************************************************
  1386. * brief
  1387. *    EPZS Block Type Predictors
  1388. ************************************************************************
  1389. */
  1390. static void EPZSBlockTypePredictors (int block_x, int block_y, int blocktype, int ref, int list,
  1391.                                      EPZSStructure * predictor, int *prednum)
  1392. {
  1393.   short *****all_mv = img->all_mv[list];
  1394.   short block_shift_mv = 8 + mv_rescale;
  1395.   MotionVector *cur_mv = &predictor->point[*prednum].motion;
  1396.   cur_mv->mv_x = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][0]), mv_rescale);
  1397.   cur_mv->mv_y = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][1]), mv_rescale);
  1398.   //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  1399.   *prednum += (*((int*) cur_mv) != 0);
  1400.   if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
  1401.   {
  1402.     cur_mv = &predictor->point[*prednum].motion;
  1403.     cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][0]), block_shift_mv );
  1404.     cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][1]), block_shift_mv );
  1405.     //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  1406.     *prednum += (*((int*) cur_mv) != 0);
  1407.     cur_mv = &predictor->point[*prednum].motion;
  1408.     cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][0]), block_shift_mv );
  1409.     cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][1]), block_shift_mv );
  1410.     //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  1411.     *prednum += (*((int*) cur_mv) != 0);
  1412.   }
  1413.   if (blocktype != 1)
  1414.   {
  1415.     cur_mv = &predictor->point[*prednum].motion;
  1416.     cur_mv->mv_x = rshift_rnd((all_mv[ref][1][block_y][block_x][0]), mv_rescale);
  1417.     cur_mv->mv_y = rshift_rnd((all_mv[ref][1][block_y][block_x][1]), mv_rescale);
  1418.     //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  1419.     *prednum += (*((int*) cur_mv) != 0);
  1420.   }
  1421.   if (blocktype != 4)
  1422.   {
  1423.     cur_mv = &predictor->point[*prednum].motion;
  1424.     cur_mv->mv_x = rshift_rnd((all_mv[ref][4][block_y][block_x][0]), mv_rescale);
  1425.     cur_mv->mv_y = rshift_rnd((all_mv[ref][4][block_y][block_x][1]), mv_rescale);
  1426.     //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0);
  1427.     *prednum += (*((int*) cur_mv) != 0);
  1428.   }
  1429. }
  1430. /*!
  1431. ************************************************************************
  1432. * brief
  1433. *    EPZS Window Based Predictors
  1434. ************************************************************************
  1435. */
  1436. static void EPZSWindowPredictors (short mv[2], EPZSStructure *predictor, int *prednum, int extended)
  1437. {
  1438.   int pos;
  1439.   EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;
  1440.   SPoint *wPoint = &windowPred->point[0];
  1441.   SPoint *pPoint = &predictor->point[(*prednum)];
  1442.   for (pos = 0; pos < windowPred->searchPoints; pos++)
  1443.   {
  1444.     (pPoint  )->motion.mv_x = mv[0] + (wPoint  )->motion.mv_x;
  1445.     (pPoint++)->motion.mv_y = mv[1] + (wPoint++)->motion.mv_y;    
  1446.   }
  1447.   *prednum += windowPred->searchPoints;
  1448. }
  1449. /*!
  1450. ***********************************************************************
  1451. * brief
  1452. *    FAST Motion Estimation using EPZS
  1453. *    AMT/HYC
  1454. ***********************************************************************
  1455. */
  1456. int                                           //  ==> minimum motion cost after search
  1457. EPZSPelBlockMotionSearch (Macroblock *currMB, // <--  current Macroblock
  1458.                           imgpel * cur_pic,   // <--  original pixel values for the AxB block
  1459.                           short ref,          // <--  reference picture
  1460.                           int list,           // <--  reference list
  1461.                           int list_offset,    // <--  offset for Mbaff
  1462.                           char ***refPic,     // <--  reference array
  1463.                           short ****tmp_mv,   // <--  mv array
  1464.                           int pic_pix_x,      // <--  absolute x-coordinate of regarded AxB block
  1465.                           int pic_pix_y,      // <--  absolute y-coordinate of regarded AxB block
  1466.                           int blocktype,      // <--  block type (1-16x16 ... 7-4x4)
  1467.                           short pred_mv[2],   // <--  motion vector predictor in sub-pel units
  1468.                           short mv[2],        // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  1469.                           int search_range,   // <--  1-d search range in pel units
  1470.                           int min_mcost,      // <--  minimum motion cost (cost for center or huge value)
  1471.                           int lambda_factor,  // <--  lagrangian parameter for determining motion cost
  1472.                           int apply_weights)  // <--  perform weight based ME
  1473. {
  1474.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  1475.   short blocksize_y = params->blc_size[blocktype][1];  // vertical block size
  1476.   short blocksize_x = params->blc_size[blocktype][0];  // horizontal block size
  1477.   short blockshape_x = (blocksize_x >> 2);  // horizontal block size in 4-pel units
  1478.   short blockshape_y = (blocksize_y >> 2);  // vertical block size in 4-pel units
  1479.   short mb_x = pic_pix_x - img->opix_x;
  1480.   short mb_y = pic_pix_y - img->opix_y;
  1481.   short pic_pix_x2 = pic_pix_x >> 2;
  1482.   short pic_pix_y2 = pic_pix_y >> 2;
  1483.   short block_x = (mb_x >> 2);
  1484.   short block_y = (mb_y >> 2);
  1485.   int   stopCriterion = medthres[blocktype];
  1486.   int   mapCenter_x = search_range - mv[0];
  1487.   int   mapCenter_y = search_range - mv[1];
  1488.   int   second_mcost = INT_MAX;  
  1489.   int   *prevSad = EPZSDistortion[list + list_offset][blocktype - 1];
  1490.   short *motion=NULL;  
  1491.   MotionVector *p_motion = NULL;
  1492.   short invalid_refs = 0;
  1493.   byte  checkMedian = FALSE;
  1494.   EPZSStructure *searchPatternF = searchPattern;
  1495.   MotionVector center, tmp, tmp2, cand, pred;
  1496.   pred.mv_x = (pic_pix_x << 2) + pred_mv[0];  // predicted position x (in sub-pel units)
  1497.   pred.mv_y = (pic_pix_y << 2) + pred_mv[1];  // predicted position x (in sub-pel units)
  1498.   center.mv_x = (pic_pix_x << (params->EPZSGrid))+ mv[0];
  1499.   center.mv_y = (pic_pix_y << (params->EPZSGrid))+ mv[1];
  1500.   cand.mv_x = center.mv_x << mv_rescale;
  1501.   cand.mv_y = center.mv_y << mv_rescale;
  1502.   tmp.mv_x = mv[0];
  1503.   tmp.mv_y = mv[1];
  1504.   tmp2.mv_x = 0;
  1505.   tmp2.mv_y = 0;
  1506.   computePred = computeUniPred[F_PEL + 3 * apply_weights];
  1507.   EPZSBlkCount ++;
  1508.   if (EPZSBlkCount == 0)
  1509.     EPZSBlkCount ++;
  1510.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  1511.   img_width  = ref_picture->size_x;
  1512.   img_height = ref_picture->size_y;
  1513.   width_pad  = ref_picture->size_x_pad;
  1514.   height_pad = ref_picture->size_y_pad;
  1515.   if (ChromaMEEnable)
  1516.   {
  1517.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  1518.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  1519.     width_pad_cr  = ref_picture->size_x_cr_pad;
  1520.     height_pad_cr = ref_picture->size_y_cr_pad;
  1521.   }
  1522.   pic_pix_x = (pic_pix_x << (params->EPZSGrid));
  1523.   pic_pix_y = (pic_pix_y << (params->EPZSGrid));
  1524.   if (params->EPZSSpatialMem)
  1525.   {
  1526. #if EPZSREF
  1527.     motion   =  EPZSMotion [list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2];
  1528.     p_motion = &EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2];
  1529. #else
  1530.     motion   =  EPZSMotion [list + list_offset][blocktype - 1][block_y][pic_pix_x2];
  1531.     p_motion = &EPZS_Motion[list + list_offset][blocktype - 1][block_y][pic_pix_x2];
  1532. #endif
  1533.   }
  1534.   //===== set function for getting reference picture lines =====
  1535.   ref_access_method = CHECK_RANGE ? FAST_ACCESS : UMV_ACCESS;
  1536.   // Clear EPZSMap
  1537.   // memset(EPZSMap[0],FALSE,searcharray*searcharray);
  1538.   // Check median candidate;
  1539.   //EPZSMap[0][0] = EPZSBlkCount;
  1540.   EPZSMap[search_range][search_range] = EPZSBlkCount;
  1541.   //--- initialize motion cost (cost for motion vector) and check ---
  1542.   min_mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
  1543.   //--- add residual cost to motion cost ---
  1544.   min_mcost += computePred(cur_pic, blocksize_y, blocksize_x,
  1545.     INT_MAX, cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4);
  1546.   // Additional threshold for ref>0
  1547.   if ((ref>0 && img->structure == FRAME)
  1548.     && (prevSad[pic_pix_x2] < imin(medthres[blocktype],min_mcost)))
  1549.   {
  1550. #if EPZSREF
  1551.     if (params->EPZSSpatialMem)
  1552. #else
  1553.     if (params->EPZSSpatialMem && ref == 0)
  1554. #endif
  1555.     {
  1556.       motion[0]  = tmp.mv_x;
  1557.       motion[1]  = tmp.mv_y;
  1558.       *p_motion = tmp;
  1559.     }
  1560.     return min_mcost;
  1561.   }
  1562.   //  if ((center.mv_x > search_range) && (center.mv_x < img_width  - search_range - blocksize_x) &&
  1563.   //(center.mv_y > search_range) && (center.mv_y < img_height - search_range - blocksize_y)   )
  1564.   if ( (center.mv_x > search_range) && (center.mv_x < ((img_width  - blocksize_x) << (params->EPZSGrid)) - search_range)
  1565.     && (center.mv_y > search_range) && (center.mv_y < ((img_height - blocksize_y) << (params->EPZSGrid)) - search_range))
  1566.   {
  1567.     ref_access_method = FAST_ACCESS;
  1568.   }
  1569.   else
  1570.   {
  1571.     ref_access_method = UMV_ACCESS;
  1572.   }
  1573.   //! If medthres satisfied, then terminate, otherwise generate Predictors
  1574.   //! Condition could be strengthened by consideration distortion of adjacent partitions.
  1575.   if (min_mcost > stopCriterion)
  1576.   {
  1577.     int mb_available_right   = (img->mb_x < (img_width  >> 4) - 1);
  1578.     int mb_available_below   = (img->mb_y < (img_height >> 4) - 1);
  1579.     int block_available_right;
  1580.     int block_available_below;
  1581.     int prednum = 5;
  1582.     int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
  1583.     int totalCheckPts = 0, motionDirection = 0;
  1584.     int conditionEPZS;
  1585.     MotionVector tmv;
  1586.     int pos, mcost;
  1587.     PixelPos block_a, block_b, block_c, block_d;
  1588.     int *mb_size = img->mb_size[IS_LUMA];
  1589.     get4x4Neighbour (currMB, mb_x - 1          , mb_y    , mb_size, &block_a);
  1590.     get4x4Neighbour (currMB, mb_x              , mb_y - 1, mb_size, &block_b);
  1591.     get4x4Neighbour (currMB, mb_x + blocksize_x, mb_y - 1, mb_size, &block_c);
  1592.     get4x4Neighbour (currMB, mb_x - 1          , mb_y - 1, mb_size, &block_d);
  1593.     if (mb_y > 0)
  1594.     {
  1595.       if (mb_x < 8)   // first column of 8x8 blocks
  1596.       {
  1597.         if (mb_y == 8)
  1598.         {
  1599.           block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  1600.           if (blocksize_x == MB_BLOCK_SIZE)
  1601.             block_c.available = 0;
  1602.         }
  1603.         else
  1604.         {
  1605.           block_available_right = (mb_x + blocksize_x != 8) || mb_available_right;
  1606.           if (mb_x + blocksize_x == 8)
  1607.             block_c.available = 0;
  1608.         }
  1609.       }
  1610.       else
  1611.       {
  1612.         block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  1613.         if (mb_x + blocksize_x == MB_BLOCK_SIZE)
  1614.           block_c.available = 0;
  1615.       }
  1616.     }
  1617.     else
  1618.     {
  1619.       block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  1620.     }
  1621.     block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below);
  1622.     stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blockshape_x);
  1623.     //! Add Spatial Predictors in predictor list.
  1624.     //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little
  1625.     //! in terms of performance and could be removed with little penalty if any.
  1626.     invalid_refs = EPZSSpatialPredictors (block_a, block_b, block_c, block_d,
  1627.       list, list_offset, ref, refPic[list], tmp_mv[list], predictor);
  1628.     if (params->EPZSSpatialMem)
  1629.       EPZSSpatialMemPredictors (list + list_offset, ref, blocktype - 1, pic_pix_x2,
  1630.       blockshape_x, blockshape_y, block_y, &prednum, img_width>>2, predictor);
  1631.     // Temporal predictors
  1632.     if (params->EPZSTemporal)
  1633.       EPZSTemporalPredictors (list, list_offset, ref, pic_pix_x2, pic_pix_y2, predictor, &prednum,
  1634.       block_a.available, block_b.available, block_available_right,
  1635.       block_available_below, blockshape_x, blockshape_y, stopCriterion, min_mcost);
  1636.     //! Window Size Based Predictors
  1637.     //! Basically replaces a Hierarchical ME concept and helps escaping local minima, or
  1638.     //! determining large motion variations.
  1639.     //! Following predictors can be adjusted further (i.e. removed, conditioned etc)
  1640.     //! based on distortion, correlation of adjacent MVs, complexity etc. These predictors
  1641.     //! and their conditioning could also be moved after all other predictors have been
  1642.     //! tested. Adaptation could also be based on type of material and coding mode (i.e.
  1643.     //! field/frame coding,MBAFF etc considering the higher dependency with opposite parity field
  1644.     //conditionEPZS = ((min_mcost > stopCriterion)
  1645.     // && (params->EPZSFixed > 1 || (params->EPZSFixed && img->type == P_SLICE)));
  1646.     //conditionEPZS = ((ref == 0) && (blocktype < 5) && (min_mcost > stopCriterion)
  1647.     //&& (params->EPZSFixed > 1 || (params->EPZSFixed && img->type == P_SLICE)));
  1648.     conditionEPZS = ((min_mcost > stopCriterion) && ((ref < 2 && blocktype < 5)
  1649.       || ((img->structure!=FRAME || list_offset) && ref < 3))
  1650.       && (params->EPZSFixed > 1 || (params->EPZSFixed && img->type == P_SLICE)));
  1651.     if (conditionEPZS)
  1652.       EPZSWindowPredictors (mv, predictor, &prednum,
  1653.       (blocktype < 5) && (invalid_refs > 2) && (ref < 1 + (img->structure!=FRAME || list_offset)));
  1654.     //! Blocktype/Reference dependent predictors.
  1655.     //! Since already mvs for other blocktypes/references have been computed, we can reuse
  1656.     //! them in order to easier determine the optimal point. Use of predictors could depend
  1657.     //! on cost,
  1658.     //conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion) || img->structure != FRAME || list_offset);
  1659.     conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion));
  1660.     // above seems to result in memory leak issues which need to be resolved
  1661.     if (conditionEPZS && img->current_mb_nr != 0 && params->EPZSBlockType)
  1662.       EPZSBlockTypePredictors (block_x, block_y, blocktype, ref, list, predictor, &prednum);
  1663.     //! Check all predictors
  1664.     for (pos = 0; pos < prednum; pos++)
  1665.     {
  1666.       tmv = predictor->point[pos].motion;
  1667.       //if (((iabs (tmv.mv_x - mv[0]) > search_range || iabs (tmv.mv_y - mv[1]) > search_range)) && (tmv.mv_x || tmv.mv_y))
  1668.       if (iabs (tmv.mv_x - mv[0]) > search_range || iabs (tmv.mv_y - mv[1]) > search_range)
  1669.         continue;
  1670.       if ((iabs (tmv.mv_x - mv[0]) <= search_range) && (iabs (tmv.mv_y - mv[1]) <= search_range))
  1671.       {
  1672.         if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] == EPZSBlkCount)
  1673.           continue;
  1674.         else
  1675.           EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
  1676.       }
  1677.       cand.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
  1678.       cand.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
  1679.       //--- set motion cost (cost for motion vector) and check ---
  1680.       mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
  1681.       if (mcost >= second_mcost) continue;
  1682.       //ref_access_method = CHECK_RANGE ? FAST_ACCESS : UMV_ACCESS;
  1683.       mcost += computePred(cur_pic, blocksize_y,blocksize_x,
  1684.         second_mcost - mcost, cand.mv_x + IMG_PAD_SIZE_TIMES4,cand.mv_y + IMG_PAD_SIZE_TIMES4);
  1685.       //--- check if motion cost is less than minimum cost ---
  1686.       if (mcost < min_mcost)
  1687.       {
  1688.         tmp2 = tmp;
  1689.         tmp  = tmv;
  1690.         second_mcost = min_mcost;
  1691.         min_mcost = mcost;
  1692.         checkMedian = TRUE;
  1693.       }
  1694.       //else if (mcost < second_mcost && (tmp.mv_x != tmv.mv_x || tmp.mv_y != tmv.mv_y))
  1695.       else if (mcost < second_mcost)
  1696.       {
  1697.         tmp2 = tmv;
  1698.         second_mcost = mcost;
  1699.         checkMedian = TRUE;
  1700.       }
  1701.     }
  1702.     //! Refine using EPZS pattern if needed
  1703.     //! Note that we are using a conservative threshold method. Threshold
  1704.     //! could be tested after checking only a certain number of predictors
  1705.     //! instead of the full set. Code could be easily modified for this task.
  1706.     if (min_mcost > stopCriterion)
  1707.     {
  1708.       //! Adapt pattern based on different conditions.
  1709.       if (params->EPZSPattern != 0)
  1710.       {
  1711.         if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
  1712.         {
  1713.           if ((tmp.mv_x == 0 && tmp.mv_y == 0)
  1714.             || (iabs (tmp.mv_x - mv[0]) < (2<<(2-mv_rescale)) && iabs (tmp.mv_y - mv[1]) < (2<<(2-mv_rescale))))
  1715.             searchPatternF = sdiamond;
  1716.           else
  1717.             searchPatternF = square;
  1718.         }
  1719.         else if (blocktype > 5 || (ref > 0 && blocktype != 1))
  1720.           searchPatternF = square;
  1721.         else
  1722.           searchPatternF = searchPattern;
  1723.       }
  1724.       totalCheckPts = searchPatternF->searchPoints;
  1725.       //! center on best predictor
  1726.       center = tmp;
  1727.       while(1)
  1728.       {
  1729.         do
  1730.         {
  1731.           checkPts = totalCheckPts;
  1732.           do
  1733.           {
  1734.             tmv.mv_x = center.mv_x + searchPatternF->point[pointNumber].motion.mv_x;
  1735.             tmv.mv_y = center.mv_y + searchPatternF->point[pointNumber].motion.mv_y;
  1736.             cand.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
  1737.             cand.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
  1738.             if ((iabs (tmv.mv_x - mv[0]) <= search_range) && (iabs (tmv.mv_y - mv[1]) <= search_range))
  1739.             {
  1740.               if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] != EPZSBlkCount)
  1741.                 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
  1742.               else
  1743.               {
  1744.                 pointNumber += 1;
  1745.                 if (pointNumber >= searchPatternF->searchPoints)
  1746.                   pointNumber -= searchPatternF->searchPoints;
  1747.                 checkPts -= 1;
  1748.                 continue;
  1749.               }
  1750.               mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
  1751.               if (mcost < min_mcost)
  1752.               {
  1753.                 ref_access_method = CHECK_RANGE ? FAST_ACCESS : UMV_ACCESS;
  1754.                 mcost += computePred(cur_pic, blocksize_y,blocksize_x,
  1755.                   min_mcost - mcost, cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4);
  1756.                 if (mcost < min_mcost)
  1757.                 {
  1758.                   tmp = tmv;
  1759.                   min_mcost = mcost;
  1760.                   motionDirection = pointNumber;
  1761.                 }
  1762.               }
  1763.             }
  1764.             pointNumber += 1;
  1765.             if (pointNumber >= searchPatternF->searchPoints)
  1766.               pointNumber -= searchPatternF->searchPoints;
  1767.             checkPts -= 1;
  1768.           }
  1769.           while (checkPts > 0);
  1770.           if (nextLast || ((tmp.mv_x == center.mv_x) && (tmp.mv_y == center.mv_y)))
  1771.           {
  1772.             patternStop     = searchPatternF->stopSearch;
  1773.             searchPatternF  = searchPatternF->nextpattern;
  1774.             totalCheckPts   = searchPatternF->searchPoints;
  1775.             nextLast        = searchPatternF->nextLast;
  1776.             motionDirection = 0;
  1777.             pointNumber = 0;
  1778.           }
  1779.           else
  1780.           {
  1781.             totalCheckPts = searchPatternF->point[motionDirection].next_points;
  1782.             pointNumber = searchPatternF->point[motionDirection].start_nmbr;
  1783.             center = tmp;
  1784.           }
  1785.         }
  1786.         while (patternStop != 1);
  1787.         if ((ref>0) && (img->structure == FRAME) && (( 4 * prevSad[pic_pix_x2] < min_mcost) ||
  1788.           ((3 * prevSad[pic_pix_x2] < min_mcost) && (prevSad[pic_pix_x2] <= stopCriterion))))
  1789.         {
  1790.           mv[0] = tmp.mv_x;
  1791.           mv[1] = tmp.mv_y;
  1792. #if EPZSREF
  1793.           if (params->EPZSSpatialMem)
  1794. #else
  1795.           if (params->EPZSSpatialMem && ref == 0)
  1796. #endif
  1797.           {
  1798.             motion[0] = tmp.mv_x;
  1799.             motion[1] = tmp.mv_y;
  1800.             *p_motion  = tmp;
  1801.           }
  1802.           return min_mcost;
  1803.         }
  1804.         //! Check Second best predictor with EPZS pattern
  1805.         conditionEPZS = (checkMedian == TRUE)
  1806.           && ((img->type == P_SLICE) || (blocktype < 5))
  1807.           && (min_mcost > stopCriterion) && (params->EPZSDual > 0);
  1808.         if (!conditionEPZS) break;
  1809.         pointNumber = 0;
  1810.         patternStop = 0;
  1811.         motionDirection = 0;
  1812.         nextLast = 0;
  1813.         if ((tmp.mv_x == 0 && tmp.mv_y == 0)  || (tmp.mv_x == mv[0] && tmp.mv_y == mv[1]))
  1814.         {
  1815.           if (iabs (tmp.mv_x - mv[0]) < (2<<(2-mv_rescale)) && iabs (tmp.mv_y - mv[1]) < (2<<(2-mv_rescale)))
  1816.             searchPatternF = sdiamond;
  1817.           else
  1818.             searchPatternF = square;
  1819.         }
  1820.         else
  1821.           searchPatternF = searchPatternD;
  1822.         totalCheckPts = searchPatternF->searchPoints;
  1823.         //! Second best. Note that following code is identical as for best predictor.
  1824.         center = tmp2;
  1825.         checkMedian = FALSE;
  1826.       }
  1827.     }
  1828.   }
  1829.   if ((ref==0) || (prevSad[pic_pix_x2] > min_mcost))
  1830.     prevSad[pic_pix_x2] = min_mcost;
  1831. #if EPZSREF
  1832.   if (params->EPZSSpatialMem)
  1833. #else
  1834.   if (params->EPZSSpatialMem && ref == 0)
  1835. #endif
  1836.   {
  1837.     motion[0] = tmp.mv_x;
  1838.     motion[1] = tmp.mv_y;
  1839.     *p_motion = tmp;
  1840.     //printf("value %d %d %d %dn", p_motion->mv_x, p_motion->mv_y, EPZS_Motion[list + list_offset][ref][0][0][0].mv_x, EPZS_Motion[list + list_offset][ref][0][0][0].mv_y);
  1841.     //printf("xxxxx %d %d %d %dn", p_motion->mv_x, p_motion->mv_y, EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2].mv_x, EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2].mv_y);
  1842.   }
  1843.   mv[0] = tmp.mv_x;
  1844.   mv[1] = tmp.mv_y;
  1845.   return min_mcost;
  1846. }
  1847. /*!
  1848. ***********************************************************************
  1849. * brief
  1850. *    FAST Motion Estimation using EPZS
  1851. *    AMT/HYC
  1852. ***********************************************************************
  1853. */
  1854. int                                                //  ==> minimum motion cost after search
  1855. EPZSBiPredBlockMotionSearch (Macroblock *currMB,   // <--  Current Macroblock
  1856.                              imgpel * cur_pic,     // <--  original pixel values for the AxB block
  1857.                              short  ref,           // <--  reference picture
  1858.                              int    list,          // <--  reference list
  1859.                              int    list_offset,   // <--  offset for Mbaff
  1860.                              char  ***refPic,      // <--  reference array
  1861.                              short  ****tmp_mv,    // <--  mv array
  1862.                              int    pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  1863.                              int    pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  1864.                              int    blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  1865.                              short  pred_mv1[2],   // <--  motion vector predictor in sub-pel units
  1866.                              short  pred_mv2[2],   // <--  motion vector predictor in sub-pel units
  1867.                              short  mv[2],         // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units
  1868.                              short  static_mv[2],       // <--> in: search center (x|y) 
  1869.                              int    search_range,  // <--  1-d search range in pel units
  1870.                              int    min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  1871.                              int    iteration_no,  // <--  bi pred iteration number
  1872.                              int    lambda_factor, // <--  lagrangian parameter for determining motion cost
  1873.                              int    apply_weights  // <--  perform weight based ME
  1874.                              )
  1875. {
  1876.   StorablePicture *ref_picture1 = listX[list       + list_offset][ref];
  1877.   StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0];
  1878.   short blocksize_y  = params->blc_size[blocktype][1];        // vertical block size
  1879.   short blocksize_x  = params->blc_size[blocktype][0];        // horizontal block size
  1880.   short blockshape_x = (blocksize_x >> 2);  // horizontal block size in 4-pel units
  1881. //  short blockshape_y = (blocksize_y >> 2);  // vertical block size in 4-pel units
  1882.   short mb_x = pic_pix_x - img->opix_x;
  1883.   short mb_y = pic_pix_y - img->opix_y;
  1884.   short pic_pix_x2 = pic_pix_x >> 2;
  1885.   //short pic_pix_y2 = pic_pix_y >> 2;
  1886.   int   stopCriterion = medthres[blocktype];
  1887.   int   mapCenter_x = search_range - mv[0];
  1888.   int   mapCenter_y = search_range - mv[1];
  1889.   int   second_mcost = INT_MAX;
  1890.   int   *prevSad = EPZSBiDistortion[list + list_offset][blocktype - 1];
  1891.   short invalid_refs = 0;
  1892.   byte  checkMedian = FALSE;
  1893.   EPZSStructure *searchPatternF = searchPattern;
  1894.   static MotionVector center1, center2, tmp, tmp2, cand, cand1, cand2, pred1, pred2;
  1895.   pred1.mv_x   = (pic_pix_x << 2) + pred_mv1[0]; // predicted position x (in sub-pel units)
  1896.   pred1.mv_y   = (pic_pix_y << 2) + pred_mv1[1]; // predicted position y (in sub-pel units)
  1897.   pred2.mv_x   = (pic_pix_x << 2) + pred_mv2[0]; // predicted position x (in sub-pel units)
  1898.   pred2.mv_y   = (pic_pix_y << 2) + pred_mv2[1]; // predicted position y (in sub-pel units)
  1899.   center1.mv_x = (pic_pix_x << (params->EPZSGrid))+ mv[0];
  1900.   center1.mv_y = (pic_pix_y << (params->EPZSGrid))+ mv[1];
  1901.   center2.mv_x = (pic_pix_x << (params->EPZSGrid))+ static_mv[0];
  1902.   center2.mv_y = (pic_pix_y << (params->EPZSGrid))+ static_mv[1];
  1903.   cand1.mv_x   = center1.mv_x << mv_rescale;
  1904.   cand1.mv_y   = center1.mv_y << mv_rescale;
  1905.   cand2.mv_x   = center2.mv_x << mv_rescale;
  1906.   cand2.mv_y   = center2.mv_y << mv_rescale;
  1907.   tmp.mv_x = mv[0];
  1908.   tmp.mv_y = mv[1];
  1909.   tmp2.mv_x = 0;
  1910.   tmp2.mv_y = 0;
  1911.   EPZSBlkCount ++;
  1912.   if (EPZSBlkCount == 0)
  1913.     EPZSBlkCount ++;
  1914.   ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
  1915.   ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
  1916.   img_width  = ref_picture1->size_x;
  1917.   img_height = ref_picture1->size_y;
  1918.   width_pad  = ref_picture1->size_x_pad;
  1919.   height_pad = ref_picture1->size_y_pad;
  1920.   if (apply_weights)
  1921.   {
  1922.     computeBiPred = computeBiPred2[F_PEL];
  1923.   }
  1924.   else
  1925.   {
  1926.     computeBiPred = computeBiPred1[F_PEL];
  1927.   }
  1928.   if ( ChromaMEEnable )
  1929.   {
  1930.     ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
  1931.     ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
  1932.     ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
  1933.     ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
  1934.     width_pad_cr  = ref_picture1->size_x_cr_pad;
  1935.     height_pad_cr = ref_picture1->size_y_cr_pad;
  1936.   }
  1937.   pic_pix_x = (pic_pix_x << (params->EPZSGrid));
  1938.   pic_pix_y = (pic_pix_y << (params->EPZSGrid));
  1939.   //===== set function for getting reference picture lines from reference 1 =====
  1940.   if ((cand1.mv_x >= 0) && (cand1.mv_x < img_width  - blocksize_x) &&(cand.mv_y >= 0) && (cand1.mv_y < img_height - blocksize_y))
  1941.   {
  1942.     bipred1_access_method = FAST_ACCESS;
  1943.   }
  1944.   else
  1945.   {
  1946.     bipred1_access_method = UMV_ACCESS;
  1947.   }
  1948.   //===== set function for getting reference picture lines from reference 2 =====
  1949.   if ((cand2.mv_x >= 0) && (cand2.mv_x < img_width  - blocksize_x) &&(cand.mv_y >= 0) && (cand2.mv_y < img_height - blocksize_y))
  1950.   {
  1951.     bipred2_access_method = FAST_ACCESS;
  1952.   }
  1953.   else
  1954.   {
  1955.     bipred2_access_method = UMV_ACCESS;
  1956.   }
  1957.   // Clear EPZSMap
  1958.   //memset(EPZSMap[0],FALSE,searcharray*searcharray);
  1959.   // Check median candidate;
  1960.   //EPZSMap[0][0] = EPZSBlkCount;
  1961.   EPZSMap[search_range][search_range] = EPZSBlkCount;
  1962.   //--- initialize motion cost (cost for motion vector) and check ---
  1963.   min_mcost  = MV_COST_SMP (lambda_factor, cand1.mv_x, cand1.mv_y, pred1.mv_x, pred1.mv_y);
  1964.   min_mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);
  1965.   //--- add residual cost to motion cost ---
  1966.   min_mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, INT_MAX,
  1967.     cand1.mv_x + IMG_PAD_SIZE_TIMES4,
  1968.     cand1.mv_y + IMG_PAD_SIZE_TIMES4,
  1969.     cand2.mv_x + IMG_PAD_SIZE_TIMES4,
  1970.     cand2.mv_y + IMG_PAD_SIZE_TIMES4);
  1971.   //! If medthres satisfied, then terminate, otherwise generate Predictors
  1972.   if (min_mcost > stopCriterion)
  1973.   {
  1974.     int mb_available_right   = (img->mb_x < (img_width  >> 4) - 1);
  1975.     int mb_available_below   = (img->mb_y < (img_height >> 4) - 1);
  1976.     int block_available_right;
  1977.     int block_available_below;
  1978.     int prednum = 5;
  1979.     int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
  1980.     int totalCheckPts = 0, motionDirection = 0;
  1981.     int conditionEPZS;
  1982.     MotionVector tmv;
  1983.     int pos, mcost;
  1984.     PixelPos block_a, block_b, block_c, block_d;
  1985.     int *mb_size = img->mb_size[IS_LUMA];
  1986.     get4x4Neighbour (currMB, mb_x - 1          , mb_y    , mb_size, &block_a);
  1987.     get4x4Neighbour (currMB, mb_x              , mb_y - 1, mb_size, &block_b);
  1988.     get4x4Neighbour (currMB, mb_x + blocksize_x, mb_y - 1, mb_size, &block_c);
  1989.     get4x4Neighbour (currMB, mb_x - 1          , mb_y - 1, mb_size, &block_d);
  1990.     if (mb_y > 0)
  1991.     {
  1992.       if (mb_x < 8)   // first column of 8x8 blocks
  1993.       {
  1994.         if (mb_y == 8)
  1995.         {
  1996.           block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  1997.           if (blocksize_x == MB_BLOCK_SIZE)
  1998.             block_c.available = 0;
  1999.         }
  2000.         else
  2001.         {
  2002.           block_available_right = (mb_x + blocksize_x != 8) || mb_available_right;
  2003.           if (mb_x + blocksize_x == 8)
  2004.             block_c.available = 0;
  2005.         }
  2006.       }
  2007.       else
  2008.       {
  2009.         block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  2010.         if (mb_x + blocksize_x == MB_BLOCK_SIZE)
  2011.           block_c.available = 0;
  2012.       }
  2013.     }
  2014.     else
  2015.     {
  2016.       block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
  2017.     }
  2018.     block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below);
  2019.     stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blockshape_x);
  2020.     // stopCriterion = (11 * medthres[blocktype]) >> 3;
  2021.     //! Add Spatial Predictors in predictor list.
  2022.     //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little
  2023.     //! in terms of performance and could be removed with little penalty if any.
  2024.     invalid_refs = EPZSSpatialPredictors (block_a, block_b, block_c, block_d,
  2025.       list, list_offset, ref, refPic[list], tmp_mv[list], predictor);
  2026.     //! Check all predictors
  2027.     for (pos = 0; pos < prednum; pos++)
  2028.     {
  2029.       tmv = predictor->point[pos].motion;
  2030.       //if ((iabs (tmv.mv_x - mv[0]) > search_range || iabs (tmv.mv_y - mv[1]) > search_range) && (tmv.mv_x || tmv.mv_y))
  2031.       if (iabs (tmv.mv_x - mv[0]) > search_range || iabs (tmv.mv_y - mv[1]) > search_range)
  2032.         continue;
  2033.       if ((iabs (tmv.mv_x - mv[0]) <= search_range) && (iabs (tmv.mv_y - mv[1]) <= search_range))
  2034.       {
  2035.         if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] == EPZSBlkCount)
  2036.           continue;
  2037.         else
  2038.           EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
  2039.       }
  2040.       cand.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
  2041.       cand.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
  2042.       //--- set motion cost (cost for motion vector) and check ---
  2043.       mcost  = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred1.mv_x, pred1.mv_y);
  2044.       mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);
  2045.       if (mcost >= second_mcost) continue;
  2046.       mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, 
  2047.         second_mcost - mcost,
  2048.         cand.mv_x + IMG_PAD_SIZE_TIMES4 , cand.mv_y + IMG_PAD_SIZE_TIMES4,
  2049.         cand2.mv_x + IMG_PAD_SIZE_TIMES4, cand2.mv_y + IMG_PAD_SIZE_TIMES4);
  2050.       //--- check if motion cost is less than minimum cost ---
  2051.       if (mcost < min_mcost)
  2052.       {
  2053.         tmp2 = tmp;
  2054.         tmp  = tmv;
  2055.         second_mcost = min_mcost;
  2056.         min_mcost = mcost;
  2057.         checkMedian = TRUE;
  2058.       }
  2059.       //else if (mcost < second_mcost && (tmp.mv_x != tmv.mv_x || tmp.mv_y != tmv.mv_y))
  2060.       else if (mcost < second_mcost)
  2061.       {
  2062.         tmp2 = tmv;
  2063.         second_mcost = mcost;
  2064.         checkMedian = TRUE;
  2065.       }
  2066.     }
  2067.     //! Refine using EPZS pattern if needed
  2068.     //! Note that we are using a conservative threshold method. Threshold
  2069.     //! could be tested after checking only a certain number of predictors
  2070.     //! instead of the full set. Code could be easily modified for this task.
  2071.     if (min_mcost > stopCriterion)
  2072.     {
  2073.       //! Adapt pattern based on different conditions.
  2074.       if (params->EPZSPattern != 0)
  2075.       {
  2076.         if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
  2077.         {
  2078.           if ((tmp.mv_x == 0 && tmp.mv_y == 0)
  2079.             || (iabs (tmp.mv_x - mv[0]) < (2<<(2-mv_rescale)) && iabs (tmp.mv_y - mv[1]) < (2<<(2-mv_rescale))))
  2080.             searchPatternF = sdiamond;
  2081.           else
  2082.             searchPatternF = square;
  2083.         }
  2084.         else if (blocktype > 5 || (ref > 0 && blocktype != 1))
  2085.           searchPatternF = square;
  2086.         else
  2087.           searchPatternF = searchPattern;
  2088.       }
  2089.       totalCheckPts = searchPatternF->searchPoints;
  2090.       //! center on best predictor
  2091.       center1 = tmp;
  2092.       while (1)
  2093.       {
  2094.         do
  2095.         {
  2096.           checkPts = totalCheckPts;
  2097.           do
  2098.           {
  2099.             tmv.mv_x = center1.mv_x + searchPatternF->point[pointNumber].motion.mv_x;
  2100.             tmv.mv_y = center1.mv_y + searchPatternF->point[pointNumber].motion.mv_y;
  2101.             cand.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
  2102.             cand.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
  2103.             if ((iabs (tmv.mv_x - mv[0]) <= search_range) && (iabs (tmv.mv_y - mv[1]) <= search_range))
  2104.             {
  2105.               if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] != EPZSBlkCount)
  2106.                 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
  2107.               else
  2108.               {
  2109.                 pointNumber += 1;
  2110.                 if (pointNumber >= searchPatternF->searchPoints)
  2111.                   pointNumber -= searchPatternF->searchPoints;
  2112.                 checkPts -= 1;
  2113.                 continue;
  2114.               }
  2115.               mcost  = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred2.mv_x, pred2.mv_y);
  2116.               mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);              
  2117.               if (mcost < min_mcost)
  2118.               {
  2119.                 mcost += computeBiPred(cur_pic,
  2120.                   blocksize_y, blocksize_x, min_mcost - mcost,
  2121.                   cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4,
  2122.                   cand2.mv_x + IMG_PAD_SIZE_TIMES4,
  2123.                   cand2.mv_y + IMG_PAD_SIZE_TIMES4);
  2124.                 if (mcost < min_mcost)
  2125.                 {
  2126.                   tmp = tmv;
  2127.                   min_mcost = mcost;
  2128.                   motionDirection = pointNumber;
  2129.                 }
  2130.               }
  2131.             }
  2132.             pointNumber += 1;
  2133.             if (pointNumber >= searchPatternF->searchPoints)
  2134.               pointNumber -= searchPatternF->searchPoints;
  2135.             checkPts -= 1;
  2136.           }
  2137.           while (checkPts > 0);
  2138.           if (nextLast || ((tmp.mv_x == center1.mv_x) && (tmp.mv_y == center1.mv_y)))
  2139.           {
  2140.             patternStop     = searchPatternF->stopSearch;
  2141.             searchPatternF  = searchPatternF->nextpattern;
  2142.             totalCheckPts   = searchPatternF->searchPoints;
  2143.             nextLast        = searchPatternF->nextLast;
  2144.             motionDirection = 0;
  2145.             pointNumber = 0;
  2146.           }
  2147.           else
  2148.           {
  2149.             totalCheckPts = searchPatternF->point[motionDirection].next_points;
  2150.             pointNumber = searchPatternF->point[motionDirection].start_nmbr;
  2151.             center1 = tmp;
  2152.           }
  2153.         }
  2154.         while (patternStop != 1);
  2155.         //! Check Second best predictor with EPZS pattern
  2156.         conditionEPZS = (checkMedian == TRUE)
  2157.           && (blocktype < 5) 
  2158.           && (min_mcost > stopCriterion) && (params->EPZSDual > 0);
  2159.         if (!conditionEPZS) break;
  2160.         pointNumber = 0;
  2161.         patternStop = 0;
  2162.         motionDirection = 0;
  2163.         nextLast = 0;
  2164.         if ((tmp.mv_x == 0 && tmp.mv_y == 0) || (tmp.mv_x == mv[0] && tmp.mv_y == mv[1]))
  2165.         {
  2166.           if (iabs (tmp.mv_x - mv[0]) < (2<<(2-mv_rescale)) && iabs (tmp.mv_y - mv[1]) < (2<<(2-mv_rescale)))
  2167.             searchPatternF = sdiamond;
  2168.           else
  2169.             searchPatternF = square;
  2170.         }
  2171.         else
  2172.           searchPatternF = searchPatternD;
  2173.         totalCheckPts = searchPatternF->searchPoints;
  2174.         //! Second best. Note that following code is identical as for best predictor.
  2175.         center1 = tmp2;
  2176.         checkMedian = FALSE;
  2177.       }
  2178.     }
  2179.   }
  2180.   if (iteration_no == 0)
  2181.   {
  2182.     prevSad[pic_pix_x2] = min_mcost;
  2183.   }
  2184.   mv[0] = tmp.mv_x;
  2185.   mv[1] = tmp.mv_y;
  2186.   return min_mcost;
  2187. }
  2188. /*!
  2189. ***********************************************************************
  2190. * brief
  2191. *    Report function for EPZS Fast ME
  2192. *    AMT/HYC
  2193. ***********************************************************************
  2194. */
  2195. void EPZSOutputStats (InputParameters *params, FILE * stat, short stats_file)
  2196. {
  2197.   if (stats_file == 1)
  2198.   {
  2199.     fprintf (stat, " EPZS Pattern                 : %sn",c_EPZSPattern[params->EPZSPattern]);
  2200.     fprintf (stat, " EPZS Dual Pattern            : %sn",c_EPZSDualPattern[params->EPZSDual]);
  2201.     fprintf (stat, " EPZS Fixed Predictors        : %sn",c_EPZSFixed[params->EPZSFixed]);
  2202.     fprintf (stat, " EPZS Temporal Predictors     : %sn",c_EPZSOther[params->EPZSTemporal]);
  2203.     fprintf (stat, " EPZS Spatial Predictors      : %sn",c_EPZSOther[params->EPZSSpatialMem]);
  2204.     fprintf (stat, " EPZS Thresholds (16x16)      : (%d %d %d)n",medthres[1], minthres[1], maxthres[1]);
  2205.     fprintf (stat, " EPZS Subpel ME               : %sn",c_EPZSOther[params->EPZSSubPelME]);
  2206.     fprintf (stat, " EPZS Subpel ME BiPred        : %sn",c_EPZSOther[params->EPZSSubPelMEBiPred]);
  2207.   }
  2208.   else
  2209.   {
  2210.     fprintf (stat, " EPZS Pattern                      : %sn",c_EPZSPattern[params->EPZSPattern]);
  2211.     fprintf (stat, " EPZS Dual Pattern                 : %sn",c_EPZSDualPattern[params->EPZSDual]);
  2212.     fprintf (stat, " EPZS Fixed Predictors             : %sn",c_EPZSFixed[params->EPZSFixed]);
  2213.     fprintf (stat, " EPZS Temporal Predictors          : %sn",c_EPZSOther[params->EPZSTemporal]);
  2214.     fprintf (stat, " EPZS Spatial Predictors           : %sn",c_EPZSOther[params->EPZSSpatialMem]);
  2215.     fprintf (stat, " EPZS Thresholds (16x16)           : (%d %d %d)n",medthres[1], minthres[1], maxthres[1]);
  2216.     fprintf (stat, " EPZS Subpel ME                    : %sn",c_EPZSOther[params->EPZSSubPelME]);
  2217.     fprintf (stat, " EPZS Subpel ME BiPred             : %sn",c_EPZSOther[params->EPZSSubPelMEBiPred]);
  2218.   }
  2219. }
  2220. /*!
  2221.  ***********************************************************************
  2222.  * brief
  2223.  *    Fast sub pixel block motion search to support EPZS
  2224.  ***********************************************************************
  2225.  */
  2226. int                                                   //  ==> minimum motion cost after search
  2227. EPZSSubPelBlockMotionSearch (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  2228.                              short     ref,           // <--  reference frame (0... or -1 (backward))
  2229.                              int       list,          // <--  reference picture list
  2230.                              int       list_offset,   // <--  MBAFF list offset
  2231.                              int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  2232.                              int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  2233.                              int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  2234.                              short     pred_mv[2],    // <--  motion vector predictor in sub-pel units
  2235.                              short     mv[2],         // <--> in: search center / out: motion vector - in pel units
  2236.                              int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  2237.                              int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  2238.                              int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  2239.                              int*      lambda,        // <--  lagrangian parameter for determining motion cost
  2240.                              int       apply_weights  // <--  use weight based ME
  2241.                              )
  2242. {
  2243.   int   pos, best_pos = 0, second_pos = 0, mcost;
  2244.   int   second_mcost = INT_MAX;
  2245.   int   cand_mv_x, cand_mv_y;
  2246.   int   blocksize_x     = params->blc_size[blocktype][0];
  2247.   int   blocksize_y     = params->blc_size[blocktype][1];
  2248.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
  2249.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
  2250.   int   max_pos2        = ( (!start_me_refinement_hp || !start_me_refinement_qp) ? imax(1,search_pos2) : search_pos2);
  2251.   StorablePicture *ref_picture = listX[list+list_offset][ref];
  2252.   int max_pos_x4 = ((ref_picture->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  2253.   int max_pos_y4 = ((ref_picture->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  2254.   int start_pos = 5, end_pos = max_pos2;  
  2255.   int lambda_factor = lambda[H_PEL];
  2256.   computePred = computeUniPred[H_PEL + 3 * apply_weights];
  2257.   ref_pic_sub.luma = ref_picture->p_curr_img_sub;
  2258.   width_pad  = ref_picture->size_x_pad;
  2259.   height_pad = ref_picture->size_y_pad;
  2260.   if ( ChromaMEEnable )
  2261.   {
  2262.     ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
  2263.     ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
  2264.     width_pad_cr  = ref_picture->size_x_cr_pad;
  2265.     height_pad_cr = ref_picture->size_y_cr_pad;
  2266.   }
  2267.   /*********************************
  2268.    *****                       *****
  2269.    *****  HALF-PEL REFINEMENT  *****
  2270.    *****                       *****
  2271.    *********************************/
  2272.   //===== set function for getting pixel values =====
  2273.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  2274.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1))
  2275.   {
  2276.     ref_access_method = FAST_ACCESS;
  2277.   }
  2278.   else
  2279.   {
  2280.     ref_access_method = UMV_ACCESS;
  2281.   }
  2282.   //===== loop over search positions =====
  2283.   for (best_pos = 0, pos = start_me_refinement_hp; pos < 5; pos++)
  2284.   {
  2285.     cand_mv_x = mv[0] + search_point_hp[pos][0];    // quarter-pel units
  2286.     cand_mv_y = mv[1] + search_point_hp[pos][1];    // quarter-pel units
  2287.     //----- set motion vector cost -----
  2288.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  2289.     mcost += computePred( orig_pic, blocksize_y, blocksize_x,
  2290.       INT_MAX, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  2291.     if (mcost < min_mcost)
  2292.     {
  2293.       second_mcost = min_mcost;
  2294.       second_pos  = best_pos;
  2295.       min_mcost = mcost;
  2296.       best_pos  = pos;
  2297.     }
  2298.     else if (mcost < second_mcost)
  2299.     {
  2300.       second_mcost = mcost;
  2301.       second_pos  = pos;
  2302.     }
  2303.   }
  2304.   if (best_pos ==0 && (pred_mv[0] == mv[0]) && (pred_mv[1] - mv[1])== 0 && min_mcost < subthres[blocktype])
  2305.       return min_mcost;
  2306.   if (best_pos != 0 && second_pos != 0)
  2307.   {
  2308.     switch (best_pos ^ second_pos)
  2309.     {
  2310.     case 1:
  2311.       start_pos = 6;
  2312.       end_pos   = 7;
  2313.       break;
  2314.     case 3:
  2315.       start_pos = 5;
  2316.       end_pos   = 6;
  2317.       break;
  2318.     case 5:
  2319.       start_pos = 8;
  2320.       end_pos   = 9;
  2321.       break;
  2322.     case 7:
  2323.       start_pos = 7;
  2324.       end_pos   = 8;
  2325.       break;
  2326.     default:
  2327.       break;
  2328.     }
  2329.   }
  2330.   else
  2331.   {
  2332.     switch (best_pos + second_pos)
  2333.     {
  2334.     case 0:
  2335.       start_pos = 5;
  2336.       end_pos   = 5;
  2337.       break;
  2338.     case 1:
  2339.       start_pos = 8;
  2340.       end_pos   = 10;
  2341.       break;
  2342.     case 2:
  2343.       start_pos = 5;
  2344.       end_pos   = 7;
  2345.       break;
  2346.     case 5:
  2347.       start_pos = 6;
  2348.       end_pos   = 8;
  2349.       break;
  2350.     case 7:
  2351.       start_pos = 7;
  2352.       end_pos   = 9;
  2353.       break;
  2354.     default:
  2355.       break;
  2356.     }
  2357.   }
  2358.   if (best_pos !=0 || (iabs(pred_mv[0] - mv[0]) + iabs(pred_mv[1] - mv[1])))
  2359.   {
  2360.     for (pos = start_pos; pos < end_pos; pos++)
  2361.     {
  2362.       cand_mv_x = mv[0] + search_point_hp[pos][0];    // quarter-pel units
  2363.       cand_mv_y = mv[1] + search_point_hp[pos][1];    // quarter-pel units
  2364.       //----- set motion vector cost -----
  2365.       mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  2366.       if (mcost >= min_mcost) continue;
  2367.       mcost += computePred( orig_pic, blocksize_y, blocksize_x,
  2368.         min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  2369.       if (mcost < min_mcost)
  2370.       {
  2371.         min_mcost = mcost;
  2372.         best_pos  = pos;
  2373.       }
  2374.     }
  2375.   }
  2376.   if (best_pos)
  2377.   {
  2378.     mv[0] += search_point_hp[best_pos][0];
  2379.     mv[1] += search_point_hp[best_pos][1];
  2380.   }
  2381.   if ( !start_me_refinement_qp )
  2382.     min_mcost = INT_MAX;
  2383.   /************************************
  2384.   *****                          *****
  2385.   *****  QUARTER-PEL REFINEMENT  *****
  2386.   *****                          *****
  2387.   ************************************/
  2388.   //===== set function for getting pixel values =====
  2389.   if ((pic4_pix_x + mv[0] > 0) && (pic4_pix_x + mv[0] < max_pos_x4) &&
  2390.     (pic4_pix_y + mv[1] > 0) && (pic4_pix_y + mv[1] < max_pos_y4)   )
  2391.   {
  2392.     ref_access_method = FAST_ACCESS;
  2393.   }
  2394.   else
  2395.   {
  2396.     ref_access_method = UMV_ACCESS;
  2397.   }
  2398.   computePred = computeUniPred[Q_PEL + 3 * apply_weights];
  2399.   lambda_factor = lambda[Q_PEL];
  2400.   second_pos = 0;
  2401.   second_mcost = INT_MAX;
  2402.   //===== loop over search positions =====
  2403.   for (best_pos = 0, pos = start_me_refinement_qp; pos < 5; pos++)
  2404.   {
  2405.     cand_mv_x = mv[0] + search_point_qp[pos][0];    // quarter-pel units
  2406.     cand_mv_y = mv[1] + search_point_qp[pos][1];    // quarter-pel units
  2407.     //----- set motion vector cost -----
  2408.     mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  2409.     mcost += computePred( orig_pic, blocksize_y, blocksize_x,
  2410.       INT_MAX, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  2411.     if (mcost < min_mcost)
  2412.     {
  2413.       second_mcost = min_mcost;
  2414.       second_pos  = best_pos;
  2415.       min_mcost = mcost;
  2416.       best_pos  = pos;
  2417.     }
  2418.     else if (mcost < second_mcost)
  2419.     {
  2420.       second_mcost = mcost;
  2421.       second_pos  = pos;
  2422.     }
  2423.   }
  2424.   if (best_pos ==0 && (pred_mv[0] == mv[0]) && (pred_mv[1] - mv[1])== 0 && min_mcost < subthres[blocktype])
  2425.   {
  2426.     return min_mcost;
  2427.   }
  2428.   start_pos = 5;
  2429.   end_pos = search_pos4;
  2430.   if (best_pos != 0 && second_pos != 0)
  2431.   {
  2432.     switch (best_pos ^ second_pos)
  2433.     {
  2434.     case 1:
  2435.       start_pos = 6;
  2436.       end_pos   = 7;
  2437.       break;
  2438.     case 3:
  2439.       start_pos = 5;
  2440.       end_pos   = 6;
  2441.       break;
  2442.     case 5:
  2443.       start_pos = 8;
  2444.       end_pos   = 9;
  2445.       break;
  2446.     case 7:
  2447.       start_pos = 7;
  2448.       end_pos   = 8;
  2449.       break;
  2450.     default:
  2451.       break;
  2452.     }
  2453.   }
  2454.   else
  2455.   {
  2456.     switch (best_pos + second_pos)
  2457.     {
  2458.       //case 0:
  2459.       //start_pos = 5;
  2460.       //end_pos   = 5;
  2461.       //break;
  2462.     case 1:
  2463.       start_pos = 8;
  2464.       end_pos   = 10;
  2465.       break;
  2466.     case 2:
  2467.       start_pos = 5;
  2468.       end_pos   = 7;
  2469.       break;
  2470.     case 5:
  2471.       start_pos = 6;
  2472.       end_pos   = 8;
  2473.       break;
  2474.     case 7:
  2475.       start_pos = 7;
  2476.       end_pos   = 9;
  2477.       break;
  2478.     default:
  2479.       break;
  2480.     }
  2481.   }
  2482.   if (best_pos !=0 || (iabs(pred_mv[0] - mv[0]) + iabs(pred_mv[1] - mv[1])))
  2483.   {
  2484.     for (pos = start_pos; pos < end_pos; pos++)
  2485.     {
  2486.       cand_mv_x = mv[0] + search_point_qp[pos][0];    // quarter-pel units
  2487.       cand_mv_y = mv[1] + search_point_qp[pos][1];    // quarter-pel units
  2488.       //----- set motion vector cost -----
  2489.       mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv[0], pred_mv[1]);
  2490.       if (mcost >= min_mcost) continue;
  2491.       mcost += computePred( orig_pic, blocksize_y, blocksize_x,
  2492.         min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
  2493.       if (mcost < min_mcost)
  2494.       {
  2495.         min_mcost = mcost;
  2496.         best_pos  = pos;
  2497.       }
  2498.     }
  2499.   }
  2500.   if (best_pos)
  2501.   {
  2502.     mv[0] += search_point_qp [best_pos][0];
  2503.     mv[1] += search_point_qp [best_pos][1];
  2504.   }
  2505.   //===== return minimum motion cost =====
  2506.   return min_mcost;
  2507. }
  2508. /*!
  2509.  ***********************************************************************
  2510.  * brief
  2511.  *    Fast bipred sub pixel block motion search to support EPZS
  2512.  ***********************************************************************
  2513.  */
  2514. int                                                   //  ==> minimum motion cost after search
  2515. EPZSSubPelBlockSearchBiPred (imgpel*   orig_pic,      // <--  original pixel values for the AxB block
  2516.                              short     ref,           // <--  reference frame (0... or -1 (backward))
  2517.                              int       list,          // <--  reference picture list
  2518.                              int       pic_pix_x,     // <--  absolute x-coordinate of regarded AxB block
  2519.                              int       pic_pix_y,     // <--  absolute y-coordinate of regarded AxB block
  2520.                              int       blocktype,     // <--  block type (1-16x16 ... 7-4x4)
  2521.                              short     pred_mv1[2],   // <--  motion vector predictor (x) in sub-pel units
  2522.                              short     pred_mv2[2],   // <--  motion vector predictor (x) in sub-pel units
  2523.                              short     mv[2],         // <--> in: search center (x) / out: motion vector (x) - in pel units
  2524.                              short     static_mv[2],  // <--> in: search center (x) / out: motion vector (x) - in pel units
  2525.                              int       search_pos2,   // <--  search positions for    half-pel search  (default: 9)
  2526.                              int       search_pos4,   // <--  search positions for quarter-pel search  (default: 9)
  2527.                              int       min_mcost,     // <--  minimum motion cost (cost for center or huge value)
  2528.                              int       *lambda,       // <--  lagrangian parameter for determining motion cost
  2529.                              int       apply_weights  // <--  perform weight based ME
  2530.                              )
  2531. {
  2532.   int   list_offset   = img->mb_data[img->current_mb_nr].list_offset;
  2533.   int   pos, best_pos = 0, second_pos = 0, mcost;
  2534.   int   second_mcost = INT_MAX;
  2535.   int   cand_mv_x, cand_mv_y;
  2536.   int   blocksize_x     = params->blc_size[blocktype][0];
  2537.   int   blocksize_y     = params->blc_size[blocktype][1];
  2538.   int   pic4_pix_x      = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
  2539.   int   pic4_pix_y      = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
  2540.   int   start_hp        = (min_mcost == INT_MAX) ? 0 : start_me_refinement_hp;
  2541.   int   max_pos2        = ( (!start_me_refinement_hp || !start_me_refinement_qp) ? imax(1,search_pos2) : search_pos2);
  2542.   int   smv_x = static_mv[0] + pic4_pix_x;
  2543.   int   smv_y = static_mv[1] + pic4_pix_y;
  2544.   StorablePicture *ref_picture1 = listX[list       + list_offset][ref];
  2545.   StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0];
  2546.   int max_pos_x4 = ((ref_picture1->size_x - blocksize_x + 2*IMG_PAD_SIZE)<<2);
  2547.   int max_pos_y4 = ((ref_picture1->size_y - blocksize_y + 2*IMG_PAD_SIZE)<<2);
  2548.   int start_pos = 5, end_pos = max_pos2;
  2549.   int lambda_factor = lambda[H_PEL];
  2550.   ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
  2551.   ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
  2552.   img_width     = ref_picture1->size_x;
  2553.   img_height    = ref_picture1->size_y;
  2554.   width_pad    = ref_picture1->size_x_pad;
  2555.   height_pad   = ref_picture1->size_y_pad;
  2556.   if (apply_weights)
  2557.   {    
  2558.     computeBiPred = computeBiPred2[H_PEL];
  2559.   }
  2560.   else
  2561.   {
  2562.     computeBiPred = computeBiPred1[H_PEL];
  2563.   }
  2564.   if ( ChromaMEEnable )
  2565.   {
  2566.     ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
  2567.     ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
  2568.     ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
  2569.     ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
  2570.     width_pad_cr  = ref_picture1->size_x_cr_pad;
  2571.     height_pad_cr = ref_picture1->size_y_cr_pad;
  2572.   }
  2573.   /*********************************
  2574.    *****                       *****
  2575.    *****  HALF-PEL REFINEMENT  *****
  2576.    *****                       *****
  2577.    *********************************/
  2578.   //===== set function for getting pixel values =====
  2579.   if ((pic4_pix_x + mv[0] > 1) && (pic4_pix_x + mv[0] < max_pos_x4 - 1) &&
  2580.     (pic4_pix_y + mv[1] > 1) && (pic4_pix_y + mv[1] < max_pos_y4 - 1))
  2581.   {
  2582.     bipred1_access_method = FAST_ACCESS;
  2583.   }
  2584.   else
  2585.   {
  2586.     bipred1_access_method = UMV_ACCESS;
  2587.   }
  2588.   if ((pic4_pix_x + static_mv[0] > 1) && (pic4_pix_x + static_mv[0] < max_pos_x4 - 1) &&
  2589.     (pic4_pix_y + static_mv[1] > 1) && (pic4_pix_y + static_mv[1] < max_pos_y4 - 1))
  2590.   {
  2591.     bipred2_access_method = FAST_ACCESS;
  2592.   }
  2593.   else
  2594.   {
  2595.     bipred2_access_method = UMV_ACCESS;
  2596.   }
  2597.   //===== loop over search positions =====
  2598.   for (best_pos = 0, pos = start_hp; pos < 5; pos++)
  2599.   {
  2600.     cand_mv_x = mv[0] + search_point_hp[pos][0];    // quarter-pel units
  2601.     cand_mv_y = mv[1] + search_point_hp[pos][1];    // quarter-pel units
  2602.     //----- set motion vector cost -----
  2603.     mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  2604.     mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  2605.     mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, INT_MAX,
  2606.       cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y, smv_x, smv_y);
  2607.     if (mcost < min_mcost)
  2608.     {
  2609.       second_mcost = min_mcost;
  2610.       second_pos  = best_pos;
  2611.       min_mcost = mcost;
  2612.       best_pos  = pos;
  2613.     }
  2614.     else if (mcost < second_mcost)
  2615.     {
  2616.       second_mcost = mcost;
  2617.       second_pos  = pos;
  2618.     }
  2619.   }
  2620. //  if (best_pos ==0 && (pred_mv1[0] == mv[0]) && (pred_mv1[1] - mv[1])== 0 && min_mcost < subthres[blocktype])
  2621.       //return min_mcost;
  2622.   if (best_pos != 0 && second_pos != 0)
  2623.   {
  2624.     switch (best_pos ^ second_pos)
  2625.     {
  2626.     case 1:
  2627.       start_pos = 6;
  2628.       end_pos   = 7;
  2629.       break;
  2630.     case 3:
  2631.       start_pos = 5;
  2632.       end_pos   = 6;
  2633.       break;
  2634.     case 5:
  2635.       start_pos = 8;
  2636.       end_pos   = 9;
  2637.       break;
  2638.     case 7:
  2639.       start_pos = 7;
  2640.       end_pos   = 8;
  2641.       break;
  2642.     default:
  2643.       break;
  2644.     }
  2645.   }
  2646.   else
  2647.   {
  2648.     switch (best_pos + second_pos)
  2649.     {
  2650.     case 0:
  2651.       start_pos = 5;
  2652.       end_pos   = 5;
  2653.       break;
  2654.     case 1:
  2655.       start_pos = 8;
  2656.       end_pos   = 10;
  2657.       break;
  2658.     case 2:
  2659.       start_pos = 5;
  2660.       end_pos   = 7;
  2661.       break;
  2662.     case 5:
  2663.       start_pos = 6;
  2664.       end_pos   = 8;
  2665.       break;
  2666.     case 7:
  2667.       start_pos = 7;
  2668.       end_pos   = 9;
  2669.       break;
  2670.     default:
  2671.       break;
  2672.     }
  2673.   }
  2674.   if (best_pos !=0 || (iabs(pred_mv1[0] - mv[0]) + iabs(pred_mv1[1] - mv[1])))
  2675.   {
  2676.     for (pos = start_pos; pos < end_pos; pos++)
  2677.     {
  2678.       cand_mv_x = mv[0] + search_point_hp[pos][0];    // quarter-pel units
  2679.       cand_mv_y = mv[1] + search_point_hp[pos][1];    // quarter-pel units
  2680.       //----- set motion vector cost -----
  2681.       mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  2682.       mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  2683.       if (mcost >= min_mcost) continue;
  2684.       mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, min_mcost - mcost,
  2685.         cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y, smv_x, smv_y);
  2686.       if (mcost < min_mcost)
  2687.       {
  2688.         min_mcost = mcost;
  2689.         best_pos  = pos;
  2690.       }
  2691.     }
  2692.   }
  2693.   if (best_pos)
  2694.   {
  2695.     mv[0] += search_point_hp [best_pos][0];
  2696.     mv[1] += search_point_hp [best_pos][1];
  2697.   }
  2698.   computeBiPred = apply_weights? computeBiPred2[Q_PEL] : computeBiPred1[Q_PEL];
  2699.   /************************************
  2700.   *****                          *****
  2701.   *****  QUARTER-PEL REFINEMENT  *****
  2702.   *****                          *****
  2703.   ************************************/
  2704.   //===== set function for getting pixel values =====
  2705.   if ((pic4_pix_x + mv[0] > 0) && (pic4_pix_x + mv[0] < max_pos_x4) &&
  2706.     (pic4_pix_y + mv[1] > 0) && (pic4_pix_y + mv[1] < max_pos_y4))
  2707.   {
  2708.     bipred1_access_method = FAST_ACCESS;
  2709.   }
  2710.   else
  2711.   {
  2712.     bipred1_access_method = UMV_ACCESS;
  2713.   }
  2714.   if ((pic4_pix_x + static_mv[0] > 0) && (pic4_pix_x + static_mv[0] < max_pos_x4) &&
  2715.     (pic4_pix_y + static_mv[1] > 0) && (pic4_pix_y + static_mv[1] < max_pos_y4))
  2716.   {
  2717.     bipred2_access_method = FAST_ACCESS;
  2718.   }
  2719.   else
  2720.   {
  2721.     bipred2_access_method = UMV_ACCESS;
  2722.   }
  2723.   if ( !start_me_refinement_qp )
  2724.     min_mcost = INT_MAX;
  2725.   lambda_factor = lambda[Q_PEL];
  2726.   second_pos = 0;
  2727.   second_mcost = INT_MAX;
  2728.   //===== loop over search positions =====
  2729.   for (best_pos = 0, pos = start_me_refinement_qp; pos < 5; pos++)
  2730.   {
  2731.     cand_mv_x = mv[0] + search_point_qp[pos][0];    // quarter-pel units
  2732.     cand_mv_y = mv[1] + search_point_qp[pos][1];    // quarter-pel units
  2733.     //----- set motion vector cost -----
  2734.     mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  2735.     mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  2736.     mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, INT_MAX,
  2737.       cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y, smv_x, smv_y);
  2738.     if (mcost < min_mcost)
  2739.     {
  2740.       second_mcost = min_mcost;
  2741.       second_pos  = best_pos;
  2742.       min_mcost = mcost;
  2743.       best_pos  = pos;
  2744.     }
  2745.     else if (mcost < second_mcost)
  2746.     {
  2747.       second_mcost = mcost;
  2748.       second_pos  = pos;
  2749.     }
  2750.   }
  2751.   start_pos = 5;
  2752.   end_pos = search_pos4;
  2753.   if (best_pos != 0 && second_pos != 0)
  2754.   {
  2755.     switch (best_pos ^ second_pos)
  2756.     {
  2757.     case 1:
  2758.       start_pos = 6;
  2759.       end_pos   = 7;
  2760.       break;
  2761.     case 3:
  2762.       start_pos = 5;
  2763.       end_pos   = 6;
  2764.       break;
  2765.     case 5:
  2766.       start_pos = 8;
  2767.       end_pos   = 9;
  2768.       break;
  2769.     case 7:
  2770.       start_pos = 7;
  2771.       end_pos   = 8;
  2772.       break;
  2773.     default:
  2774.       break;
  2775.     }
  2776.   }
  2777.   else
  2778.   {
  2779.     switch (best_pos + second_pos)
  2780.     {
  2781.       //case 0:
  2782.       //start_pos = 5;
  2783.       //end_pos   = 5;
  2784.       //break;
  2785.     case 1:
  2786.       start_pos = 8;
  2787.       end_pos   = 10;
  2788.       break;
  2789.     case 2:
  2790.       start_pos = 5;
  2791.       end_pos   = 7;
  2792.       break;
  2793.     case 5:
  2794.       start_pos = 6;
  2795.       end_pos   = 8;
  2796.       break;
  2797.     case 7:
  2798.       start_pos = 7;
  2799.       end_pos   = 9;
  2800.       break;
  2801.     default:
  2802.       break;
  2803.     }
  2804.   }
  2805.   if (best_pos !=0 || (iabs(pred_mv1[0] - mv[0]) + iabs(pred_mv1[1] - mv[1])))
  2806.   {
  2807.     for (pos = start_pos; pos < end_pos; pos++)
  2808.     {
  2809.       cand_mv_x = mv[0] + search_point_qp[pos][0];    // quarter-pel units
  2810.       cand_mv_y = mv[1] + search_point_qp[pos][1];    // quarter-pel units
  2811.       //----- set motion vector cost -----
  2812.       mcost  = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv1[0], pred_mv1[1]);
  2813.       mcost += MV_COST_SMP (lambda_factor, static_mv[0], static_mv[1], pred_mv2[0], pred_mv2[1]);
  2814.       if (mcost >= min_mcost) continue;
  2815.       mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, min_mcost - mcost,
  2816.         cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y, smv_x, smv_y);
  2817.       if (mcost < min_mcost)
  2818.       {
  2819.         min_mcost = mcost;
  2820.         best_pos  = pos;
  2821.       }
  2822.     }
  2823.   }
  2824.   if (best_pos)
  2825.   {
  2826.     mv[0] += search_point_qp[best_pos][0];
  2827.     mv[1] += search_point_qp[best_pos][1];
  2828.   }
  2829.   //===== return minimum motion cost =====
  2830.   return min_mcost;
  2831. }