Coverage Report

Created: 2026-05-16 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/svt_psnr.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4
 * This source code is subject to the terms of the BSD 2 Clause License and
5
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
 * was not distributed with this source code in the LICENSE file, you can
7
 * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8
 * Media Patent License 1.0 was not distributed with this source code in the
9
 * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10
 */
11
12
#include "definitions.h"
13
#include <assert.h>
14
#include <math.h>
15
#include "svt_psnr.h"
16
#include "pic_buffer_desc.h"
17
#include "aom_dsp_rtcd.h"
18
19
static inline uint32_t variance(const uint8_t* a, int32_t a_stride, const uint8_t* b, int32_t b_stride, int32_t w,
20
0
                                int32_t h) {
21
0
    int      i, j;
22
0
    uint32_t sse = 0;
23
24
0
    for (i = 0; i < h; ++i) {
25
0
        for (j = 0; j < w; ++j) {
26
0
            sse += SQR(a[j] - b[j]);
27
0
        }
28
29
0
        a += a_stride;
30
0
        b += b_stride;
31
0
    }
32
0
    return sse;
33
0
}
34
35
uint32_t svt_aom_mse16x16_c(const uint8_t* src_ptr, int32_t source_stride, const uint8_t* ref_ptr,
36
0
                            int32_t recon_stride) {
37
0
    return variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16);
38
0
}
39
40
int64_t svt_aom_get_sse(const uint8_t* a, int32_t a_stride, const uint8_t* b, int32_t b_stride, int32_t width,
41
0
                        int32_t height) {
42
0
    const int32_t dw        = width & 15;
43
0
    const int32_t dh        = height & 15;
44
0
    int64_t       total_sse = 0;
45
0
    uint32_t      sse;
46
0
    int32_t       x, y;
47
48
0
    if (dw > 0) {
49
0
        sse = variance(&a[width - dw], a_stride, &b[width - dw], b_stride, dw, height);
50
0
        total_sse += sse;
51
0
    }
52
53
0
    if (dh > 0) {
54
0
        sse = variance(&a[(height - dh) * a_stride], a_stride, &b[(height - dh) * b_stride], b_stride, width - dw, dh);
55
0
        total_sse += sse;
56
0
    }
57
58
0
    for (y = 0; y < height / 16; ++y) {
59
0
        const uint8_t* pa = a;
60
0
        const uint8_t* pb = b;
61
0
        for (x = 0; x < width / 16; ++x) {
62
0
            sse = svt_aom_mse16x16(pa, a_stride, pb, b_stride);
63
64
0
            total_sse += sse;
65
66
0
            pa += 16;
67
0
            pb += 16;
68
0
        }
69
70
0
        a += 16 * a_stride;
71
0
        b += 16 * b_stride;
72
0
    }
73
74
0
    return total_sse;
75
0
}
76
77
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
78
static inline int64_t highbd_variance(const uint8_t* a8, int32_t a_stride, const uint8_t* b8, int32_t b_stride,
79
0
                                      int32_t w, int32_t h) {
80
0
    const uint16_t* a   = CONVERT_TO_SHORTPTR(a8);
81
0
    const uint16_t* b   = CONVERT_TO_SHORTPTR(b8);
82
0
    int64_t         sse = 0;
83
0
    for (int32_t i = 0; i < h; ++i) {
84
0
        for (int32_t j = 0; j < w; ++j) {
85
0
            sse += (uint32_t)(SQR(a[j] - b[j]));
86
0
        }
87
0
        a += a_stride;
88
0
        b += b_stride;
89
0
    }
90
0
    return sse;
91
0
}
92
93
int64_t svt_aom_highbd_get_sse(const uint8_t* a, int32_t a_stride, const uint8_t* b, int32_t b_stride, int32_t width,
94
0
                               int32_t height) {
95
0
    int64_t       total_sse = 0;
96
0
    int32_t       x, y;
97
0
    const int32_t dw = width % 16;
98
0
    const int32_t dh = height % 16;
99
0
    uint32_t      sse;
100
0
    if (dw > 0) {
101
0
        sse = (uint32_t)highbd_variance(&a[width - dw], a_stride, &b[width - dw], b_stride, dw, height);
102
0
        total_sse += sse;
103
0
    }
104
0
    if (dh > 0) {
105
0
        sse = (uint32_t)highbd_variance(
106
0
            &a[(height - dh) * a_stride], a_stride, &b[(height - dh) * b_stride], b_stride, width - dw, dh);
107
0
        total_sse += sse;
108
0
    }
109
0
    for (y = 0; y < height / 16; ++y) {
110
0
        const uint8_t* pa = a;
111
0
        const uint8_t* pb = b;
112
0
        for (x = 0; x < width / 16; ++x) {
113
0
            sse = svt_aom_highbd_mse16x16(pa, a_stride, pb, b_stride);
114
115
0
            total_sse += sse;
116
0
            pa += 16;
117
0
            pb += 16;
118
0
        }
119
0
        a += 16 * a_stride;
120
0
        b += 16 * b_stride;
121
0
    }
122
0
    return total_sse;
123
0
}
124
125
static void highbd_variance64(const uint8_t* a8, int a_stride, const uint8_t* b8, int b_stride, int w, int h,
126
0
                              uint64_t* sse, int64_t* sum) {
127
0
    const uint16_t* a    = CONVERT_TO_SHORTPTR(a8);
128
0
    const uint16_t* b    = CONVERT_TO_SHORTPTR(b8);
129
0
    int64_t         tsum = 0;
130
0
    uint64_t        tsse = 0;
131
0
    for (int i = 0; i < h; ++i) {
132
0
        int32_t lsum = 0;
133
0
        for (int j = 0; j < w; ++j) {
134
0
            const int diff = a[j] - b[j];
135
0
            lsum += diff;
136
0
            tsse += (uint32_t)(diff * diff);
137
0
        }
138
0
        tsum += lsum;
139
0
        a += a_stride;
140
0
        b += b_stride;
141
0
    }
142
0
    *sum = tsum;
143
0
    *sse = tsse;
144
0
}
145
146
static void highbd_10_variance(const uint8_t* a8, int a_stride, const uint8_t* b8, int b_stride, int w, int h,
147
0
                               uint32_t* sse, int* sum) {
148
0
    uint64_t sse_long = 0;
149
0
    int64_t  sum_long = 0;
150
0
    highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long);
