• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

tests/tiny_psnr.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
00003  *
00004  * This file is part of FFmpeg.
00005  *
00006  * FFmpeg is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * FFmpeg is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with FFmpeg; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <inttypes.h>
00025 #include <assert.h>
00026 
00027 #define FFMIN(a,b) ((a) > (b) ? (b) : (a))
00028 #define F 100
00029 #define SIZE 2048
00030 
00031 uint64_t exp16_table[21]={
00032      65537,
00033      65538,
00034      65540,
00035      65544,
00036      65552,
00037      65568,
00038      65600,
00039      65664,
00040      65793,
00041      66050,
00042      66568,
00043      67616,
00044      69763,
00045      74262,
00046      84150,
00047     108051,
00048     178145,
00049     484249,
00050    3578144,
00051  195360063,
00052  582360139072LL,
00053 };
00054 
00055 #if 0
00056 // 16.16 fixpoint exp()
00057 static unsigned int exp16(unsigned int a){
00058     int i;
00059     int out= 1<<16;
00060 
00061     for(i=19;i>=0;i--){
00062         if(a&(1<<i))
00063             out= (out*exp16_table[i] + (1<<15))>>16;
00064     }
00065 
00066     return out;
00067 }
00068 #endif
00069 
00070 // 16.16 fixpoint log()
00071 static int64_t log16(uint64_t a){
00072     int i;
00073     int out=0;
00074 
00075     if(a < 1<<16)
00076         return -log16((1LL<<32) / a);
00077     a<<=16;
00078 
00079     for(i=20;i>=0;i--){
00080         int64_t b= exp16_table[i];
00081         if(a<(b<<16)) continue;
00082         out |= 1<<i;
00083         a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b;
00084     }
00085     return out;
00086 }
00087 
00088 static uint64_t int_sqrt(uint64_t a)
00089 {
00090     uint64_t ret=0;
00091     int s;
00092     uint64_t ret_sq=0;
00093 
00094     for(s=31; s>=0; s--){
00095         uint64_t b= ret_sq + (1ULL<<(s*2)) + (ret<<s)*2;
00096         if(b<=a){
00097             ret_sq=b;
00098             ret+= 1ULL<<s;
00099         }
00100     }
00101     return ret;
00102 }
00103 
00104 int main(int argc,char* argv[]){
00105     int i, j;
00106     uint64_t sse=0;
00107     uint64_t dev;
00108     FILE *f[2];
00109     uint8_t buf[2][SIZE];
00110     uint64_t psnr;
00111     int len= argc<4 ? 1 : atoi(argv[3]);
00112     int64_t max= (1<<(8*len))-1;
00113     int shift= argc<5 ? 0 : atoi(argv[4]);
00114     int skip_bytes = argc<6 ? 0 : atoi(argv[5]);
00115     int size0=0;
00116     int size1=0;
00117     int maxdist = 0;
00118 
00119     if(argc<3){
00120         printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
00121         printf("WAV headers are skipped automatically.\n");
00122         return 1;
00123     }
00124 
00125     f[0]= fopen(argv[1], "rb");
00126     f[1]= fopen(argv[2], "rb");
00127     if(!f[0] || !f[1]){
00128         fprintf(stderr, "Could not open input files.\n");
00129         return 1;
00130     }
00131 
00132     for (i = 0; i < 2; i++) {
00133         uint8_t *p = buf[i];
00134         if (fread(p, 1, 12, f[i]) != 12)
00135             return 1;
00136         if (!memcmp(p,   "RIFF", 4) &&
00137             !memcmp(p+8, "WAVE", 4)) {
00138             if (fread(p, 1, 8, f[i]) != 8)
00139                 return 1;
00140             while (memcmp(p, "data", 4)) {
00141                 int s = p[4] | p[5]<<8 | p[6]<<16 | p[7]<<24;
00142                 fseek(f[i], s, SEEK_CUR);
00143                 if (fread(p, 1, 8, f[i]) != 8)
00144                     return 1;
00145             }
00146         } else {
00147             fseek(f[i], -12, SEEK_CUR);
00148         }
00149     }
00150 
00151     fseek(f[shift<0], abs(shift), SEEK_CUR);
00152 
00153     fseek(f[0],skip_bytes,SEEK_CUR);
00154     fseek(f[1],skip_bytes,SEEK_CUR);
00155 
00156     for(;;){
00157         int s0= fread(buf[0], 1, SIZE, f[0]);
00158         int s1= fread(buf[1], 1, SIZE, f[1]);
00159 
00160         for(j=0; j<FFMIN(s0,s1); j++){
00161             int64_t a= buf[0][j];
00162             int64_t b= buf[1][j];
00163             int dist;
00164             if(len==2){
00165                 a= (int16_t)(a | (buf[0][++j]<<8));
00166                 b= (int16_t)(b | (buf[1][  j]<<8));
00167             }
00168             sse += (a-b) * (a-b);
00169             dist = abs(a-b);
00170             if (dist > maxdist) maxdist = dist;
00171         }
00172         size0 += s0;
00173         size1 += s1;
00174         if(s0+s1<=0)
00175             break;
00176     }
00177 
00178     i= FFMIN(size0,size1)/len;
00179     if(!i) i=1;
00180     dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );
00181     if(sse)
00182         psnr= ((2*log16(max<<16) + log16(i) - log16(sse))*284619LL*F + (1LL<<31)) / (1LL<<32);
00183     else
00184         psnr= 1000*F-1; //floating point free infinity :)
00185 
00186     printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",
00187         (int)(dev/F), (int)(dev%F),
00188         (int)(psnr/F), (int)(psnr%F),
00189         maxdist,
00190         size0, size1);
00191     return 0;
00192 }
00193 
00194 

Generated on Wed Apr 11 2012 07:31:37 for FFmpeg by  doxygen 1.7.1