Example #1
0
File: adm.c Project: Netflix/vmaf
int adm(const char *ref_path, const char *dis_path, int w, int h, const char *fmt)
{
    double score = 0;
    double score_num = 0;
    double score_den = 0;
    double scores[2*4];
    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, OPT_RANGE_PIXEL_OFFSET, w, h, stride);
        }
        else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le"))
        {
            ret = read_image_w(ref_rfile, ref_buf, OPT_RANGE_PIXEL_OFFSET, 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, OPT_RANGE_PIXEL_OFFSET, w, h, stride);
        }
        else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le"))
        {
            ret = read_image_w(dis_rfile, dis_buf, OPT_RANGE_PIXEL_OFFSET, 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
        if ((ret = compute_adm(ref_buf, dis_buf, w, h, stride, stride, &score, &score_num, &score_den, scores, ADM_BORDER_FACTOR)))
        {
            printf("error: compute_adm failed.\n");
            fflush(stdout);
            goto fail_or_end;
        }

        // print
        printf("adm: %d %f\n", frm_idx, score);
        fflush(stdout);
        printf("adm_num: %d %f\n", frm_idx, score_num);
        fflush(stdout);
        printf("adm_den: %d %f\n", frm_idx, score_den);
        fflush(stdout);
        for(int scale=0;scale<4;scale++) {
            printf("adm_num_scale%d: %d %f\n", scale, frm_idx, scores[2*scale]);
            fflush(stdout);
            printf("adm_den_scale%d: %d %f\n", scale, frm_idx, scores[2*scale+1]);
            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;
}
Example #2
0
int psnr(const char *ref_path, const char *dis_path, int w, int h, const char *fmt)
{
	double 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 ((!feof(ref_rfile)) && (!feof(dis_rfile)))
	{
		// 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)
		{
			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)
		{
			goto fail_or_end;
		}

		// compute
		if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p"))
		{
			// max psnr 60.0 for 8-bit per Ioannis
			ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.0, 60.0);
		}
		else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le"))
		{
			// 10 bit gets normalized to 8 bit, peak is 1023 / 4.0 = 255.75
			// max psnr 72.0 for 10-bit per Ioannis
			ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.75, 72.0);
		}
		else
		{
			printf("error: unknown format %s.\n", fmt);
			fflush(stdout);
			goto fail_or_end;
		}
		if (ret)
		{
			printf("error: compute_psnr failed.\n");
			fflush(stdout);
			goto fail_or_end;
		}

		// print
		printf("psnr: %d %f\n", frm_idx, 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;
}