Skip to content

Commit 7e16db0

Browse files
ssablin-metakylophone
authored andcommitted
ssim: add scale parameter to control decimation factor
The SSIM feature extractor internally downscales input images to a resolution in the 256-384 pixel range before computing the SSIM score. For high-resolution content this discards fine spatial detail, causing SSIM to underestimate quality differences between codecs. Add a user-controllable "scale" integer parameter (0-10) to the float_ssim feature extractor: - scale=0 (default): auto-compute from resolution (existing behavior) - scale=1: no downscaling, compute SSIM at original resolution - scale=2..10: explicit integer decimation factor Usage: --feature float_ssim=scale=1 This change is backward-compatible: the default value of 0 preserves the existing auto-scaling behavior. No CLI parsing changes are needed since the feature option infrastructure already supports key=value pairs. See CWG-G053i for detailed analysis of the issue and BD-rate results demonstrating the impact of downscaling on SSIM accuracy at high resolutions.
1 parent 332dde6 commit 7e16db0

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

libvmaf/src/feature/float_ssim.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef struct SsimState {
3535
bool enable_db;
3636
bool clip_db;
3737
double max_db;
38+
int scale;
3839
} SsimState;
3940

4041
static const VmafOption options[] = {
@@ -59,6 +60,15 @@ static const VmafOption options[] = {
5960
.type = VMAF_OPT_TYPE_BOOL,
6061
.default_val.b = false,
6162
},
63+
{
64+
.name = "scale",
65+
.help = "decimation scale factor (0=auto, 1=no downscaling, 2-10=explicit)",
66+
.offset = offsetof(SsimState, scale),
67+
.type = VMAF_OPT_TYPE_INT,
68+
.default_val.i = 0,
69+
.min = 0,
70+
.max = 10,
71+
},
6272
{ 0 }
6373
};
6474

@@ -115,7 +125,7 @@ static int extract(VmafFeatureExtractor *fex,
115125
double score, l_score, c_score, s_score;
116126
err = compute_ssim(s->ref, s->dist, ref_pic->w[0], ref_pic->h[0],
117127
s->float_stride, s->float_stride,
118-
&score, &l_score, &c_score, &s_score);
128+
&score, &l_score, &c_score, &s_score, s->scale);
119129
if (err) return err;
120130

121131
if (s->enable_db)

libvmaf/src/feature/ssim.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ float _ssim_reduce(int w, int h, void *ctx)
4747

4848
int compute_ssim(const float *ref, const float *cmp, int w, int h,
4949
int ref_stride, int cmp_stride, double *score,
50-
double *l_score, double *c_score, double *s_score)
50+
double *l_score, double *c_score, double *s_score,
51+
int scale_override)
5152
{
5253

5354
int ret = 1;
@@ -77,7 +78,11 @@ int compute_ssim(const float *ref, const float *cmp, int w, int h,
7778
int gaussian = 1; /* 0 for 8x8 square window, 1 for 11x11 circular-symmetric Gaussian window (default) */
7879

7980
/* initialize algorithm parameters */
80-
scale = _max( 1, _round( (float)_min(w,h) / 256.0f ) );
81+
if (scale_override > 0) {
82+
scale = scale_override;
83+
} else {
84+
scale = _max( 1, _round( (float)_min(w,h) / 256.0f ) );
85+
}
8186
if (args) {
8287
if(args->f) {
8388
scale = args->f;

libvmaf/src/feature/ssim.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818

1919
int compute_ssim(const float *ref, const float *cmp, int w, int h,
2020
int ref_stride, int cmp_stride, double *score,
21-
double *l_score, double *c_score, double *s_score);
21+
double *l_score, double *c_score, double *s_score,
22+
int scale_override);

0 commit comments

Comments
 (0)