sad.cpp revision 59f566c4ec3dfc097ad8163523e522280b27e5c3
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
26ULong num_sad_MB = 0;
27ULong num_sad_Blk = 0;
28ULong num_sad_MB_call = 0;
29ULong 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
47Int SAD_Macroblock_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
48Int SAD_MB_HTFM_Collect(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
49Int SAD_MB_HTFM(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
50Int SAD_Block_C(UChar *ref,UChar *blk,Int dmin,Int lx,void *extra_info)
51Int SAD_Blk_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
52Int SAD_MB_PADDING(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
53Int SAD_MB_PAD1(UChar *ref,UChar *cur,Int dmin,Int lx,Int *rep);
54Int SAD_MB_PADDING_HTFM_Collect(UChar *ref,UChar *cur,Int dmin,Int lx,void *extra_info)
55Int SAD_MB_PADDING_HTFM(UChar *ref,UChar *cur,Int dmin,Int lx,void *vptr)
56*/
57
58
59#ifdef __cplusplus
60extern "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 ************/
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
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
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 ************/
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