Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /* contains
     19 Int HalfPel1_SAD_MB(UChar *ref,UChar *blk,Int dmin,Int width,Int ih,Int jh)
     20 Int HalfPel2_SAD_MB(UChar *ref,UChar *blk,Int dmin,Int width)
     21 Int HalfPel1_SAD_Blk(UChar *ref,UChar *blk,Int dmin,Int width,Int ih,Int jh)
     22 Int HalfPel2_SAD_Blk(UChar *ref,UChar *blk,Int dmin,Int width)
     23 
     24 Int SAD_MB_HalfPel_C(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
     25 Int SAD_MB_HP_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
     26 Int SAD_MB_HP_HTFM(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
     27 Int SAD_Blk_HalfPel_C(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
     28 */
     29 
     30 //#include <stdlib.h> /* for RAND_MAX */
     31 #include "mp4def.h"
     32 #include "mp4lib_int.h"
     33 #include "sad_halfpel_inline.h"
     34 
     35 #ifdef _SAD_STAT
     36 ULong num_sad_HP_MB = 0;
     37 ULong num_sad_HP_Blk = 0;
     38 ULong num_sad_HP_MB_call = 0;
     39 ULong num_sad_HP_Blk_call = 0;
     40 #define NUM_SAD_HP_MB_CALL()    num_sad_HP_MB_call++
     41 #define NUM_SAD_HP_MB()         num_sad_HP_MB++
     42 #define NUM_SAD_HP_BLK_CALL()   num_sad_HP_Blk_call++
     43 #define NUM_SAD_HP_BLK()        num_sad_HP_Blk++
     44 #else
     45 #define NUM_SAD_HP_MB_CALL()
     46 #define NUM_SAD_HP_MB()
     47 #define NUM_SAD_HP_BLK_CALL()
     48 #define NUM_SAD_HP_BLK()
     49 #endif
     50 
     51 
     52 #ifdef __cplusplus
     53 extern "C"
     54 {
     55 #endif
     56     /*==================================================================
     57         Function:   HalfPel1_SAD_MB
     58         Date:       03/27/2001
     59         Purpose:    Compute SAD 16x16 between blk and ref in halfpel
     60                     resolution,
     61         Changes:
     62       ==================================================================*/
     63     /* One component is half-pel */
     64     Int HalfPel1_SAD_MB(UChar *ref, UChar *blk, Int dmin, Int width, Int ih, Int jh)
     65     {
     66         Int i, j;
     67         Int sad = 0;
     68         UChar *kk, *p1, *p2;
     69         Int temp;
     70 
     71         OSCL_UNUSED_ARG(jh);
     72 
     73         p1 = ref;
     74         if (ih) p2 = ref + 1;
     75         else p2 = ref + width;
     76         kk  = blk;
     77 
     78         for (i = 0; i < 16; i++)
     79         {
     80             for (j = 0; j < 16; j++)
     81             {
     82 
     83                 temp = ((p1[j] + p2[j] + 1) >> 1) - *kk++;
     84                 sad += PV_ABS(temp);
     85             }
     86 
     87             if (sad > dmin)
     88                 return sad;
     89             p1 += width;
     90             p2 += width;
     91         }
     92         return sad;
     93     }
     94 
     95     /* Two components need half-pel */
     96     Int HalfPel2_SAD_MB(UChar *ref, UChar *blk, Int dmin, Int width)
     97     {
     98         Int i, j;
     99         Int sad = 0;
    100         UChar *kk, *p1, *p2, *p3, *p4;
    101         Int temp;
    102 
    103         p1 = ref;
    104         p2 = ref + 1;
    105         p3 = ref + width;
    106         p4 = ref + width + 1;
    107         kk  = blk;
    108 
    109         for (i = 0; i < 16; i++)
    110         {
    111             for (j = 0; j < 16; j++)
    112             {
    113 
    114                 temp = ((p1[j] + p2[j] + p3[j] + p4[j] + 2) >> 2) - *kk++;
    115                 sad += PV_ABS(temp);
    116             }
    117 
    118             if (sad > dmin)
    119                 return sad;
    120 
    121             p1 += width;
    122             p3 += width;
    123             p2 += width;
    124             p4 += width;
    125         }
    126         return sad;
    127     }
    128 
    129 #ifndef NO_INTER4V
    130     /*==================================================================
    131         Function:   HalfPel1_SAD_Blk
    132         Date:       03/27/2001
    133         Purpose:    Compute SAD 8x8 between blk and ref in halfpel
    134                     resolution.
    135         Changes:
    136       ==================================================================*/
    137     /* One component needs half-pel */
    138     Int HalfPel1_SAD_Blk(UChar *ref, UChar *blk, Int dmin, Int width, Int ih, Int jh)
    139     {
    140         Int i, j;
    141         Int sad = 0;
    142         UChar *kk, *p1, *p2;
    143         Int temp;
    144 
    145         OSCL_UNUSED_ARG(jh);
    146 
    147         p1 = ref;
    148         if (ih) p2 = ref + 1;
    149         else p2 = ref + width;
    150         kk  = blk;
    151 
    152         for (i = 0; i < 8; i++)
    153         {
    154             for (j = 0; j < 8; j++)
    155             {
    156 
    157                 temp = ((p1[j] + p2[j] + 1) >> 1) - *kk++;
    158                 sad += PV_ABS(temp);
    159             }
    160 
    161             if (sad > dmin)
    162                 return sad;
    163             p1 += width;
    164             p2 += width;
    165             kk += 8;
    166         }
    167         return sad;
    168     }
    169     /* Two components need half-pel */
    170     Int HalfPel2_SAD_Blk(UChar *ref, UChar *blk, Int dmin, Int width)
    171     {
    172         Int i, j;
    173         Int sad = 0;
    174         UChar *kk, *p1, *p2, *p3, *p4;
    175         Int temp;
    176 
    177         p1 = ref;
    178         p2 = ref + 1;
    179         p3 = ref + width;
    180         p4 = ref + width + 1;
    181         kk  = blk;
    182 
    183         for (i = 0; i < 8; i++)
    184         {
    185             for (j = 0; j < 8; j++)
    186             {
    187 
    188                 temp = ((p1[j] + p2[j] + p3[j] + p4[j] + 2) >> 2) - *kk++;
    189                 sad += PV_ABS(temp);
    190             }
    191 
    192             if (sad > dmin)
    193                 return sad;
    194 
    195             p1 += width;
    196             p3 += width;
    197             p2 += width;
    198             p4 += width;
    199             kk += 8;
    200         }
    201         return sad;
    202     }
    203 #endif // NO_INTER4V
    204     /*===============================================================
    205         Function:   SAD_MB_HalfPel
    206         Date:       09/17/2000
    207         Purpose:    Compute the SAD on the half-pel resolution
    208         Input/Output:   hmem is assumed to be a pointer to the starting
    209                     point of the search in the 33x33 matrix search region
    210         Changes:
    211     11/7/00:     implemented MMX
    212       ===============================================================*/
    213     /*==================================================================
    214         Function:   SAD_MB_HalfPel_C
    215         Date:       04/30/2001
    216         Purpose:    Compute SAD 16x16 between blk and ref in halfpel
    217                     resolution,
    218         Changes:
    219       ==================================================================*/
    220     /* One component is half-pel */
    221     Int SAD_MB_HalfPel_Cxhyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    222     {
    223         Int i, j;
    224         Int sad = 0;
    225         UChar *kk, *p1, *p2, *p3, *p4;
    226 //  Int sumref=0;
    227         Int temp;
    228         Int rx = dmin_rx & 0xFFFF;
    229 
    230         OSCL_UNUSED_ARG(extra_info);
    231 
    232         NUM_SAD_HP_MB_CALL();
    233 
    234         p1 = ref;
    235         p2 = ref + 1;
    236         p3 = ref + rx;
    237         p4 = ref + rx + 1;
    238         kk  = blk;
    239 
    240         for (i = 0; i < 16; i++)
    241         {
    242             for (j = 0; j < 16; j++)
    243             {
    244 
    245                 temp = ((p1[j] + p2[j] + p3[j] + p4[j] + 2) >> 2) - *kk++;
    246                 sad += PV_ABS(temp);
    247             }
    248 
    249             NUM_SAD_HP_MB();
    250 
    251             if (sad > (Int)((ULong)dmin_rx >> 16))
    252                 return sad;
    253 
    254             p1 += rx;
    255             p3 += rx;
    256             p2 += rx;
    257             p4 += rx;
    258         }
    259         return sad;
    260     }
    261 
    262     Int SAD_MB_HalfPel_Cyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    263     {
    264         Int i, j;
    265         Int sad = 0;
    266         UChar *kk, *p1, *p2;
    267 //  Int sumref=0;
    268         Int temp;
    269         Int rx = dmin_rx & 0xFFFF;
    270 
    271         OSCL_UNUSED_ARG(extra_info);
    272 
    273         NUM_SAD_HP_MB_CALL();
    274 
    275         p1 = ref;
    276         p2 = ref + rx; /* either left/right or top/bottom pixel */
    277         kk  = blk;
    278 
    279         for (i = 0; i < 16; i++)
    280         {
    281             for (j = 0; j < 16; j++)
    282             {
    283 
    284                 temp = ((p1[j] + p2[j] + 1) >> 1) - *kk++;
    285                 sad += PV_ABS(temp);
    286             }
    287 
    288             NUM_SAD_HP_MB();
    289 
    290             if (sad > (Int)((ULong)dmin_rx >> 16))
    291                 return sad;
    292             p1 += rx;
    293             p2 += rx;
    294         }
    295         return sad;
    296     }
    297 
    298     Int SAD_MB_HalfPel_Cxh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    299     {
    300         Int i, j;
    301         Int sad = 0;
    302         UChar *kk, *p1;
    303 //  Int sumref=0;
    304         Int temp;
    305         Int rx = dmin_rx & 0xFFFF;
    306 
    307         OSCL_UNUSED_ARG(extra_info);
    308 
    309         NUM_SAD_HP_MB_CALL();
    310 
    311         p1 = ref;
    312         kk  = blk;
    313 
    314         for (i = 0; i < 16; i++)
    315         {
    316             for (j = 0; j < 16; j++)
    317             {
    318 
    319                 temp = ((p1[j] + p1[j+1] + 1) >> 1) - *kk++;
    320                 sad += PV_ABS(temp);
    321             }
    322 
    323             NUM_SAD_HP_MB();
    324 
    325             if (sad > (Int)((ULong)dmin_rx >> 16))
    326                 return sad;
    327             p1 += rx;
    328         }
    329         return sad;
    330     }
    331 
    332 #ifdef HTFM  /* HTFM with uniform subsampling implementation, 2/28/01 */
    333 
    334 //Checheck here
    335     Int SAD_MB_HP_HTFM_Collectxhyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    336     {
    337         Int i, j;
    338         Int sad = 0;
    339         UChar *p1, *p2;
    340         Int rx = dmin_rx & 0xFFFF;
    341         Int refwx4 = rx << 2;
    342         Int saddata[16];      /* used when collecting flag (global) is on */
    343         Int difmad, tmp, tmp2;
    344         HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info;
    345         Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg);
    346         UInt *countbreak = &(htfm_stat->countbreak);
    347         Int *offsetRef = htfm_stat->offsetRef;
    348         ULong cur_word;
    349 
    350         NUM_SAD_HP_MB_CALL();
    351 
    352         blk -= 4;
    353 
    354         for (i = 0; i < 16; i++) /* 16 stages */
    355         {
    356             p1 = ref + offsetRef[i];
    357             p2 = p1 + rx;
    358 
    359             j = 4;/* 4 lines */
    360             do
    361             {
    362                 cur_word = *((ULong*)(blk += 4));
    363                 tmp = p1[12] + p2[12];
    364                 tmp2 = p1[13] + p2[13];
    365                 tmp += tmp2;
    366                 tmp2 = (cur_word >> 24) & 0xFF;
    367                 tmp += 2;
    368                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    369                 tmp = p1[8] + p2[8];
    370                 tmp2 = p1[9] + p2[9];
    371                 tmp += tmp2;
    372                 tmp2 = (cur_word >> 16) & 0xFF;
    373                 tmp += 2;
    374                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    375                 tmp = p1[4] + p2[4];
    376                 tmp2 = p1[5] + p2[5];
    377                 tmp += tmp2;
    378                 tmp2 = (cur_word >> 8) & 0xFF;
    379                 tmp += 2;
    380                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    381                 tmp2 = p1[1] + p2[1];
    382                 tmp = p1[0] + p2[0];
    383                 p1 += refwx4;
    384                 p2 += refwx4;
    385                 tmp += tmp2;
    386                 tmp2 = (cur_word & 0xFF);
    387                 tmp += 2;
    388                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    389             }
    390             while (--j);
    391 
    392             NUM_SAD_HP_MB();
    393 
    394             saddata[i] = sad;
    395 
    396             if (i > 0)
    397             {
    398                 if (sad > (Int)((ULong)dmin_rx >> 16))
    399                 {
    400                     difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    401                     (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    402                     (*countbreak)++;
    403                     return sad;
    404                 }
    405             }
    406         }
    407         difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    408         (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    409         (*countbreak)++;
    410 
    411         return sad;
    412     }
    413 
    414     Int SAD_MB_HP_HTFM_Collectyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    415     {
    416         Int i, j;
    417         Int sad = 0;
    418         UChar *p1, *p2;
    419         Int rx = dmin_rx & 0xFFFF;
    420         Int refwx4 = rx << 2;
    421         Int saddata[16];      /* used when collecting flag (global) is on */
    422         Int difmad, tmp, tmp2;
    423         HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info;
    424         Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg);
    425         UInt *countbreak = &(htfm_stat->countbreak);
    426         Int *offsetRef = htfm_stat->offsetRef;
    427         ULong cur_word;
    428 
    429         NUM_SAD_HP_MB_CALL();
    430 
    431         blk -= 4;
    432 
    433         for (i = 0; i < 16; i++) /* 16 stages */
    434         {
    435             p1 = ref + offsetRef[i];
    436             p2 = p1 + rx;
    437             j = 4;
    438             do
    439             {
    440                 cur_word = *((ULong*)(blk += 4));
    441                 tmp = p1[12];
    442                 tmp2 = p2[12];
    443                 tmp++;
    444                 tmp2 += tmp;
    445                 tmp = (cur_word >> 24) & 0xFF;
    446                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    447                 tmp = p1[8];
    448                 tmp2 = p2[8];
    449                 tmp++;
    450                 tmp2 += tmp;
    451                 tmp = (cur_word >> 16) & 0xFF;
    452                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    453                 tmp = p1[4];
    454                 tmp2 = p2[4];
    455                 tmp++;
    456                 tmp2 += tmp;
    457                 tmp = (cur_word >> 8) & 0xFF;
    458                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    459                 tmp = p1[0];
    460                 p1 += refwx4;
    461                 tmp2 = p2[0];
    462                 p2 += refwx4;
    463                 tmp++;
    464                 tmp2 += tmp;
    465                 tmp = (cur_word & 0xFF);
    466                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    467             }
    468             while (--j);
    469 
    470             NUM_SAD_HP_MB();
    471 
    472             saddata[i] = sad;
    473 
    474             if (i > 0)
    475             {
    476                 if (sad > (Int)((ULong)dmin_rx >> 16))
    477                 {
    478                     difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    479                     (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    480                     (*countbreak)++;
    481                     return sad;
    482                 }
    483             }
    484         }
    485         difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    486         (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    487         (*countbreak)++;
    488 
    489         return sad;
    490     }
    491 
    492     Int SAD_MB_HP_HTFM_Collectxh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    493     {
    494         Int i, j;
    495         Int sad = 0;
    496         UChar *p1;
    497         Int rx = dmin_rx & 0xFFFF;
    498         Int refwx4 = rx << 2;
    499         Int saddata[16];      /* used when collecting flag (global) is on */
    500         Int difmad, tmp, tmp2;
    501         HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info;
    502         Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg);
    503         UInt *countbreak = &(htfm_stat->countbreak);
    504         Int *offsetRef = htfm_stat->offsetRef;
    505         ULong cur_word;
    506 
    507         NUM_SAD_HP_MB_CALL();
    508 
    509         blk -= 4;
    510 
    511         for (i = 0; i < 16; i++) /* 16 stages */
    512         {
    513             p1 = ref + offsetRef[i];
    514 
    515             j = 4; /* 4 lines */
    516             do
    517             {
    518                 cur_word = *((ULong*)(blk += 4));
    519                 tmp = p1[12];
    520                 tmp2 = p1[13];
    521                 tmp++;
    522                 tmp2 += tmp;
    523                 tmp = (cur_word >> 24) & 0xFF;
    524                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    525                 tmp = p1[8];
    526                 tmp2 = p1[9];
    527                 tmp++;
    528                 tmp2 += tmp;
    529                 tmp = (cur_word >> 16) & 0xFF;
    530                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    531                 tmp = p1[4];
    532                 tmp2 = p1[5];
    533                 tmp++;
    534                 tmp2 += tmp;
    535                 tmp = (cur_word >> 8) & 0xFF;
    536                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    537                 tmp = p1[0];
    538                 tmp2 = p1[1];
    539                 p1 += refwx4;
    540                 tmp++;
    541                 tmp2 += tmp;
    542                 tmp = (cur_word & 0xFF);
    543                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    544             }
    545             while (--j);
    546 
    547             NUM_SAD_HP_MB();
    548 
    549             saddata[i] = sad;
    550 
    551             if (i > 0)
    552             {
    553                 if (sad > (Int)((ULong)dmin_rx >> 16))
    554                 {
    555                     difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    556                     (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    557                     (*countbreak)++;
    558                     return sad;
    559                 }
    560             }
    561         }
    562         difmad = saddata[0] - ((saddata[1] + 1) >> 1);
    563         (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
    564         (*countbreak)++;
    565 
    566         return sad;
    567     }
    568 
    569     Int SAD_MB_HP_HTFMxhyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    570     {
    571         Int i, j;
    572         Int sad = 0, tmp, tmp2;
    573         UChar *p1, *p2;
    574         Int rx = dmin_rx & 0xFFFF;
    575         Int refwx4 = rx << 2;
    576         Int sadstar = 0, madstar;
    577         Int *nrmlz_th = (Int*) extra_info;
    578         Int *offsetRef = nrmlz_th + 32;
    579         ULong cur_word;
    580 
    581         madstar = (ULong)dmin_rx >> 20;
    582 
    583         NUM_SAD_HP_MB_CALL();
    584 
    585         blk -= 4;
    586 
    587         for (i = 0; i < 16; i++) /* 16 stages */
    588         {
    589             p1 = ref + offsetRef[i];
    590             p2 = p1 + rx;
    591 
    592             j = 4; /* 4 lines */
    593             do
    594             {
    595                 cur_word = *((ULong*)(blk += 4));
    596                 tmp = p1[12] + p2[12];
    597                 tmp2 = p1[13] + p2[13];
    598                 tmp += tmp2;
    599                 tmp2 = (cur_word >> 24) & 0xFF;
    600                 tmp += 2;
    601                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    602                 tmp = p1[8] + p2[8];
    603                 tmp2 = p1[9] + p2[9];
    604                 tmp += tmp2;
    605                 tmp2 = (cur_word >> 16) & 0xFF;
    606                 tmp += 2;
    607                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    608                 tmp = p1[4] + p2[4];
    609                 tmp2 = p1[5] + p2[5];
    610                 tmp += tmp2;
    611                 tmp2 = (cur_word >> 8) & 0xFF;
    612                 tmp += 2;
    613                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    614                 tmp2 = p1[1] + p2[1];
    615                 tmp = p1[0] + p2[0];
    616                 p1 += refwx4;
    617                 p2 += refwx4;
    618                 tmp += tmp2;
    619                 tmp2 = (cur_word & 0xFF);
    620                 tmp += 2;
    621                 sad = INTERP2_SUB_SAD(sad, tmp, tmp2);;
    622             }
    623             while (--j);
    624 
    625             NUM_SAD_HP_MB();
    626 
    627             sadstar += madstar;
    628             if (sad > sadstar - nrmlz_th[i] || sad > (Int)((ULong)dmin_rx >> 16))
    629             {
    630                 return 65536;
    631             }
    632         }
    633 
    634         return sad;
    635     }
    636 
    637     Int SAD_MB_HP_HTFMyh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    638     {
    639         Int i, j;
    640         Int sad = 0, tmp, tmp2;
    641         UChar *p1, *p2;
    642         Int rx = dmin_rx & 0xFFFF;
    643         Int refwx4 = rx << 2;
    644         Int sadstar = 0, madstar;
    645         Int *nrmlz_th = (Int*) extra_info;
    646         Int *offsetRef = nrmlz_th + 32;
    647         ULong cur_word;
    648 
    649         madstar = (ULong)dmin_rx >> 20;
    650 
    651         NUM_SAD_HP_MB_CALL();
    652 
    653         blk -= 4;
    654 
    655         for (i = 0; i < 16; i++) /* 16 stages */
    656         {
    657             p1 = ref + offsetRef[i];
    658             p2 = p1 + rx;
    659             j = 4;
    660             do
    661             {
    662                 cur_word = *((ULong*)(blk += 4));
    663                 tmp = p1[12];
    664                 tmp2 = p2[12];
    665                 tmp++;
    666                 tmp2 += tmp;
    667                 tmp = (cur_word >> 24) & 0xFF;
    668                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    669                 tmp = p1[8];
    670                 tmp2 = p2[8];
    671                 tmp++;
    672                 tmp2 += tmp;
    673                 tmp = (cur_word >> 16) & 0xFF;
    674                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    675                 tmp = p1[4];
    676                 tmp2 = p2[4];
    677                 tmp++;
    678                 tmp2 += tmp;
    679                 tmp = (cur_word >> 8) & 0xFF;
    680                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    681                 tmp = p1[0];
    682                 p1 += refwx4;
    683                 tmp2 = p2[0];
    684                 p2 += refwx4;
    685                 tmp++;
    686                 tmp2 += tmp;
    687                 tmp = (cur_word & 0xFF);
    688                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    689             }
    690             while (--j);
    691 
    692             NUM_SAD_HP_MB();
    693             sadstar += madstar;
    694             if (sad > sadstar - nrmlz_th[i] || sad > (Int)((ULong)dmin_rx >> 16))
    695             {
    696                 return 65536;
    697             }
    698         }
    699 
    700         return sad;
    701     }
    702 
    703     Int SAD_MB_HP_HTFMxh(UChar *ref, UChar *blk, Int dmin_rx, void *extra_info)
    704     {
    705         Int i, j;
    706         Int sad = 0, tmp, tmp2;
    707         UChar *p1;
    708         Int rx = dmin_rx & 0xFFFF;
    709         Int refwx4 = rx << 2;
    710         Int sadstar = 0, madstar;
    711         Int *nrmlz_th = (Int*) extra_info;
    712         Int *offsetRef = nrmlz_th + 32;
    713         ULong cur_word;
    714 
    715         madstar = (ULong)dmin_rx >> 20;
    716 
    717         NUM_SAD_HP_MB_CALL();
    718 
    719         blk -= 4;
    720 
    721         for (i = 0; i < 16; i++) /* 16 stages */
    722         {
    723             p1 = ref + offsetRef[i];
    724 
    725             j = 4;/* 4 lines */
    726             do
    727             {
    728                 cur_word = *((ULong*)(blk += 4));
    729                 tmp = p1[12];
    730                 tmp2 = p1[13];
    731                 tmp++;
    732                 tmp2 += tmp;
    733                 tmp = (cur_word >> 24) & 0xFF;
    734                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    735                 tmp = p1[8];
    736                 tmp2 = p1[9];
    737                 tmp++;
    738                 tmp2 += tmp;
    739                 tmp = (cur_word >> 16) & 0xFF;
    740                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    741                 tmp = p1[4];
    742                 tmp2 = p1[5];
    743                 tmp++;
    744                 tmp2 += tmp;
    745                 tmp = (cur_word >> 8) & 0xFF;
    746                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    747                 tmp = p1[0];
    748                 tmp2 = p1[1];
    749                 p1 += refwx4;
    750                 tmp++;
    751                 tmp2 += tmp;
    752                 tmp = (cur_word & 0xFF);
    753                 sad = INTERP1_SUB_SAD(sad, tmp, tmp2);;
    754             }
    755             while (--j);
    756 
    757             NUM_SAD_HP_MB();
    758 
    759             sadstar += madstar;
    760             if (sad > sadstar - nrmlz_th[i] || sad > (Int)((ULong)dmin_rx >> 16))
    761             {
    762                 return 65536;
    763             }
    764         }
    765 
    766         return sad;
    767     }
    768 
    769 #endif /* HTFM */
    770 
    771 #ifndef NO_INTER4V
    772     /*==================================================================
    773         Function:   SAD_Blk_HalfPel_C
    774         Date:       04/30/2001
    775         Purpose:    Compute SAD 16x16 between blk and ref in halfpel
    776                     resolution,
    777         Changes:
    778       ==================================================================*/
    779     /* One component is half-pel */
    780     Int SAD_Blk_HalfPel_C(UChar *ref, UChar *blk, Int dmin, Int width, Int rx, Int xh, Int yh, void *extra_info)
    781     {
    782         Int i, j;
    783         Int sad = 0;
    784         UChar *kk, *p1, *p2, *p3, *p4;
    785         Int temp;
    786 
    787         OSCL_UNUSED_ARG(extra_info);
    788 
    789         NUM_SAD_HP_BLK_CALL();
    790 
    791         if (xh && yh)
    792         {
    793             p1 = ref;
    794             p2 = ref + xh;
    795             p3 = ref + yh * rx;
    796             p4 = ref + yh * rx + xh;
    797             kk  = blk;
    798 
    799             for (i = 0; i < 8; i++)
    800             {
    801                 for (j = 0; j < 8; j++)
    802                 {
    803 
    804                     temp = ((p1[j] + p2[j] + p3[j] + p4[j] + 2) >> 2) - kk[j];
    805                     sad += PV_ABS(temp);
    806                 }
    807 
    808                 NUM_SAD_HP_BLK();
    809 
    810                 if (sad > dmin)
    811                     return sad;
    812 
    813                 p1 += rx;
    814                 p3 += rx;
    815                 p2 += rx;
    816                 p4 += rx;
    817                 kk += width;
    818             }
    819             return sad;
    820         }
    821         else
    822         {
    823             p1 = ref;
    824             p2 = ref + xh + yh * rx; /* either left/right or top/bottom pixel */
    825 
    826             kk  = blk;
    827 
    828             for (i = 0; i < 8; i++)
    829             {
    830                 for (j = 0; j < 8; j++)
    831                 {
    832 
    833                     temp = ((p1[j] + p2[j] + 1) >> 1) - kk[j];
    834                     sad += PV_ABS(temp);
    835                 }
    836 
    837                 NUM_SAD_HP_BLK();
    838 
    839                 if (sad > dmin)
    840                     return sad;
    841                 p1 += rx;
    842                 p2 += rx;
    843                 kk += width;
    844             }
    845             return sad;
    846         }
    847     }
    848 #endif /* NO_INTER4V */
    849 
    850 #ifdef __cplusplus
    851 }
    852 #endif
    853 
    854 
    855 
    856