Mercurial > libavcodec.hg
annotate dct-test.c @ 12494:94eaea836bf4 libavcodec
Check avctx width/height more thoroughly (e.g. all values 0 except width would
have been accepted before).
Also do not fail if they are invalid but instead override them to 0.
This allows decoding e.g. MPEG video when only the container values are corrupted.
For encoding a value of 0,0 of course makes no sense, but was allowed
through before and will be caught by an extra check in the encode function.
author | reimar |
---|---|
date | Wed, 15 Sep 2010 04:46:55 +0000 |
parents | 9fef0a8ddd63 |
children |
rev | line source |
---|---|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
1 /* |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
2 * (c) 2001 Fabrice Bellard |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
3 * 2007 Marc Hoffman <marc.hoffman@analog.com> |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
15 * Lesser General Public License for more details. |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
16 * |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
20 */ |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
3398
diff
changeset
|
21 |
1106 | 22 /** |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11414
diff
changeset
|
23 * @file |
8724
2c5662c41129
cosmetics: Remove period after copyright statement non-sentence.
diego
parents:
8718
diff
changeset
|
24 * DCT test (c) 2001 Fabrice Bellard |
1106 | 25 * Started from sample code by Juan J. Sierralta P. |
26 */ | |
27 | |
0 | 28 #include <stdlib.h> |
29 #include <stdio.h> | |
30 #include <string.h> | |
31 #include <sys/time.h> | |
32 #include <unistd.h> | |
5118
3b190bc34546
Add some #includes to allow compilation without HAVE_AV_CONFIG_H.
diego
parents:
5110
diff
changeset
|
33 #include <math.h> |
0 | 34 |
12475
9fef0a8ddd63
Move mm_support() from libavcodec to libavutil, make it a public
stefano
parents:
12456
diff
changeset
|
35 #include "libavutil/cpu.h" |
7130
601509a430f7
Replace redundant MAX macro declaration by proper use of FFMAX.
diego
parents:
7125
diff
changeset
|
36 #include "libavutil/common.h" |
9199
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
9189
diff
changeset
|
37 #include "libavutil/lfg.h" |
0 | 38 |
633 | 39 #include "simple_idct.h" |
8223 | 40 #include "aandcttab.h" |
1557 | 41 #include "faandct.h" |
6407 | 42 #include "faanidct.h" |
8430 | 43 #include "x86/idct_xvid.h" |
11408 | 44 #include "dctref.h" |
33 | 45 |
2872 | 46 #undef printf |
47 | |
8250 | 48 void ff_mmx_idct(DCTELEM *data); |
49 void ff_mmxext_idct(DCTELEM *data); | |
33 | 50 |
8250 | 51 void odivx_idct_c(short *block); |
633 | 52 |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
53 // BFIN |
8250 | 54 void ff_bfin_idct(DCTELEM *block); |
55 void ff_bfin_fdct(DCTELEM *block); | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
56 |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
57 // ALTIVEC |
8250 | 58 void fdct_altivec(DCTELEM *block); |
59 //void idct_altivec(DCTELEM *block);?? no routine | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
60 |
8351 | 61 // ARM |
11414 | 62 void ff_j_rev_dct_arm(DCTELEM *data); |
63 void ff_simple_idct_arm(DCTELEM *data); | |
64 void ff_simple_idct_armv5te(DCTELEM *data); | |
8351 | 65 void ff_simple_idct_armv6(DCTELEM *data); |
66 void ff_simple_idct_neon(DCTELEM *data); | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
67 |
8622 | 68 void ff_simple_idct_axp(DCTELEM *data); |
69 | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
70 struct algo { |
7125
65e7e714c770
Mark constant structure member as const to avoid some warnings.
diego
parents:
6602
diff
changeset
|
71 const char *name; |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
72 enum { FDCT, IDCT } is_idct; |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
73 void (* func) (DCTELEM *block); |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
74 void (* ref) (DCTELEM *block); |
8350 | 75 enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format; |
6543
948d9453432b
check mm_flags for each DCT and skips the ones that can't be run
gpoirier
parents:
6542
diff
changeset
|
76 int mm_support; |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
77 }; |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
78 |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
79 #ifndef FAAN_POSTSCALE |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
80 #define FAAN_SCALE SCALE_PERM |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
81 #else |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
82 #define FAAN_SCALE NO_PERM |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
83 #endif |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
84 |
7155 | 85 static int cpu_flags; |
86 | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
87 struct algo algos[] = { |
9293 | 88 {"REF-DBL", 0, ff_ref_fdct, ff_ref_fdct, NO_PERM}, |
89 {"FAAN", 0, ff_faandct, ff_ref_fdct, FAAN_SCALE}, | |
90 {"FAANI", 1, ff_faanidct, ff_ref_idct, NO_PERM}, | |
91 {"IJG-AAN-INT", 0, fdct_ifast, ff_ref_fdct, SCALE_PERM}, | |
92 {"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, ff_ref_fdct, NO_PERM}, | |
93 {"REF-DBL", 1, ff_ref_idct, ff_ref_idct, NO_PERM}, | |
94 {"INT", 1, j_rev_dct, ff_ref_idct, MMX_PERM}, | |
95 {"SIMPLE-C", 1, ff_simple_idct, ff_ref_idct, NO_PERM}, | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
96 |
8590 | 97 #if HAVE_MMX |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
98 {"MMX", 0, ff_fdct_mmx, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX}, |
8590 | 99 #if HAVE_MMX2 |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
100 {"MMX2", 0, ff_fdct_mmx2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX2}, |
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
101 {"SSE2", 0, ff_fdct_sse2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_SSE2}, |
5110 | 102 #endif |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
103 |
8590 | 104 #if CONFIG_GPL |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
105 {"LIBMPEG2-MMX", 1, ff_mmx_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX}, |
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
106 {"LIBMPEG2-MMX2", 1, ff_mmxext_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX2}, |
5109 | 107 #endif |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
108 {"SIMPLE-MMX", 1, ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX}, |
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
109 {"XVID-MMX", 1, ff_idct_xvid_mmx, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX}, |
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
110 {"XVID-MMX2", 1, ff_idct_xvid_mmx2, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX2}, |
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
111 {"XVID-SSE2", 1, ff_idct_xvid_sse2, ff_ref_idct, SSE2_PERM, AV_CPU_FLAG_SSE2}, |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
112 #endif |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
113 |
8590 | 114 #if HAVE_ALTIVEC |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
115 {"altivecfdct", 0, fdct_altivec, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_ALTIVEC}, |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
116 #endif |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
117 |
8590 | 118 #if ARCH_BFIN |
9293 | 119 {"BFINfdct", 0, ff_bfin_fdct, ff_ref_fdct, NO_PERM}, |
120 {"BFINidct", 1, ff_bfin_idct, ff_ref_idct, NO_PERM}, | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
121 #endif |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
122 |
8590 | 123 #if ARCH_ARM |
11414 | 124 {"SIMPLE-ARM", 1, ff_simple_idct_arm, ff_ref_idct, NO_PERM }, |
125 {"INT-ARM", 1, ff_j_rev_dct_arm, ff_ref_idct, MMX_PERM }, | |
8590 | 126 #if HAVE_ARMV5TE |
11414 | 127 {"SIMPLE-ARMV5TE", 1, ff_simple_idct_armv5te, ff_ref_idct, NO_PERM }, |
8351 | 128 #endif |
8590 | 129 #if HAVE_ARMV6 |
9293 | 130 {"SIMPLE-ARMV6", 1, ff_simple_idct_armv6, ff_ref_idct, MMX_PERM }, |
8351 | 131 #endif |
8590 | 132 #if HAVE_NEON |
9293 | 133 {"SIMPLE-NEON", 1, ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM }, |
8351 | 134 #endif |
8359 | 135 #endif /* ARCH_ARM */ |
8351 | 136 |
8622 | 137 #if ARCH_ALPHA |
9293 | 138 {"SIMPLE-ALPHA", 1, ff_simple_idct_axp, ff_ref_idct, NO_PERM }, |
8622 | 139 #endif |
140 | |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
141 { 0 } |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
142 }; |
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
143 |
0 | 144 #define AANSCALE_BITS 12 |
145 | |
4197 | 146 uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; |
633 | 147 |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
148 static int64_t gettime(void) |
0 | 149 { |
150 struct timeval tv; | |
151 gettimeofday(&tv,NULL); | |
1064 | 152 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; |
0 | 153 } |
154 | |
155 #define NB_ITS 20000 | |
156 #define NB_ITS_SPEED 50000 | |
157 | |
33 | 158 static short idct_mmx_perm[64]; |
159 | |
633 | 160 static short idct_simple_mmx_perm[64]={ |
2979 | 161 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, |
162 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, | |
163 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, | |
164 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, | |
165 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, | |
166 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, | |
167 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, | |
168 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, | |
633 | 169 }; |
170 | |
6602 | 171 static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; |
172 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
173 static void idct_mmx_init(void) |
33 | 174 { |
175 int i; | |
176 | |
177 /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ | |
178 for (i = 0; i < 64; i++) { | |
2979 | 179 idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); |
180 // idct_simple_mmx_perm[i] = simple_block_permute_op(i); | |
33 | 181 } |
182 } | |
183 | |
10961
34a65026fa06
Move array specifiers outside DECLARE_ALIGNED() invocations
mru
parents:
9793
diff
changeset
|
184 DECLARE_ALIGNED(16, static DCTELEM, block)[64]; |
34a65026fa06
Move array specifiers outside DECLARE_ALIGNED() invocations
mru
parents:
9793
diff
changeset
|
185 DECLARE_ALIGNED(8, static DCTELEM, block1)[64]; |
34a65026fa06
Move array specifiers outside DECLARE_ALIGNED() invocations
mru
parents:
9793
diff
changeset
|
186 DECLARE_ALIGNED(8, static DCTELEM, block_org)[64]; |
33 | 187 |
7155 | 188 static inline void mmx_emms(void) |
189 { | |
8590 | 190 #if HAVE_MMX |
12456
a5ddb39627fd
Rename FF_MM_ symbols related to CPU features flags as AV_CPU_FLAG_
stefano
parents:
11644
diff
changeset
|
191 if (cpu_flags & AV_CPU_FLAG_MMX) |
8031 | 192 __asm__ volatile ("emms\n\t"); |
7155 | 193 #endif |
194 } | |
195 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
196 static void dct_error(const char *name, int is_idct, |
33 | 197 void (*fdct_func)(DCTELEM *block), |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
198 void (*fdct_ref)(DCTELEM *block), int form, int test) |
0 | 199 { |
200 int it, i, scale; | |
201 int err_inf, v; | |
1064 | 202 int64_t err2, ti, ti1, it1; |
203 int64_t sysErr[64], sysErrMax=0; | |
633 | 204 int maxout=0; |
205 int blockSumErrMax=0, blockSumErr; | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
206 AVLFG prng; |
0 | 207 |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
208 av_lfg_init(&prng, 1); |
0 | 209 |
210 err_inf = 0; | |
211 err2 = 0; | |
633 | 212 for(i=0; i<64; i++) sysErr[i]=0; |
0 | 213 for(it=0;it<NB_ITS;it++) { |
633 | 214 for(i=0;i<64;i++) |
215 block1[i] = 0; | |
216 switch(test){ | |
2967 | 217 case 0: |
633 | 218 for(i=0;i<64;i++) |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
219 block1[i] = (av_lfg_get(&prng) % 512) -256; |
635 | 220 if (is_idct){ |
9293 | 221 ff_ref_fdct(block1); |
635 | 222 |
223 for(i=0;i<64;i++) | |
224 block1[i]>>=3; | |
225 } | |
633 | 226 break; |
227 case 1:{ | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
228 int num = av_lfg_get(&prng) % 10 + 1; |
633 | 229 for(i=0;i<num;i++) |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
230 block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % 512 -256; |
633 | 231 }break; |
232 case 2: | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
233 block1[0] = av_lfg_get(&prng) % 4096 - 2048; |
633 | 234 block1[63]= (block1[0]&1)^1; |
235 break; | |
236 } | |
33 | 237 |
633 | 238 #if 0 // simulate mismatch control |
239 { int sum=0; | |
240 for(i=0;i<64;i++) | |
241 sum+=block1[i]; | |
242 | |
2967 | 243 if((sum&1)==0) block1[63]^=1; |
633 | 244 } |
245 #endif | |
246 | |
247 for(i=0; i<64; i++) | |
248 block_org[i]= block1[i]; | |
33 | 249 |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
250 if (form == MMX_PERM) { |
633 | 251 for(i=0;i<64;i++) |
33 | 252 block[idct_mmx_perm[i]] = block1[i]; |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
253 } else if (form == MMX_SIMPLE_PERM) { |
633 | 254 for(i=0;i<64;i++) |
255 block[idct_simple_mmx_perm[i]] = block1[i]; | |
256 | |
6602 | 257 } else if (form == SSE2_PERM) { |
258 for(i=0; i<64; i++) | |
259 block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i]; | |
8350 | 260 } else if (form == PARTTRANS_PERM) { |
261 for(i=0; i<64; i++) | |
262 block[(i&0x24) | ((i&3)<<3) | ((i>>3)&3)] = block1[i]; | |
2979 | 263 } else { |
633 | 264 for(i=0; i<64; i++) |
265 block[i]= block1[i]; | |
33 | 266 } |
633 | 267 #if 0 // simulate mismatch control for tested IDCT but not the ref |
268 { int sum=0; | |
269 for(i=0;i<64;i++) | |
270 sum+=block[i]; | |
271 | |
2967 | 272 if((sum&1)==0) block[63]^=1; |
633 | 273 } |
274 #endif | |
33 | 275 |
0 | 276 fdct_func(block); |
7155 | 277 mmx_emms(); |
33 | 278 |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
279 if (form == SCALE_PERM) { |
0 | 280 for(i=0; i<64; i++) { |
8223 | 281 scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i]; |
633 | 282 block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS; |
283 } | |
284 } | |
285 | |
33 | 286 fdct_ref(block1); |
0 | 287 |
633 | 288 blockSumErr=0; |
0 | 289 for(i=0;i<64;i++) { |
290 v = abs(block[i] - block1[i]); | |
291 if (v > err_inf) | |
292 err_inf = v; | |
293 err2 += v * v; | |
2979 | 294 sysErr[i] += block[i] - block1[i]; |
295 blockSumErr += v; | |
296 if( abs(block[i])>maxout) maxout=abs(block[i]); | |
0 | 297 } |
633 | 298 if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr; |
299 #if 0 // print different matrix pairs | |
300 if(blockSumErr){ | |
301 printf("\n"); | |
302 for(i=0; i<64; i++){ | |
303 if((i&7)==0) printf("\n"); | |
304 printf("%4d ", block_org[i]); | |
305 } | |
306 for(i=0; i<64; i++){ | |
307 if((i&7)==0) printf("\n"); | |
308 printf("%4d ", block[i] - block1[i]); | |
309 } | |
310 } | |
311 #endif | |
0 | 312 } |
7130
601509a430f7
Replace redundant MAX macro declaration by proper use of FFMAX.
diego
parents:
7125
diff
changeset
|
313 for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i])); |
2967 | 314 |
633 | 315 #if 1 // dump systematic errors |
316 for(i=0; i<64; i++){ | |
2979 | 317 if(i%8==0) printf("\n"); |
9189 | 318 printf("%7d ", (int)sysErr[i]); |
633 | 319 } |
320 printf("\n"); | |
321 #endif | |
2967 | 322 |
633 | 323 printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", |
33 | 324 is_idct ? "IDCT" : "DCT", |
633 | 325 name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax); |
326 #if 1 //Speed test | |
0 | 327 /* speed test */ |
633 | 328 for(i=0;i<64;i++) |
329 block1[i] = 0; | |
330 switch(test){ | |
2967 | 331 case 0: |
633 | 332 for(i=0;i<64;i++) |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
333 block1[i] = av_lfg_get(&prng) % 512 -256; |
635 | 334 if (is_idct){ |
9293 | 335 ff_ref_fdct(block1); |
635 | 336 |
337 for(i=0;i<64;i++) | |
338 block1[i]>>=3; | |
339 } | |
633 | 340 break; |
341 case 1:{ | |
342 case 2: | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
343 block1[0] = av_lfg_get(&prng) % 512 -256; |
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
344 block1[1] = av_lfg_get(&prng) % 512 -256; |
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
345 block1[2] = av_lfg_get(&prng) % 512 -256; |
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
346 block1[3] = av_lfg_get(&prng) % 512 -256; |
633 | 347 }break; |
348 } | |
0 | 349 |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
350 if (form == MMX_PERM) { |
633 | 351 for(i=0;i<64;i++) |
33 | 352 block[idct_mmx_perm[i]] = block1[i]; |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
353 } else if(form == MMX_SIMPLE_PERM) { |
633 | 354 for(i=0;i<64;i++) |
355 block[idct_simple_mmx_perm[i]] = block1[i]; | |
356 } else { | |
357 for(i=0; i<64; i++) | |
358 block[i]= block1[i]; | |
33 | 359 } |
360 | |
0 | 361 ti = gettime(); |
362 it1 = 0; | |
363 do { | |
364 for(it=0;it<NB_ITS_SPEED;it++) { | |
633 | 365 for(i=0; i<64; i++) |
366 block[i]= block1[i]; | |
367 // memcpy(block, block1, sizeof(DCTELEM) * 64); | |
5127 | 368 // do not memcpy especially not fastmemcpy because it does movntq !!! |
0 | 369 fdct_func(block); |
370 } | |
371 it1 += NB_ITS_SPEED; | |
372 ti1 = gettime() - ti; | |
373 } while (ti1 < 1000000); | |
7155 | 374 mmx_emms(); |
0 | 375 |
633 | 376 printf("%s %s: %0.1f kdct/s\n", |
33 | 377 is_idct ? "IDCT" : "DCT", |
0 | 378 name, (double)it1 * 1000.0 / (double)ti1); |
633 | 379 #endif |
0 | 380 } |
381 | |
10961
34a65026fa06
Move array specifiers outside DECLARE_ALIGNED() invocations
mru
parents:
9793
diff
changeset
|
382 DECLARE_ALIGNED(8, static uint8_t, img_dest)[64]; |
34a65026fa06
Move array specifiers outside DECLARE_ALIGNED() invocations
mru
parents:
9793
diff
changeset
|
383 DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64]; |
720 | 384 |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
385 static void idct248_ref(uint8_t *dest, int linesize, int16_t *block) |
720 | 386 { |
387 static int init; | |
388 static double c8[8][8]; | |
389 static double c4[4][4]; | |
390 double block1[64], block2[64], block3[64]; | |
391 double s, sum, v; | |
392 int i, j, k; | |
393 | |
394 if (!init) { | |
395 init = 1; | |
396 | |
397 for(i=0;i<8;i++) { | |
398 sum = 0; | |
399 for(j=0;j<8;j++) { | |
400 s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0); | |
401 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0); | |
402 sum += c8[i][j] * c8[i][j]; | |
403 } | |
404 } | |
2967 | 405 |
720 | 406 for(i=0;i<4;i++) { |
407 sum = 0; | |
408 for(j=0;j<4;j++) { | |
409 s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0); | |
410 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0); | |
411 sum += c4[i][j] * c4[i][j]; | |
412 } | |
413 } | |
414 } | |
415 | |
416 /* butterfly */ | |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
417 s = 0.5 * sqrt(2.0); |
720 | 418 for(i=0;i<4;i++) { |
419 for(j=0;j<8;j++) { | |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
420 block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s; |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
421 block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s; |
720 | 422 } |
423 } | |
424 | |
425 /* idct8 on lines */ | |
426 for(i=0;i<8;i++) { | |
427 for(j=0;j<8;j++) { | |
428 sum = 0; | |
429 for(k=0;k<8;k++) | |
430 sum += c8[k][j] * block1[8*i+k]; | |
431 block2[8*i+j] = sum; | |
432 } | |
433 } | |
434 | |
435 /* idct4 */ | |
436 for(i=0;i<8;i++) { | |
437 for(j=0;j<4;j++) { | |
438 /* top */ | |
439 sum = 0; | |
440 for(k=0;k<4;k++) | |
441 sum += c4[k][j] * block2[8*(2*k)+i]; | |
442 block3[8*(2*j)+i] = sum; | |
443 | |
444 /* bottom */ | |
445 sum = 0; | |
446 for(k=0;k<4;k++) | |
447 sum += c4[k][j] * block2[8*(2*k+1)+i]; | |
448 block3[8*(2*j+1)+i] = sum; | |
449 } | |
450 } | |
451 | |
452 /* clamp and store the result */ | |
453 for(i=0;i<8;i++) { | |
454 for(j=0;j<8;j++) { | |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
455 v = block3[8*i+j]; |
720 | 456 if (v < 0) |
457 v = 0; | |
458 else if (v > 255) | |
459 v = 255; | |
460 dest[i * linesize + j] = (int)rint(v); | |
461 } | |
462 } | |
463 } | |
464 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
465 static void idct248_error(const char *name, |
1064 | 466 void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block)) |
720 | 467 { |
468 int it, i, it1, ti, ti1, err_max, v; | |
469 | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
470 AVLFG prng; |
9199
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
9189
diff
changeset
|
471 |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
472 av_lfg_init(&prng, 1); |
2967 | 473 |
720 | 474 /* just one test to see if code is correct (precision is less |
475 important here) */ | |
476 err_max = 0; | |
477 for(it=0;it<NB_ITS;it++) { | |
2967 | 478 |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
479 /* XXX: use forward transform to generate values */ |
720 | 480 for(i=0;i<64;i++) |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
481 block1[i] = av_lfg_get(&prng) % 256 - 128; |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
482 block1[0] += 1024; |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
483 |
720 | 484 for(i=0; i<64; i++) |
485 block[i]= block1[i]; | |
486 idct248_ref(img_dest1, 8, block); | |
2967 | 487 |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
488 for(i=0; i<64; i++) |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
489 block[i]= block1[i]; |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
490 idct248_put(img_dest, 8, block); |
2967 | 491 |
722
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
492 for(i=0;i<64;i++) { |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
493 v = abs((int)img_dest[i] - (int)img_dest1[i]); |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
494 if (v == 255) |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
495 printf("%d %d\n", img_dest[i], img_dest1[i]); |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
496 if (v > err_max) |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
497 err_max = v; |
ff90043f4a2d
in fact IDCT248 needs to be normalized as I suspected
bellard
parents:
720
diff
changeset
|
498 } |
720 | 499 #if 0 |
500 printf("ref=\n"); | |
501 for(i=0;i<8;i++) { | |
502 int j; | |
503 for(j=0;j<8;j++) { | |
504 printf(" %3d", img_dest1[i*8+j]); | |
505 } | |
506 printf("\n"); | |
507 } | |
2967 | 508 |
720 | 509 printf("out=\n"); |
510 for(i=0;i<8;i++) { | |
511 int j; | |
512 for(j=0;j<8;j++) { | |
513 printf(" %3d", img_dest[i*8+j]); | |
514 } | |
515 printf("\n"); | |
516 } | |
517 #endif | |
518 } | |
519 printf("%s %s: err_inf=%d\n", | |
520 1 ? "IDCT248" : "DCT248", | |
521 name, err_max); | |
522 | |
523 ti = gettime(); | |
524 it1 = 0; | |
525 do { | |
526 for(it=0;it<NB_ITS_SPEED;it++) { | |
527 for(i=0; i<64; i++) | |
528 block[i]= block1[i]; | |
529 // memcpy(block, block1, sizeof(DCTELEM) * 64); | |
5127 | 530 // do not memcpy especially not fastmemcpy because it does movntq !!! |
720 | 531 idct248_put(img_dest, 8, block); |
532 } | |
533 it1 += NB_ITS_SPEED; | |
534 ti1 = gettime() - ti; | |
535 } while (ti1 < 1000000); | |
7155 | 536 mmx_emms(); |
720 | 537 |
538 printf("%s %s: %0.1f kdct/s\n", | |
539 1 ? "IDCT248" : "DCT248", | |
540 name, (double)it1 * 1000.0 / (double)ti1); | |
541 } | |
542 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9293
diff
changeset
|
543 static void help(void) |
33 | 544 { |
633 | 545 printf("dct-test [-i] [<test-number>]\n" |
546 "test-number 0 -> test with random matrixes\n" | |
547 " 1 -> test with random sparse matrixes\n" | |
548 " 2 -> do 3. test from mpeg4 std\n" | |
720 | 549 "-i test IDCT implementations\n" |
550 "-4 test IDCT248 implementations\n"); | |
33 | 551 } |
552 | |
0 | 553 int main(int argc, char **argv) |
554 { | |
720 | 555 int test_idct = 0, test_248_dct = 0; |
633 | 556 int c,i; |
557 int test=1; | |
12475
9fef0a8ddd63
Move mm_support() from libavcodec to libavutil, make it a public
stefano
parents:
12456
diff
changeset
|
558 cpu_flags = av_get_cpu_flags(); |
33 | 559 |
9293 | 560 ff_ref_dct_init(); |
33 | 561 idct_mmx_init(); |
7135
6bd6a2da306e
Define mm_flags/support to be 0 on architectures where they don't exist.
astrange
parents:
7130
diff
changeset
|
562 |
4197 | 563 for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; |
633 | 564 for(i=0;i<MAX_NEG_CROP;i++) { |
4197 | 565 cropTbl[i] = 0; |
566 cropTbl[i + MAX_NEG_CROP + 256] = 255; | |
633 | 567 } |
2967 | 568 |
33 | 569 for(;;) { |
720 | 570 c = getopt(argc, argv, "ih4"); |
33 | 571 if (c == -1) |
572 break; | |
573 switch(c) { | |
574 case 'i': | |
575 test_idct = 1; | |
576 break; | |
720 | 577 case '4': |
578 test_248_dct = 1; | |
579 break; | |
633 | 580 default : |
33 | 581 case 'h': |
582 help(); | |
4754 | 583 return 0; |
33 | 584 } |
585 } | |
2967 | 586 |
633 | 587 if(optind <argc) test= atoi(argv[optind]); |
2967 | 588 |
33 | 589 printf("ffmpeg DCT/IDCT test\n"); |
590 | |
720 | 591 if (test_248_dct) { |
6001 | 592 idct248_error("SIMPLE-C", ff_simple_idct248_put); |
33 | 593 } else { |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
594 for (i=0;algos[i].name;i++) |
7140
654f063dc099
Use a local variable instead of mm_flags in dct-test.
astrange
parents:
7135
diff
changeset
|
595 if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) { |
4755
b7c27288e509
platform-independent restructuring and code simplification
diego
parents:
4754
diff
changeset
|
596 dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test); |
720 | 597 } |
33 | 598 } |
0 | 599 return 0; |
600 } |