zoukankan      html  css  js  c++  java
  • EPZS搜索过程

    EPZS(Enhance Predictive Zonal Search) 增强预测区域搜索,是一种整像素运动估计的搜索算法。

    EPZS采用的是相关性较高的预测方法。这里的相关性较高是指,更多地根据已有的条件,来进行运动向量的预测(如采用相邻块的mv作为当前搜索块的mv进行预测)。

    Search Set

    在搜索范围内的所有mv,可以被归结为集合SS,EPZS会从SS中按照其算法的规律来选择特定的子集SS′。SS′可以包含以下几种搜索方式。

    1.S1S1,mvp,(0, 0)

    mvprev,mv(0,0)mvprev,mv(0,0)

     

    2.S2S2,当前块的相邻块mv,包括ABCD四个mv,co-located块mv,做mv_scale,即对于POC的距离进行比例增减。

    mva,mvb,mvc,mvd,mvcomva,mvb,mvc,mvd,mvco

     

    3.S3S3,这种方式基于第0个参考图像的mv,当前参考图像的mv需要由ref0的mv以POC的距离做mv_scale后得到

    mvrefn=mvref0POCcurPOCnPOCcurPOC0mvrefn=mvref0⋅POCcur−POCnPOCcur−POC0


     

    4.S4S4,以mvp或者(0, 0)为中心,呈正方形窗口的mv集合

    mvwindowmvwindow

    5.S5S5,由于运动有可能不是匀速地运动,而是以相同加速度来进行,因此可以用前两张编码图像的mv计算出当前mv

    mvcur=mvt1+(mvt1mvt2)mvcur=mvt−1+(mvt−1−mvt−2)

     

    6.S6S6,co-located块的相邻mv,需做mv_scale

    mvcola,mvcolb,mvcolc,mvcoldmvcola,mvcolb,mvcolc,mvcold

    7.S7S7,Memory Prediction即采用同一块位置中,上一个块类型(Block type - 1)做预测得到的mv,采用其相邻mv,做mv_scale

    mvpreva,mvprevb,mvprevc,mvprevdmvpreva,mvprevb,mvprevc,mvprevd

    8.S8S8,如果采用的是HME(Hierarchical Motion Estimation)分层运动估计的编码方式,那么应该选择该次HME运动估计的参考图像,从参考图像中选择co-located块,以及co-located块周边的块(带col块共9个块)的mv作为候选mv

    mvhme_co,mvhme_surround_of_comvhme_co,mvhme_surround_of_co

     

    9.S9S9,上层块mv,做mv_scale

    mv4×4=mv8×4,mv8×4=mv8×8,mv4×4=mv8×4,mv8×4=mv8×8,…

    从如上的mv集合明显看出,基本上,如果当前mv是由参考图像已有mv预测出来的情况,都需要进行mv_scale,以此提高mv预测的准确性。

    在预测完所有mv的可能位置后,得到mv集合SS,由于此处进行的是整像素预测,所以需要对mv求整。接下来需要在SS中求出mv_cost最小的mv,当然,mv需要在search range内。

    Termination

    Termination用于判断当前mv预测是否满足停止条件(mv_cost < stopCriterion),满足则代表当前mv预测已经足够准确,可以退出。

    1. 在求出第一个子集S1S1的mv_cost后,进行第一次Termination,记为T1T1。T1T1是由当前块类型的像素点个数(如16x16像素点个数为256)与lambda联合组成。JM18.6中T1T1,即stopCriterion的值为如下形式:
      stopCriterion=(Npixel×34)×2LAMBDA_ACCURACY_BITS+LAMBDA_DISTstopCriterion=(Npixel×34)×2LAMBDA_ACCURACY_BITS+LAMBDA_DIST
    2. 如果第一个停止条件不能满足,则接下来需要对所有的mv集合进行预测,从中选出mv_cost最小的mv。在得到最小mv后,进行第二次Termination,记为T2T2。T2T2由3块类型的相邻块中最小SAD,用stopCriterionT1stopCriterionT1修正计算得来。
      • 首先定义上界与下界:
        UpperLower=(Npixel×3)×2LAMBDA_ACCURACY_BITS+LAMBDA_DIST=(Npixel×14)×2LAMBDA_ACCURACY_BITS+LAMBDA_DISTUpper=(Npixel×3)×2LAMBDA_ACCURACY_BITS+LAMBDA_DISTLower=(Npixel×14)×2LAMBDA_ACCURACY_BITS+LAMBDA_DIST
      • 上下界修正:
        tmpStopCriterion=Mid(Min(SADA,SADB,SADC),Upper,Lower)tmpStopCriterion=Mid(Min(SADA,SADB,SADC),Upper,Lower)
      • StopCriterion修正:
        stopCriterion=(Max(tmpStopCriterion,stopCriterion)×8+stopCriterion)8+LAMBDA_DISTstopCriterion=(Max(tmpStopCriterion,stopCriterion)×8+stopCriterion)8+LAMBDA_DIST
    3. 如果第二个停止条件仍然不满足,接下来进行最后的小区域搜索,搜索方式有菱形,正方形,大菱形等。如果搜索得到最佳mv为菱形(或正方形)的中心点,则停止搜索,得到最终的最佳整数mv。可以参考http://www.cnblogs.com/TaigaCon/p/3788984.html

    相对于UMHS,EPZS更多地考虑了运动的相关性,基本上采用的都是用已得到的mv预测当前mv,这种方式在规律运动图像的预测中会比UMHS更有效率。但是UMHS的预测更加考虑周全,对搜索范围进行了更细密的搜索,一旦碰上无规律运动图像,UMHS预测可以得到比EPZS更准确的预测效果。因此,根据图像性质来选择不同的搜索算法将能更好地提升编码质量。

    jm18.6:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    /*!
    ***********************************************************************
    * rief
    *    FAST Motion Estimation using EPZS
    *    AMT/HYC
    ***********************************************************************
    */
    distblk                                            //  ==> minimum motion cost after search
    EPZS_motion_estimation (Macroblock * currMB,     // <--  current Macroblock
                              MotionVector * pred_mv,  // <--  motion vector predictor in sub-pel units
                              MEBlock * mv_block,      // <--  motion vector information
                              distblk min_mcost,       // <--  minimum motion cost (cost for center or huge value)
                              int lambda_factor        // <--  lagrangian parameter for determining motion cost
                              )
    {
      Slice *currSlice = currMB->p_Slice;
      VideoParameters *p_Vid = currMB->p_Vid;
      InputParameters *p_Inp = currMB->p_Inp;
      EPZSParameters *p_EPZS = currSlice->p_EPZS;
      PicMotionParams **motion = p_Vid->enc_picture->mv_info;
     
      int blocktype = mv_block->blocktype;
     
      int list = mv_block->list;
      int cur_list = list + currMB->list_offset;
      short ref = mv_block->ref_idx;
      MotionVector *mv = &mv_block->mv[list];
      SearchWindow *searchRange = &mv_block->searchRange;
      int mapCenter_x = searchRange->max_x - mv->mv_x;
      int mapCenter_y = searchRange->max_y - mv->mv_y;
      StorablePicture *ref_picture = currSlice->listX[cur_list][ref];
     
      distblk lambda_dist = weighted_cost(lambda_factor, 2);
      distblk stopCriterion = p_EPZS->medthres[blocktype] + lambda_dist;
      distblk *prevSad = &p_EPZS->distortion[cur_list][blocktype - 1][mv_block->pos_x2];
     
      MotionVector *p_motion = NULL; //only work for EPZSSpatialMem
     
      EPZSStructure *searchPatternF = p_EPZS->searchPattern;
      uint16 **EPZSMap = &p_EPZS->EPZSMap[mapCenter_y];
      uint16 *EPZSPoint = &p_EPZS->EPZSMap[searchRange->max_y][searchRange->max_x];
     
      MotionVector center = pad_MVs (*mv, mv_block);
      MotionVector pred = pad_MVs (*pred_mv, mv_block);
      MotionVector tmp = *mv, cand = center;
     
      ++p_EPZS->BlkCount;
      if (p_EPZS->BlkCount == 0)
        ++p_EPZS->BlkCount;
     
      if (p_Inp->EPZSSpatialMem)
      {
    #if EPZSREF
        p_motion = &p_EPZS->p_motion[cur_list][ref][blocktype - 1][mv_block->block_y][mv_block->pos_x2];
    #else
        p_motion = &p_EPZS->p_motion[cur_list][blocktype - 1][mv_block->block_y][mv_block->pos_x2];
    #endif
      }
     
      // Clear EPZSMap
      // memset(EPZSMap[0],FALSE,searcharray*searcharray);
      // Check median candidate;
      //p_EPZS->EPZSMap[0][0] = p_EPZS->BlkCount;
      *EPZSPoint = p_EPZS->BlkCount;
     
      //--- initialize motion cost (cost for motion vector) and check ---
      //(0,0)作为mv
      min_mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred);
     
      //--- add residual cost to motion cost ---
      min_mcost += mv_block->computePredFPel (ref_picture, mv_block, DISTBLK_MAX - min_mcost, &cand);
     
      // Additional threshold for ref>0
      if ((ref > 0 && currSlice->structure == FRAME) && (*prevSad < distblkmin (p_EPZS->medthres[blocktype] + lambda_dist, min_mcost)))
      {//满足返回条件
    #if EPZSREF
        if (p_Inp->EPZSSpatialMem)
    #else
        if (p_Inp->EPZSSpatialMem && ref == 0)
    #endif
        {
          *p_motion = tmp;
        }
        return min_mcost;
      }
     
      //! If p_EPZS->medthres satisfied, then terminate, otherwise generate Predictors
      //! Condition could be strengthened by consideration distortion of adjacent partitions.
      if (min_mcost > stopCriterion)
      {
        SPoint *p_EPZS_point = p_EPZS->predictor->point;
        Boolean checkMedian = FALSE;
        distblk second_mcost = DISTBLK_MAX;
        distblk mcost;
        int prednum = 5;
        int conditionEPZS;
        MotionVector tmp2 = {0, 0}, tmv;
        int pos;
        short invalid_refs = 0;
     
        stopCriterion = EPZSDetermineStopCriterion (p_EPZS, prevSad, mv_block, lambda_dist);
     
        if (min_mcost < (stopCriterion >> 1))
        {
    #if EPZSREF
          if (p_Inp->EPZSSpatialMem)
    #else
          if (p_Inp->EPZSSpatialMem && ref == 0)
    #endif
          {
            *p_motion = tmp;
          }
     
          return min_mcost;
        }
     
        //! Add Spatial Predictors in predictor list.
        //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little
        //! in terms of performance and could be removed with little penalty if any.
        //当前块相邻mv,做mv_scale
        invalid_refs = EPZS_spatial_predictors (p_EPZS, mv_block,
          list, currMB->list_offset, ref, motion);
     
     
     
        //当前类型的block_type(8x4)的上一个block_type(8x8),相同位置留下来的mv,采用其相邻mv
        /*
         *     
         *   +--------+----+----+                
         *   |        |    B    |                
         *   |        |____A____|                
         *   |        |         |                
         *   |        |         |                
         *   |        +----+----+                
         *   |                  |                
         *   |                  |                
         *   |                  |                
         *   |                  |                
         *   +------------------+                
         *   
         *   B : 8x4    A 8x8
         *     macroblock                     
         *                                    
         *memory_mv_b = surrounding_of_mv_a
         *采用mv_a的相邻mv
         *
         */
        if (p_Inp->EPZSSpatialMem)
          EPZS_spatial_memory_predictors (p_EPZS, mv_block, cur_list, &prednum, ref_picture->size_x >> 2);
        
        //if (p_Inp->HMEEnable == 1 && p_Inp->EPZSUseHMEPredictors == 1 && blocktype == 4)
        //if (p_Inp->HMEEnable == 1 && p_Inp->EPZSUseHMEPredictors == 1 && (currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE || p_Inp->EnableReorderBslice) )
        //如果采用HME(Hierarchical Motion Estimate),即B帧的参考图像选择方式有所不同
        //选择此时的分层参考图像(Hierarchical ref pic)对应块的相邻mv
        if (p_Inp->HMEEnable == 1 && p_Inp->EPZSUseHMEPredictors == 1)
          EPZS_hierarchical_predictors (p_EPZS, mv_block, &prednum, ref_picture, currSlice);
     
    #if (MVC_EXTENSION_ENABLE)
        if ( p_Inp->EPZSTemporal[currSlice->view_id] && blocktype < 5 )
    #else
        // Temporal predictors
        //colocate块的相邻块mv
        if (p_Inp->EPZSTemporal && blocktype < 5)
    #endif
        {
          EPZS_temporal_predictors (currMB, ref_picture, p_EPZS, mv_block, &prednum, stopCriterion, min_mcost);
        }
     
        //! Window Size Based Predictors
        //! Basically replaces a Hierarchical ME concept and helps escaping local minima, or
        //! determining large motion variations.
        //! Following predictors can be adjusted further (i.e. removed, conditioned etc)
        //! based on distortion, correlation of adjacent MVs, complexity etc. These predictors
        //! and their conditioning could also be moved after all other predictors have been
        //! tested. Adaptation could also be based on type of material and coding mode (i.e.
        //! field/frame coding,MBAFF etc considering the higher dependency with opposite parity field
        //conditionEPZS = ((min_mcost > stopCriterion)
        // && (p_Inp->EPZSFixed > 1 || (p_Inp->EPZSFixed && currSlice->slice_type == P_SLICE)));
        //conditionEPZS = ((ref == 0) && (blocktype < 5) && (min_mcost > stopCriterion)
        //&& (p_Inp->EPZSFixed > 1 || (p_Inp->EPZSFixed && currSlice->slice_type == P_SLICE)));
        //conditionEPZS = ((min_mcost > stopCriterion) && ((ref < 2 && blocktype < 4)
        conditionEPZS = (p_Inp->EPZSFixed == 3 && (currMB->mb_x == 0 || currMB->mb_y == 0))
          || ((min_mcost > 3 * stopCriterion) && ((ref < 2 && blocktype < 4) || (ref < 1 && blocktype == 4)
          || ((currSlice->structure != FRAME || currMB->list_offset)
          && ref < 3))
          && (p_Inp->EPZSFixed > 1 || (p_Inp->EPZSFixed && currSlice->slice_type == P_SLICE)));
     
        //正方形窗口mv
        if (conditionEPZS)
          EPZSWindowPredictors (mv, p_EPZS->predictor, &prednum,
          (p_Inp->EPZSAggressiveWindow != 0) || ((blocktype < 5) && (invalid_refs > 2) && (ref < 1 + (currSlice->structure != FRAME || currMB->list_offset)))
          ? p_EPZS->window_predictor_ext : p_EPZS->window_predictor);
     
        //! Blocktype/Reference dependent predictors.
        //! Since already mvs for other blocktypes/references have been computed, we can reuse
        //! them in order to easier determine the optimal point. Use of predictors could depend
        //! on cost,
        //conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion) || currSlice->structure != FRAME || currMB->list_offset);
        conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > 2 * stopCriterion));
     
        //上层宏块mv,做mv_scale
        if (conditionEPZS && currMB->mbAddrX != 0 && p_Inp->EPZSBlockType)
          EPZSBlockTypePredictorsMB (currSlice, mv_block, p_EPZS_point, &prednum);
     
        //! Check all predictors
         
        //循环内,对所有的cand mv(S1,S2,S3,S4)做cost.取出最佳mv
        for (pos = 0; pos < prednum; ++pos)
        {
          tmv = p_EPZS_point[pos].motion;
          set_integer_mv(&tmv);
     
          //if (((iabs (tmv.mv_x - mv->mv_x) > searchRange->max_x || iabs (tmv.mv_y - mv->mv_y) > searchRange->max_y)) && (tmv.mv_x || tmv.mv_y))
          if ((iabs (tmv.mv_x - mv->mv_x) - searchRange->max_x <= 0) && (iabs (tmv.mv_y - mv->mv_y) - searchRange->max_y <= 0))
          {
            EPZSPoint = &EPZSMap[tmv.mv_y][mapCenter_x + tmv.mv_x];
            if (*EPZSPoint != p_EPZS->BlkCount)
            {
              *EPZSPoint = p_EPZS->BlkCount;
              cand = pad_MVs (tmv, mv_block);
     
              //--- set motion cost (cost for motion vector) and check ---
              mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred);
     
              if (mcost < second_mcost)
              {
                mcost += mv_block->computePredFPel (ref_picture, mv_block, second_mcost - mcost, &cand);
     
                //--- check if motion cost is less than minimum cost ---
                if (mcost < min_mcost)
                {
                  tmp2 = tmp;
                  tmp = tmv;
                  second_mcost = min_mcost;
                  min_mcost = mcost;
                  checkMedian = TRUE;
                }
                //else if (mcost < second_mcost && (tmp.mv_x != tmv.mv_x || tmp.mv_y != tmv.mv_y))
                else if (mcost < second_mcost)
                {
                  tmp2 = tmv;
                  second_mcost = mcost;
                  checkMedian = TRUE;
                }
              }
            }
          }
        }
     
        //! Refine using EPZS pattern if needed
        //! Note that we are using a conservative threshold method. Threshold
        //! could be tested after checking only a certain number of predictors
        //! instead of the full set. Code could be easily modified for this task.
        if (min_mcost > stopCriterion)
        {
          const int mv_range = 10;
          int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
          int totalCheckPts = 0, motionDirection = 0;
     
          //! Adapt pattern based on different conditions.
          if (p_Inp->EPZSPattern != 0)
          {
            if ((min_mcost < stopCriterion + ((3 * p_EPZS->medthres[blocktype]) >> 1)))
            {
              if ((tmp.mv_x == 0 && tmp.mv_y == 0)
                || (iabs (tmp.mv_x - mv->mv_x) < (mv_range) && iabs (tmp.mv_y - mv->mv_y) < (mv_range)))
                searchPatternF = p_Vid->sdiamond;
              else
                searchPatternF = p_Vid->square;
            }
            else if (blocktype > 4 || (ref > 0 && blocktype != 1))
              searchPatternF = p_Vid->square;
            else
              searchPatternF = p_EPZS->searchPattern;
          }
     
          //! center on best predictor
          center = tmp;
     
          for (;;)
          {
            totalCheckPts = searchPatternF->searchPoints;
            do
            {//循环对得到的最佳mv是做小范围搜索:square,dimond,etc.
              checkPts = totalCheckPts;
              do
              {//循环对小范围进行各个像素点的搜索
                tmv = add_MVs (center, &(searchPatternF->point[pointNumber].motion));
     
                if (((iabs (tmv.mv_x - mv->mv_x) - searchRange->max_x) <= 0) && ((iabs (tmv.mv_y - mv->mv_y) - searchRange->max_y) <= 0))
                {
                  //EPZSMap用于记录当前点是否被搜索过,一旦搜索过,则不再搜索,这样的话就不会跟//! Check all predictors重复了
                  EPZSPoint = &EPZSMap[tmv.mv_y][mapCenter_x + tmv.mv_x];
                  if (*EPZSPoint != p_EPZS->BlkCount)
                  {
                    *EPZSPoint = p_EPZS->BlkCount;
                    cand = pad_MVs (tmv, mv_block);
     
                    mcost = mv_cost (p_Vid, lambda_factor, &cand, &pred);
     
                    if (mcost < min_mcost)
                    {
                      mcost += mv_block->computePredFPel (ref_picture, mv_block, min_mcost - mcost, &cand);
     
                      if (mcost < min_mcost)
                      {
                        tmp = tmv;
                        min_mcost = mcost;
                        motionDirection = pointNumber;
                      }
                    }
                  }
                }
                ++pointNumber;
                if (pointNumber >= searchPatternF->searchPoints)
                  pointNumber -= searchPatternF->searchPoints;
                checkPts--;
              }
              while (checkPts > 0);
               
              //对得到的最佳mv,如果是center(第一次的center是mvp),则停止当前循环
              if (nextLast || ((tmp.mv_x == center.mv_x) && (tmp.mv_y == center.mv_y)))
              {
                patternStop = searchPatternF->stopSearch;
                searchPatternF = searchPatternF->nextpattern;
                totalCheckPts = searchPatternF->searchPoints;
                nextLast = searchPatternF->nextLast;
                motionDirection = 0;
                pointNumber = 0;
              }
              else
              {
                totalCheckPts = searchPatternF->point[motionDirection].next_points;
                pointNumber = searchPatternF->point[motionDirection].start_nmbr;
                center = tmp;
              }
            }
            while (patternStop != 1);
     
            if ((ref > 0) && (currSlice->structure == FRAME)
              && ((4 * *prevSad < min_mcost) || ((3 * *prevSad < min_mcost) && (*prevSad <= stopCriterion))))
            {
              *mv = tmp;
    #if EPZSREF
              if (p_Inp->EPZSSpatialMem)
    #else 
              if (p_Inp->EPZSSpatialMem && ref == 0)
    #endif 
              {
                *p_motion = tmp;
              }
     
              return min_mcost;
            }
     
            //! Check Second best predictor with EPZS pattern
            conditionEPZS = (checkMedian == TRUE)
              && ((currSlice->slice_type == P_SLICE) || (blocktype < 5))
              && (min_mcost > stopCriterion) && (p_Inp->EPZSDual > 0);
     
            if (!conditionEPZS)
              break;
            //如果上方条件有多于0个不满足的,则退出循环
            //退出条件1:  EPZSDual = 0 ,即循环只需要执行一次
            //        2:  cost足够小了
            //        3:  blocktypc = 5,6,7
            //        4:  不为P_SLICE
            //        5:  checkMedian = false,即由于EPZSDual,而执行完了第二次
     
            pointNumber = 0;
            patternStop = 0;
            motionDirection = 0;
            nextLast = 0;
     
            if ((tmp.mv_x == 0 && tmp.mv_y == 0) || (tmp.mv_x == mv->mv_x && tmp.mv_y == mv->mv_y))
            {
              if (iabs (tmp.mv_x - mv->mv_x) < (mv_range) && iabs (tmp.mv_y - mv->mv_y) < (mv_range))
                searchPatternF = p_Vid->sdiamond;
              else
                searchPatternF = p_Vid->square;
            }
            else
              searchPatternF = p_EPZS->searchPatternD;
     
            //! Second best. Note that following code is identical as for best predictor.
            //由于EPZSDual > 0,开启第二次循环,以原点(当前mv_block所在坐标)为中心,开始搜索
            center = tmp2;
            checkMedian = FALSE;
          }
        }
      }
     
      if ((ref == 0) || (*prevSad > min_mcost))
        *prevSad = min_mcost;
    #if EPZSREF
      if (p_Inp->EPZSSpatialMem)
    #else 
      if (p_Inp->EPZSSpatialMem && ref == 0)
    #endif 
      {
        *p_motion = tmp;
        //printf("value %d %d %d %d ", p_motion->mv_x, p_motion->mv_y, p_motion[cur_list][ref][0][0][0].mv_x, p_motion[list + list_offset][ref][0][0][0].mv_y);
        //printf("xxxxx %d %d %d %d ", p_motion->mv_x, p_motion->mv_y, p_motion[cur_list][ref][blocktype - 1][mv_block->block_y][pic_pix_x2].mv_x, p_motion[cur_list][ref][blocktype - 1][mv_block->block_y][pic_pix_x2].mv_y);
      }
     
      *mv = tmp;
     
      return min_mcost;
    }

    View Code

  • 相关阅读:
    hdu 6049 Sdjpx Is Happy
    L2-012. 关于堆的判断
    L2-010. 排座位
    L2-009. 抢红包
    L2-007. 家庭房产
    L2-008. 最长对称子串
    L2-011. 玩转二叉树
    l2-006 树的遍历
    l2-005
    l1-20 帅到没朋友
  • 原文地址:https://www.cnblogs.com/xumaojun/p/8523571.html
Copyright © 2011-2022 走看看