14630fc648eea257103b8e8ef15648230c1a2399
[vlc.git] / modules / video_filter / dynamicoverlay / dynamicoverlay_commands.c
1 /*****************************************************************************
2  * dynamicoverlay_commands.c : dynamic overlay plugin commands
3  *****************************************************************************
4  * Copyright (C) 2008 the VideoLAN team
5  * $Id$
6  *
7  * Author: Søren Bøg <avacore@videolan.org>
8  *         Jean-Paul Saman <jpsaman@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <vlc/vlc.h>
30 #include <vlc_arrays.h>
31 #include <vlc_vout.h>
32 #include <vlc_filter.h>
33 #include <vlc_osd.h>
34
35 #include <string.h>
36 #include <ctype.h>
37 #include <sys/shm.h>
38
39 #include "dynamicoverlay.h"
40
41
42 /*****************************************************************************
43  * overlay_t: Overlay descriptor
44  *****************************************************************************/
45
46 overlay_t *OverlayCreate( void )
47 {
48     overlay_t *p_ovl = malloc( sizeof( overlay_t ) );
49     if( p_ovl == NULL )
50        return NULL;
51     memset( p_ovl, 0, sizeof( overlay_t ) );
52
53     p_ovl->i_x = p_ovl->i_y = 0;
54     p_ovl->i_alpha = 0xFF;
55     p_ovl->b_active = VLC_FALSE;
56     vout_InitFormat( &p_ovl->format, VLC_FOURCC( '\0','\0','\0','\0') , 0, 0,
57                      VOUT_ASPECT_FACTOR );
58     memcpy( &p_ovl->fontstyle, &default_text_style, sizeof(struct text_style_t) );
59     p_ovl->data.p_text = NULL;
60
61     return p_ovl;
62 }
63
64 int OverlayDestroy( overlay_t *p_ovl )
65 {
66     if( p_ovl->data.p_text != NULL )
67         free( p_ovl->data.p_text );
68
69     return VLC_SUCCESS;
70 }
71
72 /*****************************************************************************
73  * Command parsers
74  *****************************************************************************/
75 static int skip_space( char **psz_command )
76 {
77     char *psz_temp = *psz_command;
78
79     while( isspace( *psz_temp ) )
80     {
81         ++psz_temp;
82     }
83     if( psz_temp == *psz_command )
84     {
85         return VLC_EGENERIC;
86     }
87     *psz_command = psz_temp;
88     return VLC_SUCCESS;
89 }
90
91 static int parse_digit( char **psz_command, int32_t *value )
92 {
93     char *psz_temp;
94     *value = strtol( *psz_command, &psz_temp, 10 );
95     if( psz_temp == *psz_command )
96     {
97         return VLC_EGENERIC;
98     }
99     *psz_command = psz_temp;
100     return VLC_SUCCESS;
101 }
102
103 static int parse_char( char **psz_command, char **psz_end,
104                        int count, char *psz_value )
105 {
106     if( *psz_end - *psz_command < count )
107     {
108         return VLC_EGENERIC;
109     }
110     memcpy( psz_value, *psz_command, count );
111     *psz_command += count;
112     return VLC_SUCCESS;
113 }
114
115 static int parser_DataSharedMem( char *psz_command,
116                                  char *psz_end,
117                                  commandparams_t *p_params )
118 {
119     /* Parse: 0 128 128 RGBA 9404459 */
120     skip_space( &psz_command );
121     if( isdigit( *psz_command ) )
122     {
123         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
124             return VLC_EGENERIC;
125     }
126     skip_space( &psz_command );
127     if( isdigit( *psz_command ) )
128     {
129         if( parse_digit( &psz_command, &p_params->i_width ) == VLC_EGENERIC )
130             return VLC_EGENERIC;
131     }
132     skip_space( &psz_command );
133     if( isdigit( *psz_command ) )
134     {
135         if( parse_digit( &psz_command, &p_params->i_height ) == VLC_EGENERIC )
136             return VLC_EGENERIC;
137     }
138     skip_space( &psz_command );
139     if( isascii( *psz_command ) )
140     {
141         if( parse_char( &psz_command, &psz_end, 4, (char*)&p_params->fourcc )
142             == VLC_EGENERIC )
143             return VLC_EGENERIC;
144     }
145     skip_space( &psz_command );
146     if( isdigit( *psz_command ) )
147     {
148         if( parse_digit( &psz_command, &p_params->i_shmid ) == VLC_EGENERIC )
149             return VLC_EGENERIC;
150     }
151     return VLC_SUCCESS;
152 }
153
154 static int parser_Id( char *psz_command, char *psz_end,
155                       commandparams_t *p_params )
156 {
157     (void)(psz_end);
158     skip_space( &psz_command );
159     if( isdigit( *psz_command ) )
160     {
161         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
162             return VLC_EGENERIC;
163     }
164     return VLC_SUCCESS;
165 }
166
167 static int parser_None( char *psz_command, char *psz_end,
168                         commandparams_t *p_params )
169 {
170     (void)(psz_command);
171     (void)(psz_end);
172     (void)(p_params);
173     return VLC_SUCCESS;
174 }
175
176 static int parser_SetAlpha( char *psz_command, char *psz_end,
177                             commandparams_t *p_params )
178 {
179     (void)(psz_end);
180     skip_space( &psz_command );
181     if( isdigit( *psz_command ) )
182     {
183         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC  )
184             return VLC_EGENERIC;
185     }
186     skip_space( &psz_command );
187     if( isdigit( *psz_command ) )
188     {
189         if( parse_digit( &psz_command, &p_params->i_alpha ) == VLC_EGENERIC )
190             return VLC_EGENERIC;
191     }
192     return VLC_SUCCESS;
193 }
194
195 static int parser_SetPosition( char *psz_command, char *psz_end,
196                                commandparams_t *p_params )
197 {
198     (void)(psz_end);
199     skip_space( &psz_command );
200     if( isdigit( *psz_command ) )
201     {
202         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
203             return VLC_EGENERIC;
204     }
205     skip_space( &psz_command );
206     if( isdigit( *psz_command ) )
207     {
208         if( parse_digit( &psz_command, &p_params->i_x ) == VLC_EGENERIC )
209             return VLC_EGENERIC;
210     }
211     skip_space( &psz_command );
212     if( isdigit( *psz_command ) )
213     {
214         if( parse_digit( &psz_command, &p_params->i_y ) == VLC_EGENERIC )
215             return VLC_EGENERIC;
216     }
217     return VLC_SUCCESS;
218 }
219
220 static int parser_SetTextAlpha( char *psz_command, char *psz_end,
221                                 commandparams_t *p_params )
222 {
223     (void)(psz_end);
224     skip_space( &psz_command );
225     if( isdigit( *psz_command ) )
226     {
227         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
228             return VLC_EGENERIC;
229     }
230     skip_space( &psz_command );
231     if( isdigit( *psz_command ) )
232     {
233         if( parse_digit( &psz_command, &p_params->fontstyle.i_font_alpha ) == VLC_EGENERIC )
234             return VLC_EGENERIC;
235     }
236     return VLC_SUCCESS;
237 }
238
239 static int parser_SetTextColor( char *psz_command, char *psz_end,
240                                 commandparams_t *p_params )
241 {
242     int r, g, b;
243     (void)(psz_end);
244     skip_space( &psz_command );
245     if( isdigit( *psz_command ) )
246     {
247         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
248             return VLC_EGENERIC;
249     }
250     skip_space( &psz_command );
251     if( isdigit( *psz_command ) )
252     {
253         if( parse_digit( &psz_command, &r ) == VLC_EGENERIC )
254             return VLC_EGENERIC;
255     }
256     skip_space( &psz_command );
257     if( isdigit( *psz_command ) )
258     {
259         if( parse_digit( &psz_command, &g ) == VLC_EGENERIC )
260             return VLC_EGENERIC;
261     }
262     skip_space( &psz_command );
263     if( isdigit( *psz_command ) )
264     {
265         if( parse_digit( &psz_command, &b ) == VLC_EGENERIC )
266             return VLC_EGENERIC;
267     }
268     p_params->fontstyle.i_font_color = (r<<24) | (g<<16) | (b<<8);
269     return VLC_SUCCESS;
270 }
271
272 static int parser_SetTextSize( char *psz_command, char *psz_end,
273                                commandparams_t *p_params )
274 {
275     (void)(psz_end);
276     skip_space( &psz_command );
277     if( isdigit( *psz_command ) )
278     {
279         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
280             return VLC_EGENERIC;
281     }
282     skip_space( &psz_command );
283     if( isdigit( *psz_command ) )
284     {
285         if( parse_digit( &psz_command, &p_params->fontstyle.i_font_size ) == VLC_EGENERIC )
286             return VLC_EGENERIC;
287     }
288     return VLC_SUCCESS;
289 }
290
291 static int parser_SetVisibility( char *psz_command, char *psz_end,
292                                  commandparams_t *p_params )
293 {
294     (void)(psz_end);
295     skip_space( &psz_command );
296     if( isdigit( *psz_command ) )
297     {
298         if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
299             return VLC_EGENERIC;
300     }
301     skip_space( &psz_command );
302     if( isdigit( *psz_command ) )
303     {
304         int32_t i_vis = 0;
305         if( parse_digit( &psz_command, &i_vis ) == VLC_EGENERIC )
306             return VLC_EGENERIC;
307         p_params->b_visible = (i_vis == 1) ? VLC_TRUE : VLC_FALSE;
308     }
309     return VLC_SUCCESS;
310 }
311
312 /*****************************************************************************
313  * Command unparser functions
314  *****************************************************************************/
315
316 static int unparse_default( const commandparams_t *p_results,
317                             buffer_t *p_output )
318 {
319     (void)(p_results);
320     VLC_UNUSED(p_output);
321     return VLC_SUCCESS;
322 }
323
324 static int unparse_GenImage( const commandparams_t *p_results,
325                              buffer_t *p_output )
326 {
327     int ret = BufferPrintf( p_output, " %d", p_results->i_id );
328     if( ret != VLC_SUCCESS )
329         return ret;
330
331     return VLC_SUCCESS;
332 }
333
334 static int unparse_GetAlpha( const commandparams_t *p_results,
335                              buffer_t *p_output )
336 {
337     int ret = BufferPrintf( p_output, " %d", p_results->i_alpha );
338     if( ret != VLC_SUCCESS )
339         return ret;
340
341     return VLC_SUCCESS;
342 }
343
344 static int unparse_GetPosition( const commandparams_t *p_results,
345                                 buffer_t *p_output )
346 {
347     int ret = BufferPrintf( p_output, " %d", p_results->i_x );
348     if( ret != VLC_SUCCESS )
349         return ret;
350
351     ret = BufferPrintf( p_output, " %d", p_results->i_y );
352     if( ret != VLC_SUCCESS )
353         return ret;
354
355     return VLC_SUCCESS;
356 }
357
358 static int unparse_GetTextAlpha( const commandparams_t *p_results,
359                                  buffer_t *p_output )
360 {
361     int ret = BufferPrintf( p_output, " %d", p_results->fontstyle.i_font_alpha );
362     if( ret != VLC_SUCCESS )
363         return ret;
364
365     return VLC_SUCCESS;
366 }
367
368 static int unparse_GetTextColor( const commandparams_t *p_results,
369                                  buffer_t *p_output )
370 {
371     int ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0xff0000)>>24 );
372     if( ret != VLC_SUCCESS )
373         return ret;
374
375     ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0x00ff00)>>16 );
376     if( ret != VLC_SUCCESS )
377         return ret;
378
379     ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0x0000ff)>>8 );
380     if( ret != VLC_SUCCESS )
381         return ret;
382
383     return VLC_SUCCESS;
384 }
385
386 static int unparse_GetTextSize( const commandparams_t *p_results,
387                                 buffer_t *p_output )
388 {
389     int ret = BufferPrintf( p_output, " %d", p_results->fontstyle.i_font_size );
390     if( ret != VLC_SUCCESS )
391         return ret;
392
393     return VLC_SUCCESS;
394 }
395
396 static int unparse_GetVisibility( const commandparams_t *p_results,
397                              buffer_t *p_output )
398 {
399     int ret = BufferPrintf( p_output, " %d", (p_results->b_visible ? 1 : 0) );
400     if( ret != VLC_SUCCESS ) {
401         return ret;
402     }
403     return VLC_SUCCESS;
404 }
405
406 /*****************************************************************************
407  * Command functions
408  *****************************************************************************/
409 static int exec_DataSharedMem( filter_t *p_filter,
410                                const commandparams_t *p_params,
411                                commandparams_t *p_results )
412 {
413     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
414     struct shmid_ds shminfo;
415     overlay_t *p_ovl;
416     size_t i_size;
417
418     (void)(p_results);
419
420     p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
421     if( p_ovl == NULL )
422     {
423         msg_Err( p_filter, "Invalid overlay: %d", p_params->i_id );
424         return VLC_EGENERIC;
425     }
426
427     if( shmctl( p_params->i_shmid, IPC_STAT, &shminfo ) == -1 )
428     {
429         msg_Err( p_filter, "Unable to access shared memory" );
430         return VLC_EGENERIC;
431     }
432     i_size = shminfo.shm_segsz;
433
434     if( p_params->fourcc == VLC_FOURCC('T','E','X','T') )
435     {
436         char *p_data;
437
438         if( (p_params->i_height != 1) || (p_params->i_width < 1) )
439         {
440             msg_Err( p_filter,
441                      "Invalid width and/or height. when specifing text height "
442                      "must be 1 and width the number of bytes in the string, "
443                      "including the null terminator" );
444             return VLC_EGENERIC;
445         }
446
447         if( (size_t)p_params->i_width > i_size )
448         {
449             msg_Err( p_filter,
450                      "Insufficient data in shared memory. need %d, got %d",
451                      p_params->i_width, i_size );
452             return VLC_EGENERIC;
453         }
454
455         p_ovl->data.p_text = malloc( p_params->i_width );
456         if( p_ovl->data.p_text == NULL )
457         {
458             msg_Err( p_filter, "Unable to allocate string storage" );
459             return VLC_ENOMEM;
460         }
461
462         vout_InitFormat( &p_ovl->format, VLC_FOURCC('T','E','X','T'),
463                          0, 0, 0 );
464
465         p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
466         if( p_data == NULL )
467         {
468             msg_Err( p_filter, "Unable to attach to shared memory" );
469             free( p_ovl->data.p_text );
470             p_ovl->data.p_text = NULL;
471             return VLC_ENOMEM;
472         }
473
474         memcpy( p_ovl->data.p_text, p_data, p_params->i_width );
475
476         shmdt( p_data );
477     }
478     else
479     {
480         uint8_t *p_data, *p_in;
481         size_t i_neededsize = 0;
482
483         p_ovl->data.p_pic = malloc( sizeof( picture_t ) );
484         if( p_ovl->data.p_pic == NULL )
485         {
486             msg_Err( p_filter, "Unable to allocate picture structure" );
487             return VLC_ENOMEM;
488         }
489
490         vout_InitFormat( &p_ovl->format, p_params->fourcc,
491                          p_params->i_width, p_params->i_height,
492                          VOUT_ASPECT_FACTOR );
493         if( vout_AllocatePicture( p_filter, p_ovl->data.p_pic,
494                                   p_ovl->format.i_chroma, p_params->i_width,
495                                   p_params->i_height, p_ovl->format.i_aspect ) )
496         {
497             msg_Err( p_filter, "Unable to allocate picture" );
498             free( p_ovl->data.p_pic );
499             p_ovl->data.p_pic = NULL;
500             return VLC_ENOMEM;
501         }
502
503         for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
504              ++i_plane )
505         {
506             i_neededsize += p_ovl->data.p_pic->p[i_plane].i_visible_lines *
507                             p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
508         }
509
510         if( i_neededsize > i_size )
511         {
512             msg_Err( p_filter,
513                      "Insufficient data in shared memory. need %d, got %d",
514                      i_neededsize, i_size );
515             p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
516             free( p_ovl->data.p_pic );
517             p_ovl->data.p_pic = NULL;
518             return VLC_EGENERIC;
519         }
520
521         p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
522         if( p_data == NULL )
523         {
524             msg_Err( p_filter, "Unable to attach to shared memory" );
525             p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
526             free( p_ovl->data.p_pic );
527             p_ovl->data.p_pic = NULL;
528             return VLC_ENOMEM;
529         }
530
531         p_in = p_data;
532         for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
533              ++i_plane )
534         {
535             uint8_t *p_out = p_ovl->data.p_pic->p[i_plane].p_pixels;
536             for( size_t i_line = 0;
537                  i_line < (size_t)p_ovl->data.p_pic->p[i_plane].i_visible_lines;
538                  ++i_line )
539             {
540                 p_filter->p_libvlc->pf_memcpy( p_out, p_in,
541                                 p_ovl->data.p_pic->p[i_plane].i_visible_pitch );
542                 p_out += p_ovl->data.p_pic->p[i_plane].i_pitch;
543                 p_in += p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
544             }
545         }
546         shmdt( p_data );
547     }
548
549     p_sys->b_updated = p_ovl->b_active;
550
551     return VLC_SUCCESS;
552 }
553
554 static int exec_DeleteImage( filter_t *p_filter,
555                              const commandparams_t *p_params,
556                              commandparams_t *p_results )
557 {
558     (void)(p_results);
559     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
560     p_sys->b_updated = VLC_TRUE;
561
562     return ListRemove( &p_sys->overlays, p_params->i_id );
563 }
564
565 static int exec_EndAtomic( filter_t *p_filter,
566                            const commandparams_t *p_params,
567                            commandparams_t *p_results )
568 {
569     (void)(p_params);
570     (void)(p_results);
571     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
572     QueueTransfer( &p_sys->pending, &p_sys->atomic );
573     p_sys->b_atomic = VLC_FALSE;
574     return VLC_SUCCESS;
575 }
576
577 static int exec_GenImage( filter_t *p_filter,
578                           const commandparams_t *p_params,
579                           commandparams_t *p_results )
580 {
581     (void)(p_params);
582     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
583
584     overlay_t *p_ovl = OverlayCreate();
585     if( p_ovl == NULL )
586         return VLC_ENOMEM;
587
588     ssize_t i_idx = ListAdd( &p_sys->overlays, p_ovl );
589     if( i_idx < 0 )
590         return i_idx;
591
592     p_results->i_id = i_idx;
593     return VLC_SUCCESS;
594 }
595
596 static int exec_GetAlpha( filter_t *p_filter,
597                           const commandparams_t *p_params,
598                           commandparams_t *p_results )
599 {
600     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
601     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
602     if( p_ovl == NULL )
603         return VLC_EGENERIC;
604
605     p_results->i_alpha = p_ovl->i_alpha;
606     return VLC_SUCCESS;
607 }
608
609 static int exec_GetPosition( filter_t *p_filter,
610                              const commandparams_t *p_params,
611                              commandparams_t *p_results )
612 {
613     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
614     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
615     if( p_ovl == NULL )
616         return VLC_EGENERIC;
617
618     p_results->i_x = p_ovl->i_x;
619     p_results->i_y = p_ovl->i_y;
620     return VLC_SUCCESS;
621 }
622
623 static int exec_GetTextAlpha( filter_t *p_filter,
624                               const commandparams_t *p_params,
625                               commandparams_t *p_results )
626 {
627     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
628     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
629     if( p_ovl == NULL )
630         return VLC_EGENERIC;
631
632     p_results->fontstyle.i_font_alpha = p_ovl->fontstyle.i_font_alpha;
633     return VLC_SUCCESS;
634 }
635
636 static int exec_GetTextColor( filter_t *p_filter,
637                               const commandparams_t *p_params,
638                               commandparams_t *p_results )
639 {
640     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
641     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
642     if( p_ovl == NULL )
643         return VLC_EGENERIC;
644
645     p_results->fontstyle.i_font_color = p_ovl->fontstyle.i_font_color;
646     return VLC_SUCCESS;
647 }
648
649 static int exec_GetTextSize( filter_t *p_filter,
650                              const commandparams_t *p_params,
651                              commandparams_t *p_results )
652 {
653     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
654     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
655     if( p_ovl == NULL )
656         return VLC_EGENERIC;
657
658     p_results->fontstyle.i_font_size = p_ovl->fontstyle.i_font_size;
659     return VLC_SUCCESS;
660 }
661
662 static int exec_GetVisibility( filter_t *p_filter,
663                                const commandparams_t *p_params,
664                                commandparams_t *p_results )
665 {
666     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
667
668     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
669     if( p_ovl == NULL )
670         return VLC_EGENERIC;
671
672     p_results->b_visible = ( p_ovl->b_active == VLC_TRUE ) ? 1 : 0;
673     return VLC_SUCCESS;
674 }
675
676 static int exec_SetAlpha( filter_t *p_filter,
677                           const commandparams_t *p_params,
678                           commandparams_t *p_results )
679 {
680     (void)(p_results);
681     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
682
683     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
684     if( p_ovl == NULL )
685         return VLC_EGENERIC;
686
687     p_ovl->i_alpha = p_params->i_alpha;
688     p_sys->b_updated = p_ovl->b_active;
689     return VLC_SUCCESS;
690 }
691
692 static int exec_SetPosition( filter_t *p_filter,
693                              const commandparams_t *p_params,
694                              commandparams_t *p_results )
695 {
696     (void)(p_results);
697     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
698
699     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
700     if( p_ovl == NULL )
701         return VLC_EGENERIC;
702
703     p_ovl->i_x = p_params->i_x;
704     p_ovl->i_y = p_params->i_y;
705
706     p_sys->b_updated = p_ovl->b_active;
707     return VLC_SUCCESS;
708 }
709
710 static int exec_SetTextAlpha( filter_t *p_filter,
711                               const commandparams_t *p_params,
712                               commandparams_t *p_results )
713 {
714     (void)(p_results);
715     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
716
717     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
718     if( p_ovl == NULL )
719         return VLC_EGENERIC;
720
721     p_ovl->fontstyle.i_font_alpha = p_params->fontstyle.i_font_alpha;
722     p_sys->b_updated = p_ovl->b_active;
723     return VLC_SUCCESS;
724 }
725
726 static int exec_SetTextColor( filter_t *p_filter,
727                               const commandparams_t *p_params,
728                               commandparams_t *p_results )
729 {
730     (void)(p_results);
731     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
732
733     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
734     if( p_ovl == NULL )
735         return VLC_EGENERIC;
736
737     p_ovl->fontstyle.i_font_color = p_params->fontstyle.i_font_color;
738     p_sys->b_updated = p_ovl->b_active;
739     return VLC_SUCCESS;
740 }
741
742 static int exec_SetTextSize( filter_t *p_filter,
743                               const commandparams_t *p_params,
744                               commandparams_t *p_results )
745 {
746     (void)(p_results);
747     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
748
749     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
750     if( p_ovl == NULL )
751         return VLC_EGENERIC;
752
753     p_ovl->fontstyle.i_font_size = p_params->fontstyle.i_font_size;
754     p_sys->b_updated = p_ovl->b_active;
755     return VLC_SUCCESS;
756 }
757
758 static int exec_SetVisibility( filter_t *p_filter,
759                                const commandparams_t *p_params,
760                                commandparams_t *p_results )
761 {
762     (void)(p_results);
763     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
764
765     overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
766     if( p_ovl == NULL )
767         return VLC_EGENERIC;
768
769     p_ovl->b_active = p_params->b_visible;// ? VLC_FALSE : VLC_TRUE;
770     p_sys->b_updated = VLC_TRUE;
771     return VLC_SUCCESS;
772 }
773
774 static int exec_StartAtomic( filter_t *p_filter,
775                              const commandparams_t *p_params,
776                              commandparams_t *p_results )
777 {
778     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
779     (void)(p_params);
780     (void)(p_results);
781
782     p_sys->b_atomic = VLC_TRUE;
783     return VLC_SUCCESS;
784 }
785
786 /*****************************************************************************
787  * Command functions
788  *****************************************************************************/
789 static commanddesc_t p_commands[] =
790 {
791     {   .psz_command = "DataSharedMem",
792         .b_atomic = VLC_TRUE,
793         .pf_parser = parser_DataSharedMem,
794         .pf_execute = exec_DataSharedMem,
795         .pf_unparse = unparse_default,
796     },
797     {   .psz_command = "DeleteImage",
798         .b_atomic = VLC_TRUE,
799         .pf_parser = parser_Id,
800         .pf_execute = exec_DeleteImage,
801         .pf_unparse = unparse_default,
802     },
803     {   .psz_command = "EndAtomic",
804         .b_atomic = VLC_FALSE,
805         .pf_parser = parser_None,
806         .pf_execute = exec_EndAtomic,
807         .pf_unparse = unparse_default,
808     },
809     {   .psz_command = "GenImage",
810         .b_atomic = VLC_FALSE,
811         .pf_parser = parser_None,
812         .pf_execute = exec_GenImage,
813         .pf_unparse = unparse_GenImage,
814     },
815     {   .psz_command = "GetAlpha",
816         .b_atomic = VLC_FALSE,
817         .pf_parser = parser_Id,
818         .pf_execute = exec_GetAlpha,
819         .pf_unparse = unparse_GetAlpha,
820     },
821     {   .psz_command = "GetPosition",
822         .b_atomic = VLC_FALSE,
823         .pf_parser = parser_Id,
824         .pf_execute = exec_GetPosition,
825         .pf_unparse = unparse_GetPosition,
826     },
827     {   .psz_command = "GetTextAlpha",
828         .b_atomic = VLC_FALSE,
829         .pf_parser = parser_Id,
830         .pf_execute = exec_GetTextAlpha,
831         .pf_unparse = unparse_GetTextAlpha,
832     },
833     {   .psz_command = "GetTextColor",
834         .b_atomic = VLC_FALSE,
835         .pf_parser = parser_Id,
836         .pf_execute = exec_GetTextColor,
837         .pf_unparse = unparse_GetTextColor,
838     },
839     {   .psz_command = "GetTextSize",
840         .b_atomic = VLC_TRUE,
841         .pf_parser = parser_Id,
842         .pf_execute = exec_GetTextSize,
843         .pf_unparse = unparse_GetTextSize,
844     },
845     {   .psz_command = "GetVisibility",
846         .b_atomic = VLC_FALSE,
847         .pf_parser = parser_Id,
848         .pf_execute = exec_GetVisibility,
849         .pf_unparse = unparse_GetVisibility,
850     },
851     {   .psz_command = "SetAlpha",
852         .b_atomic = VLC_TRUE,
853         .pf_parser = parser_SetAlpha,
854         .pf_execute = exec_SetAlpha,
855         .pf_unparse = unparse_default,
856     },
857     {   .psz_command = "SetPosition",
858         .b_atomic = VLC_TRUE,
859         .pf_parser = parser_SetPosition,
860         .pf_execute = exec_SetPosition,
861         .pf_unparse = unparse_default,
862     },
863     {   .psz_command = "SetTextAlpha",
864         .b_atomic = VLC_TRUE,
865         .pf_parser = parser_SetTextAlpha,
866         .pf_execute = exec_SetTextAlpha,
867         .pf_unparse = unparse_default,
868     },
869     {   .psz_command = "SetTextColor",
870         .b_atomic = VLC_TRUE,
871         .pf_parser = parser_SetTextColor,
872         .pf_execute = exec_SetTextColor,
873         .pf_unparse = unparse_default,
874     },
875     {   .psz_command = "SetTextSize",
876         .b_atomic = VLC_TRUE,
877         .pf_parser = parser_SetTextSize,
878         .pf_execute = exec_SetTextSize,
879         .pf_unparse = unparse_default,
880     },
881     {   .psz_command = "SetVisibility",
882         .b_atomic = VLC_TRUE,
883         .pf_parser = parser_SetVisibility,
884         .pf_execute = exec_SetVisibility,
885         .pf_unparse = unparse_default,
886     },
887     {   .psz_command = "StartAtomic",
888         .b_atomic = VLC_TRUE,
889         .pf_parser = parser_None,
890         .pf_execute = exec_StartAtomic,
891         .pf_unparse = unparse_default,
892     }
893 };
894
895 void RegisterCommand( filter_t *p_filter )
896 {
897     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
898     size_t i_index = 0;
899
900     p_sys->i_commands = ARRAY_SIZE(p_commands);
901     p_sys->pp_commands = (commanddesc_t **) calloc( p_sys->i_commands, sizeof(commanddesc_t*) );
902     if( !p_sys->pp_commands ) return;
903     for( i_index = 0; i_index < p_sys->i_commands; i_index ++ )
904     {
905         p_sys->pp_commands[i_index] = (commanddesc_t *) malloc( sizeof(commanddesc_t) );
906         if( !p_sys->pp_commands[i_index] ) return;
907         p_sys->pp_commands[i_index]->psz_command = strdup( p_commands[i_index].psz_command );
908         p_sys->pp_commands[i_index]->b_atomic = p_commands[i_index].b_atomic;
909         p_sys->pp_commands[i_index]->pf_parser = p_commands[i_index].pf_parser;
910         p_sys->pp_commands[i_index]->pf_execute = p_commands[i_index].pf_execute;
911         p_sys->pp_commands[i_index]->pf_unparse = p_commands[i_index].pf_unparse;
912     }
913
914     msg_Dbg( p_filter, "%d commands are available", p_sys->i_commands );
915     for( size_t i_index = 0; i_index < p_sys->i_commands; i_index++ )
916         msg_Dbg( p_filter, "    %s", p_sys->pp_commands[i_index]->psz_command );
917 }
918
919 void UnregisterCommand( filter_t *p_filter )
920 {
921     filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
922     size_t i_index = 0;
923
924     for( i_index = 0; i_index < p_sys->i_commands; i_index++ )
925     {
926         free( p_sys->pp_commands[i_index]->psz_command );
927         free( p_sys->pp_commands[i_index] );
928     }
929     free( p_sys->pp_commands );
930     p_sys->pp_commands = NULL;
931     p_sys->i_commands = 0;
932 }