FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/h26x/h2656_sao_template.c
Date: 2026-08-14 15:11:37
Exec Total Coverage
Lines: 122 122 100.0%
Functions: 11 16 68.8%
Branches: 122 122 100.0%

Line Branch Exec Source
1 /*
2 * HEVC/VVC SAO template
3 *
4 * Copyright (C) 2024 Nuo Mi
5 * Copyright (C) 2012 - 2013 Guillaume Martres
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 252638 static void FUNC(sao_band_filter)(uint8_t *_dst, const uint8_t *_src,
25 ptrdiff_t stride_dst, ptrdiff_t stride_src,
26 const int16_t *sao_offset_val, int sao_left_class,
27 int width, int height)
28 {
29 252638 pixel *dst = (pixel *)_dst;
30 252638 const pixel *src = (const pixel *)_src;
31 252638 int offset_table[32] = { 0 };
32 int k, y, x;
33 252638 int shift = BIT_DEPTH - 5;
34
35 252638 stride_dst /= sizeof(pixel);
36 252638 stride_src /= sizeof(pixel);
37
38
2/2
✓ Branch 0 taken 505276 times.
✓ Branch 1 taken 126319 times.
1263190 for (k = 0; k < 4; k++)
39 1010552 offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1];
40
2/2
✓ Branch 0 taken 5205880 times.
✓ Branch 1 taken 126319 times.
10664398 for (y = 0; y < height; y++) {
41
2/2
✓ Branch 0 taken 303008576 times.
✓ Branch 1 taken 5205880 times.
616428912 for (x = 0; x < width; x++)
42 606017152 dst[x] = av_clip_pixel(src[x] + offset_table[(src[x] >> shift) & 31]);
43 10411760 dst += stride_dst;
44 10411760 src += stride_src;
45 }
46 252638 }
47
48 #define CMP(a, b) (((a) > (b)) - ((a) < (b)))
49
50 1285398 static void FUNC(sao_edge_filter)(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, const int16_t *sao_offset_val,
51 int eo, int width, int height) {
52
53 static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
54 static const int8_t pos[4][2][2] = {
55 { { -1, 0 }, { 1, 0 } }, // horizontal
56 { { 0, -1 }, { 0, 1 } }, // vertical
57 { { -1, -1 }, { 1, 1 } }, // 45 degree
58 { { 1, -1 }, { -1, 1 } }, // 135 degree
59 };
60 1285398 pixel *dst = (pixel *)_dst;
61 1285398 const pixel *src = (const pixel *)_src;
62 int a_stride, b_stride;
63 int x, y;
64 1285398 ptrdiff_t stride_src = (2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) / sizeof(pixel);
65 1285398 stride_dst /= sizeof(pixel);
66
67 1285398 a_stride = pos[eo][0][0] + pos[eo][0][1] * stride_src;
68 1285398 b_stride = pos[eo][1][0] + pos[eo][1][1] * stride_src;
69
2/2
✓ Branch 0 taken 29425800 times.
✓ Branch 1 taken 642699 times.
60136998 for (y = 0; y < height; y++) {
70
2/2
✓ Branch 0 taken 1527783104 times.
✓ Branch 1 taken 29425800 times.
3114417808 for (x = 0; x < width; x++) {
71 3055566208 int diff0 = CMP(src[x], src[x + a_stride]);
72 3055566208 int diff1 = CMP(src[x], src[x + b_stride]);
73 3055566208 int offset_val = edge_idx[2 + diff0 + diff1];
74 3055566208 dst[x] = av_clip_pixel(src[x] + sao_offset_val[offset_val]);
75 }
76 58851600 src += stride_src;
77 58851600 dst += stride_dst;
78 }
79 1285398 }
80
81 1230426 static void FUNC(sao_edge_restore_0)(uint8_t *_dst, const uint8_t *_src,
82 ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao,
83 const int *borders, int _width, int _height,
84 int c_idx, const uint8_t *vert_edge,
85 const uint8_t *horiz_edge, const uint8_t *diag_edge)
86 {
87 int x, y;
88 1230426 pixel *dst = (pixel *)_dst;
89 1230426 const pixel *src = (const pixel *)_src;
90 1230426 const int16_t *sao_offset_val = sao->offset_val[c_idx];
91 1230426 int sao_eo_class = sao->eo_class[c_idx];
92 1230426 int init_x = 0, width = _width, height = _height;
93
94 1230426 stride_dst /= sizeof(pixel);
95 1230426 stride_src /= sizeof(pixel);
96
97
2/2
✓ Branch 0 taken 502283 times.
✓ Branch 1 taken 112930 times.
1230426 if (sao_eo_class != SAO_EO_VERT) {
98
2/2
✓ Branch 0 taken 16605 times.
✓ Branch 1 taken 485678 times.
1004566 if (borders[0]) {
99 33210 int offset_val = sao_offset_val[0];
100
2/2
✓ Branch 0 taken 792048 times.
✓ Branch 1 taken 16605 times.
1617306 for (y = 0; y < height; y++) {
101 1584096 dst[y * stride_dst] = av_clip_pixel(src[y * stride_src] + offset_val);
102 }
103 33210 init_x = 1;
104 }
105
2/2
✓ Branch 0 taken 18481 times.
✓ Branch 1 taken 483802 times.
1004566 if (borders[2]) {
106 36962 int offset_val = sao_offset_val[0];
107 36962 int offset = width - 1;
108
2/2
✓ Branch 0 taken 855744 times.
✓ Branch 1 taken 18481 times.
1748450 for (x = 0; x < height; x++) {
109 1711488 dst[x * stride_dst + offset] = av_clip_pixel(src[x * stride_src + offset] + offset_val);
110 }
111 36962 width--;
112 }
113 }
114
2/2
✓ Branch 0 taken 511751 times.
✓ Branch 1 taken 103462 times.
1230426 if (sao_eo_class != SAO_EO_HORIZ) {
115
2/2
✓ Branch 0 taken 21398 times.
✓ Branch 1 taken 490353 times.
1023502 if (borders[1]) {
116 42796 int offset_val = sao_offset_val[0];
117
2/2
✓ Branch 0 taken 1029649 times.
✓ Branch 1 taken 21398 times.
2102094 for (x = init_x; x < width; x++)
118 2059298 dst[x] = av_clip_pixel(src[x] + offset_val);
119 }
120
2/2
✓ Branch 0 taken 28307 times.
✓ Branch 1 taken 483444 times.
1023502 if (borders[3]) {
121 56614 int offset_val = sao_offset_val[0];
122 56614 ptrdiff_t y_stride_dst = stride_dst * (height - 1);
123 56614 ptrdiff_t y_stride_src = stride_src * (height - 1);
124
2/2
✓ Branch 0 taken 1328034 times.
✓ Branch 1 taken 28307 times.
2712682 for (x = init_x; x < width; x++)
125 2656068 dst[x + y_stride_dst] = av_clip_pixel(src[x + y_stride_src] + offset_val);
126 56614 height--;
127 }
128 }
129 1230426 }
130
131 72028 static void FUNC(sao_edge_restore_1)(uint8_t *_dst, const uint8_t *_src,
132 ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao,
133 const int *borders, int _width, int _height,
134 int c_idx, const uint8_t *vert_edge,
135 const uint8_t *horiz_edge, const uint8_t *diag_edge)
136 {
137 int x, y;
138 72028 pixel *dst = (pixel *)_dst;
139 72028 const pixel *src = (const pixel *)_src;
140 72028 const int16_t *sao_offset_val = sao->offset_val[c_idx];
141 72028 int sao_eo_class = sao->eo_class[c_idx];
142 72028 int init_x = 0, init_y = 0, width = _width, height = _height;
143
144 72028 stride_dst /= sizeof(pixel);
145 72028 stride_src /= sizeof(pixel);
146
147
2/2
✓ Branch 0 taken 24174 times.
✓ Branch 1 taken 11840 times.
72028 if (sao_eo_class != SAO_EO_VERT) {
148
2/2
✓ Branch 0 taken 2079 times.
✓ Branch 1 taken 22095 times.
48348 if (borders[0]) {
149 4158 int offset_val = sao_offset_val[0];
150
2/2
✓ Branch 0 taken 138712 times.
✓ Branch 1 taken 2079 times.
281582 for (y = 0; y < height; y++) {
151 277424 dst[y * stride_dst] = av_clip_pixel(src[y * stride_src] + offset_val);
152 }
153 4158 init_x = 1;
154 }
155
2/2
✓ Branch 0 taken 1504 times.
✓ Branch 1 taken 22670 times.
48348 if (borders[2]) {
156 3008 int offset_val = sao_offset_val[0];
157 3008 int offset = width - 1;
158
2/2
✓ Branch 0 taken 103152 times.
✓ Branch 1 taken 1504 times.
209312 for (x = 0; x < height; x++) {
159 206304 dst[x * stride_dst + offset] = av_clip_pixel(src[x * stride_src + offset] + offset_val);
160 }
161 3008 width--;
162 }
163 }
164
2/2
✓ Branch 0 taken 25977 times.
✓ Branch 1 taken 10037 times.
72028 if (sao_eo_class != SAO_EO_HORIZ) {
165
2/2
✓ Branch 0 taken 3510 times.
✓ Branch 1 taken 22467 times.
51954 if (borders[1]) {
166 7020 int offset_val = sao_offset_val[0];
167
2/2
✓ Branch 0 taken 234673 times.
✓ Branch 1 taken 3510 times.
476366 for (x = init_x; x < width; x++)
168 469346 dst[x] = av_clip_pixel(src[x] + offset_val);
169 7020 init_y = 1;
170 }
171
2/2
✓ Branch 0 taken 3296 times.
✓ Branch 1 taken 22681 times.
51954 if (borders[3]) {
172 6592 int offset_val = sao_offset_val[0];
173 6592 ptrdiff_t y_stride_dst = stride_dst * (height - 1);
174 6592 ptrdiff_t y_stride_src = stride_src * (height - 1);
175
2/2
✓ Branch 0 taken 224013 times.
✓ Branch 1 taken 3296 times.
454618 for (x = init_x; x < width; x++)
176 448026 dst[x + y_stride_dst] = av_clip_pixel(src[x + y_stride_src] + offset_val);
177 6592 height--;
178 }
179 }
180
181 {
182
8/8
✓ Branch 0 taken 35317 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 5788 times.
✓ Branch 3 taken 29529 times.
✓ Branch 4 taken 5286 times.
✓ Branch 5 taken 502 times.
✓ Branch 6 taken 4748 times.
✓ Branch 7 taken 538 times.
72028 int save_upper_left = !diag_edge[0] && sao_eo_class == SAO_EO_135D && !borders[0] && !borders[1];
183
8/8
✓ Branch 0 taken 35202 times.
✓ Branch 1 taken 812 times.
✓ Branch 2 taken 7897 times.
✓ Branch 3 taken 27305 times.
✓ Branch 4 taken 6585 times.
✓ Branch 5 taken 1312 times.
✓ Branch 6 taken 6156 times.
✓ Branch 7 taken 429 times.
72028 int save_upper_right = !diag_edge[1] && sao_eo_class == SAO_EO_45D && !borders[1] && !borders[2];
184
8/8
✓ Branch 0 taken 35007 times.
✓ Branch 1 taken 1007 times.
✓ Branch 2 taken 5719 times.
✓ Branch 3 taken 29288 times.
✓ Branch 4 taken 5319 times.
✓ Branch 5 taken 400 times.
✓ Branch 6 taken 4540 times.
✓ Branch 7 taken 779 times.
72028 int save_lower_right = !diag_edge[2] && sao_eo_class == SAO_EO_135D && !borders[2] && !borders[3];
185
8/8
✓ Branch 0 taken 35084 times.
✓ Branch 1 taken 930 times.
✓ Branch 2 taken 7923 times.
✓ Branch 3 taken 27161 times.
✓ Branch 4 taken 7040 times.
✓ Branch 5 taken 883 times.
✓ Branch 6 taken 6096 times.
✓ Branch 7 taken 944 times.
72028 int save_lower_left = !diag_edge[3] && sao_eo_class == SAO_EO_45D && !borders[0] && !borders[3];
186
187 // Restore pixels that can't be modified
188
4/4
✓ Branch 0 taken 434 times.
✓ Branch 1 taken 35580 times.
✓ Branch 2 taken 320 times.
✓ Branch 3 taken 114 times.
72028 if(vert_edge[0] && sao_eo_class != SAO_EO_VERT) {
189
2/2
✓ Branch 0 taken 26483 times.
✓ Branch 1 taken 320 times.
53606 for(y = init_y+save_upper_left; y< height-save_lower_left; y++)
190 52966 dst[y*stride_dst] = src[y*stride_src];
191 }
192
4/4
✓ Branch 0 taken 542 times.
✓ Branch 1 taken 35472 times.
✓ Branch 2 taken 423 times.
✓ Branch 3 taken 119 times.
72028 if(vert_edge[1] && sao_eo_class != SAO_EO_VERT) {
193
2/2
✓ Branch 0 taken 32866 times.
✓ Branch 1 taken 423 times.
66578 for(y = init_y+save_upper_right; y< height-save_lower_right; y++)
194 65732 dst[y*stride_dst+width-1] = src[y*stride_src+width-1];
195 }
196
197
4/4
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 35468 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 147 times.
72028 if(horiz_edge[0] && sao_eo_class != SAO_EO_HORIZ) {
198
2/2
✓ Branch 0 taken 27468 times.
✓ Branch 1 taken 399 times.
55734 for(x = init_x+save_upper_left; x < width-save_upper_right; x++)
199 54936 dst[x] = src[x];
200 }
201
4/4
✓ Branch 0 taken 782 times.
✓ Branch 1 taken 35232 times.
✓ Branch 2 taken 579 times.
✓ Branch 3 taken 203 times.
72028 if(horiz_edge[1] && sao_eo_class != SAO_EO_HORIZ) {
202
2/2
✓ Branch 0 taken 40738 times.
✓ Branch 1 taken 579 times.
82634 for(x = init_x+save_lower_left; x < width-save_lower_right; x++)
203 81476 dst[(height-1)*stride_dst+x] = src[(height-1)*stride_src+x];
204 }
205
4/4
✓ Branch 0 taken 697 times.
✓ Branch 1 taken 35317 times.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 526 times.
72028 if(diag_edge[0] && sao_eo_class == SAO_EO_135D)
206 342 dst[0] = src[0];
207
4/4
✓ Branch 0 taken 812 times.
✓ Branch 1 taken 35202 times.
✓ Branch 2 taken 281 times.
✓ Branch 3 taken 531 times.
72028 if(diag_edge[1] && sao_eo_class == SAO_EO_45D)
208 562 dst[width-1] = src[width-1];
209
4/4
✓ Branch 0 taken 1007 times.
✓ Branch 1 taken 35007 times.
✓ Branch 2 taken 240 times.
✓ Branch 3 taken 767 times.
72028 if(diag_edge[2] && sao_eo_class == SAO_EO_135D)
210 480 dst[stride_dst*(height-1)+width-1] = src[stride_src*(height-1)+width-1];
211
4/4
✓ Branch 0 taken 930 times.
✓ Branch 1 taken 35084 times.
✓ Branch 2 taken 255 times.
✓ Branch 3 taken 675 times.
72028 if(diag_edge[3] && sao_eo_class == SAO_EO_45D)
212 510 dst[stride_dst*(height-1)] = src[stride_src*(height-1)];
213
214 }
215 72028 }
216
217 #undef CMP
218