/*! ************************************************************************ * \brief * Find SSIM for all three components ************************************************************************ */ void find_ssim (VideoParameters *p_Vid, InputParameters *p_Inp, ImageStructure *ref, ImageStructure *src, DistMetric *metricSSIM) { DistortionParams *p_Dist = p_Vid->p_Dist; FrameFormat *format = &ref->format; metricSSIM->value[0] = compute_ssim (p_Vid, p_Inp, ref->data[0], src->data[0], format->height[0], format->width[0], BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, 0); // Chroma. if (format->yuv_format != YUV400) { metricSSIM->value[1] = compute_ssim (p_Vid, p_Inp, ref->data[1], src->data[1], format->height[1], format->width[1], p_Vid->mb_cr_size_y, p_Vid->mb_cr_size_x, 1); metricSSIM->value[2] = compute_ssim (p_Vid, p_Inp, ref->data[2], src->data[2], format->height[1], format->width[1], p_Vid->mb_cr_size_y, p_Vid->mb_cr_size_x, 2); } { accumulate_average(metricSSIM, p_Dist->frame_ctr); accumulate_avslice(metricSSIM, p_Vid->type, p_Vid->p_Stats->frame_ctr[p_Vid->type]); } }
int ssim(const char *ref_path, const char *dis_path, int w, int h, const char *fmt) { double score = 0; double l_score = 0, c_score = 0, s_score = 0; number_t *ref_buf = 0; number_t *dis_buf = 0; number_t *temp_buf = 0; FILE *ref_rfile = 0; FILE *dis_rfile = 0; size_t data_sz; int stride; int ret = 1; if (w <= 0 || h <= 0 || (size_t)w > ALIGN_FLOOR(INT_MAX) / sizeof(number_t)) { goto fail_or_end; } stride = ALIGN_CEIL(w * sizeof(number_t)); if ((size_t)h > SIZE_MAX / stride) { goto fail_or_end; } data_sz = (size_t)stride * h; if (!(ref_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for ref_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(dis_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for dis_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(temp_buf = aligned_malloc(data_sz * 2, MAX_ALIGN))) { printf("error: aligned_malloc failed for temp_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(ref_rfile = fopen(ref_path, "rb"))) { printf("error: fopen ref_path %s failed\n", ref_path); fflush(stdout); goto fail_or_end; } if (!(dis_rfile = fopen(dis_path, "rb"))) { printf("error: fopen dis_path %s failed.\n", dis_path); fflush(stdout); goto fail_or_end; } size_t offset; if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv420p10le")) { if ((w * h) % 2 != 0) { printf("error: (w * h) %% 2 != 0, w = %d, h = %d.\n", w, h); fflush(stdout); goto fail_or_end; } offset = w * h / 2; } else if (!strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv422p10le")) { offset = w * h; } else if (!strcmp(fmt, "yuv444p") || !strcmp(fmt, "yuv444p10le")) { offset = w * h * 2; } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } int frm_idx = 0; while (1) { // read ref y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(ref_rfile, ref_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(ref_rfile, ref_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { if (feof(ref_rfile)) { ret = 0; // OK if end of file } goto fail_or_end; } // read dis y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(dis_rfile, dis_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(dis_rfile, dis_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { if (feof(dis_rfile)) { ret = 0; // OK if end of file } goto fail_or_end; } // compute ret = compute_ssim(ref_buf, dis_buf, w, h, stride, stride, &score, &l_score, &c_score, &s_score); if (ret) { printf("error: compute_ssim failed.\n"); fflush(stdout); goto fail_or_end; } // print printf("ssim: %d %f\n", frm_idx, score); printf("ssim_l: %d %f\n", frm_idx, l_score); printf("ssim_c: %d %f\n", frm_idx, c_score); printf("ssim_s: %d %f\n", frm_idx, s_score); fflush(stdout); // ref skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } // dis skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } frm_idx++; } ret = 0; fail_or_end: if (ref_rfile) { fclose(ref_rfile); } if (dis_rfile) { fclose(dis_rfile); } aligned_free(ref_buf); aligned_free(dis_buf); aligned_free(temp_buf); return ret; }
virtual void run(void) { _res = compute_ssim(_ref, _cmp, _x, _y, _b_sz); }