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 #include "mp4def.h"
19 #include "mp4lib_int.h"
20 
21 #include "sad_inline.h"
22 
23 #define Cached_lx 176
24 
25 #ifdef _SAD_STAT
26 ULong num_sad_MB = 0;
27 ULong num_sad_Blk = 0;
28 ULong num_sad_MB_call = 0;
29 ULong num_sad_Blk_call = 0;
30 
31 #define NUM_SAD_MB_CALL()       num_sad_MB_call++
32 #define NUM_SAD_MB()            num_sad_MB++
33 #define NUM_SAD_BLK_CALL()      num_sad_Blk_call++
34 #define NUM_SAD_BLK()           num_sad_Blk++
35 
36 #else
37 
38 #define NUM_SAD_MB_CALL()
39 #define NUM_SAD_MB()
40 #define NUM_SAD_BLK_CALL()
41 #define NUM_SAD_BLK()
42 
43 #endif
44 
45 
46 /* consist of
47 Int SAD_Macroblock_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
48 Int SAD_MB_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
49 Int SAD_MB_HTFM(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
50 Int SAD_Block_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
51 Int SAD_Blk_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
52 Int SAD_MB_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
53 Int SAD_MB_PAD1(UChar *ref,UChar *cur,Int dmin,Int lx,Int *rep);
54 Int SAD_MB_PADDING_HTFM_Collect(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
55 Int SAD_MB_PADDING_HTFM(UChar *ref,UChar *cur,Int dmin,Int lx,void *vptr)
56 */
57 
58 
59 #ifdef __cplusplus
60 extern "C"
61 {
62 #endif
63 
64     Int SAD_MB_PAD1(UChar *ref, UChar *cur, Int dmin, Int lx, Int *rep);
65 
66 
67     /*==================================================================
68         Function:   SAD_Macroblock
69         Date:       09/07/2000
70         Purpose:    Compute SAD 16x16 between blk and ref.
71         To do:      Uniform subsampling will be inserted later!
72                     Hypothesis Testing Fast Matching to be used later!
73         Changes:
74     11/7/00:     implemented MMX
75     1/24/01:     implemented SSE
76     ==================================================================*/
77     /********** C ************/
SAD_Macroblock_C(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)78     Int SAD_Macroblock_C(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info)
79     {
80         int32 x10;
81         Int dmin = (ULong)dmin_lx >> 16;
82         Int lx = dmin_lx & 0xFFFF;
83 
84         OSCL_UNUSED_ARG(extra_info);
85 
86         NUM_SAD_MB_CALL();
87 
88         x10 = simd_sad_mb(ref, blk, dmin, lx);
89 
90         return x10;
91     }
92 
93 #ifdef HTFM   /* HTFM with uniform subsampling implementation, 2/28/01 */
94     /*===============================================================
95         Function:   SAD_MB_HTFM_Collect and SAD_MB_HTFM
96         Date:       3/2/1
97         Purpose:    Compute the SAD on a 16x16 block using
98                     uniform subsampling and hypothesis testing fast matching
99                     for early dropout. SAD_MB_HP_HTFM_Collect is to collect
100                     the statistics to compute the thresholds to be used in
101                     SAD_MB_HP_HTFM.
102         Input/Output:
103         Changes:
104       ===============================================================*/
105 
SAD_MB_HTFM_Collect(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)106     Int SAD_MB_HTFM_Collect(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info)
107     {
108         Int i;
109         Int sad = 0;
110         UChar *p1;
111         Int lx4 = (dmin_lx << 2) & 0x3FFFC;
112         ULong cur_word;
113         Int saddata[16], tmp, tmp2;    /* used when collecting flag (global) is on */
114         Int difmad;
115         HTFM_Stat *htfm_stat = (HTFM_Stat*) extra_info;
116         Int *abs_dif_mad_avg = &(htfm_stat->abs_dif_mad_avg);
117         UInt *countbreak = &(htfm_stat->countbreak);
118         Int *offsetRef = htfm_stat->offsetRef;
119 
120         NUM_SAD_MB_CALL();
121 
122         blk -= 4;
123         for (i = 0; i < 16; i++)
124         {
125             p1 = ref + offsetRef[i];
126             cur_word = *((ULong*)(blk += 4));
127             tmp = p1[12];
128             tmp2 = (cur_word >> 24) & 0xFF;
129             sad = SUB_SAD(sad, tmp, tmp2);
130             tmp = p1[8];
131             tmp2 = (cur_word >> 16) & 0xFF;
132             sad = SUB_SAD(sad, tmp, tmp2);
133             tmp = p1[4];
134             tmp2 = (cur_word >> 8) & 0xFF;
135             sad = SUB_SAD(sad, tmp, tmp2);
136             tmp = p1[0];
137             p1 += lx4;
138             tmp2 = (cur_word & 0xFF);
139             sad = SUB_SAD(sad, tmp, tmp2);
140 
141             cur_word = *((ULong*)(blk += 4));
142             tmp = p1[12];
143             tmp2 = (cur_word >> 24) & 0xFF;
144             sad = SUB_SAD(sad, tmp, tmp2);
145             tmp = p1[8];
146             tmp2 = (cur_word >> 16) & 0xFF;
147             sad = SUB_SAD(sad, tmp, tmp2);
148             tmp = p1[4];
149             tmp2 = (cur_word >> 8) & 0xFF;
150             sad = SUB_SAD(sad, tmp, tmp2);
151             tmp = p1[0];
152             p1 += lx4;
153             tmp2 = (cur_word & 0xFF);
154             sad = SUB_SAD(sad, tmp, tmp2);
155 
156             cur_word = *((ULong*)(blk += 4));
157             tmp = p1[12];
158             tmp2 = (cur_word >> 24) & 0xFF;
159             sad = SUB_SAD(sad, tmp, tmp2);
160             tmp = p1[8];
161             tmp2 = (cur_word >> 16) & 0xFF;
162             sad = SUB_SAD(sad, tmp, tmp2);
163             tmp = p1[4];
164             tmp2 = (cur_word >> 8) & 0xFF;
165             sad = SUB_SAD(sad, tmp, tmp2);
166             tmp = p1[0];
167             p1 += lx4;
168             tmp2 = (cur_word & 0xFF);
169             sad = SUB_SAD(sad, tmp, tmp2);
170 
171             cur_word = *((ULong*)(blk += 4));
172             tmp = p1[12];
173             tmp2 = (cur_word >> 24) & 0xFF;
174             sad = SUB_SAD(sad, tmp, tmp2);
175             tmp = p1[8];
176             tmp2 = (cur_word >> 16) & 0xFF;
177             sad = SUB_SAD(sad, tmp, tmp2);
178             tmp = p1[4];
179             tmp2 = (cur_word >> 8) & 0xFF;
180             sad = SUB_SAD(sad, tmp, tmp2);
181             tmp = p1[0];
182             p1 += lx4;
183             tmp2 = (cur_word & 0xFF);
184             sad = SUB_SAD(sad, tmp, tmp2);
185 
186             NUM_SAD_MB();
187 
188             saddata[i] = sad;
189 
190             if (i > 0)
191             {
192                 if ((ULong)sad > ((ULong)dmin_lx >> 16))
193                 {
194                     difmad = saddata[0] - ((saddata[1] + 1) >> 1);
195                     (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
196                     (*countbreak)++;
197                     return sad;
198                 }
199             }
200         }
201 
202         difmad = saddata[0] - ((saddata[1] + 1) >> 1);
203         (*abs_dif_mad_avg) += ((difmad > 0) ? difmad : -difmad);
204         (*countbreak)++;
205         return sad;
206     }
207 
SAD_MB_HTFM(UChar * ref,UChar * blk,Int dmin_lx,void * extra_info)208     Int SAD_MB_HTFM(UChar *ref, UChar *blk, Int dmin_lx, void *extra_info)
209     {
210         Int sad = 0;
211         UChar *p1;
212 
213         Int i;
214         Int tmp, tmp2;
215         Int lx4 = (dmin_lx << 2) & 0x3FFFC;
216         Int sadstar = 0, madstar;
217         Int *nrmlz_th = (Int*) extra_info;
218         Int *offsetRef = (Int*) extra_info + 32;
219         ULong cur_word;
220 
221         madstar = (ULong)dmin_lx >> 20;
222 
223         NUM_SAD_MB_CALL();
224 
225         blk -= 4;
226         for (i = 0; i < 16; i++)
227         {
228             p1 = ref + offsetRef[i];
229             cur_word = *((ULong*)(blk += 4));
230             tmp = p1[12];
231             tmp2 = (cur_word >> 24) & 0xFF;
232             sad = SUB_SAD(sad, tmp, tmp2);
233             tmp = p1[8];
234             tmp2 = (cur_word >> 16) & 0xFF;
235             sad = SUB_SAD(sad, tmp, tmp2);
236             tmp = p1[4];
237             tmp2 = (cur_word >> 8) & 0xFF;
238             sad = SUB_SAD(sad, tmp, tmp2);
239             tmp = p1[0];
240             p1 += lx4;
241             tmp2 = (cur_word & 0xFF);
242             sad = SUB_SAD(sad, tmp, tmp2);
243 
244             cur_word = *((ULong*)(blk += 4));
245             tmp = p1[12];
246             tmp2 = (cur_word >> 24) & 0xFF;
247             sad = SUB_SAD(sad, tmp, tmp2);
248             tmp = p1[8];
249             tmp2 = (cur_word >> 16) & 0xFF;
250             sad = SUB_SAD(sad, tmp, tmp2);
251             tmp = p1[4];
252             tmp2 = (cur_word >> 8) & 0xFF;
253             sad = SUB_SAD(sad, tmp, tmp2);
254             tmp = p1[0];
255             p1 += lx4;
256             tmp2 = (cur_word & 0xFF);
257             sad = SUB_SAD(sad, tmp, tmp2);
258 
259             cur_word = *((ULong*)(blk += 4));
260             tmp = p1[12];
261             tmp2 = (cur_word >> 24) & 0xFF;
262             sad = SUB_SAD(sad, tmp, tmp2);
263             tmp = p1[8];
264             tmp2 = (cur_word >> 16) & 0xFF;
265             sad = SUB_SAD(sad, tmp, tmp2);
266             tmp = p1[4];
267             tmp2 = (cur_word >> 8) & 0xFF;
268             sad = SUB_SAD(sad, tmp, tmp2);
269             tmp = p1[0];
270             p1 += lx4;
271             tmp2 = (cur_word & 0xFF);
272             sad = SUB_SAD(sad, tmp, tmp2);
273 
274             cur_word = *((ULong*)(blk += 4));
275             tmp = p1[12];
276             tmp2 = (cur_word >> 24) & 0xFF;
277             sad = SUB_SAD(sad, tmp, tmp2);
278             tmp = p1[8];
279             tmp2 = (cur_word >> 16) & 0xFF;
280             sad = SUB_SAD(sad, tmp, tmp2);
281             tmp = p1[4];
282             tmp2 = (cur_word >> 8) & 0xFF;
283             sad = SUB_SAD(sad, tmp, tmp2);
284             tmp = p1[0];
285             p1 += lx4;
286             tmp2 = (cur_word & 0xFF);
287             sad = SUB_SAD(sad, tmp, tmp2);
288 
289             NUM_SAD_MB();
290 
291             sadstar += madstar;
292             if (((ULong)sad <= ((ULong)dmin_lx >> 16)) && (sad <= (sadstar - *nrmlz_th++)))
293                 ;
294             else
295                 return 65536;
296         }
297 
298         return sad;
299     }
300 #endif /* HTFM */
301 
302 #ifndef NO_INTER4V
303     /*==================================================================
304         Function:   SAD_Block
305         Date:       09/07/2000
306         Purpose:    Compute SAD 16x16 between blk and ref.
307         To do:      Uniform subsampling will be inserted later!
308                     Hypothesis Testing Fast Matching to be used later!
309         Changes:
310     11/7/00:     implemented MMX
311     1/24/01:     implemented SSE
312       ==================================================================*/
313     /********** C ************/
SAD_Block_C(UChar * ref,UChar * blk,Int dmin,Int lx,void *)314     Int SAD_Block_C(UChar *ref, UChar *blk, Int dmin, Int lx, void *)
315     {
316         Int sad = 0;
317 
318         Int i;
319         UChar *ii;
320         Int *kk;
321         Int tmp, tmp2, tmp3, mask = 0xFF;
322         Int width = (lx - 32);
323 
324         NUM_SAD_BLK_CALL();
325 
326         ii = ref;
327         kk  = (Int*)blk; /* assuming word-align for blk */
328         for (i = 0; i < 8; i++)
329         {
330             tmp3 = kk[1];
331             tmp = ii[7];
332             tmp2 = (UInt)tmp3 >> 24;
333             sad = SUB_SAD(sad, tmp, tmp2);
334             tmp = ii[6];
335             tmp2 = (tmp3 >> 16) & mask;
336             sad = SUB_SAD(sad, tmp, tmp2);
337             tmp = ii[5];
338             tmp2 = (tmp3 >> 8) & mask;
339             sad = SUB_SAD(sad, tmp, tmp2);
340             tmp = ii[4];
341             tmp2 = tmp3 & mask;
342             sad = SUB_SAD(sad, tmp, tmp2);
343             tmp3 = *kk;
344             kk += (width >> 2);
345             tmp = ii[3];
346             tmp2 = (UInt)tmp3 >> 24;
347             sad = SUB_SAD(sad, tmp, tmp2);
348             tmp = ii[2];
349             tmp2 = (tmp3 >> 16) & mask;
350             sad = SUB_SAD(sad, tmp, tmp2);
351             tmp = ii[1];
352             tmp2 = (tmp3 >> 8) & mask;
353             sad = SUB_SAD(sad, tmp, tmp2);
354             tmp = *ii;
355             ii += lx;
356             tmp2 = tmp3 & mask;
357             sad = SUB_SAD(sad, tmp, tmp2);
358 
359             NUM_SAD_BLK();
360 
361             if (sad > dmin)
362                 return sad;
363         }
364 
365         return sad;
366     }
367 
368 #endif /* NO_INTER4V */
369 
370 #ifdef __cplusplus
371 }
372 #endif
373 
374 
375 
376