~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/dct-test.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-01-12 22:23:28 UTC
  • mfrom: (0.4.7 sid)
  • mto: This revision was merged to the branch mainline in revision 76.
  • Revision ID: package-import@ubuntu.com-20120112222328-8jqdyodym3p84ygu
Tags: 2:1.0~rc4.dfsg1+svn34540-1
* New upstream snapshot
* upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
void ff_simple_idct_axp(DCTELEM *data);
69
69
 
70
70
struct algo {
71
 
  const char *name;
72
 
  enum { FDCT, IDCT } is_idct;
73
 
  void (* func) (DCTELEM *block);
74
 
  void (* ref)  (DCTELEM *block);
75
 
  enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format;
76
 
  int  mm_support;
 
71
    const char *name;
 
72
    void (*func)(DCTELEM *block);
 
73
    enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
 
74
                     SSE2_PERM, PARTTRANS_PERM } format;
 
75
    int mm_support;
 
76
    int nonspec;
77
77
};
78
78
 
79
79
#ifndef FAAN_POSTSCALE
84
84
 
85
85
static int cpu_flags;
86
86
 
87
 
struct algo algos[] = {
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},
96
 
 
97
 
#if HAVE_MMX
98
 
  {"MMX",             0, ff_fdct_mmx,        ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX},
99
 
#if HAVE_MMX2
100
 
  {"MMX2",            0, ff_fdct_mmx2,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX2},
101
 
  {"SSE2",            0, ff_fdct_sse2,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_SSE2},
102
 
#endif
103
 
 
 
87
static const struct algo fdct_tab[] = {
 
88
    { "REF-DBL",        ff_ref_fdct,           NO_PERM    },
 
89
    { "FAAN",           ff_faandct,            FAAN_SCALE },
 
90
    { "IJG-AAN-INT",    fdct_ifast,            SCALE_PERM },
 
91
    { "IJG-LLM-INT",    ff_jpeg_fdct_islow_8,  NO_PERM    },
 
92
 
 
93
#if HAVE_MMX
 
94
    { "MMX",            ff_fdct_mmx,           NO_PERM,   AV_CPU_FLAG_MMX     },
 
95
    { "MMX2",           ff_fdct_mmx2,          NO_PERM,   AV_CPU_FLAG_MMX2    },
 
96
    { "SSE2",           ff_fdct_sse2,          NO_PERM,   AV_CPU_FLAG_SSE2    },
 
97
#endif
 
98
 
 
99
#if HAVE_ALTIVEC
 
100
    { "altivecfdct",    fdct_altivec,          NO_PERM,   AV_CPU_FLAG_ALTIVEC },
 
101
#endif
 
102
 
 
103
#if ARCH_BFIN
 
104
    { "BFINfdct",       ff_bfin_fdct,          NO_PERM  },
 
105
#endif
 
106
 
 
107
    { 0 }
 
108
};
 
109
 
 
110
static const struct algo idct_tab[] = {
 
111
    { "FAANI",          ff_faanidct,           NO_PERM  },
 
112
    { "REF-DBL",        ff_ref_idct,           NO_PERM  },
 
113
    { "INT",            j_rev_dct,             MMX_PERM },
 
114
    { "SIMPLE-C",       ff_simple_idct_8,      NO_PERM  },
 
115
 
 
116
#if HAVE_MMX
104
117
#if CONFIG_GPL
105
 
  {"LIBMPEG2-MMX",    1, ff_mmx_idct,        ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX},
106
 
  {"LIBMPEG2-MMX2",   1, ff_mmxext_idct,     ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX2},
107
 
#endif
108
 
  {"SIMPLE-MMX",      1, ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX},
109
 
  {"XVID-MMX",        1, ff_idct_xvid_mmx,   ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX},
110
 
  {"XVID-MMX2",       1, ff_idct_xvid_mmx2,  ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX2},
111
 
  {"XVID-SSE2",       1, ff_idct_xvid_sse2,  ff_ref_idct, SSE2_PERM, AV_CPU_FLAG_SSE2},
112
 
#endif
113
 
 
114
 
#if HAVE_ALTIVEC
115
 
  {"altivecfdct",     0, fdct_altivec,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_ALTIVEC},
 
118
    { "LIBMPEG2-MMX",   ff_mmx_idct,           MMX_PERM,  AV_CPU_FLAG_MMX,  1 },
 
119
    { "LIBMPEG2-MMX2",  ff_mmxext_idct,        MMX_PERM,  AV_CPU_FLAG_MMX2, 1 },
 
120
#endif
 
121
    { "SIMPLE-MMX",     ff_simple_idct_mmx,  MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX },
 
122
    { "XVID-MMX",       ff_idct_xvid_mmx,      NO_PERM,   AV_CPU_FLAG_MMX,  1 },
 
123
    { "XVID-MMX2",      ff_idct_xvid_mmx2,     NO_PERM,   AV_CPU_FLAG_MMX2, 1 },
 
124
    { "XVID-SSE2",      ff_idct_xvid_sse2,     SSE2_PERM, AV_CPU_FLAG_SSE2, 1 },
116
125
#endif
117
126
 
118
127
#if ARCH_BFIN
119
 
  {"BFINfdct",        0, ff_bfin_fdct,       ff_ref_fdct, NO_PERM},
120
 
  {"BFINidct",        1, ff_bfin_idct,       ff_ref_idct, NO_PERM},
 
128
    { "BFINidct",       ff_bfin_idct,          NO_PERM  },
121
129
#endif
122
130
 
123
131
#if ARCH_ARM
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 },
 
