2 * Generates a synthetic YUV video sequence suitable for codec testing.
4 * copyright (c) Sebastien Bechet <s.bechet@av7.net>
6 * This file is part of FFmpeg.
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.
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.
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
28 #define MY_PI 205887 //(M_PI*FIX)
30 static int64_t int_pow(int64_t a
, int p
){
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
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
48 return a
- int_pow(a
, 3)/6 + int_pow(a
, 5)/120 - int_pow(a
, 7)/5040;
52 #define ONE_HALF (1 << (SCALEBITS - 1))
53 #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5))
54 typedef unsigned char UINT8
;
56 static void rgb24_to_yuv420p(UINT8
*lum
, UINT8
*cb
, UINT8
*cr
,
57 UINT8
*src
, int width
, int height
)
59 int wrap
, wrap3
, x
, y
;
60 int r
, g
, b
, r1
, g1
, b1
;
66 for(y
=0;y
<height
;y
+=2) {
67 for(x
=0;x
<width
;x
+=2) {
74 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
75 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
82 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
83 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
93 lum
[0] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
94 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
101 lum
[1] = (FIX(0.29900) * r
+ FIX(0.58700) * g
+
102 FIX(0.11400) * b
+ ONE_HALF
) >> SCALEBITS
;
104 cb
[0] = ((- FIX(0.16874) * r1
- FIX(0.33126) * g1
+
105 FIX(0.50000) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
106 cr
[0] = ((FIX(0.50000) * r1
- FIX(0.41869) * g1
-
107 FIX(0.08131) * b1
+ 4 * ONE_HALF
- 1) >> (SCALEBITS
+ 2)) + 128;
120 #define DEFAULT_WIDTH 352
121 #define DEFAULT_HEIGHT 288
122 #define DEFAULT_NB_PICT 50
124 static void pgmyuv_save(const char *filename
, int w
, int h
,
125 unsigned char *rgb_tab
)
129 unsigned char *cb
, *cr
;
130 unsigned char *lum_tab
, *cb_tab
, *cr_tab
;
132 lum_tab
= malloc(w
* h
);
133 cb_tab
= malloc((w
* h
) / 4);
134 cr_tab
= malloc((w
* h
) / 4);
136 rgb24_to_yuv420p(lum_tab
, cb_tab
, cr_tab
, rgb_tab
, w
, h
);
138 f
= fopen(filename
,"wb");
139 fprintf(f
, "P5\n%d %d\n%d\n", w
, (h
* 3) / 2, 255);
140 fwrite(lum_tab
, 1, w
* h
, f
);
146 fwrite(cb
, 1, w2
, f
);
147 fwrite(cr
, 1, w2
, f
);
158 unsigned char *rgb_tab
;
159 int width
, height
, wrap
;
161 static void put_pixel(int x
, int y
, int r
, int g
, int b
)
165 if (x
< 0 || x
>= width
||
166 y
< 0 || y
>= height
)
169 p
= rgb_tab
+ y
* wrap
+ x
* 3;
175 unsigned char tab_r
[256*256];
176 unsigned char tab_g
[256*256];
177 unsigned char tab_b
[256*256];
183 static int ipol(uint8_t *src
, int x
, int y
){
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;
195 return (((1<<16) - frac_y
)*s0
+ frac_y
*s1
)>>24;
198 static void gen_image(int num
, int w
, int h
)
200 const int c
= h_cos
[teta
];
201 const int s
= h_sin
[teta
];
203 const int xi
= -(w
/2) * c
;
204 const int yi
= (w
/2) * s
;
206 const int xj
= -(h
/2) * s
;
207 const int yj
= -(h
/2) * c
;
217 x
= xprime
+ xi
+ FIXP
*w
/2;
220 y
= yprime
+ yi
+ FIXP
*h
/2;
223 for ( i
=0 ; i
<w
; i
++ ) {
227 put_pixel(i
, j
, ipol(tab_r
, x
, y
), ipol(tab_g
, x
, y
), ipol(tab_b
, x
, y
));
231 dep
= ((x
>>16)&255) + (((y
>>16)&255)<<8);
232 put_pixel(i
, j
, tab_r
[dep
], tab_g
[dep
], tab_b
[dep
]);
237 teta
= (teta
+1) % 360;
243 static void init_demo(const char *filename
) {
251 fichier
= fopen(filename
,"rb");
257 fread(line
, 1, 15, fichier
);
259 fread(line
,1,3*W
,fichier
);
261 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];
269 for (i
=0;i
<360;i
++) {
270 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
;
277 int main(int argc
, char **argv
)
283 printf("usage: %s directory/ image.pnm\n"
284 "generate a test video stream\n", argv
[0]);
291 rgb_tab
= malloc(w
* h
* 3);
298 for(i
=0;i
<DEFAULT_NB_PICT
;i
++) {
299 snprintf(buf
, sizeof(buf
), "%s%02d.pgm", argv
[1], i
);
301 pgmyuv_save(buf
, w
, h
, rgb_tab
);