151
0
    *sse = (uint32_t)ROUND_POWER_OF_TWO(sse_long, 4);
152
0
    *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2);
153
0
}
154
155
#define HIGHBD_VAR(W, H)                                                                 \
156
    uint32_t svt_aom_highbd_10_variance##W##x##H##_c(                                    \
157
0
        const uint8_t* a, int a_stride, const uint8_t* b, int b_stride, uint32_t* sse) { \
158
0
        int     sum;                                                                     \
159
0
        int64_t var;                                                                     \
160
0
        highbd_10_variance(a, a_stride, b, b_stride, W, H, sse, &sum);                   \
161
0
        var = (int64_t)(*sse) - (((int64_t)sum * sum) / (W * H));                        \
162
0
        return (var >= 0) ? (uint32_t)var : 0;                                           \
163
0
    }
Unexecuted instantiation: svt_aom_highbd_10_variance128x128_c
Unexecuted instantiation: svt_aom_highbd_10_variance128x64_c
Unexecuted instantiation: svt_aom_highbd_10_variance64x128_c
Unexecuted instantiation: svt_aom_highbd_10_variance64x64_c
Unexecuted instantiation: svt_aom_highbd_10_variance64x32_c
Unexecuted instantiation: svt_aom_highbd_10_variance32x64_c
Unexecuted instantiation: svt_aom_highbd_10_variance32x32_c
Unexecuted instantiation: svt_aom_highbd_10_variance32x16_c
Unexecuted instantiation: svt_aom_highbd_10_variance16x32_c
Unexecuted instantiation: svt_aom_highbd_10_variance16x16_c
Unexecuted instantiation: svt_aom_highbd_10_variance16x8_c
Unexecuted instantiation: svt_aom_highbd_10_variance8x16_c
Unexecuted instantiation: svt_aom_highbd_10_variance8x8_c
Unexecuted instantiation: svt_aom_highbd_10_variance8x4_c
Unexecuted instantiation: svt_aom_highbd_10_variance4x8_c
Unexecuted instantiation: svt_aom_highbd_10_variance4x4_c
Unexecuted instantiation: svt_aom_highbd_10_variance4x16_c
Unexecuted instantiation: svt_aom_highbd_10_variance16x4_c
Unexecuted instantiation: svt_aom_highbd_10_variance8x32_c
Unexecuted instantiation: svt_aom_highbd_10_variance32x8_c
Unexecuted instantiation: svt_aom_highbd_10_variance16x64_c
Unexecuted instantiation: svt_aom_highbd_10_variance64x16_c
164
165
HIGHBD_VAR(128, 128)
166
HIGHBD_VAR(128, 64)
167
HIGHBD_VAR(64, 128)
168
HIGHBD_VAR(64, 64)
169
HIGHBD_VAR(64, 32)
170
HIGHBD_VAR(32, 64)
171
HIGHBD_VAR(32, 32)
172
HIGHBD_VAR(32, 16)
173
HIGHBD_VAR(16, 32)
174
HIGHBD_VAR(16, 16)
175
HIGHBD_VAR(16, 8)
176
HIGHBD_VAR(8, 16)
177
HIGHBD_VAR(8, 8)
178
HIGHBD_VAR(8, 4)
179
HIGHBD_VAR(4, 8)
180
HIGHBD_VAR(4, 4)
181
HIGHBD_VAR(4, 16)
182
HIGHBD_VAR(16, 4)
183
HIGHBD_VAR(8, 32)
184
HIGHBD_VAR(32, 8)
185
HIGHBD_VAR(16, 64)
186
HIGHBD_VAR(64, 16)
187
#endif
188
189
int64_t svt_aom_get_y_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart, int32_t width,
190
0
                               int32_t vstart, int32_t height) {
191
0
    return svt_aom_get_sse(a->y_buffer + vstart * a->y_stride + hstart,
192
0
                           a->y_stride,
193
0
                           b->y_buffer + vstart * b->y_stride + hstart,
194
0
                           b->y_stride,
195
0
                           width,
196
0
                           height);
197
0
}
198
199
int64_t svt_aom_get_u_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart, int32_t width,
200
0
                               int32_t vstart, int32_t height) {
201
0
    return svt_aom_get_sse(a->u_buffer + vstart * a->uv_stride + hstart,
202
0
                           a->uv_stride,
203
0
                           b->u_buffer + vstart * b->uv_stride + hstart,
204
0
                           b->uv_stride,
205
0
                           width,
206
0
                           height);
207
0
}
208
209
int64_t svt_aom_get_v_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart, int32_t width,
210
0
                               int32_t vstart, int32_t height) {
211
0
    return svt_aom_get_sse(a->v_buffer + vstart * a->uv_stride + hstart,
212
0
                           a->uv_stride,
213
0
                           b->v_buffer + vstart * b->uv_stride + hstart,
214
0
                           b->uv_stride,
215
0
                           width,
216
0
                           height);
217
0
}
218
219
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
220
int64_t svt_aom_highbd_get_y_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart,
221
0
                                      int32_t width, int32_t vstart, int32_t height) {
222
0
    return svt_aom_highbd_get_sse(a->y_buffer + vstart * a->y_stride + hstart,
223
0
                                  a->y_stride,
224
0
                                  b->y_buffer + vstart * b->y_stride + hstart,
225
0
                                  b->y_stride,
226
0
                                  width,
227
0
                                  height);
228
0
}
229
230
int64_t svt_aom_highbd_get_u_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart,
231
0
                                      int32_t width, int32_t vstart, int32_t height) {
232
0
    return svt_aom_highbd_get_sse(a->u_buffer + vstart * a->uv_stride + hstart,
233
0
                                  a->uv_stride,
234
0
                                  b->u_buffer + vstart * b->uv_stride + hstart,
235
0
                                  b->uv_stride,
236
0
                                  width,
237
0
                                  height);
238
0
}
239
240
int64_t svt_aom_highbd_get_v_sse_part(const Yv12BufferConfig* a, const Yv12BufferConfig* b, int32_t hstart,
241
0
                                      int32_t width, int32_t vstart, int32_t height) {
242
0
    return svt_aom_highbd_get_sse(a->v_buffer + vstart * a->uv_stride + hstart,
243
0
                                  a->uv_stride,
244
0
                                  b->v_buffer + vstart * b->uv_stride + hstart,
245
0
                                  b->uv_stride,
246
0
                                  width,
247
0
                                  height);
248
0
}
249
#endif