• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
HalfPel1_SAD_MB(UChar * ref,UChar * blk,Int dmin,Int width,Int ih,Int jh)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 */
HalfPel2_SAD_MB(UChar * ref,UChar * blk,Int dmin,Int width)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 */
HalfPel1_SAD_Blk(UChar * ref,UChar * blk,Int dmin,Int width,Int ih,Int jh)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 */
HalfPel2_SAD_Blk(UChar * ref,UChar * blk,Int dmin,Int width)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 */
SAD_MB_HalfPel_Cxhyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HalfPel_Cyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HalfPel_Cxh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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
SAD_MB_HP_HTFM_Collectxhyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HP_HTFM_Collectyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HP_HTFM_Collectxh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HP_HTFMxhyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HP_HTFMyh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 
SAD_MB_HP_HTFMxh(UChar * ref,UChar * blk,Int dmin_rx,void * extra_info)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 */
SAD_Blk_HalfPel_C(UChar * ref,UChar * blk,Int dmin,Int width,Int rx,Int xh,Int yh,void * extra_info)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