Skip to content

cambi: 10-bit full_ref with a larger source copies the distorted plane at the wrong stride #1670

Description

@lusoris

Summary. With 10-bit input, cambi with full_ref=true and a source (src_width / src_height) larger than the encoded picture scores the distorted plane with its rows at the wrong offsets, so the reported cambi is wrong.

Where. libvmaf/src/feature/cambi.c, decimate_generic_uint16_and_convert_to_10b() (master 0497a0f29, around line 751). When the input and output sizes are equal and bpc == 10, the plane is copied with one call:

memcpy(out_data, data, stride * pic->h[0] * sizeof(uint16_t));

This assumes out_stride == stride. With full_ref=true the working picture is allocated at the larger of the source and encode sizes, so out_stride is wider than the input stride and every row after the first lands at the wrong place. The 12- and 16-bit branch next to it already copies row by row with both strides, and 8-bit input takes a different path, so only 10-bit input is affected.

How to reproduce. Any 10-bit 4:2:0 pair, scored once without and once with a larger source, for example with a 480x270 pair:

vmaf -r ref_480x270_10b.yuv -d dis_480x270_10b.yuv -w 480 -h 270 -p 420 -b 10 \
     --feature cambi --no_prediction --precision max
vmaf -r ref_480x270_10b.yuv -d dis_480x270_10b.yuv -w 480 -h 270 -p 420 -b 10 \
     --feature cambi=full_ref=true:src_width=960:src_height=540 --no_prediction --precision max

The distorted-side cambi of the second run should equal the first (it is the distorted score at the encode size), but it does not. On one 10-bit clip we measured frame 0 at 0.0048362395598900215 with full_ref against 0.3734397949735747 without; 0 of 5 frames matched.

Suggested fix. Copy row by row with both strides, as the other branch does:

for (unsigned i = 0; i < out_h; i++)
    memcpy(out_data + i * out_stride, data + i * stride, out_w * sizeof(uint16_t));

With that change the full_ref run equals the no-reference run on every frame we tried, and 8-, 12- and 16-bit results are unchanged.

Found while testing the VMAFx fork (https://github.com/VMAFx/vmafx), where the fix and a regression test are in VMAFx/vmafx#2111.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions