Clean up old automake options.
[theora.git] / tools / process_modedec_stats.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include "../lib/modedec.h"
6 #if !defined(OC_COLLECT_METRICS)
7 # error "Recompile libtheoraenc and encoder_example with -DOC_COLLECT_METRICS"
8 #endif
9 #define OC_COLLECT_NO_ENC_FUNCS (1)
10 #include "../lib/collect.c"
11
12
13
14 ogg_int16_t     OC_MODE_LOGQ_TMP[OC_LOGQ_BINS][3][2];
15 oc_mode_metrics OC_MODE_METRICS_SATD_TMP[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS];
16 oc_mode_metrics OC_MODE_METRICS_SAD_TMP[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS];
17
18 ogg_int16_t     OC_MODE_LOGQ_BASE[OC_LOGQ_BINS][3][2];
19 oc_mode_metrics OC_MODE_METRICS_SATD_BASE[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS];
20 oc_mode_metrics OC_MODE_METRICS_SAD_BASE[OC_LOGQ_BINS-1][3][2][OC_COMP_BINS];
21
22
23 static int logq_cmp(ogg_int16_t(*a)[3][2],ogg_int16_t(*b)[3][2]){
24   int pli;
25   int qti;
26   int qi;
27   for(pli=0;pli<3;pli++){
28     for(qti=0;qti<2;qti++){
29       for(qi=0;qi<OC_LOGQ_BINS-1;qi++){
30         if(a[qi][pli][qti]!=b[qi][pli][qti]){
31           return EXIT_FAILURE;
32         }
33       }
34     }
35   }
36   return EXIT_SUCCESS;
37 }
38
39 int main(int _argc,const char **_argv){
40   FILE *fmetrics;
41   int   want_base;
42   int   have_base;
43   int   want_output;
44   int   have_output;
45   int   processing_options;
46   int   i;
47   want_base=have_base=want_output=have_output=0;
48   processing_options=1;
49   for(i=1;i<_argc;i++){
50     int pli;
51     int qti;
52     int qi;
53     int si;
54     if(processing_options&&!want_base&&!want_output){
55       if(strcmp(_argv[i],"-b")==0){
56         want_base=1;
57         continue;
58       }
59       if(strcmp(_argv[i],"-o")==0){
60         want_output=1;
61         if(have_output)break;
62         continue;
63       }
64       if(strcmp(_argv[i],"--")==0){
65         processing_options=0;
66         continue;
67       }
68     }
69     if(want_output){
70       OC_MODE_METRICS_FILENAME=_argv[i];
71       have_output=1;
72       want_output=0;
73       continue;
74     }
75     fmetrics=fopen(_argv[i],"rb");
76     if(fmetrics==NULL){
77       fprintf(stderr,"Error opening '%s' for reading.\n",_argv[i]);
78       return EXIT_FAILURE;
79     }
80     if(want_base){
81       if(fread(OC_MODE_LOGQ_BASE,sizeof(OC_MODE_LOGQ_BASE),1,fmetrics)<1){
82         fprintf(stderr,"Error reading quantizer bins from '%s'.\n",_argv[i]);
83         return EXIT_FAILURE;
84       }
85       if(fread(OC_MODE_METRICS_SATD_BASE,sizeof(OC_MODE_METRICS_SATD_BASE),1,fmetrics)<1){
86         fprintf(stderr,"Error reading SATD metrics from '%s'.\n",_argv[i]);
87         return EXIT_FAILURE;
88       }
89       if(fread(OC_MODE_METRICS_SAD_BASE,sizeof(OC_MODE_METRICS_SAD_BASE),1,fmetrics)<1){
90         fprintf(stderr,"Error reading SAD metrics from '%s'.\n",_argv[i]);
91         return EXIT_FAILURE;
92       }
93       if(OC_HAS_MODE_METRICS){
94         if(logq_cmp(OC_MODE_LOGQ,OC_MODE_LOGQ_BASE)){
95           fprintf(stderr,
96            "Error: quantizer bins in '%s' do not match previous files.\n",
97            _argv[i]);
98           return EXIT_FAILURE;
99         }
100       }
101       want_base=0;
102       have_base=1;
103     }
104     else if(!OC_HAS_MODE_METRICS){
105       if(fread(OC_MODE_LOGQ,sizeof(OC_MODE_LOGQ),1,fmetrics)<1){
106         fprintf(stderr,"Error reading quantizer bins from '%s'.\n",_argv[i]);
107         return EXIT_FAILURE;
108       }
109       if(fread(OC_MODE_METRICS_SATD,sizeof(OC_MODE_METRICS_SATD),1,fmetrics)<1){
110         fprintf(stderr,"Error reading SATD metrics from '%s'.\n",_argv[i]);
111         return EXIT_FAILURE;
112       }
113       if(fread(OC_MODE_METRICS_SAD,sizeof(OC_MODE_METRICS_SAD),1,fmetrics)<1){
114         fprintf(stderr,"Error reading SAD metrics from '%s'.\n",_argv[i]);
115         return EXIT_FAILURE;
116       }
117       if(have_base){
118         if(logq_cmp(OC_MODE_LOGQ,OC_MODE_LOGQ_BASE)){
119           fprintf(stderr,
120            "Error: quantizer bins in '%s' do not match previous files.\n",
121            _argv[i]);
122           return EXIT_FAILURE;
123         }
124       }
125       OC_HAS_MODE_METRICS=1;
126     }
127     else{
128       if(fread(OC_MODE_LOGQ_TMP,sizeof(OC_MODE_LOGQ_TMP),1,fmetrics)<1){
129         fprintf(stderr,"Error reading quantizer bins from '%s'.\n",_argv[i]);
130         return EXIT_FAILURE;
131       }
132       if(fread(OC_MODE_METRICS_SATD_TMP,sizeof(OC_MODE_METRICS_SATD_TMP),1,fmetrics)<1){
133         fprintf(stderr,"Error reading SATD metrics from '%s'.\n",_argv[i]);
134         return EXIT_FAILURE;
135       }
136       if(fread(OC_MODE_METRICS_SAD_TMP,sizeof(OC_MODE_METRICS_SAD_TMP),1,fmetrics)<1){
137         fprintf(stderr,"Error reading SAD metrics from '%s'.\n",_argv[i]);
138         return EXIT_FAILURE;
139       }
140       if(logq_cmp(OC_MODE_LOGQ,OC_MODE_LOGQ_TMP)){
141         fprintf(stderr,
142          "Error: quantizer bins in '%s' do not match previous files.\n",
143          _argv[i]);
144         return EXIT_FAILURE;
145       }
146       for(pli=0;pli<3;pli++){
147         for(qti=0;qti<2;qti++){
148           for(qi=0;qi<OC_LOGQ_BINS-1;qi++){
149             for(si=0;si<OC_COMP_BINS;si++){
150               oc_mode_metrics m[3];
151               *(m+0)=*(OC_MODE_METRICS_SATD[qi][pli][qti]+si);
152               *(m+1)=*(OC_MODE_METRICS_SATD_TMP[qi][pli][qti]+si);
153               /*Subtract out the contribution from the base.*/
154               if(have_base){
155                 m[2].w=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].w;
156                 m[2].s=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].s;
157                 m[2].q=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].q;
158                 m[2].r=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].r;
159                 m[2].d=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].d;
160                 m[2].s2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].s2;
161                 m[2].sq=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sq;
162                 m[2].q2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].q2;
163                 m[2].sr=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sr;
164                 m[2].qr=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].qr;
165                 m[2].r2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].r2;
166                 m[2].sd=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sd;
167                 m[2].qd=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].qd;
168                 m[2].d2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].d2;
169                 m[2].s2q=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].s2q;
170                 m[2].sq2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sq2;
171                 m[2].sqr=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sqr;
172                 m[2].sqd=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].sqd;
173                 m[2].s2q2=-OC_MODE_METRICS_SATD_BASE[qi][pli][qti][si].s2q2;
174               }
175               oc_mode_metrics_merge(OC_MODE_METRICS_SATD[qi][pli][qti]+si,
176                m,2+have_base);
177             }
178             for(si=0;si<OC_COMP_BINS;si++){
179               oc_mode_metrics m[3];
180               *(m+0)=*(OC_MODE_METRICS_SAD[qi][pli][qti]+si);
181               *(m+1)=*(OC_MODE_METRICS_SAD_TMP[qi][pli][qti]+si);
182               /*Subtract out the contribution from the base.*/
183               if(have_base){
184                 m[2].w=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].w;
185                 m[2].s=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].s;
186                 m[2].q=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].q;
187                 m[2].r=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].r;
188                 m[2].d=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].d;
189                 m[2].s2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].s2;
190                 m[2].sq=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sq;
191                 m[2].q2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].q2;
192                 m[2].sr=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sr;
193                 m[2].qr=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].qr;
194                 m[2].r2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].r2;
195                 m[2].sd=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sd;
196                 m[2].qd=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].qd;
197                 m[2].d2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].d2;
198                 m[2].s2q=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].s2q;
199                 m[2].sq2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sq2;
200                 m[2].sqr=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sqr;
201                 m[2].sqd=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].sqd;
202                 m[2].s2q2=-OC_MODE_METRICS_SAD_BASE[qi][pli][qti][si].s2q2;
203               }
204               oc_mode_metrics_merge(OC_MODE_METRICS_SAD[qi][pli][qti]+si,
205                m,2+have_base);
206             }
207           }
208         }
209       }
210     }
211     fclose(fmetrics);
212   }
213   /*If the user specified -b but no base stats file, report an error.*/
214   if(want_base){
215     fprintf(stderr,"Error: missing base file argument.\n");
216     OC_HAS_MODE_METRICS=0;
217   }
218   /*If the user specified -o with no file name, or multiple -o's, report an
219      error.*/
220   if(OC_HAS_MODE_METRICS&&want_output){
221     if(have_output)fprintf(stderr,"Error: multiple output file arguments.\n");
222     else fprintf(stderr,"Error: missing output file argument.\n");
223     OC_HAS_MODE_METRICS=0;
224   }
225   if(!OC_HAS_MODE_METRICS){
226     fprintf(stderr,"Usage: %s "
227      "[-b <base.stats>] <in1.stats> [<in2.stats> ...] [-o <out.stats>]\n",
228      _argv[0]);
229     return EXIT_FAILURE;
230   }
231   /*Claim not to have metrics yet so update starts fresh.*/
232   OC_HAS_MODE_METRICS=0;
233   oc_mode_metrics_update(OC_MODE_METRICS_SATD,100,0,
234    OC_MODE_RD_SATD,OC_SATD_SHIFT,OC_MODE_RD_WEIGHT_SATD);
235   oc_mode_metrics_update(OC_MODE_METRICS_SAD,100,0,
236    OC_MODE_RD_SAD,OC_SAD_SHIFT,OC_MODE_RD_WEIGHT_SAD);
237   oc_mode_metrics_print(stdout);
238   if(have_output)oc_mode_metrics_dump();
239   return EXIT_SUCCESS;
240 }