132
    { "SIMPLE-ARM",     ff_simple_idct_arm,    NO_PERM  },
 
133
    { "INT-ARM",        ff_j_rev_dct_arm,      MMX_PERM },
 
134
#endif
126
135
#if HAVE_ARMV5TE
127
 
  {"SIMPLE-ARMV5TE",  1, ff_simple_idct_armv5te, ff_ref_idct, NO_PERM },
 
136
    { "SIMPLE-ARMV5TE", ff_simple_idct_armv5te,NO_PERM  },
128
137
#endif
129
138
#if HAVE_ARMV6
130
 
  {"SIMPLE-ARMV6",    1, ff_simple_idct_armv6, ff_ref_idct, MMX_PERM },
 
139
    { "SIMPLE-ARMV6",   ff_simple_idct_armv6,  MMX_PERM },
131
140
#endif
132
141
#if HAVE_NEON
133
 
  {"SIMPLE-NEON",     1, ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM },
 
142
    { "SIMPLE-NEON",    ff_simple_idct_neon,   PARTTRANS_PERM },
134
143
#endif
135
 
#endif /* ARCH_ARM */
136
144
 
137
145
#if ARCH_ALPHA
138
 
  {"SIMPLE-ALPHA",    1, ff_simple_idct_axp,  ff_ref_idct, NO_PERM },
 
146
    { "SIMPLE-ALPHA",   ff_simple_idct_axp,    NO_PERM },
139
147
#endif
140
148
 
141
 
  { 0 }
 
149
    { 0 }
142
150
};
143
151
 
144
152
#define AANSCALE_BITS 12
145
153
 
146
 
uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
147
 
 
148
154
static int64_t gettime(void)
149
155
{
150
156
    struct timeval tv;
151
 
    gettimeofday(&tv,NULL);
 
157
    gettimeofday(&tv, NULL);
152
158
    return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
153
159
}
154
160
 
157
163
 
158
164
static short idct_mmx_perm[64];
159
165
 
160
 
