cutcutcodec.core.analysis.video.quality.vmaf_official

Parse the ffmpeg vmaf metric.

Notes

Deprecated pakage, use the static vmaf function instead.

Functions

to_yuvfile(frames)

Write the frame into a standard full range .yuv file in yuv444p16le pixel format.

vmaf(ref, dis[, threads])

Call the Netflix vmaf metric on the frames.

Details

cutcutcodec.core.analysis.video.quality.vmaf_official.to_yuvfile(frames: Tensor | Iterable[Tensor]) Path[source]

Write the frame into a standard full range .yuv file in yuv444p16le pixel format.

Parameters

frameslist[torch.Tensor]

A (or several) video frame, assumed to be in yuv (YpPbPr) format, with \((y', p_b, p_r) \in [0, 1] \times \left[-\frac{1}{2}, \frac{1}{2}\right]^2\).

Returns

filenamepathlib.Path

The filename to the yuv file.

Examples

>>> import pathlib
>>> import subprocess
>>> import torch
>>> from cutcutcodec.core.analysis.video.quality.vmaf import to_yuvfile
>>> from cutcutcodec.core.io.read_ffmpeg import ContainerInputFFMPEG
>>> frame = torch.rand((720, 1080, 3))
>>> frame[:, :, 1:] -= 0.5
>>> yuvfile = to_yuvfile(frame)
>>> _ = subprocess.run(
...     [
...         "ffmpeg", "-y", "-f", "rawvideo",
...         "-s", "1080x720", "-pix_fmt", "yuv444p16le", "-color_range", "pc",
...         "-i", str(yuvfile),
...         "-c:v", "libaom-av1", "-crf", "0",
...         "/tmp/tmp.avif",
...     ],
...     check=True, capture_output=True
... )
>>> yuvfile.unlink()
>>> with ContainerInputFFMPEG("/tmp/tmp.avif") as container:
...     frame_bis = container.out_streams[0].snapshot(0, (720, 1080))
...
>>> pathlib.Path("/tmp/tmp.avif").unlink()
>>> assert torch.allclose(frame, frame_bis, atol=1e-3)
>>>
cutcutcodec.core.analysis.video.quality.vmaf_official.vmaf(ref: Tensor, dis: Tensor, threads: int = 0) Tensor[source]

Call the Netflix vmaf metric on the frames.

Parameters

refarraylike

The reference video frames, transmitted to to_yuvfile, shape ([*batch], height, width, 3).

disarraylike

The distorted video frames, transmitted to to_yuvfile, shape ([*batch], height, width, 3).

threadsint, optional

Defines the number of threads. The value -1 means that the function uses as many calculation threads as there are cores. The default value (0) allows the same behavior as (-1) if the function is called in the main thread, otherwise (1) to avoid nested threads. Any other positive value corresponds to the number of threads used.

Returns

vmafarraylike

All the vmaf values for the pairwise frames.

Examples

>>> import numpy as np
>>> from cutcutcodec.core.analysis.video.quality import vmaf
>>> np.random.seed(0)
>>> ref = np.random.random((720, 1080, 3))  # It could also be a torch array list...
>>> ref[:, :, 1:] -= 0.5  # yuv format
>>> dis = ref.copy()
>>> dis[:, :, 0] = 0.8 * dis[:, :, 0] + 0.2 * np.random.random((720, 1080))
>>> vmaf(ref, dis).round(1)
np.float64(33.7)
>>>