1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libyuv/util/psnr_main.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,561 @@ 1.4 +/* 1.5 + * Copyright 2013 The LibYuv Project Authors. All rights reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 +// Get PSNR or SSIM for video sequence. Assuming RAW 4:2:0 Y:Cb:Cr format 1.15 +// To build: g++ -O3 -o psnr psnr.cc ssim.cc psnr_main.cc 1.16 +// or VisualC: cl /Ox psnr.cc ssim.cc psnr_main.cc 1.17 +// 1.18 +// To enable OpenMP and SSE2 1.19 +// gcc: g++ -msse2 -O3 -fopenmp -o psnr psnr.cc ssim.cc psnr_main.cc 1.20 +// vc: cl /arch:SSE2 /Ox /openmp psnr.cc ssim.cc psnr_main.cc 1.21 +// 1.22 +// Usage: psnr org_seq rec_seq -s width height [-skip skip_org skip_rec] 1.23 + 1.24 +#ifndef _CRT_SECURE_NO_WARNINGS 1.25 +#define _CRT_SECURE_NO_WARNINGS 1.26 +#endif 1.27 + 1.28 +#include <stddef.h> 1.29 +#include <stdio.h> 1.30 +#include <stdlib.h> 1.31 +#include <string.h> 1.32 +#ifdef _OPENMP 1.33 +#include <omp.h> 1.34 +#endif 1.35 + 1.36 +#include "./psnr.h" 1.37 +#include "./ssim.h" 1.38 + 1.39 +struct metric { 1.40 + double y, u, v, all; 1.41 + double min_y, min_u, min_v, min_all; 1.42 + double global_y, global_u, global_v, global_all; 1.43 + int min_frame; 1.44 +}; 1.45 + 1.46 +// options 1.47 +bool verbose = false; 1.48 +bool quiet = false; 1.49 +bool show_name = false; 1.50 +bool do_swap_uv = false; 1.51 +bool do_psnr = false; 1.52 +bool do_ssim = false; 1.53 +bool do_mse = false; 1.54 +bool do_lssim = false; 1.55 +int image_width = 0, image_height = 0; 1.56 +int fileindex_org = 0; // argv argument contains the source file name. 1.57 +int fileindex_rec = 0; // argv argument contains the destination file name. 1.58 +int num_rec = 0; 1.59 +int num_skip_org = 0; 1.60 +int num_skip_rec = 0; 1.61 +int num_frames = 0; 1.62 +#ifdef _OPENMP 1.63 +int num_threads = 0; 1.64 +#endif 1.65 + 1.66 +// Parse PYUV format. ie name.1920x800_24Hz_P420.yuv 1.67 +bool ExtractResolutionFromFilename(const char* name, 1.68 + int* width_ptr, 1.69 + int* height_ptr) { 1.70 + // Isolate the .width_height. section of the filename by searching for a 1.71 + // dot or underscore followed by a digit. 1.72 + for (int i = 0; name[i]; ++i) { 1.73 + if ((name[i] == '.' || name[i] == '_') && 1.74 + name[i + 1] >= '0' && name[i + 1] <= '9') { 1.75 + int n = sscanf(name + i + 1, "%dx%d", width_ptr, height_ptr); // NOLINT 1.76 + if (2 == n) { 1.77 + return true; 1.78 + } 1.79 + } 1.80 + } 1.81 + return false; 1.82 +} 1.83 + 1.84 +// Scale Y channel from 16..240 to 0..255. 1.85 +// This can be useful when comparing codecs that are inconsistant about Y 1.86 +uint8 ScaleY(uint8 y) { 1.87 + int ny = (y - 16) * 256 / 224; 1.88 + if (ny < 0) ny = 0; 1.89 + if (ny > 255) ny = 255; 1.90 + return static_cast<uint8>(ny); 1.91 +} 1.92 + 1.93 +// MSE = Mean Square Error 1.94 +double GetMSE(double sse, double size) { 1.95 + return sse / size; 1.96 +} 1.97 + 1.98 +void PrintHelp(const char * program) { 1.99 + printf("%s [-options] org_seq rec_seq [rec_seq2.. etc]\n", program); 1.100 + printf("options:\n"); 1.101 + printf(" -s <width> <height> .... specify YUV size, mandatory if none of the " 1.102 + "sequences have the\n"); 1.103 + printf(" resolution embedded in their filename (ie. " 1.104 + "name.1920x800_24Hz_P420.yuv)\n"); 1.105 + printf(" -psnr .................. compute PSNR (default)\n"); 1.106 + printf(" -ssim .................. compute SSIM\n"); 1.107 + printf(" -mse ................... compute MSE\n"); 1.108 + printf(" -swap .................. Swap U and V plane\n"); 1.109 + printf(" -skip <org> <rec> ...... Number of frame to skip of org and rec\n"); 1.110 + printf(" -frames <num> .......... Number of frames to compare\n"); 1.111 +#ifdef _OPENMP 1.112 + printf(" -t <num> ............... Number of threads\n"); 1.113 +#endif 1.114 + printf(" -n ..................... Show file name\n"); 1.115 + printf(" -v ..................... verbose++\n"); 1.116 + printf(" -q ..................... quiet\n"); 1.117 + printf(" -h ..................... this help\n"); 1.118 + exit(0); 1.119 +} 1.120 + 1.121 +void ParseOptions(int argc, const char* argv[]) { 1.122 + if (argc <= 1) PrintHelp(argv[0]); 1.123 + for (int c = 1; c < argc; ++c) { 1.124 + if (!strcmp(argv[c], "-v")) { 1.125 + verbose = true; 1.126 + } else if (!strcmp(argv[c], "-q")) { 1.127 + quiet = true; 1.128 + } else if (!strcmp(argv[c], "-n")) { 1.129 + show_name = true; 1.130 + } else if (!strcmp(argv[c], "-psnr")) { 1.131 + do_psnr = true; 1.132 + } else if (!strcmp(argv[c], "-mse")) { 1.133 + do_mse = true; 1.134 + } else if (!strcmp(argv[c], "-ssim")) { 1.135 + do_ssim = true; 1.136 + } else if (!strcmp(argv[c], "-lssim")) { 1.137 + do_ssim = true; 1.138 + do_lssim = true; 1.139 + } else if (!strcmp(argv[c], "-swap")) { 1.140 + do_swap_uv = true; 1.141 + } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { 1.142 + PrintHelp(argv[0]); 1.143 + } else if (!strcmp(argv[c], "-s") && c + 2 < argc) { 1.144 + image_width = atoi(argv[++c]); // NOLINT 1.145 + image_height = atoi(argv[++c]); // NOLINT 1.146 + } else if (!strcmp(argv[c], "-skip") && c + 2 < argc) { 1.147 + num_skip_org = atoi(argv[++c]); // NOLINT 1.148 + num_skip_rec = atoi(argv[++c]); // NOLINT 1.149 + } else if (!strcmp(argv[c], "-frames") && c + 1 < argc) { 1.150 + num_frames = atoi(argv[++c]); // NOLINT 1.151 +#ifdef _OPENMP 1.152 + } else if (!strcmp(argv[c], "-t") && c + 1 < argc) { 1.153 + num_threads = atoi(argv[++c]); // NOLINT 1.154 +#endif 1.155 + } else if (argv[c][0] == '-') { 1.156 + fprintf(stderr, "Unknown option. %s\n", argv[c]); 1.157 + } else if (fileindex_org == 0) { 1.158 + fileindex_org = c; 1.159 + } else if (fileindex_rec == 0) { 1.160 + fileindex_rec = c; 1.161 + num_rec = 1; 1.162 + } else { 1.163 + ++num_rec; 1.164 + } 1.165 + } 1.166 + if (fileindex_org == 0 || fileindex_rec == 0) { 1.167 + fprintf(stderr, "Missing filenames\n"); 1.168 + PrintHelp(argv[0]); 1.169 + } 1.170 + if (num_skip_org < 0 || num_skip_rec < 0) { 1.171 + fprintf(stderr, "Skipped frames incorrect\n"); 1.172 + PrintHelp(argv[0]); 1.173 + } 1.174 + if (num_frames < 0) { 1.175 + fprintf(stderr, "Number of frames incorrect\n"); 1.176 + PrintHelp(argv[0]); 1.177 + } 1.178 + if (image_width == 0 || image_height == 0) { 1.179 + int org_width, org_height; 1.180 + int rec_width, rec_height; 1.181 + bool org_res_avail = ExtractResolutionFromFilename(argv[fileindex_org], 1.182 + &org_width, 1.183 + &org_height); 1.184 + bool rec_res_avail = ExtractResolutionFromFilename(argv[fileindex_rec], 1.185 + &rec_width, 1.186 + &rec_height); 1.187 + if (org_res_avail) { 1.188 + if (rec_res_avail) { 1.189 + if ((org_width == rec_width) && (org_height == rec_height)) { 1.190 + image_width = org_width; 1.191 + image_height = org_height; 1.192 + } else { 1.193 + fprintf(stderr, "Sequences have different resolutions.\n"); 1.194 + PrintHelp(argv[0]); 1.195 + } 1.196 + } else { 1.197 + image_width = org_width; 1.198 + image_height = org_height; 1.199 + } 1.200 + } else if (rec_res_avail) { 1.201 + image_width = rec_width; 1.202 + image_height = rec_height; 1.203 + } else { 1.204 + fprintf(stderr, "Missing dimensions.\n"); 1.205 + PrintHelp(argv[0]); 1.206 + } 1.207 + } 1.208 +} 1.209 + 1.210 +bool UpdateMetrics(uint8* ch_org, uint8* ch_rec, 1.211 + const int y_size, const int uv_size, const size_t total_size, 1.212 + int number_of_frames, 1.213 + metric* cur_distortion_psnr, 1.214 + metric* distorted_frame, bool do_psnr) { 1.215 + const int uv_offset = (do_swap_uv ? uv_size : 0); 1.216 + const uint8* const u_org = ch_org + y_size + uv_offset; 1.217 + const uint8* const u_rec = ch_rec + y_size; 1.218 + const uint8* const v_org = ch_org + y_size + (uv_size - uv_offset); 1.219 + const uint8* const v_rec = ch_rec + y_size + uv_size; 1.220 + if (do_psnr) { 1.221 + double y_err = ComputeSumSquareError(ch_org, ch_rec, y_size); 1.222 + double u_err = ComputeSumSquareError(u_org, u_rec, uv_size); 1.223 + double v_err = ComputeSumSquareError(v_org, v_rec, uv_size); 1.224 + const double total_err = y_err + u_err + v_err; 1.225 + cur_distortion_psnr->global_y += y_err; 1.226 + cur_distortion_psnr->global_u += u_err; 1.227 + cur_distortion_psnr->global_v += v_err; 1.228 + cur_distortion_psnr->global_all += total_err; 1.229 + distorted_frame->y = ComputePSNR(y_err, static_cast<double>(y_size)); 1.230 + distorted_frame->u = ComputePSNR(u_err, static_cast<double>(uv_size)); 1.231 + distorted_frame->v = ComputePSNR(v_err, static_cast<double>(uv_size)); 1.232 + distorted_frame->all = ComputePSNR(total_err, 1.233 + static_cast<double>(total_size)); 1.234 + } else { 1.235 + distorted_frame->y = CalcSSIM(ch_org, ch_rec, image_width, image_height); 1.236 + distorted_frame->u = CalcSSIM(u_org, u_rec, image_width / 2, 1.237 + image_height / 2); 1.238 + distorted_frame->v = CalcSSIM(v_org, v_rec, image_width / 2, 1.239 + image_height / 2); 1.240 + distorted_frame->all = 1.241 + (distorted_frame->y + distorted_frame->u + distorted_frame->v) 1.242 + / total_size; 1.243 + distorted_frame->y /= y_size; 1.244 + distorted_frame->u /= uv_size; 1.245 + distorted_frame->v /= uv_size; 1.246 + 1.247 + if (do_lssim) { 1.248 + distorted_frame->all = CalcLSSIM(distorted_frame->all); 1.249 + distorted_frame->y = CalcLSSIM(distorted_frame->y); 1.250 + distorted_frame->u = CalcLSSIM(distorted_frame->u); 1.251 + distorted_frame->v = CalcLSSIM(distorted_frame->v); 1.252 + } 1.253 + } 1.254 + 1.255 + cur_distortion_psnr->y += distorted_frame->y; 1.256 + cur_distortion_psnr->u += distorted_frame->u; 1.257 + cur_distortion_psnr->v += distorted_frame->v; 1.258 + cur_distortion_psnr->all += distorted_frame->all; 1.259 + 1.260 + bool ismin = false; 1.261 + if (distorted_frame->y < cur_distortion_psnr->min_y) 1.262 + cur_distortion_psnr->min_y = distorted_frame->y; 1.263 + if (distorted_frame->u < cur_distortion_psnr->min_u) 1.264 + cur_distortion_psnr->min_u = distorted_frame->u; 1.265 + if (distorted_frame->v < cur_distortion_psnr->min_v) 1.266 + cur_distortion_psnr->min_v = distorted_frame->v; 1.267 + if (distorted_frame->all < cur_distortion_psnr->min_all) { 1.268 + cur_distortion_psnr->min_all = distorted_frame->all; 1.269 + cur_distortion_psnr->min_frame = number_of_frames; 1.270 + ismin = true; 1.271 + } 1.272 + return ismin; 1.273 +} 1.274 + 1.275 +int main(int argc, const char* argv[]) { 1.276 + ParseOptions(argc, argv); 1.277 + if (!do_psnr && !do_ssim) { 1.278 + do_psnr = true; 1.279 + } 1.280 + 1.281 +#ifdef _OPENMP 1.282 + if (num_threads) { 1.283 + omp_set_num_threads(num_threads); 1.284 + } 1.285 + if (verbose) { 1.286 + printf("OpenMP %d procs\n", omp_get_num_procs()); 1.287 + } 1.288 +#endif 1.289 + // Open original file (first file argument) 1.290 + FILE* const file_org = fopen(argv[fileindex_org], "rb"); 1.291 + if (file_org == NULL) { 1.292 + fprintf(stderr, "Cannot open %s\n", argv[fileindex_org]); 1.293 + exit(1); 1.294 + } 1.295 + 1.296 + // Open all files to compare to 1.297 + FILE** file_rec = new FILE* [num_rec]; 1.298 + memset(file_rec, 0, num_rec * sizeof(FILE*)); // NOLINT 1.299 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.300 + file_rec[cur_rec] = fopen(argv[fileindex_rec + cur_rec], "rb"); 1.301 + if (file_rec[cur_rec] == NULL) { 1.302 + fprintf(stderr, "Cannot open %s\n", argv[fileindex_rec + cur_rec]); 1.303 + fclose(file_org); 1.304 + for (int i = 0; i < cur_rec; ++i) { 1.305 + fclose(file_rec[i]); 1.306 + } 1.307 + delete[] file_rec; 1.308 + exit(1); 1.309 + } 1.310 + } 1.311 + 1.312 + const int y_size = image_width * image_height; 1.313 + const int uv_size = ((image_width + 1) / 2) * ((image_height + 1) / 2); 1.314 + const size_t total_size = y_size + 2 * uv_size; // NOLINT 1.315 +#if defined(_MSC_VER) 1.316 + _fseeki64(file_org, 1.317 + static_cast<__int64>(num_skip_org) * 1.318 + static_cast<__int64>(total_size), SEEK_SET); 1.319 +#else 1.320 + fseek(file_org, num_skip_org * total_size, SEEK_SET); 1.321 +#endif 1.322 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.323 +#if defined(_MSC_VER) 1.324 + _fseeki64(file_rec[cur_rec], 1.325 + static_cast<__int64>(num_skip_rec) * 1.326 + static_cast<__int64>(total_size), 1.327 + SEEK_SET); 1.328 +#else 1.329 + fseek(file_rec[cur_rec], num_skip_rec * total_size, SEEK_SET); 1.330 +#endif 1.331 + } 1.332 + 1.333 + uint8* const ch_org = new uint8[total_size]; 1.334 + uint8* const ch_rec = new uint8[total_size]; 1.335 + if (ch_org == NULL || ch_rec == NULL) { 1.336 + fprintf(stderr, "No memory available\n"); 1.337 + fclose(file_org); 1.338 + for (int i = 0; i < num_rec; ++i) { 1.339 + fclose(file_rec[i]); 1.340 + } 1.341 + delete[] ch_org; 1.342 + delete[] ch_rec; 1.343 + delete[] file_rec; 1.344 + exit(1); 1.345 + } 1.346 + 1.347 + metric* const distortion_psnr = new metric[num_rec]; 1.348 + metric* const distortion_ssim = new metric[num_rec]; 1.349 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.350 + metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; 1.351 + cur_distortion_psnr->y = 0.0; 1.352 + cur_distortion_psnr->u = 0.0; 1.353 + cur_distortion_psnr->v = 0.0; 1.354 + cur_distortion_psnr->all = 0.0; 1.355 + cur_distortion_psnr->min_y = kMaxPSNR; 1.356 + cur_distortion_psnr->min_u = kMaxPSNR; 1.357 + cur_distortion_psnr->min_v = kMaxPSNR; 1.358 + cur_distortion_psnr->min_all = kMaxPSNR; 1.359 + cur_distortion_psnr->min_frame = 0; 1.360 + cur_distortion_psnr->global_y = 0.0; 1.361 + cur_distortion_psnr->global_u = 0.0; 1.362 + cur_distortion_psnr->global_v = 0.0; 1.363 + cur_distortion_psnr->global_all = 0.0; 1.364 + distortion_ssim[cur_rec] = cur_distortion_psnr[cur_rec]; 1.365 + } 1.366 + 1.367 + if (verbose) { 1.368 + printf("Size: %dx%d\n", image_width, image_height); 1.369 + } 1.370 + 1.371 + if (!quiet) { 1.372 + printf("Frame"); 1.373 + if (do_psnr) { 1.374 + printf("\t PSNR-Y \t PSNR-U \t PSNR-V \t PSNR-All \t Frame"); 1.375 + } 1.376 + if (do_ssim) { 1.377 + printf("\t SSIM-Y\t SSIM-U\t SSIM-V\t SSIM-All\t Frame"); 1.378 + } 1.379 + if (show_name) { 1.380 + printf("\tName\n"); 1.381 + } else { 1.382 + printf("\n"); 1.383 + } 1.384 + } 1.385 + 1.386 + int number_of_frames; 1.387 + for (number_of_frames = 0; ; ++number_of_frames) { 1.388 + if (num_frames && number_of_frames >= num_frames) 1.389 + break; 1.390 + 1.391 + size_t bytes_org = fread(ch_org, sizeof(uint8), total_size, file_org); 1.392 + if (bytes_org < total_size) 1.393 + break; 1.394 + 1.395 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.396 + size_t bytes_rec = fread(ch_rec, sizeof(uint8), 1.397 + total_size, file_rec[cur_rec]); 1.398 + if (bytes_rec < total_size) 1.399 + break; 1.400 + 1.401 + if (verbose) { 1.402 + printf("%5d", number_of_frames); 1.403 + } 1.404 + if (do_psnr) { 1.405 + metric distorted_frame; 1.406 + metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; 1.407 + bool ismin = UpdateMetrics(ch_org, ch_rec, 1.408 + y_size, uv_size, total_size, 1.409 + number_of_frames, 1.410 + cur_distortion_psnr, 1.411 + &distorted_frame, true); 1.412 + if (verbose) { 1.413 + printf("\t%10.6f", distorted_frame.y); 1.414 + printf("\t%10.6f", distorted_frame.u); 1.415 + printf("\t%10.6f", distorted_frame.v); 1.416 + printf("\t%10.6f", distorted_frame.all); 1.417 + printf("\t%5s", ismin ? "min" : ""); 1.418 + } 1.419 + } 1.420 + if (do_ssim) { 1.421 + metric distorted_frame; 1.422 + metric* cur_distortion_ssim = &distortion_ssim[cur_rec]; 1.423 + bool ismin = UpdateMetrics(ch_org, ch_rec, 1.424 + y_size, uv_size, total_size, 1.425 + number_of_frames, 1.426 + cur_distortion_ssim, 1.427 + &distorted_frame, false); 1.428 + if (verbose) { 1.429 + printf("\t%10.6f", distorted_frame.y); 1.430 + printf("\t%10.6f", distorted_frame.u); 1.431 + printf("\t%10.6f", distorted_frame.v); 1.432 + printf("\t%10.6f", distorted_frame.all); 1.433 + printf("\t%5s", ismin ? "min" : ""); 1.434 + } 1.435 + } 1.436 + if (verbose) { 1.437 + if (show_name) { 1.438 + printf("\t%s", argv[fileindex_rec + cur_rec]); 1.439 + } 1.440 + printf("\n"); 1.441 + } 1.442 + } 1.443 + } 1.444 + 1.445 + // Final PSNR computation. 1.446 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.447 + metric* cur_distortion_psnr = &distortion_psnr[cur_rec]; 1.448 + metric* cur_distortion_ssim = &distortion_ssim[cur_rec]; 1.449 + if (number_of_frames > 0) { 1.450 + const double norm = 1. / static_cast<double>(number_of_frames); 1.451 + cur_distortion_psnr->y *= norm; 1.452 + cur_distortion_psnr->u *= norm; 1.453 + cur_distortion_psnr->v *= norm; 1.454 + cur_distortion_psnr->all *= norm; 1.455 + cur_distortion_ssim->y *= norm; 1.456 + cur_distortion_ssim->u *= norm; 1.457 + cur_distortion_ssim->v *= norm; 1.458 + cur_distortion_ssim->all *= norm; 1.459 + } 1.460 + 1.461 + if (do_psnr) { 1.462 + const double global_psnr_y = ComputePSNR( 1.463 + cur_distortion_psnr->global_y, 1.464 + static_cast<double>(y_size) * number_of_frames); 1.465 + const double global_psnr_u = ComputePSNR( 1.466 + cur_distortion_psnr->global_u, 1.467 + static_cast<double>(uv_size) * number_of_frames); 1.468 + const double global_psnr_v = ComputePSNR( 1.469 + cur_distortion_psnr->global_v, 1.470 + static_cast<double>(uv_size) * number_of_frames); 1.471 + const double global_psnr_all = ComputePSNR( 1.472 + cur_distortion_psnr->global_all, 1.473 + static_cast<double>(total_size) * number_of_frames); 1.474 + printf("Global:\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.475 + global_psnr_y, 1.476 + global_psnr_u, 1.477 + global_psnr_v, 1.478 + global_psnr_all, 1.479 + number_of_frames); 1.480 + if (show_name) { 1.481 + printf("\t%s", argv[fileindex_rec + cur_rec]); 1.482 + } 1.483 + printf("\n"); 1.484 + } 1.485 + 1.486 + if (!quiet) { 1.487 + printf("Avg:"); 1.488 + if (do_psnr) { 1.489 + printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.490 + cur_distortion_psnr->y, 1.491 + cur_distortion_psnr->u, 1.492 + cur_distortion_psnr->v, 1.493 + cur_distortion_psnr->all, 1.494 + number_of_frames); 1.495 + } 1.496 + if (do_ssim) { 1.497 + printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.498 + cur_distortion_ssim->y, 1.499 + cur_distortion_ssim->u, 1.500 + cur_distortion_ssim->v, 1.501 + cur_distortion_ssim->all, 1.502 + number_of_frames); 1.503 + } 1.504 + if (show_name) { 1.505 + printf("\t%s", argv[fileindex_rec + cur_rec]); 1.506 + } 1.507 + printf("\n"); 1.508 + } 1.509 + if (!quiet) { 1.510 + printf("Min:"); 1.511 + if (do_psnr) { 1.512 + printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.513 + cur_distortion_psnr->min_y, 1.514 + cur_distortion_psnr->min_u, 1.515 + cur_distortion_psnr->min_v, 1.516 + cur_distortion_psnr->min_all, 1.517 + cur_distortion_psnr->min_frame); 1.518 + } 1.519 + if (do_ssim) { 1.520 + printf("\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.521 + cur_distortion_ssim->min_y, 1.522 + cur_distortion_ssim->min_u, 1.523 + cur_distortion_ssim->min_v, 1.524 + cur_distortion_ssim->min_all, 1.525 + cur_distortion_ssim->min_frame); 1.526 + } 1.527 + if (show_name) { 1.528 + printf("\t%s", argv[fileindex_rec + cur_rec]); 1.529 + } 1.530 + printf("\n"); 1.531 + } 1.532 + 1.533 + if (do_mse) { 1.534 + double global_mse_y = GetMSE(cur_distortion_psnr->global_y, 1.535 + static_cast<double>(y_size) * number_of_frames); 1.536 + double global_mse_u = GetMSE(cur_distortion_psnr->global_u, 1.537 + static_cast<double>(uv_size) * number_of_frames); 1.538 + double global_mse_v = GetMSE(cur_distortion_psnr->global_v, 1.539 + static_cast<double>(uv_size) * number_of_frames); 1.540 + double global_mse_all = GetMSE(cur_distortion_psnr->global_all, 1.541 + static_cast<double>(total_size) * number_of_frames); 1.542 + printf("MSE:\t%10.6f\t%10.6f\t%10.6f\t%10.6f\t%5d", 1.543 + global_mse_y, 1.544 + global_mse_u, 1.545 + global_mse_v, 1.546 + global_mse_all, 1.547 + number_of_frames); 1.548 + if (show_name) { 1.549 + printf("\t%s", argv[fileindex_rec + cur_rec]); 1.550 + } 1.551 + printf("\n"); 1.552 + } 1.553 + } 1.554 + fclose(file_org); 1.555 + for (int cur_rec = 0; cur_rec < num_rec; ++cur_rec) { 1.556 + fclose(file_rec[cur_rec]); 1.557 + } 1.558 + delete[] distortion_psnr; 1.559 + delete[] distortion_ssim; 1.560 + delete[] ch_org; 1.561 + delete[] ch_rec; 1.562 + delete[] file_rec; 1.563 + return 0; 1.564 +}