Statistics
| Branch: | Revision:

ffmpeg / tests / tiny_psnr.c @ d370e3e9

History | View | Annotate | Download (4.54 KB)

1 67cbe681 Michael Niedermayer
/*
2
 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
3
 *
4 244e1e64 Diego Biurrun
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7 67cbe681 Michael Niedermayer
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9 244e1e64 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
10 67cbe681 Michael Niedermayer
 *
11 244e1e64 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
12 67cbe681 Michael Niedermayer
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17 244e1e64 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
18 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 67cbe681 Michael Niedermayer
 */
20
21
#include <stdio.h>
22 ba96e97f Michael Niedermayer
#include <stdlib.h>
23 c43d77c1 Måns Rullgård
#include <string.h>
24 67cbe681 Michael Niedermayer
#include <inttypes.h>
25 9e2a16e1 Michael Niedermayer
#include <assert.h>
26 67cbe681 Michael Niedermayer
27 1e90317b Michael Niedermayer
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
28 67cbe681 Michael Niedermayer
#define F 100
29
#define SIZE 2048
30
31 0c90161f Michael Niedermayer
uint64_t exp16_table[21]={
32 9e2a16e1 Michael Niedermayer
     65537,
33
     65538,
34
     65540,
35
     65544,
36
     65552,
37
     65568,
38
     65600,
39
     65664,
40
     65793,
41
     66050,
42
     66568,
43
     67616,
44
     69763,
45
     74262,
46
     84150,
47
    108051,
48
    178145,
49
    484249,
50
   3578144,
51
 195360063,
52 0c90161f Michael Niedermayer
 582360139072LL,
53 9e2a16e1 Michael Niedermayer
};
54 e9b67fe4 Diego Biurrun
55
#if 0
56 2d2fe557 Diego Biurrun
// 16.16 fixpoint exp()
57
static unsigned int exp16(unsigned int a){
58
    int i;
59
    int out= 1<<16;
60

61
    for(i=19;i>=0;i--){
62
        if(a&(1<<i))
63
            out= (out*exp16_table[i] + (1<<15))>>16;
64
    }
65 9e2a16e1 Michael Niedermayer

66 2d2fe557 Diego Biurrun
    return out;
67
}
68 e9b67fe4 Diego Biurrun
#endif
69
70 9e2a16e1 Michael Niedermayer
// 16.16 fixpoint log()
71 0c90161f Michael Niedermayer
static int64_t log16(uint64_t a){
72 9e2a16e1 Michael Niedermayer
    int i;
73
    int out=0;
74 0c90161f Michael Niedermayer
75
    if(a < 1<<16)
76
        return -log16((1LL<<32) / a);
77 9e2a16e1 Michael Niedermayer
    a<<=16;
78 115329f1 Diego Biurrun
79 0c90161f Michael Niedermayer
    for(i=20;i>=0;i--){
80 8176bd1a Michael Niedermayer
        int64_t b= exp16_table[i];
81
        if(a<(b<<16)) continue;
82 9e2a16e1 Michael Niedermayer
        out |= 1<<i;
83 8176bd1a Michael Niedermayer
        a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b;
84 9e2a16e1 Michael Niedermayer
    }
85
    return out;
86
}
87
88 67cbe681 Michael Niedermayer
static uint64_t int_sqrt(uint64_t a)
89
{
90
    uint64_t ret=0;
91
    int s;
92
    uint64_t ret_sq=0;
93
94
    for(s=31; s>=0; s--){
95
        uint64_t b= ret_sq + (1ULL<<(s*2)) + (ret<<s)*2;
96
        if(b<=a){
97
            ret_sq=b;
98
            ret+= 1ULL<<s;
99
        }
100
    }
101
    return ret;
102
}
103
104
int main(int argc,char* argv[]){
105
    int i, j;
106
    uint64_t sse=0;
107
    uint64_t dev;
108
    FILE *f[2];
109
    uint8_t buf[2][SIZE];
110 9e2a16e1 Michael Niedermayer
    uint64_t psnr;
111 ba96e97f Michael Niedermayer
    int len= argc<4 ? 1 : atoi(argv[3]);
112 0c90161f Michael Niedermayer
    int64_t max= (1<<(8*len))-1;
113 ba96e97f Michael Niedermayer
    int shift= argc<5 ? 0 : atoi(argv[4]);
114 b8889ea5 Benjamin Larsson
    int skip_bytes = argc<6 ? 0 : atoi(argv[5]);
115 1e90317b Michael Niedermayer
    int size0=0;
116
    int size1=0;
117 cb0067ec Vitor Sessak
    int maxdist = 0;
118 115329f1 Diego Biurrun
119 0c90161f Michael Niedermayer
    if(argc<3){
120 b8889ea5 Benjamin Larsson
        printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
121 c43d77c1 Måns Rullgård
        printf("WAV headers are skipped automatically.\n");
122 3ec8d24a Måns Rullgård
        return 1;
123 67cbe681 Michael Niedermayer
    }
124 115329f1 Diego Biurrun
125 0d6d0cf9 Michael Niedermayer
    f[0]= fopen(argv[1], "rb");
126
    f[1]= fopen(argv[2], "rb");
127 e740c796 Michael Niedermayer
    if(!f[0] || !f[1]){
128 cc8de8e8 Diego Biurrun
        fprintf(stderr, "Could not open input files.\n");
129 3ec8d24a Måns Rullgård
        return 1;
130 e740c796 Michael Niedermayer
    }
131 c43d77c1 Måns Rullgård
132
    for (i = 0; i < 2; i++) {
133
        uint8_t *p = buf[i];
134 cd3cb048 Måns Rullgård
        if (fread(p, 1, 12, f[i]) != 12)
135
            return 1;
136 c43d77c1 Måns Rullgård
        if (!memcmp(p,   "RIFF", 4) &&
137
            !memcmp(p+8, "WAVE", 4)) {
138 cd3cb048 Måns Rullgård
            if (fread(p, 1, 8, f[i]) != 8)
139
                return 1;
140 c43d77c1 Måns Rullgård
            while (memcmp(p, "data", 4)) {
141
                int s = p[4] | p[5]<<8 | p[6]<<16 | p[7]<<24;
142
                fseek(f[i], s, SEEK_CUR);
143 cd3cb048 Måns Rullgård
                if (fread(p, 1, 8, f[i]) != 8)
144
                    return 1;
145 c43d77c1 Måns Rullgård
            }
146
        } else {
147
            fseek(f[i], -12, SEEK_CUR);
148
        }
149
    }
150
151 f6dddd33 Måns Rullgård
    fseek(f[shift<0], abs(shift), SEEK_CUR);
152 67cbe681 Michael Niedermayer
153 b8889ea5 Benjamin Larsson
    fseek(f[0],skip_bytes,SEEK_CUR);
154
    fseek(f[1],skip_bytes,SEEK_CUR);
155
156 1e90317b Michael Niedermayer
    for(;;){
157
        int s0= fread(buf[0], 1, SIZE, f[0]);
158
        int s1= fread(buf[1], 1, SIZE, f[1]);
159 115329f1 Diego Biurrun
160 1e90317b Michael Niedermayer
        for(j=0; j<FFMIN(s0,s1); j++){
161 0c90161f Michael Niedermayer
            int64_t a= buf[0][j];
162
            int64_t b= buf[1][j];
163 cb0067ec Vitor Sessak
            int dist;
164 0c90161f Michael Niedermayer
            if(len==2){
165
                a= (int16_t)(a | (buf[0][++j]<<8));
166
                b= (int16_t)(b | (buf[1][  j]<<8));
167
            }
168 67cbe681 Michael Niedermayer
            sse += (a-b) * (a-b);
169 cb0067ec Vitor Sessak
            dist = abs(a-b);
170
            if (dist > maxdist) maxdist = dist;
171 67cbe681 Michael Niedermayer
        }
172 1e90317b Michael Niedermayer
        size0 += s0;
173
        size1 += s1;
174
        if(s0+s1<=0)
175
            break;
176 67cbe681 Michael Niedermayer
    }
177 115329f1 Diego Biurrun
178 1e90317b Michael Niedermayer
    i= FFMIN(size0,size1)/len;
179 eeaa742c Michael Niedermayer
    if(!i) i=1;
180 0c90161f Michael Niedermayer
    dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );
181 9e2a16e1 Michael Niedermayer
    if(sse)
182 b00803e0 Justin Ruggles
        psnr= ((2*log16(max<<16) + log16(i) - log16(sse))*284619LL*F + (1LL<<31)) / (1LL<<32);
183 9e2a16e1 Michael Niedermayer
    else
184 1e90317b Michael Niedermayer
        psnr= 1000*F-1; //floating point free infinity :)
185 115329f1 Diego Biurrun
186 cb0067ec Vitor Sessak
    printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",
187 115329f1 Diego Biurrun
        (int)(dev/F), (int)(dev%F),
188 9e2a16e1 Michael Niedermayer
        (int)(psnr/F), (int)(psnr%F),
189 cb0067ec Vitor Sessak
        maxdist,
190 1e90317b Michael Niedermayer
        size0, size1);
191 67cbe681 Michael Niedermayer
    return 0;
192
}
193 9e2a16e1 Michael Niedermayer