/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 |