ffmpeg / tests / rotozoom.c @ 99e8b22d
History | View | Annotate | Download (7.15 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 | * This file is part of FFmpeg.
|
||
7 | *
|
||
8 | * FFmpeg is free software; you can redistribute it and/or
|
||
9 | * 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 | * FFmpeg is distributed in the hope that it will be useful,
|
||
14 | * 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 | * License along with FFmpeg; if not, write to the Free Software
|
||
20 | * 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 | #define FIXP (1<<16) |
||
28 | #define MY_PI 205887 //(M_PI*FIX) |
||
29 | |||
30 | static int64_t int_pow(int64_t a, int p){ |
||
31 | int64_t v= FIXP; |
||
32 | |||
33 | for(; p; p--){
|
||
34 | v*= a; |
||
35 | v/= FIXP; |
||
36 | } |
||
37 | |||
38 | return v;
|
||
39 | } |
||
40 | |||
41 | static int64_t int_sin(int64_t a){
|
||
42 | if(a<0) a= MY_PI-a; // 0..inf |
||
43 | a %= 2*MY_PI; // 0..2PI |
||
44 | |||
45 | if(a>=MY_PI*3/2) a -= 2*MY_PI; // -PI/2 .. 3PI/2 |
||
46 | if(a>=MY_PI/2 ) a = MY_PI - a; // -PI/2 .. PI/2 |
||
47 | 115329f1 | Diego Biurrun | |
48 | 6afd3b92 | Michael Niedermayer | return a - int_pow(a, 3)/6 + int_pow(a, 5)/120 - int_pow(a, 7)/5040; |
49 | } |
||
50 | 66961636 | Michael Niedermayer | |
51 | #define SCALEBITS 8 |
||
52 | #define ONE_HALF (1 << (SCALEBITS - 1)) |
||
53 | bb270c08 | Diego Biurrun | #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) |
54 | 66961636 | Michael Niedermayer | typedef unsigned char UINT8; |
55 | |||
56 | static void rgb24_to_yuv420p(UINT8 *lum, UINT8 *cb, UINT8 *cr, |
||
57 | UINT8 *src, int width, int height) |
||
58 | { |
||
59 | int wrap, wrap3, x, y;
|
||
60 | int r, g, b, r1, g1, b1;
|
||
61 | UINT8 *p; |
||
62 | |||
63 | wrap = width; |
||
64 | wrap3 = width * 3;
|
||
65 | p = src; |
||
66 | for(y=0;y<height;y+=2) { |
||
67 | for(x=0;x<width;x+=2) { |
||
68 | r = p[0];
|
||
69 | g = p[1];
|
||
70 | b = p[2];
|
||
71 | r1 = r; |
||
72 | g1 = g; |
||
73 | b1 = b; |
||
74 | 115329f1 | Diego Biurrun | lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + |
75 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
76 | r = p[3];
|
||
77 | g = p[4];
|
||
78 | b = p[5];
|
||
79 | r1 += r; |
||
80 | g1 += g; |
||
81 | b1 += b; |
||
82 | 115329f1 | Diego Biurrun | lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + |
83 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
84 | p += wrap3; |
||
85 | lum += wrap; |
||
86 | |||
87 | r = p[0];
|
||
88 | g = p[1];
|
||
89 | b = p[2];
|
||
90 | r1 += r; |
||
91 | g1 += g; |
||
92 | b1 += b; |
||
93 | 115329f1 | Diego Biurrun | lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g + |
94 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
95 | r = p[3];
|
||
96 | g = p[4];
|
||
97 | b = p[5];
|
||
98 | r1 += r; |
||
99 | g1 += g; |
||
100 | b1 += b; |
||
101 | 115329f1 | Diego Biurrun | lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g + |
102 | 66961636 | Michael Niedermayer | FIX(0.11400) * b + ONE_HALF) >> SCALEBITS; |
103 | 115329f1 | Diego Biurrun | |
104 | cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + |
||
105 | 66961636 | Michael Niedermayer | FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; |
106 | 115329f1 | Diego Biurrun | cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 - |
107 | 66961636 | Michael Niedermayer | FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128; |
108 | |||
109 | cb++; |
||
110 | cr++; |
||
111 | p += -wrap3 + 2 * 3; |
||
112 | lum += -wrap + 2;
|
||
113 | } |
||
114 | p += wrap3; |
||
115 | lum += wrap; |
||
116 | } |
||
117 | } |
||
118 | |||
119 | /* cif format */
|
||
120 | #define DEFAULT_WIDTH 352 |
||
121 | #define DEFAULT_HEIGHT 288 |
||
122 | 6afd3b92 | Michael Niedermayer | #define DEFAULT_NB_PICT 50 |
123 | 66961636 | Michael Niedermayer | |
124 | void pgmyuv_save(const char *filename, int w, int h, |
||
125 | unsigned char *rgb_tab) |
||
126 | { |
||
127 | FILE *f; |
||
128 | int i, h2, w2;
|
||
129 | unsigned char *cb, *cr; |
||
130 | unsigned char *lum_tab, *cb_tab, *cr_tab; |
||
131 | |||
132 | lum_tab = malloc(w * h); |
||
133 | cb_tab = malloc((w * h) / 4);
|
||
134 | cr_tab = malloc((w * h) / 4);
|
||
135 | |||
136 | rgb24_to_yuv420p(lum_tab, cb_tab, cr_tab, rgb_tab, w, h); |
||
137 | |||
138 | 6feb1de5 | Michael Niedermayer | f = fopen(filename,"wb");
|
139 | 66961636 | Michael Niedermayer | fprintf(f, "P5\n%d %d\n%d\n", w, (h * 3) / 2, 255); |
140 | fwrite(lum_tab, 1, w * h, f);
|
||
141 | h2 = h / 2;
|
||
142 | w2 = w / 2;
|
||
143 | cb = cb_tab; |
||
144 | cr = cr_tab; |
||
145 | for(i=0;i<h2;i++) { |
||
146 | fwrite(cb, 1, w2, f);
|
||
147 | fwrite(cr, 1, w2, f);
|
||
148 | cb += w2; |
||
149 | cr += w2; |
||
150 | } |
||
151 | fclose(f); |
||
152 | |||
153 | free(lum_tab); |
||
154 | free(cb_tab); |
||
155 | free(cr_tab); |
||
156 | } |
||
157 | |||
158 | unsigned char *rgb_tab; |
||
159 | int width, height, wrap;
|
||
160 | |||
161 | void put_pixel(int x, int y, int r, int g, int b) |
||
162 | { |
||
163 | unsigned char *p; |
||
164 | |||
165 | if (x < 0 || x >= width || |
||
166 | y < 0 || y >= height)
|
||
167 | return;
|
||
168 | |||
169 | p = rgb_tab + y * wrap + x * 3;
|
||
170 | p[0] = r;
|
||
171 | p[1] = g;
|
||
172 | p[2] = b;
|
||
173 | } |
||
174 | |||
175 | unsigned char tab_r[256*256]; |
||
176 | unsigned char tab_g[256*256]; |
||
177 | unsigned char tab_b[256*256]; |
||
178 | |||
179 | int teta = 0; |
||
180 | int h_cos [360]; |
||
181 | int h_sin [360]; |
||
182 | |||
183 | 2add6b5d | Michael Niedermayer | static int ipol(uint8_t *src, int x, int y){ |
184 | int int_x= x>>16; |
||
185 | int int_y= y>>16; |
||
186 | int frac_x= x&0xFFFF; |
||
187 | int frac_y= y&0xFFFF; |
||
188 | int s00= src[ ( int_x &255) + 256*( int_y &255) ]; |
||
189 | int s01= src[ ((int_x+1)&255) + 256*( int_y &255) ]; |
||
190 | int s10= src[ ( int_x &255) + 256*((int_y+1)&255) ]; |
||
191 | int s11= src[ ((int_x+1)&255) + 256*((int_y+1)&255) ]; |
||
192 | int s0= (((1<<16) - frac_x)*s00 + frac_x*s01)>>8; |
||
193 | int s1= (((1<<16) - frac_x)*s10 + frac_x*s11)>>8; |
||
194 | 115329f1 | Diego Biurrun | |
195 | 2add6b5d | Michael Niedermayer | return (((1<<16) - frac_y)*s0 + frac_y*s1)>>24; |
196 | } |
||
197 | |||
198 | 66961636 | Michael Niedermayer | void gen_image(int num, int w, int h) |
199 | { |
||
200 | const int c = h_cos [teta]; |
||
201 | const int s = h_sin [teta]; |
||
202 | 115329f1 | Diego Biurrun | |
203 | 66961636 | Michael Niedermayer | const int xi = -(w/2) * c; |
204 | const int yi = (w/2) * s; |
||
205 | 115329f1 | Diego Biurrun | |
206 | 66961636 | Michael Niedermayer | const int xj = -(h/2) * s; |
207 | const int yj = -(h/2) * c; |
||
208 | int i,j;
|
||
209 | 115329f1 | Diego Biurrun | |
210 | 66961636 | Michael Niedermayer | int x,y;
|
211 | int xprime = xj;
|
||
212 | int yprime = yj;
|
||
213 | |||
214 | |||
215 | for (j=0;j<h;j++) { |
||
216 | |||
217 | 6afd3b92 | Michael Niedermayer | x = xprime + xi + FIXP*w/2;
|
218 | 66961636 | Michael Niedermayer | xprime += s; |
219 | |||
220 | 6afd3b92 | Michael Niedermayer | y = yprime + yi + FIXP*h/2;
|
221 | 66961636 | Michael Niedermayer | yprime += c; |
222 | 115329f1 | Diego Biurrun | |
223 | 66961636 | Michael Niedermayer | for ( i=0 ; i<w ; i++ ) { |
224 | x += c; |
||
225 | y -= s; |
||
226 | 2add6b5d | Michael Niedermayer | #if 1 |
227 | put_pixel(i, j, ipol(tab_r, x, y), ipol(tab_g, x, y), ipol(tab_b, x, y)); |
||
228 | #else
|
||
229 | 67f7f316 | Fabrice Bellard | { |
230 | unsigned dep;
|
||
231 | dep = ((x>>16)&255) + (((y>>16)&255)<<8); |
||
232 | put_pixel(i, j, tab_r[dep], tab_g[dep], tab_b[dep]); |
||
233 | } |
||
234 | 2add6b5d | Michael Niedermayer | #endif
|
235 | 66961636 | Michael Niedermayer | } |
236 | } |
||
237 | teta = (teta+1) % 360; |
||
238 | } |
||
239 | |||
240 | 6afd3b92 | Michael Niedermayer | #define W 256 |
241 | #define H 256 |
||
242 | |||
243 | 67f7f316 | Fabrice Bellard | void init_demo(const char *filename) { |
244 | 66961636 | Michael Niedermayer | int i,j;
|
245 | 6afd3b92 | Michael Niedermayer | int h;
|
246 | int radian;
|
||
247 | char line[3 * W]; |
||
248 | 66961636 | Michael Niedermayer | |
249 | FILE *fichier; |
||
250 | |||
251 | 6feb1de5 | Michael Niedermayer | fichier = fopen(filename,"rb");
|
252 | 67f7f316 | Fabrice Bellard | if (!fichier) {
|
253 | perror(filename); |
||
254 | exit(1);
|
||
255 | } |
||
256 | 115329f1 | Diego Biurrun | |
257 | 66961636 | Michael Niedermayer | fread(line, 1, 15, fichier); |
258 | 6afd3b92 | Michael Niedermayer | for (i=0;i<H;i++) { |
259 | fread(line,1,3*W,fichier); |
||
260 | for (j=0;j<W;j++) { |
||
261 | bb270c08 | Diego Biurrun | tab_r[W*i+j] = line[3*j ];
|
262 | tab_g[W*i+j] = line[3*j + 1]; |
||
263 | tab_b[W*i+j] = line[3*j + 2]; |
||
264 | 66961636 | Michael Niedermayer | } |
265 | } |
||
266 | fclose(fichier); |
||
267 | |||
268 | /* tables sin/cos */
|
||
269 | for (i=0;i<360;i++) { |
||
270 | 6afd3b92 | Michael Niedermayer | radian = 2*i*MY_PI/360; |
271 | h = 2*FIXP + int_sin (radian);
|
||
272 | h_cos[i] = ( h * int_sin (radian + MY_PI/2) )/2/FIXP; |
||
273 | h_sin[i] = ( h * int_sin (radian ) )/2/FIXP;
|
||
274 | 66961636 | Michael Niedermayer | } |
275 | } |
||
276 | |||
277 | int main(int argc, char **argv) |
||
278 | { |
||
279 | int w, h, i;
|
||
280 | char buf[1024]; |
||
281 | |||
282 | 67f7f316 | Fabrice Bellard | if (argc != 3) { |
283 | printf("usage: %s directory/ image.pnm\n"
|
||
284 | 66961636 | Michael Niedermayer | "generate a test video stream\n", argv[0]); |
285 | exit(1);
|
||
286 | } |
||
287 | |||
288 | w = DEFAULT_WIDTH; |
||
289 | h = DEFAULT_HEIGHT; |
||
290 | |||
291 | rgb_tab = malloc(w * h * 3);
|
||
292 | wrap = w * 3;
|
||
293 | width = w; |
||
294 | height = h; |
||
295 | |||
296 | 67f7f316 | Fabrice Bellard | init_demo(argv[2]);
|
297 | 66961636 | Michael Niedermayer | |
298 | 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 | } |