ffmpeg / tests / rotozoom.c @ e1e0ca70
History | View | Annotate | Download (7.55 KB)
1 | 66961636 | Michael Niedermayer | /*
|
---|---|---|---|
2 | * Generates a synthetic YUV video sequence suitable for codec testing.
|
||
3 | 01d193aa | Diego Biurrun | *
|
4 | * copyright (c) Sebastien Bechet <s.bechet@av7.net>
|
||
5 | *
|
||
6 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
7 | 01d193aa | Diego Biurrun | *
|
8 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
9 | 01d193aa | Diego Biurrun | * modify it under the terms of the GNU Lesser General Public
|
10 | * License as published by the Free Software Foundation; either
|
||
11 | * version 2.1 of the License, or (at your option) any later version.
|
||
12 | *
|
||
13 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
14 | 01d193aa | Diego Biurrun | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
16 | * Lesser General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU Lesser General Public
|
||
19 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
20 | 01d193aa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 | 66961636 | Michael Niedermayer | */
|
22 | 01d193aa | Diego Biurrun | |
23 | 66961636 | Michael Niedermayer | #include <stdlib.h> |
24 | #include <stdio.h> |
||
25 | 6afd3b92 | Michael Niedermayer | #include <inttypes.h> |
26 | |||
27 | f628559d | Diego Biurrun | #define FIXP (1 << 16) |
28 | #define MY_PI 205887 //(M_PI * FIX) |
||
29 | 6afd3b92 | Michael Niedermayer | |
30 | f628559d | Diego Biurrun | static int64_t int_pow(int64_t a, int p) |
31 | { |
||
32 | int64_t v = FIXP; |
||
33 | 6afd3b92 | Michael Niedermayer | |
34 | f628559d | Diego Biurrun | for (; p; p--) {
|
35 | v *= a; |
||
36 | v /= FIXP; |
||
37 | 6afd3b92 | Michael Niedermayer | } |
38 | |||
39 | return v;
|
||
40 | } |
||
41 | |||
42 | f628559d | Diego Biurrun | static int64_t int_sin(int64_t a)
|
43 | { |
||
44 | if (a < 0) |
||
45 | a = MY_PI - a; // 0..inf
|
||
46 | a %= 2 * MY_PI; // 0..2PI |
||
47 | 6afd3b92 | Michael Niedermayer | |
48 | f628559d | Diego Biurrun | if (a >= MY_PI * 3 / 2) |
49 | a -= 2 * MY_PI; // -PI / 2 .. 3PI / 2 |
||
50 | if (a >= MY_PI /2) |
||
51 | a = MY_PI - a; // -PI / 2 .. PI / 2
|
||
52 | 115329f1 | Diego Biurrun | |
53 | f628559d | Diego Biurrun | return a - int_pow(a, 3) / 6 + int_pow(a, 5) / 120 - int_pow(a, 7) / 5040; |
54 | 6afd3b92 | Michael Niedermayer | } |
55 | 66961636 | Michael Niedermayer | |
56 | #define SCALEBITS 8 |
||
57 | #define ONE_HALF (1 << (SCALEBITS - 1)) |
||
58 | f628559d | Diego Biurrun | #define FIX(x) ((int) ((x) * (1L << SCALEBITS) + 0.5)) |
59 | 66961636 | Michael Niedermayer | |
60 | 5a37c12c | Diego Biurrun | static void rgb24_to_yuv420p(unsigned char *lum, unsigned char *cb, |
61 | unsigned char *cr, unsigned char *src, |
||
62 | int width, int height) |
||
63 | 66961636 | Michael Niedermayer | { |
64 | int wrap, wrap3, x, y;
|
||
65 | int r, g, b, r1, g1, b1;
|
||
66 | 5a37c12c | Diego Biurrun | unsigned char *p; |
67 | 66961636 | Michael Niedermayer | |
68 | f628559d | Diego Biurrun | wrap = width; |
69 | 66961636 | Michael Niedermayer | wrap3 = width * 3;
|
70 | p = src; |
||
71 | f628559d | Diego Biurrun | for (y = 0; y < height; y += 2) { |
72 | for (x = 0; x < width; x += 2) { |
||
73 | 66961636 | Michael Niedermayer | r = p[0];
|
74 | g = p[1];
|
||
75 | b = p[2];
|
||
76 | r1 = r; |
||
77 | g1 = g; |
||
78 | b1 = b; |
||
79 | 115329f1 | Diego Biurrun | lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + |
80 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
81 | r = p[3];
|
||
82 | g = p[4];
|
||
83 | b = p[5];
|
||
84 | r1 += r; |
||
85 | g1 += g; |
||
86 | b1 += b; |
||
87 | 115329f1 | Diego Biurrun | lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + |
88 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
89 | f628559d | Diego Biurrun | p += wrap3; |
90 | 66961636 | Michael Niedermayer | lum += wrap; |
91 | |||
92 | r = p[0];
|
||
93 | g = p[1];
|
||
94 | b = p[2];
|
||
95 | r1 += r; |
||
96 | g1 += g; |
||
97 | b1 += b; |
||
98 | 115329f1 | Diego Biurrun | lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + |
99 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
100 | r = p[3];
|
||
101 | g = p[4];
|
||
102 | b = p[5];
|
||
103 | r1 += r; |
||
104 | g1 += g; |
||
105 | b1 += b; |
||
106 | 115329f1 | Diego Biurrun | lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + |
107 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
108 | 115329f1 | Diego Biurrun | |
109 | cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + |
||
110 | 66961636 | Michael Niedermayer | FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; |
111 | 115329f1 | Diego Biurrun | cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - |
112 | f628559d | Diego Biurrun | FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; |
113 | 66961636 | Michael Niedermayer | |
114 | cb++; |
||
115 | cr++; |
||
116 | f628559d | Diego Biurrun | p += -wrap3 + 2 * 3; |
117 | lum += -wrap + 2;
|
||
118 | 66961636 | Michael Niedermayer | } |
119 | f628559d | Diego Biurrun | p += wrap3; |
120 | 66961636 | Michael Niedermayer | lum += wrap; |
121 | } |
||
122 | } |
||
123 | |||
124 | /* cif format */
|
||
125 | #define DEFAULT_WIDTH 352 |
||
126 | #define DEFAULT_HEIGHT 288 |
||
127 | f628559d | Diego Biurrun | #define DEFAULT_NB_PICT 50 |
128 | 66961636 | Michael Niedermayer | |
129 | 6f2162b4 | Diego Biurrun | static void pgmyuv_save(const char *filename, int w, int h, |
130 | unsigned char *rgb_tab) |
||
131 | 66961636 | Michael Niedermayer | { |
132 | FILE *f; |
||
133 | int i, h2, w2;
|
||
134 | unsigned char *cb, *cr; |
||
135 | unsigned char *lum_tab, *cb_tab, *cr_tab; |
||
136 | |||
137 | lum_tab = malloc(w * h); |
||
138 | e9c10459 | Diego Biurrun | cb_tab = malloc(w * h / 4);
|
139 | cr_tab = malloc(w * h / 4);
|
||
140 | 66961636 | Michael Niedermayer | |
141 | rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h); |
||
142 | |||
143 | f628559d | Diego Biurrun | f = fopen(filename, "wb");
|
144 | e9c10459 | Diego Biurrun | fprintf(f, "P5\n%d %d\n%d\n", w, h * 3 / 2, 255); |
145 | 66961636 | Michael Niedermayer | fwrite(lum_tab, 1, w * h, f);
|
146 | h2 = h / 2;
|
||
147 | w2 = w / 2;
|
||
148 | cb = cb_tab; |
||
149 | cr = cr_tab; |
||
150 | f628559d | Diego Biurrun | for (i = 0; i < h2; i++) { |
151 | 66961636 | Michael Niedermayer | fwrite(cb, 1, w2, f);
|
152 | fwrite(cr, 1, w2, f);
|
||
153 | cb += w2; |
||
154 | cr += w2; |
||
155 | } |
||
156 | fclose(f); |
||
157 | |||
158 | free(lum_tab); |
||
159 | free(cb_tab); |
||
160 | free(cr_tab); |
||
161 | } |
||
162 | |||
163 | unsigned char *rgb_tab; |
||
164 | int width, height, wrap;
|
||
165 | |||
166 | 6f2162b4 | Diego Biurrun | static void put_pixel(int x, int y, int r, int g, int b) |
167 | 66961636 | Michael Niedermayer | { |
168 | unsigned char *p; |
||
169 | |||
170 | if (x < 0 || x >= width || |
||
171 | y < 0 || y >= height)
|
||
172 | return;
|
||
173 | |||
174 | p = rgb_tab + y * wrap + x * 3;
|
||
175 | p[0] = r;
|
||
176 | p[1] = g;
|
||
177 | p[2] = b;
|
||
178 | } |
||
179 | |||
180 | f628559d | Diego Biurrun | unsigned char tab_r[256 * 256]; |
181 | unsigned char tab_g[256 * 256]; |
||
182 | unsigned char tab_b[256 * 256]; |
||
183 | 66961636 | Michael Niedermayer | |
184 | int h_cos [360]; |
||
185 | int h_sin [360]; |
||
186 | |||
187 | f628559d | Diego Biurrun | static int ipol(uint8_t *src, int x, int y) |
188 | { |
||
189 | int int_x = x >> 16; |
||
190 | int int_y = y >> 16; |
||
191 | int frac_x = x & 0xFFFF; |
||
192 | int frac_y = y & 0xFFFF; |
||
193 | int s00 = src[( int_x & 255) + 256 * ( int_y & 255)]; |
||
194 | int s01 = src[((int_x + 1) & 255) + 256 * ( int_y & 255)]; |
||
195 | int s10 = src[( int_x & 255) + 256 * ((int_y + 1) & 255)]; |
||
196 | int s11 = src[((int_x + 1) & 255) + 256 * ((int_y + 1) & 255)]; |
||
197 | int s0 = (((1 << 16) - frac_x) * s00 + frac_x * s01) >> 8; |
||
198 | int s1 = (((1 << 16) - frac_x) * s10 + frac_x * s11) >> 8; |
||
199 | |||
200 | return (((1 << 16) - frac_y) * s0 + frac_y * s1) >> 24; |
||
201 | 2add6b5d | Michael Niedermayer | } |
202 | |||
203 | 6f2162b4 | Diego Biurrun | static void gen_image(int num, int w, int h) |
204 | 66961636 | Michael Niedermayer | { |
205 | f628559d | Diego Biurrun | const int c = h_cos [num % 360]; |
206 | const int s = h_sin [num % 360]; |
||
207 | 115329f1 | Diego Biurrun | |
208 | f628559d | Diego Biurrun | const int xi = -(w / 2) * c; |
209 | const int yi = (w / 2) * s; |
||
210 | 115329f1 | Diego Biurrun | |
211 | f628559d | Diego Biurrun | const int xj = -(h / 2) * s; |
212 | const int yj = -(h / 2) * c; |
||
213 | int i, j;
|
||
214 | 66961636 | Michael Niedermayer | |
215 | f628559d | Diego Biurrun | int x, y;
|
216 | int xprime = xj;
|
||
217 | int yprime = yj;
|
||
218 | 66961636 | Michael Niedermayer | |
219 | f628559d | Diego Biurrun | for (j = 0; j < h; j++) { |
220 | x = xprime + xi + FIXP * w / 2;
|
||
221 | xprime += s; |
||
222 | 66961636 | Michael Niedermayer | |
223 | f628559d | Diego Biurrun | y = yprime + yi + FIXP * h / 2;
|
224 | yprime += c; |
||
225 | 66961636 | Michael Niedermayer | |
226 | f628559d | Diego Biurrun | for (i = 0; i < w; i++ ) { |
227 | x += c; |
||
228 | y -= s; |
||
229 | put_pixel(i, j, ipol(tab_r, x, y), ipol(tab_g, x, y), ipol(tab_b, x, y)); |
||
230 | } |
||
231 | 66961636 | Michael Niedermayer | } |
232 | } |
||
233 | |||
234 | 6afd3b92 | Michael Niedermayer | #define W 256 |
235 | #define H 256 |
||
236 | |||
237 | 2131e859 | Diego Biurrun | static int init_demo(const char *filename) |
238 | f628559d | Diego Biurrun | { |
239 | int i, j;
|
||
240 | int h;
|
||
241 | int radian;
|
||
242 | char line[3 * W]; |
||
243 | |||
244 | e1e0ca70 | Diego Biurrun | FILE *input_file; |
245 | f628559d | Diego Biurrun | |
246 | e1e0ca70 | Diego Biurrun | input_file = fopen(filename, "rb");
|
247 | if (!input_file) {
|
||
248 | f628559d | Diego Biurrun | perror(filename); |
249 | 2131e859 | Diego Biurrun | return 1; |
250 | f628559d | Diego Biurrun | } |
251 | |||
252 | e1e0ca70 | Diego Biurrun | if (fread(line, 1, 15, input_file) != 15) |
253 | cbb0930f | Diego Biurrun | return 1; |
254 | f628559d | Diego Biurrun | for (i = 0; i < H; i++) { |
255 | e1e0ca70 | Diego Biurrun | if (fread(line, 1, 3 * W, input_file) != 3 * W) |
256 | cbb0930f | Diego Biurrun | return 1; |
257 | f628559d | Diego Biurrun | for (j = 0; j < W; j++) { |
258 | tab_r[W * i + j] = line[3 * j ];
|
||
259 | tab_g[W * i + j] = line[3 * j + 1]; |
||
260 | tab_b[W * i + j] = line[3 * j + 2]; |
||
261 | } |
||
262 | } |
||
263 | e1e0ca70 | Diego Biurrun | fclose(input_file); |
264 | f628559d | Diego Biurrun | |
265 | /* tables sin/cos */
|
||
266 | for (i = 0; i < 360; i++) { |
||
267 | radian = 2 * i * MY_PI / 360; |
||
268 | h = 2 * FIXP + int_sin (radian);
|
||
269 | e9c10459 | Diego Biurrun | h_cos[i] = h * int_sin(radian + MY_PI / 2) / 2 / FIXP; |
270 | h_sin[i] = h * int_sin(radian) / 2 / FIXP;
|
||
271 | 66961636 | Michael Niedermayer | } |
272 | 2131e859 | Diego Biurrun | |
273 | return 0; |
||
274 | 66961636 | Michael Niedermayer | } |
275 | |||
276 | int main(int argc, char **argv) |
||
277 | { |
||
278 | int w, h, i;
|
||
279 | char buf[1024]; |
||
280 | |||
281 | 67f7f316 | Fabrice Bellard | if (argc != 3) { |
282 | printf("usage: %s directory/ image.pnm\n"
|
||
283 | 66961636 | Michael Niedermayer | "generate a test video stream\n", argv[0]); |
284 | 771339ca | Diego Biurrun | return 1; |
285 | 66961636 | Michael Niedermayer | } |
286 | |||
287 | w = DEFAULT_WIDTH; |
||
288 | h = DEFAULT_HEIGHT; |
||
289 | |||
290 | rgb_tab = malloc(w * h * 3);
|
||
291 | f628559d | Diego Biurrun | wrap = w * 3;
|
292 | width = w; |
||
293 | height = h; |
||
294 | 66961636 | Michael Niedermayer | |
295 | 2131e859 | Diego Biurrun | if (init_demo(argv[2])) |
296 | return 1; |
||
297 | 66961636 | Michael Niedermayer | |
298 | f628559d | Diego Biurrun | for (i = 0; i < DEFAULT_NB_PICT; i++) { |
299 | 528bbdde | Sam Hocevar | snprintf(buf, sizeof(buf), "%s%02d.pgm", argv[1], i); |
300 | 66961636 | Michael Niedermayer | gen_image(i, w, h); |
301 | pgmyuv_save(buf, w, h, rgb_tab); |
||
302 | } |
||
303 | 115329f1 | Diego Biurrun | |
304 | 66961636 | Michael Niedermayer | free(rgb_tab); |
305 | return 0; |
||
306 | } |