]> git.sesse.net Git - vlc/blob - test/dynamicoverlay/overlay-test.c
Use var_InheritString for --decklink-video-connection.
[vlc] / test / dynamicoverlay / overlay-test.c
1 /*****************************************************************************
2  * overlay-test.c : test program for the dynamic overlay plugin
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Author: Søren Bøg <avacore@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <math.h>
33
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 #include <unistd.h>
37
38 /*****************************************************************************
39  * Images
40  *****************************************************************************/
41
42 #define WIDTH 128
43 #define HEIGHT 128
44
45 #define TEXT "Hello world!"
46 #define TEXTSIZE sizeof( TEXT )
47
48 char *p_imageRGBA;
49 char *p_text;
50
51 void DataCreate( void ) {
52     char *p_data = p_imageRGBA;
53     for( size_t i = 0; i < HEIGHT; ++i ) {
54         for( size_t j = 0; j < HEIGHT; ++j ) {
55             *(p_data++) = i * 4 & 0xFF;
56             *(p_data++) = 0xFF;
57             *(p_data++) = 0x00;
58             *(p_data++) = j * 4 & 0xFF;
59         }
60     }
61
62     memcpy( p_text, TEXT, TEXTSIZE );
63 }
64
65 /*****************************************************************************
66  * I/O Helpers
67  *****************************************************************************/
68
69 int IsFailure( char *psz_text ) {
70     return strncmp( psz_text, "SUCCESS:", 8 );
71 }
72
73 void CheckResult( FILE *p_res ) {
74     char psz_resp[9];
75
76     fscanf( p_res, "%8s", &psz_resp );
77     if( IsFailure( psz_resp ) ) {
78         printf( " failed\n" );
79         exit( -1 );
80     }
81 }
82
83 void CheckedCommand( FILE *p_cmd, FILE *p_res, char *p_format, ... ) {
84     va_list ap;
85     va_start( ap, p_format );
86
87     vfprintf( p_cmd, p_format, ap );
88     fflush( p_cmd );
89     if( p_res != NULL ) {
90         CheckResult( p_res );
91     }
92     va_end( ap );
93 }
94
95 int GenImage( FILE *p_cmd, FILE *p_res ) {
96     int i_overlay;
97
98     printf( "Getting an overlay..." );
99     CheckedCommand( p_cmd, p_res, "GenImage\n" );
100     fscanf( p_res, "%d", &i_overlay );
101     printf( " done. Overlay is %d\n", i_overlay );
102
103     return i_overlay;
104 }
105
106 void DeleteImage( FILE *p_cmd, FILE *p_res, int i_overlay ) {
107     printf( "Removing image..." );
108     CheckedCommand( p_cmd, p_res, "DeleteImage %d\n", i_overlay );
109     printf( " done\n" );
110 }
111
112 void StartAtomic( FILE *p_cmd, FILE *p_res ) {
113     CheckedCommand( p_cmd, p_res, "StartAtomic\n" );
114 }
115
116 void EndAtomic( FILE *p_cmd, FILE *p_res ) {
117     CheckedCommand( p_cmd, p_res, "EndAtomic\n" );
118 }
119
120 void DataSharedMem( FILE *p_cmd, FILE *p_res, int i_overlay, int i_width,
121                     int i_height, char *psz_format, int i_shmid ) {
122
123     printf( "Sending data via shared memory..." );
124     CheckedCommand( p_cmd, p_res, "DataSharedMem %d %d %d %s %d\n", i_overlay,
125                     i_width, i_height, psz_format, i_shmid );
126     printf( " done\n" );
127 }
128
129 void SetAlpha( FILE *p_cmd, FILE *p_res, int i_overlay, int i_alpha ) {
130     CheckedCommand( p_cmd, p_res, "SetAlpha %d %d\n", i_overlay, i_alpha );
131 }
132
133 void SetPosition( FILE *p_cmd, FILE *p_res, int i_overlay, int i_x, int i_y ) {
134     CheckedCommand( p_cmd, p_res, "SetPosition %d %d %d\n", i_overlay, i_x,
135                     i_y );
136 }
137
138 void SetVisibility( FILE *p_cmd, FILE *p_res, int i_overlay, int i_visible ) {
139     CheckedCommand( p_cmd, p_res, "SetVisibility %d %d\n", i_overlay,
140                     i_visible );
141 }
142
143 void SetTextAlpha( FILE *p_cmd, FILE *p_res, int i_overlay, int i_alpha ) {
144     CheckedCommand( p_cmd, p_res, "SetTextAlpha %d %d\n", i_overlay, i_alpha );
145 }
146
147 void SetTextColor( FILE *p_cmd, FILE *p_res, int i_overlay, int i_red,
148                    int i_green, int i_blue ) {
149     CheckedCommand( p_cmd, p_res, "SetTextColor %d %d %d %d\n", i_overlay,
150                     i_red, i_green, i_blue );
151 }
152
153 void SetTextSize( FILE *p_cmd, FILE *p_res, int i_overlay, int i_size ) {
154     CheckedCommand( p_cmd, p_res, "SetTextSize %d %d\n", i_overlay, i_size );
155 }
156
157 int GetTextSize( FILE *p_cmd, FILE *p_res, int i_overlay ) {
158     int i_size;
159
160     CheckedCommand( p_cmd, p_res, "GetTextSize %d\n", i_overlay );
161     fscanf( p_res, "%d", &i_size );
162
163     return i_size;
164 }
165
166 /*****************************************************************************
167  * Test Routines
168  *****************************************************************************/
169
170 void BasicTest( FILE *p_cmd, FILE *p_res, int i_overlay ) {
171     printf( "Activating overlay..." );
172     SetVisibility( p_cmd, p_res, i_overlay, 1 );
173     printf( " done\n" );
174
175     printf( "Sweeping alpha..." );
176     for( int i_alpha = 0xFF; i_alpha >= -0xFF ; i_alpha -= 8 ) {
177         SetAlpha( p_cmd, p_res, i_overlay, abs( i_alpha ) );
178         usleep( 20000 );
179     }
180     SetAlpha( p_cmd, p_res, i_overlay, 255 );
181     printf( " done\n" );
182
183     printf( "Circle motion..." );
184     for( float f_theta = 0; f_theta <= 2 * M_PI ; f_theta += M_PI / 64.0 ) {
185         SetPosition( p_cmd, p_res, i_overlay,
186                      (int)( - cos( f_theta ) * 100.0 + 100.0 ),
187                      (int)( - sin( f_theta ) * 100.0 + 100.0 ) );
188         usleep( 20000 );
189     }
190     SetPosition( p_cmd, p_res, i_overlay, 0, 100 );
191     printf( " done\n" );
192
193     printf( "Atomic motion..." );
194     StartAtomic( p_cmd, p_res );
195     SetPosition( p_cmd, NULL, i_overlay, 200, 50 );
196     sleep( 1 );
197     SetPosition( p_cmd, NULL, i_overlay, 0, 0 );
198     EndAtomic( p_cmd, p_res );
199     CheckResult( p_res );
200     CheckResult( p_res );
201     printf( " done\n" );
202
203     sleep( 5 );
204 }
205
206 void TextTest( FILE *p_cmd, FILE *p_res, int i_overlay ) {
207     printf( "Sweeping (text) alpha..." );
208     for( int i_alpha = 0xFF; i_alpha >= -0xFF ; i_alpha -= 8 ) {
209         SetTextAlpha( p_cmd, p_res, i_overlay, abs( i_alpha ) );
210         usleep( 20000 );
211     }
212     SetTextAlpha( p_cmd, p_res, i_overlay, 255 );
213     printf( " done\n" );
214
215     printf( "Sweeping colors..." );
216     for( int i_red = 0xFF; i_red >= 0x00 ; i_red -= 8 ) {
217         SetTextColor( p_cmd, p_res, i_overlay, i_red, 0xFF, 0xFF );
218         usleep( 20000 );
219     }
220     for( int i_green = 0xFF; i_green >= 0x00 ; i_green -= 8 ) {
221         SetTextColor( p_cmd, p_res, i_overlay, 0x00, i_green, 0xFF );
222         usleep( 20000 );
223     }
224     for( int i_blue = 0xFF; i_blue >= 0x00 ; i_blue -= 8 ) {
225         SetTextColor( p_cmd, p_res, i_overlay, 0x00, 0x00, i_blue );
226         usleep( 20000 );
227     }
228     SetTextColor( p_cmd, p_res, i_overlay, 0x00, 0x00, 0x00 );
229     printf( " done\n" );
230
231     printf( "Getting size..." );
232     int i_basesize = GetTextSize( p_cmd, p_res, i_overlay );
233     printf( " done. Size is %d\n", i_basesize );
234
235     printf( "Sweeping size..." );
236     for( float f_theta = 0; f_theta <= M_PI ; f_theta += M_PI / 128.0 ) {
237         SetTextSize( p_cmd, p_res, i_overlay,
238                      i_basesize * ( 1 + 3 * sin( f_theta ) ) );
239         usleep( 20000 );
240     }
241     SetTextSize( p_cmd, p_res, i_overlay, i_basesize );
242     printf( " done\n" );
243
244     sleep( 5 );
245 }
246
247 /*****************************************************************************
248  * main
249  *****************************************************************************/
250
251 int main( int i_argc, char *ppsz_argv[] ) {
252     if( i_argc != 3 ) {
253         printf( "Incorrect number of parameters.\n"
254                 "Usage is: %s command-fifo response-fifo\n", ppsz_argv[0] );
255         exit( -2 );
256     }
257
258     printf( "Creating shared memory for RGBA..." );
259     int i_shmRGBA = shmget( IPC_PRIVATE, WIDTH * HEIGHT * 4, S_IRWXU );
260     if( i_shmRGBA == -1 ) {
261         printf( " failed\n" );
262         exit( -1 );
263     }
264     printf( " done, ID is %d. Text...", i_shmRGBA );
265     int i_shmText = shmget( IPC_PRIVATE, TEXTSIZE, S_IRWXU );
266     if( i_shmText == -1 ) {
267         printf( " failed\n" );
268         exit( -1 );
269     }
270     printf( " done, ID is %d\n", i_shmText );
271
272     printf( "Attaching shared memory for RGBA..." );
273     p_imageRGBA = shmat( i_shmRGBA, NULL, 0 );
274     if( p_imageRGBA == (void*)-1 ) {
275         printf( " failed\n" );
276         exit( -1 );
277     }
278     printf( " done. Text..." );
279     p_text = shmat( i_shmText, NULL, 0 );
280     if( p_text == (void*)-1 ) {
281         printf( " failed\n" );
282         exit( -1 );
283     }
284     printf( " done\n" );
285
286     printf( "Queueing shared memory for destruction, RGBA..." );
287     if( shmctl( i_shmRGBA, IPC_RMID, 0 ) == -1 ) {
288         printf( " failed\n" );
289         exit( -1 );
290     }
291     printf( " done. Text..." );
292     if( shmctl( i_shmText, IPC_RMID, 0 ) == -1 ) {
293         printf( " failed\n" );
294         exit( -1 );
295     }
296     printf( " done\n" );
297
298     printf( "Generating data..." );
299     DataCreate();
300     printf( " done\n" );
301
302     printf( "Making FIFOs..." );
303     if( mkfifo( ppsz_argv[1], S_IRWXU ) ) {
304         if( errno != EEXIST ) {
305             printf( " failed\n" );
306             exit( -1 );
307         }
308         printf( " input already exists..." );
309     }
310     if( mkfifo( ppsz_argv[2], S_IRWXU ) ) {
311         if( errno != EEXIST ) {
312             printf( " failed\n" );
313             exit( -1 );
314         }
315         printf( " output already exists..." );
316     }
317     printf( " done\n" );
318
319     printf( "Please make sure vlc is running.\n"
320             "You should append parameters similar to the following:\n"
321             "--sub-filter overlay{input=%s,output=%s}\n",
322             ppsz_argv[1], ppsz_argv[2] );
323
324     printf( "Opening FIFOs..." );
325     FILE *p_cmd = fopen( ppsz_argv[1], "w" );
326     if( p_cmd == NULL ) {
327         printf( " failed\n" );
328         exit( -1 );
329     }
330     FILE *p_res = fopen( ppsz_argv[2], "r" );
331     if( p_res == NULL ) {
332         printf( " failed\n" );
333         exit( -1 );
334     }
335     printf( " done\n" );
336
337     int i_overlay_image = GenImage( p_cmd, p_res );
338     int i_overlay_text = GenImage( p_cmd, p_res );
339     DataSharedMem( p_cmd, p_res, i_overlay_image, WIDTH, HEIGHT, "RGBA",
340                    i_shmRGBA );
341     DataSharedMem( p_cmd, p_res, i_overlay_text, TEXTSIZE, 1, "TEXT",
342                    i_shmText );
343
344     BasicTest( p_cmd, p_res, i_overlay_image );
345     BasicTest( p_cmd, p_res, i_overlay_text );
346     TextTest( p_cmd, p_res, i_overlay_text );
347
348     DeleteImage( p_cmd, p_res, i_overlay_image );
349     DeleteImage( p_cmd, p_res, i_overlay_text );
350 }