Repository navigation
Conversation
9 of 12 tasks
lusoris
added a commit
to VMAFx/vmafx
that referenced
this pull request
Oct 2, 2026
…each with its size and the upstream change that ends it (ADR-1479 to ADR-1486) The reference for code inherited from Netflix/vmaf is Netflix's source; a difference needs an ADR. The upstream parity audit of 2026-10-02 found deliberate differences that had none of their own, or whose ADR (ADR-1033) names neither upstream's behaviour nor the size: - ADR-1479 ciede on 4:2:2: chroma flags (fork PR #1050); 0.153 on 48 of 48 frames; Netflix/vmaf#1611. - ADR-1480 speed_temporal buffers at speed_prescale above 1 (#1643); up to 195, upstream segfaults on two fixtures; Netflix/vmaf#1627. - ADR-1481 a failing extractor fails the run (#871); status only, 78 probe runs where upstream is silent and 88 where it crashes. - ADR-1482 integer adm on frames of 17 to 32 pixels (#1473, #1507); scale 3 up to 0.23; Netflix/vmaf#1599, #1600. - ADR-1483 odd-sized chroma planes round up (4f08d32); psnr_cb / cr up to 0.684 / 0.826 dB, ciede 0.198. - ADR-1484 float_ms_ssim magnitude before pow() (#641, ADR-1033 item 2); NaN upstream on the 10 px checkerboard; Netflix/vmaf#1665. - ADR-1485 apsnr of a plane without error (#641, item 1); 114 against 60 dB; Netflix/vmaf#1666. - ADR-1486 float_motion scale-1 stride (#641, item 9); up to 25.1; Netflix/vmaf#1667. Each ADR gives upstream's file and line at Netflix 9e48141b, the fork's lines, the reason found in the fork's pull request, commit or code, and the measured size from the audit. Documentation only.
vmaf_image_sad_c() with motion_add_scale1 builds the half-resolution copy of both inputs for the second scale. It passed ALIGN_CEIL(width * sizeof(float)) / sizeof(float) as the stride of the source instead of the img1_stride / img2_stride it was called with. For the luma plane the two are equal. With motion_add_uv the chroma planes are scored by the same function, from buffers float_motion allocates for the luma width (float_stride), but their width is half of it, so the stride computed from the width reads every row of the chroma plane from the wrong offset. On src01_hrc00_576x324 against src01_hrc01_576x324, motion2 of frames 1 to 3 with motion_add_scale1=true:motion_add_uv=true is 9.899102, 9.578713, 9.015887 on master and 10.248167, 9.910458, 9.330507 with this change; each option on its own is unchanged. Pass the strides the function was given. Add test_motion_sad: the sum of absolute differences of the same pixels must not depend on the stride they are stored with. The scale1 case fails on master and passes with this change; the scale0 case passes on both.
lusoris
force-pushed
the
fix/float-motion-scale1-stride
branch
from
October 8, 2026 17:17
fe3707b to
77fe5c0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With
motion_add_scale1,vmaf_image_sad_c()builds a half-resolution copy of both inputs and adds their difference to the score. It passesALIGN_CEIL(width * sizeof(float)) / sizeof(float)as the stride of the source instead of theimg1_stride/img2_strideit was called with. For luma the two are equal. Withmotion_add_uvthe chroma planes go through the same function from buffersfloat_motionallocates for the luma width, so the stride computed from the chroma width is wrong and every row of the chroma plane is read from the wrong offset.What breaks today
motion.c:70and:75-76on master9e48141b:float_motion.ccallscompute_motion()for plane 1 and 2 withref_pic->w[1]as the width ands->float_stride(computed from the luma width) as the stride. The function's own contract says the strides are in elements of the buffers passed in; the unscaled sum honours that, the scale-1 branch does not.Reproducer, GCC 16.2.1 release build, src01 576x324 (4:2:0),
motion2of frames 1 to 3 (identical under--cpumask -1):motion_add_uv=truemotion_add_scale1=trueFix
The two calls take
img1_strideandimg2_stride, and the localfloat_stridegoes away.Test
test_motion_sad(new, built whenenable_floatis on):vmaf_image_sad_c()on the same 50x21 pixels stored with a stride of 56 elements (the aligned one) and with a stride of 128. The sums must be equal, with and withoutmotion_add_scale1. The scale-1 case fails on master ("the sad must not depend on the stride"); the scale-0 case passes on both.Validation
x86-64 Linux, GCC 16.2.1, master
9e48141b, branch headfe3707b4;-Denable_float=true -Denable_checkasm=true.meson test: 26/26 here, 25/25 on master (the extra test is the new one).-Db_sanitize=address,undefined -Db_lto=false: 23 pass and 3 fail of 26 here, 22 pass and 3 fail of 25 on master;test_predictandtest_pic_preallocation(SIGABRT from LeakSanitizer) andcheckasm(heap-buffer-overflow inadm_dwt2_16) fail on both and are untouched by this change;test_motion_sadpasses..engagement/golden_compare.pymaster binary against this branch: ALL IDENTICAL (default dispatch andcpumask=-1;float_motionis not in the default model, so this checks that nothing else moved).motion_add_scale1ormotion_add_uv(vmafexec_feature_extractor_test.py) set one at a time; both single-option rows above are unchanged. No Python test sets both. The Python suite itself was not run.Not covered