static short idct_simple_mmx_perm[64]={
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,
 
166
static short idct_simple_mmx_perm[64] = {
 
167
    0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
 
168
    0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
 
169
    0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
 
170
    0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
 
171
    0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
 
172
    0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
 
173
    0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
 
174
    0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
169
175
};
170
176
 
171
 
static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
 
177
static const uint8_t idct_sse2_row_perm[8] = { 0, 4, 1, 5, 2, 6, 3, 7 };
172
178
 
173
179
static void idct_mmx_init(void)
174
180
{
177
183
    /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
178
184
    for (i = 0; i < 64; i++) {
179
185
        idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
180
 
//        idct_simple_mmx_perm[i] = simple_block_permute_op(i);
181
186
    }
182
187
}
183
188
 
184
189
DECLARE_ALIGNED(16, static DCTELEM, block)[64];
185
 
DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
186
 
DECLARE_ALIGNED(8, static DCTELEM, block_org)[64];
 
190
DECLARE_ALIGNED(8,  static DCTELEM, block1)[64];
187
191
 
188
192
static inline void mmx_emms(void)
189
193
{
193
197
#endif
194
198
}
195
199
 
196
 
static void dct_error(const char *name, int is_idct,
197
 
               void (*fdct_func)(DCTELEM *block),
198
 
               void (*fdct_ref)(DCTELEM *block), int form, int test)
199
 
{
 
200
static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
 
201
{
 
202
    int i, j;
 
203
 
 
204
    memset(block, 0, 64 * sizeof(*block));
 
205
 
 
206
    switch (test) {
 
207
    case 0:
 
208
        for (i = 0; i < 64; i++)
 
209
            block[i] = (av_lfg_get(prng) % 512) - 256;
 
210
        if (is_idct) {
 
211
            ff_ref_fdct(block);
 
212
            for (i = 0; i < 64; i++)
 
213
                block[i] >>= 3;
 
214
        }
 
215
        break;
 
216
    case 1:
 
217
        j = av_lfg_get(prng) % 10 + 1;
 
218
        for (i = 0; i < j; i++)
 
219
            block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % 512 - 256;
 
220
        break;
 
221
    case 2:
 
222
        block[ 0] = av_lfg_get(prng) % 4096 - 2048;
 
223
        block[63] = (block[0] & 1) ^ 1;
 
224
        break;
 
225
    }
 
226
}
 
227
 
 
228
static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
 
229
{
 
230
    int i;
 
231
 
 
232
    if (perm == MMX_PERM) {
 
233
        for (i = 0; i < 64; i++)
 
234
            dst[idct_mmx_perm[i]] = src[i];
 
235
    } else if (perm == MMX_SIMPLE_PERM) {
 
236
        for (i = 0; i < 64; i++)
 
237
            dst[idct_simple_mmx_perm[i]] = src[i];
 
238
    } else if (perm == SSE2_PERM) {
 
239
        for (i = 0; i < 64; i++)
 
240
            dst[(i & 0x38) | idct_sse2_row_perm[i & 7]] = src[i];
 
241
    } else if (perm == PARTTRANS_PERM) {
 
242
        for (i = 0; i < 64; i++)
 
243
            dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i];
 
244
    } else {
 
245
        for (i = 0; i < 64; i++)
 
246
            dst[i] = src[i];
 
247
    }
 
248
}
 
249
 
 
250
static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
 
251
{
 
252
    void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
200
253
    int it, i, scale;
201
254
    int err_inf, v;
202
 
    int64_t err2, ti, ti1, it1;
203
 
    int64_t sysErr[64], sysErrMax=0;
204
 
    int maxout=0;
205
 
    int blockSumErrMax=0, blockSumErr;
 
255
    int64_t err2, ti, ti1, it1, err_sum = 0;
 
256
    int64_t sysErr[64], sysErrMax = 0;
 
257
    int maxout = 0;
 
258
    int blockSumErrMax = 0, blockSumErr;
206
259
    AVLFG prng;
 
260
    double omse, ome;
 
261
    int spec_err;
207
262
 
208
263
    av_lfg_init(&prng, 1);
209
264
 
210
265
    err_inf = 0;
211
266
    err2 = 0;
212
 
    for(i=0; i<64; i++) sysErr[i]=0;
213
 
    for(it=0;it<NB_ITS;it++) {
214
 
        for(i=0;i<64;i++)
215
 
            block1[i] = 0;
216
 
        switch(test){
217
 
        case 0:
218
 
            for(i=0;i<64;i++)
219
 
                block1[i] = (av_lfg_get(&prng) % 512) -256;
220
 
            if (is_idct){
221
 
                ff_ref_fdct(block1);
222
 
 
223
 
                for(i=0;i<64;i++)
224
 
                    block1[i]>>=3;
225
 
            }
226
 
        break;
227
 
        case 1:{
228
 
            int num = av_lfg_get(&prng) % 10 + 1;
229
 
            for(i=0;i<num;i++)
230
 
                block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % 512 -256;
231
 
        }break;
232
 
        case 2:
233
 
            block1[0] = av_lfg_get(&prng) % 4096 - 2048;
234
 
            block1[63]= (block1[0]&1)^1;
235
 
        break;
236
 
        }
237
 
 
238
 
#if 0 // simulate mismatch control
239
 
{ int sum=0;
240
 
        for(i=0;i<64;i++)
241
 
           sum+=block1[i];
242
 
 
243
 
        if((sum&1)==0) block1[63]^=1;
244
 
}
245
 
#endif
246
 
 
247
 
        for(i=0; i<64; i++)
248
 
            block_org[i]= block1[i];
249
 
 
250
 
        if (form == MMX_PERM) {
251
 
            for(i=0;i<64;i++)
252
 
                block[idct_mmx_perm[i]] = block1[i];
253
 
            } else if (form == MMX_SIMPLE_PERM) {
254
 
            for(i=0;i<64;i++)
255
 
                block[idct_simple_mmx_perm[i]] = block1[i];
256
 
 
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];
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];
263
 
        } else {
264
 
            for(i=0; i<64; i++)
265
 
                block[i]= block1[i];
266
 
        }
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
 
 
272
 
        if((sum&1)==0) block[63]^=1;
273
 
}
274
 
#endif
275
 
 
276
 
        fdct_func(block);
 
267
    for (i = 0; i < 64; i++)
 
268
        sysErr[i] = 0;
 
269
    for (it = 0; it < NB_ITS; it++) {
 
270
        init_block(block1, test, is_idct, &prng);
 
271
        permute(block, block1, dct->format);
 
272
 
 
273
        dct->func(block);
277
274
        mmx_emms();
278
275
 
279
 
        if (form == SCALE_PERM) {
280
 
            for(i=0; i<64; i++) {
281
 
                scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
282
 
                block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
 
276
        if (dct->format == SCALE_PERM) {
 
277
            for (i = 0; i < 64; i++) {
 
278
                scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
 
279
                block[i] = (block[i] * scale) >> AANSCALE_BITS;
283
280
            }
284
281
        }
285
282
 
286
 
        fdct_ref(block1);
 
283
        ref(block1);
287
284
 
288
 
        blockSumErr=0;
289
 
        for(i=0;i<64;i++) {
290
 
            v = abs(block[i] - block1[i]);
 
285
        blockSumErr = 0;
 
286
        for (i = 0; i < 64; i++) {
 
287
            int err = block[i] - block1[i];
 
288
            err_sum += err;
 
289
            v = abs(err);
291
290
            if (v > err_inf)
292
291
                err_inf = v;
293
292
            err2 += v * v;
294
293
            sysErr[i] += block[i] - block1[i];
295
294
            blockSumErr += v;
296
 
            if( abs(block[i])>maxout) maxout=abs(block[i]);
 
295
            if (abs(block[i]) > maxout)
 
296
                maxout = abs(block[i]);
297
297
        }
298
 
        if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr;
299
 
#if 0 // print different matrix pairs
300
 
        if(blockSumErr){
 
298
        if (blockSumErrMax < blockSumErr)
 
299
            blockSumErrMax = blockSumErr;
 
300
    }
 
301
    for (i = 0; i < 64; i++)
 
302
        sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));
 
303
 
 
304
    for (i = 0; i < 64; i++) {
 
305
        if (i % 8 == 0)
301
306
            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
312
 
    }
313
 
    for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
314
 
 
315
 
    for(i=0; i<64; i++){
316
 
        if(i%8==0) printf("\n");
317
 
        printf("%7d ", (int)sysErr[i]);
 
307
        printf("%7d ", (int) sysErr[i]);
318
308
    }
319
309
    printf("\n");
320
310
 
321
 
    printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
322
 
           is_idct ? "IDCT" : "DCT",
323
 
           name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
 
311
    omse = (double) err2 / NB_ITS / 64;
 
312
    ome  = (double) err_sum / NB_ITS / 64;
 
313
 
 
314
    spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
 
315
 
 
316
    printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
 
317
           is_idct ? "IDCT" : "DCT", dct->name, err_inf,
 
318
           omse, ome, (double) sysErrMax / NB_ITS,
 
319
           maxout, blockSumErrMax);
 
320
 
 
321
    if (spec_err && !dct->nonspec)
 
322
        return 1;
 
323
 
 
324
    if (!speed)
 
325
        return 0;
324
326
 
325
327
    /* speed test */
326
 
    for(i=0;i<64;i++)
327
 
        block1[i] = 0;
328
 
    switch(test){
329
 
    case 0:
330
 
        for(i=0;i<64;i++)
331
 
            block1[i] = av_lfg_get(&prng) % 512 -256;
332
 
        if (is_idct){
333
 
            ff_ref_fdct(block1);
334
 
 
335
 
            for(i=0;i<64;i++)
336
 
                block1[i]>>=3;
337
 
        }
338
 
    break;
339
 
    case 1:{
340
 
    case 2:
341
 
        block1[0] = av_lfg_get(&prng) % 512 -256;
342
 
        block1[1] = av_lfg_get(&prng) % 512 -256;
343
 
        block1[2] = av_lfg_get(&prng) % 512 -256;
344
 
        block1[3] = av_lfg_get(&prng) % 512 -256;
345
 
    }break;
346
 
    }
347
 
 
348
 
    if (form == MMX_PERM) {
349
 
        for(i=0;i<64;i++)
350
 
            block[idct_mmx_perm[i]] = block1[i];
351
 
    } else if(form == MMX_SIMPLE_PERM) {
352
 
        for(i=0;i<64;i++)
353
 
            block[idct_simple_mmx_perm[i]] = block1[i];
354
 
    } else {
355
 
        for(i=0; i<64; i++)
356
 
            block[i]= block1[i];
357
 
    }
 
328
    init_block(block, test, is_idct, &prng);
 
329
    permute(block1, block, dct->format);
358
330
 
359
331
    ti = gettime();
360
332
    it1 = 0;
361
333
    do {
362
 
        for(it=0;it<NB_ITS_SPEED;it++) {
363
 
            for(i=0; i<64; i++)
364
 
                block[i]= block1[i];
365
 
//            memcpy(block, block1, sizeof(DCTELEM) * 64);
366
 
// do not memcpy especially not fastmemcpy because it does movntq !!!
367
 
            fdct_func(block);
 
334
        for (it = 0; it < NB_ITS_SPEED; it++) {
 
335
            memcpy(block, block1, sizeof(block));
 
336
            dct->func(block);
368
337
        }
369
338
        it1 += NB_ITS_SPEED;
370
339
        ti1 = gettime() - ti;
371
340
    } while (ti1 < 1000000);
372
341
    mmx_emms();
373
342
 
374
 
    printf("%s %s: %0.1f kdct/s\n",
375
 
           is_idct ? "IDCT" : "DCT",
376
 
           name, (double)it1 * 1000.0 / (double)ti1);
 
343
    printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
 
344
           (double) it1 * 1000.0 / (double) ti1);
 
345
 
 
346
    return 0;
377
347
}
378
348
 
