ffmpeg / tests / tiny_psnr.c @ c43d77c1
History  View  Annotate  Download (4.46 KB)
1 
/*


2 
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>

3 
*

4 
* This file is part of FFmpeg.

5 
*

6 
* FFmpeg is free software; you can redistribute it and/or

7 
* modify it under the terms of the GNU Lesser General Public

8 
* License as published by the Free Software Foundation; either

9 
* version 2.1 of the License, or (at your option) any later version.

10 
*

11 
* FFmpeg is distributed in the hope that it will be useful,

12 
* 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 
* License along with FFmpeg; if not, write to the Free Software

18 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301 USA

19 
*/

20  
21 
#include <stdio.h> 
22 
#include <stdlib.h> 
23 
#include <string.h> 
24 
#include <inttypes.h> 
25 
#include <assert.h> 
26  
27 
#define FFMIN(a,b) ((a) > (b) ? (b) : (a))

28 
#define F 100 
29 
#define SIZE 2048 
30  
31 
uint64_t exp16_table[21]={

32 
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 
582360139072LL,

53 
}; 
54  
55 
#if 0

56 
// 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 

66 
return out;

67 
}

68 
#endif

69  
70 
// 16.16 fixpoint log()

71 
static int64_t log16(uint64_t a){

72 
int i;

73 
int out=0; 
74  
75 
if(a < 1<<16) 
76 
return log16((1LL<<32) / a); 
77 
a<<=16;

78  
79 
for(i=20;i>=0;i){ 
80 
int64_t b= exp16_table[i]; 
81 
if(a<(b<<16)) continue; 
82 
out = 1<<i;

83 
a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b; 
84 
} 
85 
return out;

86 
} 
87  
88 
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 
uint64_t psnr; 
111 
int len= argc<4 ? 1 : atoi(argv[3]); 
112 
int64_t max= (1<<(8*len))1; 
113 
int shift= argc<5 ? 0 : atoi(argv[4]); 
114 
int skip_bytes = argc<6 ? 0 : atoi(argv[5]); 
115 
int size0=0; 
116 
int size1=0; 
117 
int maxdist = 0; 
118  
119 
if(argc<3){ 
120 
printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");

121 
printf("WAV headers are skipped automatically.\n");

122 
return 1; 
123 
} 
124  
125 
f[0]= fopen(argv[1], "rb"); 
126 
f[1]= fopen(argv[2], "rb"); 
127 
if(!f[0]  !f[1]){ 
128 
fprintf(stderr, "Could not open input files.\n");

129 
return 1; 
130 
} 
131  
132 
for (i = 0; i < 2; i++) { 
133 
uint8_t *p = buf[i]; 
134 
fread(p, 1, 12, f[i]); 
135 
if (!memcmp(p, "RIFF", 4) && 
136 
!memcmp(p+8, "WAVE", 4)) { 
137 
fread(p, 1, 8, f[i]); 
138 
while (memcmp(p, "data", 4)) { 
139 
int s = p[4]  p[5]<<8  p[6]<<16  p[7]<<24; 
140 
fseek(f[i], s, SEEK_CUR); 
141 
fread(p, 1, 8, f[i]); 
142 
} 
143 
} else {

144 
fseek(f[i], 12, SEEK_CUR);

145 
} 
146 
} 
147  
148 
fseek(f[shift<0], shift < 0 ? shift : shift, SEEK_CUR); 
149  
150 
fseek(f[0],skip_bytes,SEEK_CUR);

151 
fseek(f[1],skip_bytes,SEEK_CUR);

152  
153 
for(;;){

154 
int s0= fread(buf[0], 1, SIZE, f[0]); 
155 
int s1= fread(buf[1], 1, SIZE, f[1]); 
156  
157 
for(j=0; j<FFMIN(s0,s1); j++){ 
158 
int64_t a= buf[0][j];

159 
int64_t b= buf[1][j];

160 
int dist;

161 
if(len==2){ 
162 
a= (int16_t)(a  (buf[0][++j]<<8)); 
163 
b= (int16_t)(b  (buf[1][ j]<<8)); 
164 
} 
165 
sse += (ab) * (ab); 
166 
dist = abs(ab); 
167 
if (dist > maxdist) maxdist = dist;

168 
} 
169 
size0 += s0; 
170 
size1 += s1; 
171 
if(s0+s1<=0) 
172 
break;

173 
} 
174  
175 
i= FFMIN(size0,size1)/len; 
176 
if(!i) i=1; 
177 
dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );

178 
if(sse)

179 
psnr= ((2*log16(max<<16) + log16(i)  log16(sse))*284619LL*F + (1LL<<31)) / (1LL<<32); 
180 
else

181 
psnr= 1000*F1; //floating point free infinity :) 
182  
183 
printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",

184 
(int)(dev/F), (int)(dev%F), 
185 
(int)(psnr/F), (int)(psnr%F), 
186 
maxdist, 
187 
size0, size1); 
188 
return 0; 
189 
} 
190  
191 