FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/tests/dnn-layer-pad.c
Date: 2022-12-05 03:11:11
Exec Total Coverage
Lines: 80 92 87.0%
Functions: 4 4 100.0%
Branches: 12 18 66.7%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019 Guo Yejun
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include "libavfilter/dnn/dnn_backend_native_layer_pad.h"
25
26 #define EPSON 0.00001
27
28 1 static int test_with_mode_symmetric(void)
29 {
30 // the input data and expected data are generated with below python code.
31 /*
32 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
33 y = tf.pad(x, [[0, 0], [2, 3], [3, 2], [0, 0]], 'SYMMETRIC')
34 data = np.arange(48).reshape(1, 4, 4, 3);
35
36 sess=tf.Session()
37 sess.run(tf.global_variables_initializer())
38 output = sess.run(y, feed_dict={x: data})
39
40 print(list(data.flatten()))
41 print(list(output.flatten()))
42 print(data.shape)
43 print(output.shape)
44 */
45
46 LayerPadParams params;
47 DnnOperand operands[2];
48 int32_t input_indexes[1];
49 1 float input[1*4*4*3] = {
50 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
51 };
52 1 float expected_output[1*9*9*3] = {
53 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 6.0, 7.0, 8.0, 3.0,
54 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 6.0, 7.0, 8.0, 3.0, 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0,
55 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0,
56 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 30.0, 31.0, 32.0, 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0,
57 34.0, 35.0, 30.0, 31.0, 32.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0,
58 44.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0, 44.0, 30.0, 31.0, 32.0,
59 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0, 34.0, 35.0, 30.0, 31.0, 32.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0,
60 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0
61 };
62 float *output;
63
64 1 params.mode = LPMP_SYMMETRIC;
65 1 params.paddings[0][0] = 0;
66 1 params.paddings[0][1] = 0;
67 1 params.paddings[1][0] = 2;
68 1 params.paddings[1][1] = 3;
69 1 params.paddings[2][0] = 3;
70 1 params.paddings[2][1] = 2;
71 1 params.paddings[3][0] = 0;
72 1 params.paddings[3][1] = 0;
73
74 1 operands[0].data = input;
75 1 operands[0].dims[0] = 1;
76 1 operands[0].dims[1] = 4;
77 1 operands[0].dims[2] = 4;
78 1 operands[0].dims[3] = 3;
79 1 operands[1].data = NULL;
80
81 1 input_indexes[0] = 0;
82 1 ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
83
84 1 output = operands[1].data;
85
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 1 times.
244 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243 times.
243 if (fabs(output[i] - expected_output[i]) > EPSON) {
87 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
88 av_freep(&output);
89 return 1;
90 }
91 }
92
93 1 av_freep(&output);
94 1 return 0;
95
96 }
97
98 1 static int test_with_mode_reflect(void)
99 {
100 // the input data and expected data are generated with below python code.
101 /*
102 x = tf.placeholder(tf.float32, shape=[3, None, None, 3])
103 y = tf.pad(x, [[1, 2], [0, 0], [0, 0], [0, 0]], 'REFLECT')
104 data = np.arange(36).reshape(3, 2, 2, 3);
105
106 sess=tf.Session()
107 sess.run(tf.global_variables_initializer())
108 output = sess.run(y, feed_dict={x: data})
109
110 print(list(data.flatten()))
111 print(list(output.flatten()))
112 print(data.shape)
113 print(output.shape)
114 */
115
116 LayerPadParams params;
117 DnnOperand operands[2];
118 int32_t input_indexes[1];
119 1 float input[3*2*2*3] = {
120 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
121 };
122 1 float expected_output[6*2*2*3] = {
123 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
124 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0,
125 35.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0
126 };
127 float *output;
128
129 1 params.mode = LPMP_REFLECT;
130 1 params.paddings[0][0] = 1;
131 1 params.paddings[0][1] = 2;
132 1 params.paddings[1][0] = 0;
133 1 params.paddings[1][1] = 0;
134 1 params.paddings[2][0] = 0;
135 1 params.paddings[2][1] = 0;
136 1 params.paddings[3][0] = 0;
137 1 params.paddings[3][1] = 0;
138
139 1 operands[0].data = input;
140 1 operands[0].dims[0] = 3;
141 1 operands[0].dims[1] = 2;
142 1 operands[0].dims[2] = 2;
143 1 operands[0].dims[3] = 3;
144 1 operands[1].data = NULL;
145
146 1 input_indexes[0] = 0;
147 1 ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
148
149 1 output = operands[1].data;
150
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 1 times.
73 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (fabs(output[i] - expected_output[i]) > EPSON) {
152 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
153 av_freep(&output);
154 return 1;
155 }
156 }
157
158 1 av_freep(&output);
159 1 return 0;
160
161 }
162
163 1 static int test_with_mode_constant(void)
164 {
165 // the input data and expected data are generated with below python code.
166 /*
167 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
168 y = tf.pad(x, [[0, 0], [1, 0], [0, 0], [1, 2]], 'CONSTANT', constant_values=728)
169 data = np.arange(12).reshape(1, 2, 2, 3);
170
171 sess=tf.Session()
172 sess.run(tf.global_variables_initializer())
173 output = sess.run(y, feed_dict={x: data})
174
175 print(list(data.flatten()))
176 print(list(output.flatten()))
177 print(data.shape)
178 print(output.shape)
179 */
180
181 LayerPadParams params;
182 DnnOperand operands[2];
183 int32_t input_indexes[1];
184 1 float input[1*2*2*3] = {
185 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
186 };
187 1 float expected_output[1*3*2*6] = {
188 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0,
189 728.0, 728.0, 0.0, 1.0, 2.0, 728.0, 728.0, 728.0, 3.0, 4.0, 5.0, 728.0, 728.0,
190 728.0, 6.0, 7.0, 8.0, 728.0, 728.0, 728.0, 9.0, 10.0, 11.0, 728.0, 728.0
191 };
192 float *output;
193
194 1 params.mode = LPMP_CONSTANT;
195 1 params.constant_values = 728;
196 1 params.paddings[0][0] = 0;
197 1 params.paddings[0][1] = 0;
198 1 params.paddings[1][0] = 1;
199 1 params.paddings[1][1] = 0;
200 1 params.paddings[2][0] = 0;
201 1 params.paddings[2][1] = 0;
202 1 params.paddings[3][0] = 1;
203 1 params.paddings[3][1] = 2;
204
205 1 operands[0].data = input;
206 1 operands[0].dims[0] = 1;
207 1 operands[0].dims[1] = 2;
208 1 operands[0].dims[2] = 2;
209 1 operands[0].dims[3] = 3;
210 1 operands[1].data = NULL;
211
212 1 input_indexes[0] = 0;
213 1 ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
214
215 1 output = operands[1].data;
216
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1 times.
37 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (fabs(output[i] - expected_output[i]) > EPSON) {
218 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
219 av_freep(&output);
220 return 1;
221 }
222 }
223
224 1 av_freep(&output);
225 1 return 0;
226
227 }
228
229 1 int main(int argc, char **argv)
230 {
231
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (test_with_mode_symmetric())
232 return 1;
233
234
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (test_with_mode_reflect())
235 return 1;
236
237
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (test_with_mode_constant())
238 return 1;
239 }
240