|
1 /* |
|
2 * Copyright 2013 The LibYuv Project Authors. All rights reserved. |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license |
|
5 * that can be found in the LICENSE file in the root of the source |
|
6 * tree. An additional intellectual property rights grant can be found |
|
7 * in the file PATENTS. All contributing project authors may |
|
8 * be found in the AUTHORS file in the root of the source tree. |
|
9 */ |
|
10 |
|
11 // Get PSNR or SSIM for video sequence. Assuming RAW 4:2:0 Y:Cb:Cr format |
|
12 // To build: g++ -O3 -o psnr psnr.cc ssim.cc psnr_main.cc |
|
13 // or VisualC: cl /Ox psnr.cc ssim.cc psnr_main.cc |
|
14 // |
|
15 // To enable OpenMP and SSE2 |
|
16 // gcc: g++ -msse2 -O3 -fopenmp -o psnr psnr.cc ssim.cc psnr_main.cc |
|
17 // vc: cl /arch:SSE2 /Ox /openmp psnr.cc ssim.cc psnr_main.cc |
|
18 // |
|
19 // Usage: psnr org_seq rec_seq -s width height [-skip skip_org skip_rec] |
|
20 |
|
21 #ifndef _CRT_SECURE_NO_WARNINGS |
|
22 #define _CRT_SECURE_NO_WARNINGS |
|
23 #endif |
|
24 |
|
25 #include <stddef.h> |
|
26 #include <stdio.h> |
|
27 #include <stdlib.h> |
|
28 #include <string.h> |
|
29 #ifdef _OPENMP |
|
30 #include <omp.h> |
|
31 #endif |
|
32 |
|
33 #include "./psnr.h" |
|
34 #include "./ssim.h" |
|
35 |
|
36 struct metric { |
|
37 double y, u, v, all; |
|
38 double min_y, min_u, min_v, min_all; |
|
39 double global_y, global_u, global_v, global_all; |
|
40 int min_frame; |
|
41 }; |
|
42 |
|
43 // options |
|
44 bool verbose = false; |
|
45 bool quiet = false; |
|
46 bool show_name = false; |
|
47 bool do_swap_uv = false; |
|
48 bool do_psnr = false; |
|
49 bool do_ssim = false; |
|
50 bool do_mse = false; |
|
51 bool do_lssim = false; |
|
52 int image_width = 0, image_height = 0; |
|
53 int fileindex_org = 0; // argv argument contains the source file name. |
|
54 int fileindex_rec = 0; // argv argument contains the destination file name. |
|
55 int num_rec = 0; |
|
56 int num_skip_org = 0; |
|
57 int num_skip_rec = 0; |
|
58 int num_frames = 0; |
|
59 #ifdef _OPENMP |
|
60 int num_threads = 0; |
|
61 #endif |
|
62 |
|
63 // Parse PYUV format. ie name.1920x800_24Hz_P420.yuv |
|
64 bool ExtractResolutionFromFilename(const char* name, |
|
65 int* width_ptr, |
|
66 int* height_ptr) { |
|
67 // Isolate the .width_height. section of the filename by searching for a |
|
68 // dot or underscore followed by a digit. |
|
69 for (int i = 0; name[i]; ++i) { |
|
70 if ((name[i] == '.' || name[i] == '_') && |
|
71 name[i + 1] >= '0' && name[i + 1] <= '9') { |
|
72 int n = sscanf(name + i + 1, "%dx%d", width_ptr, height_ptr); // NOLINT |
|
73 if (2 == n) { |
|
74 return true; |
|
75 } |
|
76 } |
|
77 } |
|
78 return false; |
|
79 } |
|
80 |
|
81 // Scale Y channel from 16..240 to 0..255. |
|
82 // This can be useful when comparing codecs that are inconsistant about Y |
|
83 uint8 ScaleY(uint8 y) { |
|
84 int ny = (y - 16) * 256 / 224; |
|
85 if (ny < 0) ny = 0; |
|
86 if (ny > 255) ny = 255; |
|
87 return static_cast<uint8>(ny); |
|
88 } |
|
89 |
|
90 // MSE = Mean Square Error |
|
91 double GetMSE(double sse, double size) { |
|
92 return sse / size; |
|
93 } |
|
94 |
|
95 void PrintHelp(const char * program) { |
|
96 printf("%s [-options] org_seq rec_seq [rec_seq2.. etc]\n", program); |
|
97 printf("options:\n"); |
|
98 printf(" -s <width> <height> .... specify YUV size, mandatory if none of the " |
|
99 "sequences have the\n"); |
|
100 printf(" resolution embedded in their filename (ie. " |
|
101 "name.1920x800_24Hz_P420.yuv)\n"); |
|
102 printf(" -psnr .................. compute PSNR (default)\n"); |
|
103 printf(" -ssim .................. compute SSIM\n"); |
|
104 printf(" -mse ................... compute MSE\n"); |
|
105 printf(" -swap .................. Swap U and V plane\n"); |
|
106 printf(" -skip <org> <rec> ...... Number of frame to skip of org and rec\n"); |
|
107 printf(" -frames <num> .......... Number of frames to compare\n"); |
|
108 #ifdef _OPENMP |
|
109 printf(" -t <num> ............... Number of threads\n"); |
|
110 #endif |
|
111 printf(" -n ..................... Show file name\n"); |
|
112 printf(" -v ..................... verbose++\n"); |
|
113 printf(" -q ..................... quiet\n"); |
|
114 printf(" -h ..................... this help\n"); |
|
115 exit(0); |
|
116 } |
|
117 |
|
118 void ParseOptions(int argc, const char* argv[]) { |
|
119 if (argc <= 1) PrintHelp(argv[0]); |
|
120 for (int c = 1; c < argc; ++c) { |
|
121 if (!strcmp(argv[c], "-v")) { |
|
122 verbose = true; |
|
123 } else if (!strcmp(argv[c], "-q")) { |
|
124 quiet = true; |
|
125 } else if (!strcmp(argv[c], "-n")) { |
|
126 show_name = true; |
|
127 } else if (!strcmp(argv[c], "-psnr")) { |
|
128 do_psnr = true; |
|
129 } else if (!strcmp(argv[c], "-mse")) { |
|
130 do_mse = true; |
|
131 } else if (!strcmp(argv[c], "-ssim")) { |
|
132 do_ssim = true; |
|
133 } else if (!strcmp(argv[c], "-lssim")) { |
|
134 do_ssim = true; |
|
135 do_lssim = true; |
|
136 } else if (!strcmp(argv[c], "-swap")) { |
|
137 do_swap_uv = true; |
|
138 } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { |
|
139 PrintHelp(argv[0]); |
|
140 } else if (!strcmp(argv[c], "-s") && c + 2 < argc) { |
|
141 image_width = atoi(argv[++c]); // NOLINT |
|
142 image_height = atoi(argv[++c]); // NOLINT |
|
143 } else if (!strcmp(argv[c], "-skip") && c + 2 < argc) { |
|
144 num_skip_org = atoi(argv[++c]); // NOLINT |
|
145 num_skip_rec = atoi(argv[++c]); // NOLINT |
|
146 } else if (!strcmp(argv[c], "-frames") && c + 1 < argc) { |
|
147 num_frames = atoi(argv[++c]); // NOLINT |
|
148 #ifdef _OPENMP |
|
149 } else if (!strcmp(argv[c], "-t") && c + 1 < argc) { |
|
150 num_threads = atoi(argv[++c]); // NOLINT |
|
151 #endif |
|
152 } else if (argv[c][0] == '-') { |
|
153 fprintf(stderr, "Unknown option. %s\n", argv[c]); |
|
154 } else if (fileindex_org == 0) { |
|
155 fileindex_org = c; |
|
156 } else if (fileindex_rec == 0) { |
|
157 fileindex_rec = c; |
|
158 num_rec = 1; |
|
159 } else { |
|
160 ++num_rec; |
|
161 } |
|
162 } |
|
163 if (fileindex_org == 0 || fileindex_rec == 0) { |
|
164 fprintf(stderr, "Missing filenames\n"); |
|
165 PrintHelp(argv[0]); |
|
166 } |
|
167 if (num_skip_org < 0 || num_skip_rec < 0) { |
|
168 fprintf(stderr, "Skipped frames incorrect\n"); |
|
169 PrintHelp(argv[0]); |
|
170 } |
|
171 if (num_frames < 0) { |
|
172 fprintf(stderr, "Number of frames incorrect\n"); |
|
173 PrintHelp(argv[0]); |
|
174 } |
|
175 if (image_width == 0 || image_height == 0) { |
|
176 int org_width, org_height; |
|
177 int rec_width, rec_height; |
|
178 bool org_res_avail = ExtractResolutionFromFilename(argv[fileindex_org], |
|
179 &org_width, |
|
180 &org_height); |
|
181 bool rec_res_avail = ExtractResolutionFromFilename(argv[fileindex_rec], |
|
182 &rec_width, |
|
183 &rec_height); |
|
184 if (org_res_avail) { |
|
185 if (rec_res_avail) { |
|
186 if ((org_width == rec_width) && (org_height == rec_height)) { |
|
187 image_width = org_width; |
|
188 image_height = org_height; |
|
189 } else { |
|
190 fprintf(stderr, "Sequences have different resolutions.\n"); |
|
191 PrintHelp(argv[0]); |
|
192 } |
|
193 } else { |
|
194 image_width = org_width; |
|
195 image_height = org_height; |
|
196 } |
|
197 } else if (rec_res_avail) { |
|
198 image_width = rec_width; |
|
199 image_height = rec_height; |
|
200 } else { |
|
201 fprintf(stderr, "Missing dimensions.\n"); |
|
202 PrintHelp(argv[0]); |
|
203 } |
|
204 } |
|
205 } |
|
206 |
|
207 bool UpdateMetrics(uint8* ch_org, uint8* ch_rec, |
|
208 const int y_size, const int uv_size, const size_t total_size, |
|
209 int number_of_frames, |
|
210 metric* cur_distortion_psnr, |
|
211 metric* distorted_frame, bool do_psnr) { |
|
212 const int uv_offset = (do_swap_uv ? uv_size : 0); |
|
213 const uint8* const u_org = ch_org + y_size + uv_offset; |
|
214 const uint8* const u_rec = ch_rec + y_size; |
|
215 const uint8* const v_org = ch_org + y_size + (uv_size - uv_offset); |
|
216 const uint8* const v_rec = ch_rec + y_size + uv_size; |
|
217 if (do_psnr) { |
|
218 double y_err = ComputeSumSquareError(ch_org, ch_rec, y_size); |
|
219 double u_err = ComputeSumSquareError(u_org, u_rec, uv_size); |
|
220 double v_err = ComputeSumSquareError(v_org, v_rec, uv_size); |
|
221 const double total_err = y_err + u_err + v_err; |
|
222 cur_distortion_psnr->global_y += y_err; |
|
223 cur_distortion_psnr->global_u += u_err; |
|
224 cur_distortion_psnr->global_v += v_err; |
|
225 cur_distortion_psnr->global_all += total_err; |
|
226 distorted_frame->y = ComputePSNR(y_err, static_cast<double>(y_size)); |
|
227 distorted_frame->u = ComputePSNR(u_err, static_cast<double>(uv_size)); |
|
228 distorted_frame->v = ComputePSNR(v_err, static_cast<double>(uv_size)); |
|
229 distorted_frame->all = ComputePSNR(total_err, |
|
230 static_cast<double>(total_size)); |
|
231 } else { |
|
232 distorted_frame->y = CalcSSIM(ch_org, ch_rec, image_width, image_height); |
|
233 distorted_frame->u = CalcSSIM(u_org, u_rec, image_width / 2, |
|
234 image_height / 2); |
|
235 distorted_frame->v = CalcSSIM(v_org, v_rec, image_width / 2, |
|
236 image_height / 2); |
|
237 distorted_frame->all = |
|
238 (distorted_frame->y + distorted_frame->u + distorted_frame->v) |
|
239 / total_size; |
|
240 distorted_frame->y /= y_size; |
|
241 distorted_frame->u /= uv_size; |
|
242 distorted_frame->v /= uv_size; |
|
243 |
|
244 if (do_lssim) { |
|
245 distorted_frame->all = CalcLSSIM(distorted_frame->all); |
|
246 distorted_frame->y = CalcLSSIM(distorted_frame->y); |
|
247 distorted_frame->u = CalcLSSIM(distorted_frame->u); |
|
248 distorted_frame->v = CalcLSSIM(distorted_frame->v); |
|
249 } |
|
250 } |
|
251 |
|
252 cur_distortion_psnr->y += distorted_frame->y; |
|
253 cur_distortion_psnr->u += distorted_frame->u; |
|
254 cur_distortion_psnr->v += distorted_frame->v; |
|
255 cur_distortion_psnr->all += distorted_frame->all; |
|
256 |
|
257 bool ismin = false; |
|
258 if (distorted_frame->y < cur_distortion_psnr->min_y) |
|
259 cur_distortion_psnr->min_y = distorted_frame->y; |
|
260 if (distorted_frame->u < cur_distortion_psnr->min_u) |
|
261 cur_distortion_psnr->min_u = distorted_frame->u; |
|
262 if (distorted_frame->v < cur_distortion_psnr->min_v) |
|
263 cur_distortion_psnr->min_v = distorted_frame->v; |
|
264 if (distorted_frame->all < cur_distortion_psnr->min_all) { |
|
265 cur_distortion_psnr->min_all = distorted_frame->all; |
|
266 cur_distortion_psnr->min_frame = number_of_frames; |
|
267 ismin = true; |
|
268 } |
|
269 return ismin; |
|
270 } |
|
271 |
|
272 int main(int argc, const char* argv[]) { |
|
273 ParseOptions(argc, argv); |
|
274 if (!do_psnr && !do_ssim) { |
|
275 do_psnr = true; |
|
276 } |
|
277 |
|
278 #ifdef _OPENMP |
|
279 if (num_threads) { |
|
280 omp_set_num_threads(num_threads); |
|
281 } |
|
282 if (verbose) { |
|
283 printf("OpenMP %d procs\n", omp_get_num_procs()); |
|
284 } |
|
285 #endif |
|
286 // Open original file (first file argument) |
|
287 FILE* const file_org = fopen(argv[fileindex_org], "rb"); |
|
288 if (file_org == NULL) { |
|
289 fprintf(stderr, "Cannot open %s\n", argv[fileindex_org]); |
|
290 exit(1); |
|
291 } |
|
292 |
|
293 // Open all files to compare to |
|
294 FILE** file_rec = new FILE* [num_rec]; |
|
295 memset(file_rec, 0, num_rec * sizeof(FILE*)); // NOLINT |
|
296 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
297 file_rec[cur_rec] = fopen(argv[fileindex_rec + cur_rec], "rb"); |
|
298 if (file_rec[cur_rec] == NULL) { |
|
299 fprintf(stderr, "Cannot open %s\n", argv[fileindex_rec + cur_rec]); |
|
300 fclose(file_org); |
|
301 for (int i = 0; i < cur_rec; ++i) { |
|
302 fclose(file_rec[i]); |
|
303 } |
|
304 delete[] file_rec; |
|
305 exit(1); |
|
306 } |
|
307 } |
|
308 |
|
309 const int y_size = image_width * image_height; |
|
310 const int uv_size = ((image_width + 1) / 2) * ((image_height + 1) / 2); |
|
311 const size_t total_size = y_size + 2 * uv_size; // NOLINT |
|
312 #if defined(_MSC_VER) |
|
313 _fseeki64(file_org, |
|
314 static_cast<__int64>(num_skip_org) * |
|
315 static_cast<__int64>(total_size), SEEK_SET); |
|
316 #else |
|
317 fseek(file_org, num_skip_org * total_size, SEEK_SET); |
|
318 #endif |
|
319 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
320 #if defined(_MSC_VER) |
|
321 _fseeki64(file_rec[cur_rec], |
|
322 static_cast<__int64>(num_skip_rec) * |
|
323 static_cast<__int64>(total_size), |
|
324 SEEK_SET); |
|
325 #else |
|
326 fseek(file_rec[cur_rec], num_skip_rec * total_size, SEEK_SET); |
|
327 #endif |
|
328 } |
|
329 |
|
330 uint8* const ch_org = new uint8[total_size]; |
|
331 uint8* const ch_rec = new uint8[total_size]; |
|
332 if (ch_org == NULL || ch_rec == NULL) { |
|
333 fprintf(stderr, "No memory available\n"); |
|
334 fclose(file_org); |
|
335 for (int i = 0; i < num_rec; ++i) { |
|
336 fclose(file_rec[i]); |
|
337 } |
|
338 delete[] ch_org; |
|
339 delete[] ch_rec; |
|
340 delete[] file_rec; |
|
341 exit(1); |
|
342 } |
|
343 |
|
344 metric* const distortion_psnr = new metric[num_rec]; |
|
345 metric* const distortion_ssim = new metric[num_rec]; |
|
346 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
347 metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; |
|
348 cur_distortion_psnr->y = 0.0; |
|
349 cur_distortion_psnr->u = 0.0; |
|
350 cur_distortion_psnr->v = 0.0; |
|
351 cur_distortion_psnr->all = 0.0; |
|
352 cur_distortion_psnr->min_y = kMaxPSNR; |
|
353 cur_distortion_psnr->min_u = kMaxPSNR; |
|
354 cur_distortion_psnr->min_v = kMaxPSNR; |
|
355 cur_distortion_psnr->min_all = kMaxPSNR; |
|
356 cur_distortion_psnr->min_frame = 0; |
|
357 cur_distortion_psnr->global_y = 0.0; |
|
358 cur_distortion_psnr->global_u = 0.0; |
|
359 cur_distortion_psnr->global_v = 0.0; |
|
360 cur_distortion_psnr->global_all = 0.0; |
|
361 distortion_ssim[cur_rec] = cur_distortion_psnr[cur_rec]; |
|
362 } |
|
363 |
|
364 if (verbose) { |
|
365 printf("Size: %dx%d\n", image_width, image_height); |
|
366 } |
|
367 |
|
368 if (!quiet) { |
|
369 printf("Frame"); |
|
370 if (do_psnr) { |
|
371 printf("\t PSNR-Y \t PSNR-U \t PSNR-V \t PSNR-All \t Frame"); |
|
372 } |
|
373 if (do_ssim) { |
|
374 printf("\t SSIM-Y\t SSIM-U\t SSIM-V\t SSIM-All\t Frame"); |
|
375 } |
|
376 if (show_name) { |
|
377 printf("\tName\n"); |
|
378 } else { |
|
379 printf("\n"); |
|
380 } |
|
381 } |
|
382 |
|
383 int number_of_frames; |
|
384 for (number_of_frames = 0; ; ++number_of_frames) { |
|
385 if (num_frames && number_of_frames >= num_frames) |
|
386 break; |
|
387 |
|
388 size_t bytes_org = fread(ch_org, sizeof(uint8), total_size, file_org); |
|
389 if (bytes_org < total_size) |
|
390 break; |
|
391 |
|
392 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
393 size_t bytes_rec = fread(ch_rec, sizeof(uint8), |
|
394 total_size, file_rec[cur_rec]); |
|
395 if (bytes_rec < total_size) |
|
396 break; |
|
397 |
|
398 if (verbose) { |
|
399 printf("%5d", number_of_frames); |
|
400 } |
|
401 if (do_psnr) { |
|
402 metric distorted_frame; |
|
403 metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; |
|
404 bool ismin = UpdateMetrics(ch_org, ch_rec, |
|
405 y_size, uv_size, total_size, |
|
406 number_of_frames, |
|
407 cur_distortion_psnr, |
|
408 &distorted_frame, true); |
|
409 if (verbose) { |
|
410 printf("\t%10.6f", distorted_frame.y); |
|
411 printf("\t%10.6f", distorted_frame.u); |
|
412 printf("\t%10.6f", distorted_frame.v); |
|
413 printf("\t%10.6f", distorted_frame.all); |
|
414 printf("\t%5s", ismin ? "min" : ""); |
|
415 } |
|
416 } |
|
417 if (do_ssim) { |
|
418 metric distorted_frame; |
|
419 metric* cur_distortion_ssim = &distortion_ssim[cur_rec]; |
|
420 bool ismin = UpdateMetrics(ch_org, ch_rec, |
|
421 y_size, uv_size, total_size, |
|
422 number_of_frames, |
|
423 cur_distortion_ssim, |
|
424 &distorted_frame, false); |
|
425 if (verbose) { |
|
426 printf("\t%10.6f", distorted_frame.y); |
|
427 printf("\t%10.6f", distorted_frame.u); |
|
428 printf("\t%10.6f", distorted_frame.v); |
|
429 printf("\t%10.6f", distorted_frame.all); |
|
430 printf("\t%5s", ismin ? "min" : ""); |
|
431 } |
|
432 } |
|
433 if (verbose) { |
|
434 if (show_name) { |
|
435 printf("\t%s", argv[fileindex_rec + cur_rec]); |
|
436 } |
|
437 printf("\n"); |
|
438 } |
|
439 } |
|
440 } |
|
441 |
|
442 // Final PSNR computation. |
|
443 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
444 metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; |
|
445 metric* cur_distortion_ssim = &distortion_ssim[cur_rec]; |
|
446 if (number_of_frames > 0) { |
|
447 const double norm = 1. / static_cast<double>(number_of_frames); |
|
448 cur_distortion_psnr->y *= norm; |
|
449 cur_distortion_psnr->u *= norm; |
|
450 cur_distortion_psnr->v *= norm; |
|
451 cur_distortion_psnr->all *= norm; |
|
452 cur_distortion_ssim->y *= norm; |
|
453 cur_distortion_ssim->u *= norm; |
|
454 cur_distortion_ssim->v *= norm; |
|
455 cur_distortion_ssim->all *= norm; |
|
456 } |
|
457 |
|
458 if (do_psnr) { |
|
459 const double global_psnr_y = ComputePSNR( |
|
460 cur_distortion_psnr->global_y, |
|
461 static_cast<double>(y_size) * number_of_frames); |
|
462 const double global_psnr_u = ComputePSNR( |
|
463 cur_distortion_psnr->global_u, |
|
464 static_cast<double>(uv_size) * number_of_frames); |
|
465 const double global_psnr_v = ComputePSNR( |
|
466 cur_distortion_psnr->global_v, |
|
467 static_cast<double>(uv_size) * number_of_frames); |
|
468 const double global_psnr_all = ComputePSNR( |
|
469 cur_distortion_psnr->global_all, |
|
470 static_cast<double>(total_size) * number_of_frames); |
|
471 printf("Global:\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
472 global_psnr_y, |
|
473 global_psnr_u, |
|
474 global_psnr_v, |
|
475 global_psnr_all, |
|
476 number_of_frames); |
|
477 if (show_name) { |
|
478 printf("\t%s", argv[fileindex_rec + cur_rec]); |
|
479 } |
|
480 printf("\n"); |
|
481 } |
|
482 |
|
483 if (!quiet) { |
|
484 printf("Avg:"); |
|
485 if (do_psnr) { |
|
486 printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
487 cur_distortion_psnr->y, |
|
488 cur_distortion_psnr->u, |
|
489 cur_distortion_psnr->v, |
|
490 cur_distortion_psnr->all, |
|
491 number_of_frames); |
|
492 } |
|
493 if (do_ssim) { |
|
494 printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
495 cur_distortion_ssim->y, |
|
496 cur_distortion_ssim->u, |
|
497 cur_distortion_ssim->v, |
|
498 cur_distortion_ssim->all, |
|
499 number_of_frames); |
|
500 } |
|
501 if (show_name) { |
|
502 printf("\t%s", argv[fileindex_rec + cur_rec]); |
|
503 } |
|
504 printf("\n"); |
|
505 } |
|
506 if (!quiet) { |
|
507 printf("Min:"); |
|
508 if (do_psnr) { |
|
509 printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
510 cur_distortion_psnr->min_y, |
|
511 cur_distortion_psnr->min_u, |
|
512 cur_distortion_psnr->min_v, |
|
513 cur_distortion_psnr->min_all, |
|
514 cur_distortion_psnr->min_frame); |
|
515 } |
|
516 if (do_ssim) { |
|
517 printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
518 cur_distortion_ssim->min_y, |
|
519 cur_distortion_ssim->min_u, |
|
520 cur_distortion_ssim->min_v, |
|
521 cur_distortion_ssim->min_all, |
|
522 cur_distortion_ssim->min_frame); |
|
523 } |
|
524 if (show_name) { |
|
525 printf("\t%s", argv[fileindex_rec + cur_rec]); |
|
526 } |
|
527 printf("\n"); |
|
528 } |
|
529 |
|
530 if (do_mse) { |
|
531 double global_mse_y = GetMSE(cur_distortion_psnr->global_y, |
|
532 static_cast<double>(y_size) * number_of_frames); |
|
533 double global_mse_u = GetMSE(cur_distortion_psnr->global_u, |
|
534 static_cast<double>(uv_size) * number_of_frames); |
|
535 double global_mse_v = GetMSE(cur_distortion_psnr->global_v, |
|
536 static_cast<double>(uv_size) * number_of_frames); |
|
537 double global_mse_all = GetMSE(cur_distortion_psnr->global_all, |
|
538 static_cast<double>(total_size) * number_of_frames); |
|
539 printf("MSE:\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", |
|
540 global_mse_y, |
|
541 global_mse_u, |
|
542 global_mse_v, |
|
543 global_mse_all, |
|
544 number_of_frames); |
|
545 if (show_name) { |
|
546 printf("\t%s", argv[fileindex_rec + cur_rec]); |
|
547 } |
|
548 printf("\n"); |
|
549 } |
|
550 } |
|
551 fclose(file_org); |
|
552 for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { |
|
553 fclose(file_rec[cur_rec]); |
|
554 } |
|
555 delete[] distortion_psnr; |
|
556 delete[] distortion_ssim; |
|
557 delete[] ch_org; |
|
558 delete[] ch_rec; |
|
559 delete[] file_rec; |
|
560 return 0; |
|
561 } |