379
349
DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
391
361
    if (!init) {
392
362
        init = 1;
393
363
 
394
 
        for(i=0;i<8;i++) {
 
364
        for (i = 0; i < 8; i++) {
395
365
            sum = 0;
396
 
            for(j=0;j<8;j++) {
397
 
                s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0);
 
366
            for (j = 0; j < 8; j++) {
 
367
                s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
398
368
                c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
399
369
                sum += c8[i][j] * c8[i][j];
400
370
            }
401
371
        }
402
372
 
403
 
        for(i=0;i<4;i++) {
 
373
        for (i = 0; i < 4; i++) {
404
374
            sum = 0;
405
 
            for(j=0;j<4;j++) {
406
 
                s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0);
 
375
            for (j = 0; j < 4; j++) {
 
376
                s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
407
377
                c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
408
378
                sum += c4[i][j] * c4[i][j];
409
379
            }
412
382
 
413
383
    /* butterfly */
414
384
    s = 0.5 * sqrt(2.0);
415
 
    for(i=0;i<4;i++) {
416
 
        for(j=0;j<8;j++) {
417
 
            block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s;
418
 
            block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s;
 
385
    for (i = 0; i < 4; i++) {
 
386
        for (j = 0; j < 8; j++) {
 
387
            block1[8 * (2 * i) + j] =
 
388
                (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
 
389
            block1[8 * (2 * i + 1) + j] =
 
390
                (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
419
391
        }
420
392
    }
421
393
 
422
394
    /* idct8 on lines */
423
 
    for(i=0;i<8;i++) {
424
 
        for(j=0;j<8;j++) {
 
395
    for (i = 0; i < 8; i++) {
 
396
        for (j = 0; j < 8; j++) {
425
397
            sum = 0;
426
 
            for(k=0;k<8;k++)
427
 
                sum += c8[k][j] * block1[8*i+k];
428
 
            block2[8*i+j] = sum;
 
398
            for (k = 0; k < 8; k++)
 
399
                sum += c8[k][j] * block1[8 * i + k];
 
400
            block2[8 * i + j] = sum;
429
401
        }
430
402
    }
431
403
 
432
404
    /* idct4 */
433
 
    for(i=0;i<8;i++) {
434
 
        for(j=0;j<4;j++) {
 
405
    for (i = 0; i < 8; i++) {
 
406
        for (j = 0; j < 4; j++) {
435
407
            /* top */
436
408
            sum = 0;
437
 
            for(k=0;k<4;k++)
438
 
                sum += c4[k][j] * block2[8*(2*k)+i];
439
 
            block3[8*(2*j)+i] = sum;
 
409
            for (k = 0; k < 4; k++)
 
410
                sum += c4[k][j] * block2[8 * (2 * k) + i];
 
411
            block3[8 * (2 * j) + i] = sum;
440
412
 
441
413
            /* bottom */
442
414
            sum = 0;
443
 
            for(k=0;k<4;k++)
444
 
                sum += c4[k][j] * block2[8*(2*k+1)+i];
445
 
            block3[8*(2*j+1)+i] = sum;
 
415
            for (k = 0; k < 4; k++)
 
416
                sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
 
417
            block3[8 * (2 * j + 1) + i] = sum;
446
418
        }
447
419
    }
448
420
 
449
421
    /* clamp and store the result */
450
 
    for(i=0;i<8;i++) {
451
 
        for(j=0;j<8;j++) {
452
 
            v = block3[8*i+j];
453
 
            if (v < 0)
454
 
                v = 0;
455
 
            else if (v > 255)
456
 
                v = 255;
457
 
            dest[i * linesize + j] = (int)rint(v);
 
422
    for (i = 0; i < 8; i++) {
 
423
        for (j = 0; j < 8; j++) {
 
424
            v = block3[8 * i + j];
 
425
            if      (v < 0)   v = 0;
 
426
            else if (v > 255) v = 255;
 
427
            dest[i * linesize + j] = (int) rint(v);
458
428
        }
459
429
    }
460
430
}
461
431
 
462
432
static void idct248_error(const char *name,
463
 
                    void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block))
 
433
                          void (*idct248_put)(uint8_t *dest, int line_size,
 
434
                                              int16_t *block),
 
435
                          int speed)
464
436
{
465
437
    int it, i, it1, ti, ti1, err_max, v;
466
 
 
467
438
    AVLFG prng;
468
439
 
469
440
    av_lfg_init(&prng, 1);
471
442
    /* just one test to see if code is correct (precision is less
472
443
       important here) */
473
444
    err_max = 0;
474
 
    for(it=0;it<NB_ITS;it++) {
475
 
 
 
445
    for (it = 0; it < NB_ITS; it++) {
476
446
        /* XXX: use forward transform to generate values */
477
 
        for(i=0;i<64;i++)
 
447
        for (i = 0; i < 64; i++)
478
448
            block1[i] = av_lfg_get(&prng) % 256 - 128;
479
449
        block1[0] += 1024;
480
450
 
481
 
        for(i=0; i<64; i++)
482
 
            block[i]= block1[i];
 
451
        for (i = 0; i < 64; i++)
 
452
            block[i] = block1[i];
483
453
        idct248_ref(img_dest1, 8, block);
484
454
 
485
 
        for(i=0; i<64; i++)
486
 
            block[i]= block1[i];
 
455
        for (i = 0; i < 64; i++)
 
456
            block[i] = block1[i];
487
457
        idct248_put(img_dest, 8, block);
488
458
 
489
 
        for(i=0;i<64;i++) {
490
 
            v = abs((int)img_dest[i] - (int)img_dest1[i]);
 
459
        for (i = 0; i < 64; i++) {
 
460
            v = abs((int) img_dest[i] - (int) img_dest1[i]);
491
461
            if (v == 255)
492
462
                printf("%d %d\n", img_dest[i], img_dest1[i]);
493
463
            if (v > err_max)
494
464
                err_max = v;
495
465
        }
496
466
    }
497
 
    printf("%s %s: err_inf=%d\n",
498
 
           1 ? "IDCT248" : "DCT248",
499
 
           name, err_max);
 
467
    printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
 
468
 
 
469
    if (!speed)
 
470
        return;
500
471
 
501
472
    ti = gettime();
502
473
    it1 = 0;
503
474
    do {
504
 
        for(it=0;it<NB_ITS_SPEED;it++) {
505
 
            for(i=0; i<64; i++)
506
 
                block[i]= block1[i];
507
 
//            memcpy(block, block1, sizeof(DCTELEM) * 64);
508
 
// do not memcpy especially not fastmemcpy because it does movntq !!!
 
475
        for (it = 0; it < NB_ITS_SPEED; it++) {
 
476
            for (i = 0; i < 64; i++)
 
477
                block[i] = block1[i];
509
478
            idct248_put(img_dest, 8, block);
510
479
        }
511
480
        it1 += NB_ITS_SPEED;
513
482
    } while (ti1 < 1000000);
514
483
    mmx_emms();
515
484
 
516
 
    printf("%s %s: %0.1f kdct/s\n",
517
 
           1 ? "IDCT248" : "DCT248",
518
 
           name, (double)it1 * 1000.0 / (double)ti1);
 
485
    printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
 
486
           (double) it1 * 1000.0 / (double) ti1);
519
487
}
520
488
 
521
489
static void help(void)
525
493
           "            1 -> test with random sparse matrixes\n"
526
494
           "            2 -> do 3. test from mpeg4 std\n"
527
495
           "-i          test IDCT implementations\n"
528
 
           "-4          test IDCT248 implementations\n");
 
496
           "-4          test IDCT248 implementations\n"
 
497
           "-t          speed test\n");
529
498
}
530
499
 
531
500
int main(int argc, char **argv)
532
501
{
533
502
    int test_idct = 0, test_248_dct = 0;
534
 
    int c,i;
535
 
    int test=1;
 
503
    int c, i;
 
504
    int test = 1;
 
505
    int speed = 0;
 
506
    int err = 0;
 
507
 
536
508
    cpu_flags = av_get_cpu_flags();
537
509
 
538
510
    ff_ref_dct_init();
539
511
    idct_mmx_init();
540
512
 
541
 
    for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
542
 
    for(i=0;i<MAX_NEG_CROP;i++) {
543
 
        cropTbl[i] = 0;
544
 
        cropTbl[i + MAX_NEG_CROP + 256] = 255;
545
 
    }
546
 
 
547
 
    for(;;) {
548
 
        c = getopt(argc, argv, "ih4");
 
513
    for (;;) {
 
514
        c = getopt(argc, argv, "ih4t");
549
515
        if (c == -1)
550
516
            break;
551
 
        switch(c) {
 
517
        switch (c) {
552
518
        case 'i':
553
519
            test_idct = 1;
554
520
            break;
555
521
        case '4':
556
522
            test_248_dct = 1;
557
523
            break;
558
 
        default :
 
524
        case 't':
 
525
            speed = 1;
 
526
            break;
 
527
        default:
559
528
        case 'h':
560
529
            help();
561
530
            return 0;
562
531
        }
563
532
    }
564
533
 
565
 
    if(optind <argc) test= atoi(argv[optind]);
 
534
    if (optind < argc)
 
535
        test = atoi(argv[optind]);
566
536
 
567
 
    printf("ffmpeg DCT/IDCT test\n");
 
537
    printf("Libav DCT/IDCT test\n");
568
538
 
569
539
    if (test_248_dct) {
570
 
        idct248_error("SIMPLE-C", ff_simple_idct248_put);
 
540
        idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
571
541
    } else {
572
 
      for (i=0;algos[i].name;i++)
573
 
        if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
574
 
          dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test);
575
 
        }
 
542
        const struct algo *algos = test_idct ? idct_tab : fdct_tab;
 
543
        for (i = 0; algos[i].name; i++)
 
544
            if (!(~cpu_flags & algos[i].mm_support)) {
 
545
                err |= dct_error(&algos[i], test, test_idct, speed);
 
546
            }
576
547
    }
577
 
    return 0;
 
548
 
 
549
    return err;
578
550
}