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
19Int HalfPel1_SAD_MB(UChar *ref,UChar *blk,Int dmin,Int width,Int ih,Int jh)
20Int HalfPel2_SAD_MB(UChar *ref,UChar *blk,Int dmin,Int width)
21Int HalfPel1_SAD_Blk(UChar *ref,UChar *blk,Int dmin,Int width,Int ih,Int jh)
22Int HalfPel2_SAD_Blk(UChar *ref,UChar *blk,Int dmin,Int width)
23
24Int SAD_MB_HalfPel_C(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
25Int SAD_MB_HP_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
26Int SAD_MB_HP_HTFM(UChar *ref,UChar *blk,Int dmin,Int width,Int rx,Int xh,Int yh,void *extra_info)
27Int 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
36ULong num_sad_HP_MB = 0;
37ULong num_sad_HP_Blk = 0;
38ULong num_sad_HP_MB_call = 0;
39ULong 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
53extern "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