Repository navigation
Conversation
window_size and max_log_contrast are registered as VMAF_OPT_TYPE_INT, which vmaf_option_set() writes and option_is_default() reads through an int *, but CambiState declared both as uint16_t. max_log_contrast sits at offset 258, so UBSan reports a store and a load of a misaligned int in opt.c and feature_name.c for any model that creates cambi. The window_size store at offset 212 is aligned but covers the neighbouring src_window_size as well, and on a big-endian target either 16-bit field would read back the upper half of the int, which is zero. Declare window_size, src_window_size and max_log_contrast as int and let adjust_window_size() take an int *. The values and the defaults do not change. The new test sets every integer option of the extractor to its default on a zeroed CambiState and checks that each offset is a multiple of alignof(int), that the two fields are int sized, and that the neighbouring fields are left alone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/cambi-option-int-fields
branch
from
October 2, 2026 18:46
7ede4ad to
672b19b
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.
CambiStatedeclareswindow_sizeandmax_log_contrastasuint16_t, but both options are registered asVMAF_OPT_TYPE_INT.vmaf_option_set()writes them through anint *(opt.c,set_option_int()) andvmaf_feature_name_from_options()reads them through anint *(feature_name.c,option_is_default()). This declares both fields asint, so the option code accesses what the struct holds.What breaks today
Master
9e48141b, GCC 16.2.1,-Db_sanitize=address,undefined -Db_lto=false, any run that creates the cambi extractor:--feature cambialone gives the same two reports; with this change both runs print none. The store ismax_log_contrast, option offset 258 inCambiState(read from gdb:window_size212,src_window_size214,vlt_luma256,max_log_contrast258,heatmaps_path264).What I measured and what I infer:
heatmaps_path; the store at 212 is aligned but coverssrc_window_sizetoo, whichcambi.cassigns later (s->src_window_size = s->window_size). The three Netflix pairs pluscambi=window_size=31:max_log_contrast=4:full_ref=truescore identically on master and on this branch (.engagement/golden_compare.py, default dispatch andcpumask=-1: ALL IDENTICAL, e.g. src01 vmaf_mean 76.667831).Fix
window_size,src_window_sizeandmax_log_contrastbecomeint, andadjust_window_size()takes anint *. Defaults, ranges and values do not change; the one place a 16-bit wrap was possible (window_size * (width + height) / 375 >> 4above 65535, which needswidth + heightover about 3.1 million) now reaches the existingmax_window * max_window >= CAMBI_RECIPROCAL_LUT_SIZEcheck instead of wrapping (from reading the code; no input that large was run).I checked every
VMAF_OPT_TYPE_*option table inlibvmaf/srcagainst the declared type of its field (a script over.offset = offsetof(S, f), .type = T). The only other mismatch isfloat_adm.cadm_adm3_apply_hm, aVMAF_OPT_TYPE_BOOLoption stored in anint; it is aligned and sized so it does not trip the sanitizer, and this change leaves it alone.Test
test_integer_options_fill_int_fieldsinlibvmaf/test/test_cambi.c: on a zeroedCambiStateit sets everyVMAF_OPT_TYPE_INToption to its default throughvmaf_option_set()and asserts that each offset is a multiple of_Alignof(int), thatwindow_sizeandmax_log_contrastareintsized, that the defaults arrive, and thatsrc_window_sizeandvlt_lumakeep their values. On master it fails at the first assertion ("integer option offset is a multiple of alignof(int)"), in a release and in an ASan/UBSan build; with the change it passes.test_adjust_window_sizeusesintnow.Validation
x86-64 Linux, GCC 16.2.1, master
9e48141b. Rebased on master9e48141b(2026-10-02); the counts below and the repro were re-run on it.meson testwith-Denable_float=true -Denable_checkasm=true: 25/25 on master and here.-Db_sanitize=address,undefined -Db_lto=false, same options: 22 pass and 3 fail of 25 on both; the failures aretest_predictandtest_pic_preallocation(SIGABRT, LeakSanitizer) andcheckasm(heap-buffer-overflow inadm_dwt2_16,integer_adm.c:2603), all unchanged by this change..engagement/golden_compare.py, master binary vs this branch: ALL IDENTICAL.Relation to other changes
#1571 moves
CambiStateintocambi.hand changestest_cambi.c; the two conflict textually (struct fields,meson.build, test file). The resolution is the same three field types incambi.h.