1 /* stats.c, coding statistics */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6 * Disclaimer of Warranty
7 *
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
15 *
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
18 *
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
21 * patents.
22 *
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
26 * design.
27 *
28 */
29
30 #include <stdio.h>
31 #include <math.h>
32 #include "mpeg2enc_config.h"
33 #include "mpeg2enc_global.h"
34
35 /* private prototypes */
36 static void MPEG2_calcSNR1 _ANSI_ARGS_((unsigned char *org, unsigned char *rec,
37 int lx, int w, int h, double *pv, double *pe));
38
39
MPEG2_calcSNR(org,rec,mpeg2_struct)40 void MPEG2_calcSNR(org,rec,mpeg2_struct)
41 unsigned char *org[3];
42 unsigned char *rec[3];
43 struct MPEG2_structure *mpeg2_struct;
44 {
45 int w,h,offs;
46 double v,e;
47
48 w = mpeg2_struct->horizontal_size;
49 h = (mpeg2_struct->pict_struct==FRAME_PICTURE) ? mpeg2_struct->vertical_size : (mpeg2_struct->vertical_size>>1);
50 offs = (mpeg2_struct->pict_struct==BOTTOM_FIELD) ? mpeg2_struct->width : 0;
51
52 MPEG2_calcSNR1(org[0]+offs,rec[0]+offs,mpeg2_struct->width2,w,h,&v,&e);
53 if ( mpeg2_struct->statfile )
54 {
55 fprintf(mpeg2_struct->statfile,"Y: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
56 v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
57 }
58
59 if (mpeg2_struct->chroma_format!=CHROMA444)
60 {
61 w >>= 1;
62 offs >>= 1;
63 }
64
65 if (mpeg2_struct->chroma_format==CHROMA420)
66 h >>= 1;
67
68 MPEG2_calcSNR1(org[1]+offs,rec[1]+offs,mpeg2_struct->chrom_width2,w,h,&v,&e);
69 if ( mpeg2_struct->statfile )
70 {
71 fprintf(mpeg2_struct->statfile,"U: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
72 v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
73 }
74
75 MPEG2_calcSNR1(org[2]+offs,rec[2]+offs,mpeg2_struct->chrom_width2,w,h,&v,&e);
76 if ( mpeg2_struct->statfile )
77 {
78 fprintf(mpeg2_struct->statfile,"V: variance=%4.4g, MSE=%3.3g (%3.3g dB), SNR=%3.3g dB\n",
79 v, e, 10.0*log10(255.0*255.0/e), 10.0*log10(v/e));
80 }
81 }
82
MPEG2_calcSNR1(org,rec,lx,w,h,pv,pe)83 static void MPEG2_calcSNR1(org,rec,lx,w,h,pv,pe)
84 unsigned char *org;
85 unsigned char *rec;
86 int lx,w,h;
87 double *pv,*pe;
88 {
89 int i, j;
90 double v1, s1, s2, e2;
91
92 s1 = s2 = e2 = 0.0;
93
94 for (j=0; j<h; j++)
95 {
96 for (i=0; i<w; i++)
97 {
98 v1 = org[i];
99 s1+= v1;
100 s2+= v1*v1;
101 v1-= rec[i];
102 e2+= v1*v1;
103 }
104 org += lx;
105 rec += lx;
106 }
107
108 s1 /= w*h;
109 s2 /= w*h;
110 e2 /= w*h;
111
112 /* prevent division by zero in calcSNR() */
113 if(e2==0.0)
114 e2 = 0.00001;
115
116 *pv = s2 - s1*s1; /* variance */
117 *pe = e2; /* MSE */
118 }
119
MPEG2_stats(mpeg2_struct)120 void MPEG2_stats(mpeg2_struct)
121 struct MPEG2_structure *mpeg2_struct;
122 {
123 int i, j, k, nmb, mb_type;
124 int n_skipped, n_intra, n_ncoded, n_blocks, n_interp, n_forward, n_backward;
125 struct mbinfo *mbi;
126
127 nmb = mpeg2_struct->mb_width*mpeg2_struct->mb_height2;
128
129 n_skipped=n_intra=n_ncoded=n_blocks=n_interp=n_forward=n_backward=0;
130
131 for (k=0; k<nmb; k++)
132 {
133 mbi = mpeg2_struct->mbinfo+k;
134 if (mbi->skipped)
135 n_skipped++;
136 else if (mbi->mb_type & MB_INTRA)
137 n_intra++;
138 else if (!(mbi->mb_type & MB_PATTERN))
139 n_ncoded++;
140
141 for (i=0; i<mpeg2_struct->block_count; i++)
142 if (mbi->cbp & (1<<i))
143 n_blocks++;
144
145 if (mbi->mb_type & MB_FORWARD)
146 {
147 if (mbi->mb_type & MB_BACKWARD)
148 n_interp++;
149 else
150 n_forward++;
151 }
152 else if (mbi->mb_type & MB_BACKWARD)
153 n_backward++;
154 }
155
156 if ( mpeg2_struct->statfile )
157 {
158 fprintf(mpeg2_struct->statfile,"\npicture statistics:\n");
159 fprintf(mpeg2_struct->statfile," # of intra coded macroblocks: %4d (%.1f%%)\n",
160 n_intra,100.0*(double)n_intra/nmb);
161 fprintf(mpeg2_struct->statfile," # of coded blocks: %4d (%.1f%%)\n",
162 n_blocks,100.0*(double)n_blocks/(mpeg2_struct->block_count*nmb));
163 fprintf(mpeg2_struct->statfile," # of not coded macroblocks: %4d (%.1f%%)\n",
164 n_ncoded,100.0*(double)n_ncoded/nmb);
165 fprintf(mpeg2_struct->statfile," # of skipped macroblocks: %4d (%.1f%%)\n",
166 n_skipped,100.0*(double)n_skipped/nmb);
167 fprintf(mpeg2_struct->statfile," # of forw. pred. macroblocks: %4d (%.1f%%)\n",
168 n_forward,100.0*(double)n_forward/nmb);
169 fprintf(mpeg2_struct->statfile," # of backw. pred. macroblocks: %4d (%.1f%%)\n",
170 n_backward,100.0*(double)n_backward/nmb);
171 fprintf(mpeg2_struct->statfile," # of interpolated macroblocks: %4d (%.1f%%)\n",
172 n_interp,100.0*(double)n_interp/nmb);
173
174 fprintf(mpeg2_struct->statfile,"\nmacroblock_type map:\n");
175
176 k = 0;
177
178 for (j=0; j<mpeg2_struct->mb_height2; j++)
179 {
180 for (i=0; i<mpeg2_struct->mb_width; i++)
181 {
182 mbi = mpeg2_struct->mbinfo + k;
183 mb_type = mbi->mb_type;
184 if (mbi->skipped)
185 putc('S',mpeg2_struct->statfile);
186 else if (mb_type & MB_INTRA)
187 putc('I',mpeg2_struct->statfile);
188 else switch (mb_type & (MB_FORWARD|MB_BACKWARD))
189 {
190 case MB_FORWARD:
191 putc(mbi->motion_type==MC_FIELD ? 'f' :
192 mbi->motion_type==MC_DMV ? 'p' :
193 'F',mpeg2_struct->statfile); break;
194 case MB_BACKWARD:
195 putc(mbi->motion_type==MC_FIELD ? 'b' :
196 'B',mpeg2_struct->statfile); break;
197 case MB_FORWARD|MB_BACKWARD:
198 putc(mbi->motion_type==MC_FIELD ? 'd' :
199 'D',mpeg2_struct->statfile); break;
200 default:
201 putc('0',mpeg2_struct->statfile); break;
202 }
203
204 if (mb_type & MB_QUANT)
205 putc('Q',mpeg2_struct->statfile);
206 else if (mb_type & (MB_PATTERN|MB_INTRA))
207 putc(' ',mpeg2_struct->statfile);
208 else
209 putc('N',mpeg2_struct->statfile);
210
211 putc(' ',mpeg2_struct->statfile);
212
213 k++;
214 }
215 putc('\n',mpeg2_struct->statfile);
216 }
217
218 fprintf(mpeg2_struct->statfile,"\nmquant map:\n");
219
220 k=0;
221 for (j=0; j<mpeg2_struct->mb_height2; j++)
222 {
223 for (i=0; i<mpeg2_struct->mb_width; i++)
224 {
225 if (i==0 || mpeg2_struct->mbinfo[k].mquant!=mpeg2_struct->mbinfo[k-1].mquant)
226 fprintf(mpeg2_struct->statfile,"%3d",mpeg2_struct->mbinfo[k].mquant);
227 else
228 fprintf(mpeg2_struct->statfile," ");
229
230 k++;
231 }
232 putc('\n',mpeg2_struct->statfile);
233 }
234
235 #if 0
236 fprintf(mpeg2_struct->statfile,"\ncbp map:\n");
237
238 k=0;
239 for (j=0; j<mpeg2_struct->mb_height2; j++)
240 {
241 for (i=0; i<mpeg2_struct->mb_width; i++)
242 {
243 fprintf(mpeg2_struct->statfile,"%02x ",mpeg2_struct->mbinfo[k].cbp);
244
245 k++;
246 }
247 putc('\n',mpeg2_struct->statfile);
248 }
249
250 if (mpeg2_struct->pict_struct==FRAME_PICTURE && !mpeg2_struct->frame_pred_dct)
251 {
252 fprintf(mpeg2_struct->statfile,"\ndct_type map:\n");
253
254 k=0;
255 for (j=0; j<mpeg2_struct->mb_height2; j++)
256 {
257 for (i=0; i<mpeg2_struct->mb_width; i++)
258 {
259 if (mpeg2_struct->mbinfo[k].mb_type & (MB_PATTERN|MB_INTRA))
260 fprintf(mpeg2_struct->statfile,"%d ",mpeg2_struct->mbinfo[k].dct_type);
261 else
262 fprintf(mpeg2_struct->statfile," ");
263
264 k++;
265 }
266 putc('\n',mpeg2_struct->statfile);
267 }
268 }
269
270 if (mpeg2_struct->pict_type!=I_TYPE)
271 {
272 fprintf(mpeg2_struct->statfile,"\nforward motion vectors (first vector, horizontal):\n");
273
274 k=0;
275 for (j=0; j<mpeg2_struct->mb_height2; j++)
276 {
277 for (i=0; i<mpeg2_struct->mb_width; i++)
278 {
279 if (mpeg2_struct->mbinfo[k].mb_type & MB_FORWARD)
280 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[0][0][0]);
281 else
282 fprintf(mpeg2_struct->statfile," .");
283
284 k++;
285 }
286 putc('\n',mpeg2_struct->statfile);
287 }
288
289 fprintf(mpeg2_struct->statfile,"\nforward motion vectors (first vector, vertical):\n");
290
291 k=0;
292 for (j=0; j<mpeg2_struct->mb_height2; j++)
293 {
294 for (i=0; i<mpeg2_struct->mb_width; i++)
295 {
296 if (mpeg2_struct->mbinfo[k].mb_type & MB_FORWARD)
297 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[0][0][1]);
298 else
299 fprintf(mpeg2_struct->statfile," .");
300
301 k++;
302 }
303 putc('\n',mpeg2_struct->statfile);
304 }
305
306 fprintf(mpeg2_struct->statfile,"\nforward motion vectors (second vector, horizontal):\n");
307
308 k=0;
309 for (j=0; j<mpeg2_struct->mb_height2; j++)
310 {
311 for (i=0; i<mpeg2_struct->mb_width; i++)
312 {
313 if (mpeg2_struct->mbinfo[k].mb_type & MB_FORWARD
314 && ((mpeg2_struct->pict_struct==FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_FIELD) ||
315 (mpeg2_struct->pict_struct!=FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_16X8)))
316 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[1][0][0]);
317 else
318 fprintf(mpeg2_struct->statfile," .");
319
320 k++;
321 }
322 putc('\n',mpeg2_struct->statfile);
323 }
324
325 fprintf(mpeg2_struct->statfile,"\nforward motion vectors (second vector, vertical):\n");
326
327 k=0;
328 for (j=0; j<mpeg2_struct->mb_height2; j++)
329 {
330 for (i=0; i<mpeg2_struct->mb_width; i++)
331 {
332 if (mpeg2_struct->mbinfo[k].mb_type & MB_FORWARD
333 && ((mpeg2_struct->pict_struct==FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_FIELD) ||
334 (mpeg2_struct->pict_struct!=FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_16X8)))
335 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[1][0][1]);
336 else
337 fprintf(mpeg2_struct->statfile," .");
338
339 k++;
340 }
341 putc('\n',mpeg2_struct->statfile);
342 }
343
344
345 }
346
347 if (mpeg2_struct->pict_type==B_TYPE)
348 {
349 fprintf(mpeg2_struct->statfile,"\nbackward motion vectors (first vector, horizontal):\n");
350
351 k=0;
352 for (j=0; j<mpeg2_struct->mb_height2; j++)
353 {
354 for (i=0; i<mpeg2_struct->mb_width; i++)
355 {
356 if (mpeg2_struct->mbinfo[k].mb_type & MB_BACKWARD)
357 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[0][1][0]);
358 else
359 fprintf(mpeg2_struct->statfile," .");
360
361 k++;
362 }
363 putc('\n',mpeg2_struct->statfile);
364 }
365
366 fprintf(mpeg2_struct->statfile,"\nbackward motion vectors (first vector, vertical):\n");
367
368 k=0;
369 for (j=0; j<mpeg2_struct->mb_height2; j++)
370 {
371 for (i=0; i<mpeg2_struct->mb_width; i++)
372 {
373 if (mpeg2_struct->mbinfo[k].mb_type & MB_BACKWARD)
374 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[0][1][1]);
375 else
376 fprintf(mpeg2_struct->statfile," .");
377
378 k++;
379 }
380 putc('\n',mpeg2_struct->statfile);
381 }
382
383 fprintf(mpeg2_struct->statfile,"\nbackward motion vectors (second vector, horizontal):\n");
384
385 k=0;
386 for (j=0; j<mpeg2_struct->mb_height2; j++)
387 {
388 for (i=0; i<mpeg2_struct->mb_width; i++)
389 {
390 if (mpeg2_struct->mbinfo[k].mb_type & MB_BACKWARD
391 && ((mpeg2_struct->pict_struct==FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_FIELD) ||
392 (mpeg2_struct->pict_struct!=FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_16X8)))
393 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[1][1][0]);
394 else
395 fprintf(mpeg2_struct->statfile," .");
396
397 k++;
398 }
399 putc('\n',mpeg2_struct->statfile);
400 }
401
402 fprintf(mpeg2_struct->statfile,"\nbackward motion vectors (second vector, vertical):\n");
403
404 k=0;
405 for (j=0; j<mpeg2_struct->mb_height2; j++)
406 {
407 for (i=0; i<mpeg2_struct->mb_width; i++)
408 {
409 if (mpeg2_struct->mbinfo[k].mb_type & MB_BACKWARD
410 && ((mpeg2_struct->pict_struct==FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_FIELD) ||
411 (mpeg2_struct->pict_struct!=FRAME_PICTURE && mpeg2_struct->mbinfo[k].motion_type==MC_16X8)))
412 fprintf(mpeg2_struct->statfile,"%4d",mpeg2_struct->mbinfo[k].MV[1][1][1]);
413 else
414 fprintf(mpeg2_struct->statfile," .");
415
416 k++;
417 }
418 putc('\n',mpeg2_struct->statfile);
419 }
420
421
422 }
423 #endif
424
425 #if 0
426 /* useful for debugging */
427 fprintf(mpeg2_struct->statfile,"\nmacroblock info dump:\n");
428
429 k=0;
430 for (j=0; j<mpeg2_struct->mb_height2; j++)
431 {
432 for (i=0; i<mpeg2_struct->mb_width; i++)
433 {
434 fprintf(mpeg2_struct->statfile,"%d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
435 k,
436 mpeg2_struct->mbinfo[k].mb_type,
437 mpeg2_struct->mbinfo[k].motion_type,
438 mpeg2_struct->mbinfo[k].dct_type,
439 mpeg2_struct->mbinfo[k].mquant,
440 mpeg2_struct->mbinfo[k].cbp,
441 mpeg2_struct->mbinfo[k].skipped,
442 mpeg2_struct->mbinfo[k].MV[0][0][0],
443 mpeg2_struct->mbinfo[k].MV[0][0][1],
444 mpeg2_struct->mbinfo[k].MV[0][1][0],
445 mpeg2_struct->mbinfo[k].MV[0][1][1],
446 mpeg2_struct->mbinfo[k].MV[1][0][0],
447 mpeg2_struct->mbinfo[k].MV[1][0][1],
448 mpeg2_struct->mbinfo[k].MV[1][1][0],
449 mpeg2_struct->mbinfo[k].MV[1][1][1],
450 mpeg2_struct->mbinfo[k].mv_field_sel[0][0],
451 mpeg2_struct->mbinfo[k].mv_field_sel[0][1],
452 mpeg2_struct->mbinfo[k].mv_field_sel[1][0],
453 mpeg2_struct->mbinfo[k].mv_field_sel[1][1]);
454
455 k++;
456 }
457 }
458 #endif
459 }
460 }
461