]> git.sesse.net Git - vlc/commitdiff
Rewrite old command definitions to no longer use those filthy macros. Added all text...
authorJean-Paul Saman <jean-paul.saman@m2x.nl>
Thu, 3 Apr 2008 15:30:50 +0000 (17:30 +0200)
committerJean-Paul Saman <jean-paul.saman@m2x.nl>
Wed, 9 Apr 2008 09:44:41 +0000 (11:44 +0200)
modules/video_filter/dynamicoverlay/Modules.am
modules/video_filter/dynamicoverlay/dynamicoverlay.c
modules/video_filter/dynamicoverlay/dynamicoverlay.h
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
modules/video_filter/dynamicoverlay/dynamicoverlay_commands.c [new file with mode: 0644]
modules/video_filter/dynamicoverlay/dynamicoverlay_commands.h [deleted file]
modules/video_filter/dynamicoverlay/dynamicoverlay_list.c [new file with mode: 0644]
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c

index 8cd12b3f8b64d40fa37b073daa50182fab60ad3b..5f645e46a80b7521e9af7f409e39aaae94cfb916 100644 (file)
@@ -1,2 +1,2 @@
-SOURCES_dynamicoverlay = dynamicoverlay.c dynamicoverlay_buffer.c dynamicoverlay_queue.c
-noinst_HEADERS = dynamicoverlay.h dynamicoverlay_commands.h
+SOURCES_dynamicoverlay = dynamicoverlay_buffer.c dynamicoverlay_queue.c dynamicoverlay_list.c dynamicoverlay_commands.c  dynamicoverlay.c
+noinst_HEADERS = dynamicoverlay.h
index 399401c48550947b21843a6a634a65925419dc90..289709b41b9f4b2c9f0d5917a2ebeab3e536fe16 100644 (file)
 # include "config.h"
 #endif
 
-#include <fcntl.h>
 #include <vlc/vlc.h>
 #include <vlc_sout.h>
 #include <vlc_vout.h>
-
 #include <vlc_filter.h>
 #include <vlc_osd.h>
 
+#include <ctype.h>
+#include <fcntl.h>
+
 #include "dynamicoverlay.h"
 
 /*****************************************************************************
@@ -79,282 +80,6 @@ static const char *ppsz_filter_options[] = {
     "input", "output", NULL
 };
 
-/*****************************************************************************
- * overlay_t: Overlay descriptor
- *****************************************************************************/
-
-struct overlay_t
-{
-    int i_x, i_y;
-    int i_alpha;
-    vlc_bool_t b_active;
-
-    video_format_t format;
-    union {
-        picture_t *p_pic;
-        char *p_text;
-    } data;
-};
-typedef struct overlay_t overlay_t;
-
-static overlay_t *OverlayCreate( void )
-{
-    overlay_t *p_ovl = malloc( sizeof( overlay_t ) );
-    if( p_ovl == NULL )
-       return NULL;
-    memset( p_ovl, 0, sizeof( overlay_t ) );
-
-    p_ovl->i_x = p_ovl->i_y = 0;
-    p_ovl->i_alpha = 0xFF;
-    p_ovl->b_active = VLC_FALSE;
-    vout_InitFormat( &p_ovl->format, VLC_FOURCC( '\0','\0','\0','\0') , 0, 0,
-                     VOUT_ASPECT_FACTOR );
-    p_ovl->data.p_text = NULL;
-
-    return p_ovl;
-}
-
-static int OverlayDestroy( overlay_t *p_ovl )
-{
-    if( p_ovl->data.p_text != NULL )
-        free( p_ovl->data.p_text );
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * list_t: Command queue
- *****************************************************************************/
-
-struct list_t
-{
-    overlay_t **pp_head, **pp_tail;
-};
-typedef struct list_t list_t;
-
-static int ListInit( list_t *p_list )
-{
-    p_list->pp_head = malloc( 16 * sizeof( overlay_t * ) );
-    if( p_list->pp_head == NULL )
-        return VLC_ENOMEM;
-
-    p_list->pp_tail = p_list->pp_head + 16;
-    memset( p_list->pp_head, 0, 16 * sizeof( overlay_t * ) );
-
-    return VLC_SUCCESS;
-}
-
-static int ListDestroy( list_t *p_list )
-{
-    for( overlay_t **pp_cur = p_list->pp_head;
-         pp_cur < p_list->pp_tail;
-         ++pp_cur )
-    {
-        if( *pp_cur != NULL )
-        {
-            OverlayDestroy( *pp_cur );
-            free( *pp_cur );
-        }
-    }
-    free( p_list->pp_head );
-
-    return VLC_SUCCESS;
-}
-
-static ssize_t ListAdd( list_t *p_list, overlay_t *p_new )
-{
-    /* Find an available slot */
-    for( overlay_t **pp_cur = p_list->pp_head;
-         pp_cur < p_list->pp_tail;
-         ++pp_cur )
-    {
-        if( *pp_cur == NULL )
-        {
-            *pp_cur = p_new;
-            return pp_cur - p_list->pp_head;
-        }
-    }
-
-    /* Have to expand */
-    size_t i_size = p_list->pp_tail - p_list->pp_head;
-    size_t i_newsize = i_size * 2;
-    p_list->pp_head = realloc( p_list->pp_head,
-                               i_newsize * sizeof( overlay_t * ) );
-    if( p_list->pp_head == NULL )
-        return VLC_ENOMEM;
-
-    p_list->pp_tail = p_list->pp_head + i_newsize;
-    memset( p_list->pp_head + i_size, 0, i_size * sizeof( overlay_t * ) );
-    p_list->pp_head[i_size] = p_new;
-    return i_size;
-}
-
-static int ListRemove( list_t *p_list, size_t i_idx )
-{
-    int ret;
-
-    if( ( i_idx >= (size_t)( p_list->pp_tail - p_list->pp_head ) ) ||
-        ( p_list->pp_head[i_idx] == NULL ) )
-    {
-        return VLC_EGENERIC;
-    }
-
-    ret = OverlayDestroy( p_list->pp_head[i_idx] );
-    free( p_list->pp_head[i_idx] );
-    p_list->pp_head[i_idx] = NULL;
-
-    return ret;
-}
-
-static overlay_t *ListGet( list_t *p_list, size_t i_idx )
-{
-    if( ( i_idx >= (size_t)( p_list->pp_tail - p_list->pp_head ) ) ||
-        ( p_list->pp_head[i_idx] == NULL ) )
-    {
-        return NULL;
-    }
-    return p_list->pp_head[i_idx];
-}
-
-static overlay_t *ListWalk( list_t *p_list )
-{
-    static overlay_t **pp_cur = NULL;
-
-    if( pp_cur == NULL )
-        pp_cur = p_list->pp_head;
-    else
-        pp_cur = pp_cur + 1;
-
-    for( ; pp_cur < p_list->pp_tail; ++pp_cur )
-    {
-        if( ( *pp_cur != NULL ) &&
-            ( (*pp_cur)->b_active == VLC_TRUE )&&
-            ( (*pp_cur)->format.i_chroma != VLC_FOURCC( '\0','\0','\0','\0') ) )
-        {
-            return *pp_cur;
-        }
-    }
-    pp_cur = NULL;
-    return NULL;
-}
-
-/*****************************************************************************
- * filter_sys_t: adjust filter method descriptor
- *****************************************************************************/
-struct filter_sys_t
-{
-    buffer_t input, output;
-
-    int i_inputfd, i_outputfd;
-
-    char *psz_inputfile, *psz_outputfile;
-
-    vlc_bool_t b_updated, b_atomic;
-    queue_t atomic, pending, processed;
-    list_t overlays;
-};
-
-/*****************************************************************************
- * Command functions
- *****************************************************************************/
-
-#define SKIP \
-    { \
-        const char *psz_temp = psz_command; \
-        while( isspace( *psz_temp ) ) { \
-            ++psz_temp; \
-        } \
-        if( psz_temp == psz_command ) { \
-            return VLC_EGENERIC; \
-        } \
-        psz_command = psz_temp; \
-    }
-#define INT( name ) \
-    SKIP \
-    { \
-        char *psz_temp; \
-        p_myparams->name = strtol( psz_command, &psz_temp, 10 ); \
-        if( psz_temp == psz_command ) \
-        { \
-            return VLC_EGENERIC; \
-        } \
-        psz_command = psz_temp; \
-    }
-#define CHARS( name, count ) \
-    SKIP \
-    { \
-        if( psz_end - psz_command < count ) \
-        { \
-            return VLC_EGENERIC; \
-        } \
-        memcpy( p_myparams->name, psz_command, count ); \
-        psz_command += count; \
-    }
-#define COMMAND( name, param, ret, atomic, code ) \
-static int Command##name##Parse( const char *psz_command, \
-                                 const char *psz_end, \
-                                 commandparams_t *p_params ) \
-{ \
-    struct commandparams##name##_t *p_myparams = &p_params->name; \
-    param \
-    return VLC_SUCCESS; \
-}
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-#undef SKIP
-#undef INT
-#undef CHARS
-
-#define COMMAND( name, param, ret, atomic, code ) \
-static int Command##name##Exec( filter_t *p_filter, \
-                                const commandparams_t *p_gparams, \
-                                commandresults_t *p_gresults, \
-                                filter_sys_t *p_sys ) \
-{ \
-    const struct commandparams##name##_t *p_params = &p_gparams->name; \
-    struct commandresults##name##_t *p_results = &p_gresults->name; \
-    code \
-}
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-
-#define INT( name ) \
-    { \
-        int ret = BufferPrintf( p_output, " %d", p_myresults->name ); \
-        if( ret != VLC_SUCCESS ) { \
-            return ret; \
-        } \
-    }
-#define CHARS( name, count ) \
-    { \
-        int ret = BufferAdd( p_output, p_myresults->name, count ); \
-        if( ret != VLC_SUCCESS ) { \
-            return ret; \
-        } \
-    }
-#define COMMAND( name, param, ret, atomic, code ) \
-static int Command##name##Unparse( const commandresults_t *p_results, \
-                           buffer_t *p_output ) \
-{ \
-    const struct commandresults##name##_t *p_myresults = &p_results->name; \
-    ret \
-    return VLC_SUCCESS; \
-}
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-#undef INT
-#undef CHARS
-
-static commanddesc_t p_commands[] =
-{
-#define COMMAND( name, param, ret, atomic, code ) \
-{ #name, atomic, Command##name##Parse, Command##name##Exec, Command##name##Unparse },
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-};
-
-#define NUMCOMMANDS (sizeof(p_commands)/sizeof(commanddesc_t))
-
 /*****************************************************************************
  * Create: allocates adjust video thread output method
  *****************************************************************************
@@ -399,10 +124,7 @@ static int Create( vlc_object_t *p_this )
     var_AddCallback( p_filter, "overlay-input", AdjustCallback, p_sys );
     var_AddCallback( p_filter, "overlay-output", AdjustCallback, p_sys );
 
-    msg_Dbg( p_filter, "%d commands are available:", NUMCOMMANDS );
-    for( size_t i_index = 0; i_index < NUMCOMMANDS; ++i_index )
-        msg_Dbg( p_filter, "    %s", p_commands[i_index].psz_command );
-
+    RegisterCommand( p_filter );
     return VLC_SUCCESS;
 }
 
@@ -421,6 +143,7 @@ static void Destroy( vlc_object_t *p_this )
     QueueDestroy( &p_filter->p_sys->pending );
     QueueDestroy( &p_filter->p_sys->processed );
     ListDestroy( &p_filter->p_sys->overlays );
+    UnregisterCommand( p_filter );
 
     free( p_filter->p_sys->psz_inputfile );
     free( p_filter->p_sys->psz_outputfile );
@@ -502,74 +225,51 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
     /* Parse any complete commands */
     char *p_end, *p_cmd;
     while( ( p_end = memchr( p_sys->input.p_begin, '\n',
-                            p_sys->input.i_length ) ) )
+                             p_sys->input.i_length ) ) )
     {
+        commanddesc_t *p_cur = NULL;
+        vlc_bool_t b_found = VLC_FALSE;
+        size_t i_index = 0;
+
         *p_end = '\0';
-        p_cmd = p_sys->input.p_begin;
+        p_cmd = BufferGetToken( &p_sys->input );
 
-        commanddesc_t *p_lower = p_commands;
-        commanddesc_t *p_upper = p_commands + NUMCOMMANDS;
-        size_t i_index = 0;
-        while( 1 )
+        msg_Info( p_filter, "Search command: %s", p_cmd );
+        for( i_index = 0; i_index < p_sys->i_commands; i_index++ )
         {
-            if( ( p_cmd[i_index] == '\0' ) ||
-                isspace( p_cmd[i_index] ) )
+            p_cur = p_sys->pp_commands[i_index];
+            if( !strncmp( p_cur->psz_command, p_cmd, strlen(p_cur->psz_command) ) )
             {
+                p_cmd[strlen(p_cur->psz_command)] = '\0';
+                b_found = VLC_TRUE;
                 break;
             }
-            commanddesc_t *p_cur = p_lower;
-            while( ( p_cur < p_upper ) &&
-                   ( p_cur->psz_command[i_index] != p_cmd[i_index] ) )
-            {
-                ++p_cur;
-            }
-            p_lower = p_cur;
-            while( ( p_cur < p_upper ) &&
-                   ( p_cur->psz_command[i_index] == p_cmd[i_index] ) )
-            {
-                ++p_cur;
-            }
-            p_upper = p_cur;
-            ++i_index;
         }
-        if( p_lower >= p_upper )
+
+        if( !b_found )
         {
             /* No matching command */
-            p_cmd[i_index] = '\0';
             msg_Err( p_filter, "Got invalid command: %s", p_cmd );
             BufferPrintf( &p_sys->output, "FAILURE: %d Invalid Command\n", VLC_EGENERIC );
         }
-        else if ( p_lower + 1 < p_upper )
-        {
-            /* Command is not a unique prefix of a command */
-            p_cmd[i_index] = '\0';
-            msg_Err( p_filter, "Got ambiguous command: %s", p_cmd );
-            msg_Err( p_filter, "Possible completions are:" );
-            for( ; p_lower < p_upper; ++p_lower )
-            {
-                msg_Err( p_filter, "    %s", p_lower->psz_command );
-            }
-            BufferPrintf( &p_sys->output, "FAILURE: %d Invalid Command\n", VLC_EGENERIC );
-        }
         else
         {
-            /* Command is valid */
-            command_t *p_command = malloc( sizeof( command_t ) );
-            if( !p_command )
+            msg_Info( p_filter, "Got valid command: %s", p_cmd );
+
+            command_t *p_cmddesc = malloc( sizeof( command_t ) );
+            if( !p_cmddesc )
                 return NULL;
 
-            p_command->p_command = p_lower;
-            p_command->p_command->pf_parser( p_cmd + i_index, p_end,
-                                             &p_command->params );
+            p_cmd = p_cmd + strlen(p_cur->psz_command) +1;
+            p_cmddesc->p_command = p_cur;
+            p_cmddesc->p_command->pf_parser( p_cmd, p_end,
+                                             &p_cmddesc->params );
 
-            if( ( p_command->p_command->b_atomic == VLC_TRUE ) &&
+            if( ( p_cmddesc->p_command->b_atomic == VLC_TRUE ) &&
                 ( p_sys->b_atomic == VLC_TRUE ) )
-                QueueEnqueue( &p_sys->atomic, p_command );
+                QueueEnqueue( &p_sys->atomic, p_cmddesc );
             else
-                QueueEnqueue( &p_sys->pending, p_command );
-
-            p_cmd[i_index] = '\0';
-            msg_Dbg( p_filter, "Got valid command: %s", p_cmd );
+                QueueEnqueue( &p_sys->pending, p_cmddesc );
         }
 
         BufferDel( &p_sys->input, p_end - p_sys->input.p_begin + 1 );
@@ -581,7 +281,7 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
     {
         p_command->i_status =
             p_command->p_command->pf_execute( p_filter, &p_command->params,
-                                              &p_command->results, p_sys );
+                                              &p_command->results );
         QueueEnqueue( &p_sys->processed, p_command );
     }
 
@@ -651,18 +351,25 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
     while( (p_overlay = ListWalk( &p_sys->overlays )) )
     {
         msg_Dbg( p_filter, "Displaying overlay: %4.4s, %d, %d, %d",
-                 &p_overlay->format.i_chroma, p_overlay->i_x, p_overlay->i_y,
+                 (char*)&p_overlay->format.i_chroma, p_overlay->i_x, p_overlay->i_y,
                  p_overlay->i_alpha );
+
         if( p_overlay->format.i_chroma == VLC_FOURCC('T','E','X','T') )
         {
-            *pp_region = p_spu->pf_create_region( p_filter,
+            *pp_region = p_spu->pf_create_region( VLC_OBJECT(p_filter),
                                                   &p_overlay->format );
             if( !*pp_region )
+                break;
+            (*pp_region)->psz_text = strdup( p_overlay->data.p_text );
+            (*pp_region)->p_style = malloc( sizeof(struct text_style_t) );
+            if( !(*pp_region)->p_style )
             {
-                msg_Err( p_filter, "cannot allocate subpicture region" );
-                continue;
+                p_spu->pf_destroy_region( VLC_OBJECT(p_filter), (*pp_region) );
+                *pp_region = NULL;
+                break;
             }
             (*pp_region)->psz_text = strdup( p_overlay->data.p_text );
+            memcpy( (*pp_region)->p_style, &p_overlay->fontstyle, sizeof(text_style_t) );
         }
         else
         {
@@ -677,7 +384,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
                 continue;
             }
             vout_CopyPicture( p_filter, &clone, p_overlay->data.p_pic );
-            *pp_region = p_spu->pf_make_region( p_filter, &p_overlay->format,
+            *pp_region = p_spu->pf_make_region( VLC_OBJECT(p_filter),
+                                                &p_overlay->format,
                                                 &clone );
             if( !*pp_region )
             {
@@ -701,6 +409,12 @@ static int AdjustCallback( vlc_object_t *p_this, char const *psz_var,
                            void *p_data )
 {
     filter_sys_t *p_sys = (filter_sys_t *)p_data;
-    VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(oldval); VLC_UNUSED(newval);
+    VLC_UNUSED(p_this); VLC_UNUSED(oldval);
+
+    if( !strncmp( psz_var, "overlay-input", 13 ) )
+        p_sys->psz_inputfile = newval.psz_string;
+    else if( !strncmp( psz_var, "overlay-output", 14 ) )
+        p_sys->psz_outputfile = newval.psz_string;
+
     return VLC_EGENERIC;
 }
index c2f1f5f5f92fec3ac7ccd7793ec1fd697bb381d3..db8cac59d64830c4864f961717b574f0b1b453be 100644 (file)
@@ -24,6 +24,9 @@
 #ifndef DYNAMIC_OVERLAY_H
 #define DYNAMIC_OVERLAY_H   1
 
+#include <vlc/vlc.h>
+#include <vlc_filter.h>
+
 /*****************************************************************************
  * buffer_t: Command and response buffer
  *****************************************************************************/
@@ -42,61 +45,42 @@ int BufferDestroy( buffer_t *p_buffer );
 int BufferAdd( buffer_t *p_buffer, const char *p_data, size_t i_len );
 int BufferPrintf( buffer_t *p_buffer, const char *p_fmt, ... );
 int BufferDel( buffer_t *p_buffer, int i_len );
+char *BufferGetToken( buffer_t *p_buffer );
 
 /*****************************************************************************
  * Command structures
  *****************************************************************************/
 
- #define INT( name ) int name;
-#define CHARS( name, count ) char name[count];
-#define COMMAND( name, param, ret, atomic, code ) \
-struct commandparams##name##_t \
-{ \
-    param \
-};
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-#undef INT
-#undef CHARS
-
-union commandparams_t
+/** struct commandparams_t - command params structure */
+typedef struct commandparams_t
 {
-#define COMMAND( name, param, ret, atomic, code ) struct commandparams##name##_t name;
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-};
-typedef union commandparams_t commandparams_t;
-
-#define INT( name ) int name;
-#define CHARS( name, count ) char name[count];
-#define COMMAND( name, param, ret, atomic, code ) \
-struct commandresults##name##_t \
-{ \
-    ret \
-};
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-#undef INT
-#undef CHARS
-
-union commandresults_t {
-#define COMMAND( name, param, ret, atomic, code ) struct commandresults##name##_t name;
-#include "dynamicoverlay_commands.h"
-#undef COMMAND
-};
-typedef union commandresults_t commandresults_t;
+    int32_t i_id;       /*< overlay id */
+    int32_t i_shmid;    /*< shared memory identifier */
+
+    vlc_fourcc_t fourcc;/*< chroma */
+
+    int32_t i_x;        /*< x position of overlay */
+    int32_t i_y;        /*< y position of overlay */
+    int32_t i_width;    /*< width of overlay */
+    int32_t i_height;   /*< height of overlay */
+
+    int32_t i_alpha;    /*< alpha value of overlay */
+
+    struct text_style_t fontstyle; /*< text style */
+
+    vlc_bool_t b_visible; /*< visibility flag of overlay */
+} commandparams_t;
 
 typedef struct commanddesc_t
 {
     const char *psz_command;
     vlc_bool_t b_atomic;
-    int ( *pf_parser ) ( const char *psz_command, const char *psz_end,
+    int ( *pf_parser ) ( char *psz_command, char *psz_end,
                          commandparams_t *p_params );
     int ( *pf_execute ) ( filter_t *p_filter, const commandparams_t *p_params,
-                          commandresults_t *p_results,
-                          struct filter_sys_t *p_sys );
-    int ( *pf_unparser ) ( const commandresults_t *p_results,
-                           buffer_t *p_output );
+                          commandparams_t *p_results );
+    int ( *pf_unparse ) ( const commandparams_t *p_results,
+                          buffer_t *p_output );
 } commanddesc_t;
 
 typedef struct command_t
@@ -104,11 +88,13 @@ typedef struct command_t
     struct commanddesc_t *p_command;
     int i_status;
     commandparams_t params;
-    commandresults_t results;
-
+    commandparams_t results;
     struct command_t *p_next;
 } command_t;
 
+void RegisterCommand( filter_t *p_filter );
+void UnregisterCommand( filter_t *p_filter );
+
 /*****************************************************************************
  * queue_t: Command queue
  *****************************************************************************/
@@ -125,4 +111,60 @@ int QueueEnqueue( queue_t *p_queue, command_t *p_cmd );
 command_t *QueueDequeue( queue_t *p_queue );
 int QueueTransfer( queue_t *p_sink, queue_t *p_source );
 
+/*****************************************************************************
+ * overlay_t: Overlay descriptor
+ *****************************************************************************/
+
+typedef struct overlay_t
+{
+    int i_x, i_y;
+    int i_alpha;
+    vlc_bool_t b_active;
+
+    video_format_t format;
+    struct text_style_t fontstyle;
+    union {
+        picture_t *p_pic;
+        char *p_text;
+    } data;
+} overlay_t;
+
+overlay_t *OverlayCreate( void );
+int OverlayDestroy( overlay_t *p_ovl );
+
+/*****************************************************************************
+ * list_t: Command queue
+ *****************************************************************************/
+
+typedef struct list_t
+{
+    overlay_t **pp_head, **pp_tail;
+} list_t;
+
+int ListInit( list_t *p_list );
+int ListDestroy( list_t *p_list );
+ssize_t ListAdd( list_t *p_list, overlay_t *p_new );
+int ListRemove( list_t *p_list, size_t i_idx );
+overlay_t *ListGet( list_t *p_list, size_t i_idx );
+overlay_t *ListWalk( list_t *p_list );
+
+/*****************************************************************************
+ * filter_sys_t: adjust filter method descriptor
+ *****************************************************************************/
+
+struct filter_sys_t
+{
+    buffer_t input, output;
+
+    int i_inputfd, i_outputfd;
+    char *psz_inputfile, *psz_outputfile;
+
+    commanddesc_t **pp_commands; /* array of commands */
+    size_t i_commands;
+
+    vlc_bool_t b_updated, b_atomic;
+    queue_t atomic, pending, processed;
+    list_t overlays;
+};
+
 #endif
index 891072f20cb69eda8c4a1e632c33a6a418c4c4d9..ee0e2db4774d73832ad705c71d4a15654abc1ff5 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * dynamicoverlay_commands.def : dynamic overlay plugin commands
+ * dynamicoverlay_buffer.h : dynamic overlay buffer
  *****************************************************************************
  * Copyright (C) 2008 the VideoLAN team
  * $Id$
 #endif
 
 #include <vlc/vlc.h>
+#include <vlc_osd.h>
+#include <vlc_filter.h>
+
+#include <ctype.h>
 
 #include "dynamicoverlay.h"
 
@@ -55,6 +59,20 @@ int BufferDestroy( buffer_t *p_buffer )
     return VLC_SUCCESS;
 }
 
+char *BufferGetToken( buffer_t *p_buffer )
+{
+    char *p_char = p_buffer->p_begin;
+
+    while( isspace( p_char[0] ) || p_char[0] == '\0' )
+    {
+        if( p_char <= (p_buffer->p_begin + p_buffer->i_length) )
+            p_char++;
+        else
+            return NULL;
+    }
+    return p_char;
+}
+
 int BufferAdd( buffer_t *p_buffer, const char *p_data, size_t i_len )
 {
     if( ( p_buffer->i_size - p_buffer->i_length -
diff --git a/modules/video_filter/dynamicoverlay/dynamicoverlay_commands.c b/modules/video_filter/dynamicoverlay/dynamicoverlay_commands.c
new file mode 100644 (file)
index 0000000..14630fc
--- /dev/null
@@ -0,0 +1,932 @@
+/*****************************************************************************
+ * dynamicoverlay_commands.c : dynamic overlay plugin commands
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Author: Søren Bøg <avacore@videolan.org>
+ *         Jean-Paul Saman <jpsaman@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc/vlc.h>
+#include <vlc_arrays.h>
+#include <vlc_vout.h>
+#include <vlc_filter.h>
+#include <vlc_osd.h>
+
+#include <string.h>
+#include <ctype.h>
+#include <sys/shm.h>
+
+#include "dynamicoverlay.h"
+
+
+/*****************************************************************************
+ * overlay_t: Overlay descriptor
+ *****************************************************************************/
+
+overlay_t *OverlayCreate( void )
+{
+    overlay_t *p_ovl = malloc( sizeof( overlay_t ) );
+    if( p_ovl == NULL )
+       return NULL;
+    memset( p_ovl, 0, sizeof( overlay_t ) );
+
+    p_ovl->i_x = p_ovl->i_y = 0;
+    p_ovl->i_alpha = 0xFF;
+    p_ovl->b_active = VLC_FALSE;
+    vout_InitFormat( &p_ovl->format, VLC_FOURCC( '\0','\0','\0','\0') , 0, 0,
+                     VOUT_ASPECT_FACTOR );
+    memcpy( &p_ovl->fontstyle, &default_text_style, sizeof(struct text_style_t) );
+    p_ovl->data.p_text = NULL;
+
+    return p_ovl;
+}
+
+int OverlayDestroy( overlay_t *p_ovl )
+{
+    if( p_ovl->data.p_text != NULL )
+        free( p_ovl->data.p_text );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Command parsers
+ *****************************************************************************/
+static int skip_space( char **psz_command )
+{
+    char *psz_temp = *psz_command;
+
+    while( isspace( *psz_temp ) )
+    {
+        ++psz_temp;
+    }
+    if( psz_temp == *psz_command )
+    {
+        return VLC_EGENERIC;
+    }
+    *psz_command = psz_temp;
+    return VLC_SUCCESS;
+}
+
+static int parse_digit( char **psz_command, int32_t *value )
+{
+    char *psz_temp;
+    *value = strtol( *psz_command, &psz_temp, 10 );
+    if( psz_temp == *psz_command )
+    {
+        return VLC_EGENERIC;
+    }
+    *psz_command = psz_temp;
+    return VLC_SUCCESS;
+}
+
+static int parse_char( char **psz_command, char **psz_end,
+                       int count, char *psz_value )
+{
+    if( *psz_end - *psz_command < count )
+    {
+        return VLC_EGENERIC;
+    }
+    memcpy( psz_value, *psz_command, count );
+    *psz_command += count;
+    return VLC_SUCCESS;
+}
+
+static int parser_DataSharedMem( char *psz_command,
+                                 char *psz_end,
+                                 commandparams_t *p_params )
+{
+    /* Parse: 0 128 128 RGBA 9404459 */
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_width ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_height ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isascii( *psz_command ) )
+    {
+        if( parse_char( &psz_command, &psz_end, 4, (char*)&p_params->fourcc )
+            == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_shmid ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_Id( char *psz_command, char *psz_end,
+                      commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_None( char *psz_command, char *psz_end,
+                        commandparams_t *p_params )
+{
+    (void)(psz_command);
+    (void)(psz_end);
+    (void)(p_params);
+    return VLC_SUCCESS;
+}
+
+static int parser_SetAlpha( char *psz_command, char *psz_end,
+                            commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC  )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_alpha ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_SetPosition( char *psz_command, char *psz_end,
+                               commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_x ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_y ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_SetTextAlpha( char *psz_command, char *psz_end,
+                                commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->fontstyle.i_font_alpha ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_SetTextColor( char *psz_command, char *psz_end,
+                                commandparams_t *p_params )
+{
+    int r, g, b;
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &r ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &g ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &b ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    p_params->fontstyle.i_font_color = (r<<24) | (g<<16) | (b<<8);
+    return VLC_SUCCESS;
+}
+
+static int parser_SetTextSize( char *psz_command, char *psz_end,
+                               commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->fontstyle.i_font_size ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    return VLC_SUCCESS;
+}
+
+static int parser_SetVisibility( char *psz_command, char *psz_end,
+                                 commandparams_t *p_params )
+{
+    (void)(psz_end);
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        if( parse_digit( &psz_command, &p_params->i_id ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+    }
+    skip_space( &psz_command );
+    if( isdigit( *psz_command ) )
+    {
+        int32_t i_vis = 0;
+        if( parse_digit( &psz_command, &i_vis ) == VLC_EGENERIC )
+            return VLC_EGENERIC;
+        p_params->b_visible = (i_vis == 1) ? VLC_TRUE : VLC_FALSE;
+    }
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Command unparser functions
+ *****************************************************************************/
+
+static int unparse_default( const commandparams_t *p_results,
+                            buffer_t *p_output )
+{
+    (void)(p_results);
+    VLC_UNUSED(p_output);
+    return VLC_SUCCESS;
+}
+
+static int unparse_GenImage( const commandparams_t *p_results,
+                             buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", p_results->i_id );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetAlpha( const commandparams_t *p_results,
+                             buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", p_results->i_alpha );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetPosition( const commandparams_t *p_results,
+                                buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", p_results->i_x );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    ret = BufferPrintf( p_output, " %d", p_results->i_y );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetTextAlpha( const commandparams_t *p_results,
+                                 buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", p_results->fontstyle.i_font_alpha );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetTextColor( const commandparams_t *p_results,
+                                 buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0xff0000)>>24 );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0x00ff00)>>16 );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    ret = BufferPrintf( p_output, " %d", (p_results->fontstyle.i_font_color & 0x0000ff)>>8 );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetTextSize( const commandparams_t *p_results,
+                                buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", p_results->fontstyle.i_font_size );
+    if( ret != VLC_SUCCESS )
+        return ret;
+
+    return VLC_SUCCESS;
+}
+
+static int unparse_GetVisibility( const commandparams_t *p_results,
+                             buffer_t *p_output )
+{
+    int ret = BufferPrintf( p_output, " %d", (p_results->b_visible ? 1 : 0) );
+    if( ret != VLC_SUCCESS ) {
+        return ret;
+    }
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Command functions
+ *****************************************************************************/
+static int exec_DataSharedMem( filter_t *p_filter,
+                               const commandparams_t *p_params,
+                               commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    struct shmid_ds shminfo;
+    overlay_t *p_ovl;
+    size_t i_size;
+
+    (void)(p_results);
+
+    p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+    {
+        msg_Err( p_filter, "Invalid overlay: %d", p_params->i_id );
+        return VLC_EGENERIC;
+    }
+
+    if( shmctl( p_params->i_shmid, IPC_STAT, &shminfo ) == -1 )
+    {
+        msg_Err( p_filter, "Unable to access shared memory" );
+        return VLC_EGENERIC;
+    }
+    i_size = shminfo.shm_segsz;
+
+    if( p_params->fourcc == VLC_FOURCC('T','E','X','T') )
+    {
+        char *p_data;
+
+        if( (p_params->i_height != 1) || (p_params->i_width < 1) )
+        {
+            msg_Err( p_filter,
+                     "Invalid width and/or height. when specifing text height "
+                     "must be 1 and width the number of bytes in the string, "
+                     "including the null terminator" );
+            return VLC_EGENERIC;
+        }
+
+        if( (size_t)p_params->i_width > i_size )
+        {
+            msg_Err( p_filter,
+                     "Insufficient data in shared memory. need %d, got %d",
+                     p_params->i_width, i_size );
+            return VLC_EGENERIC;
+        }
+
+        p_ovl->data.p_text = malloc( p_params->i_width );
+        if( p_ovl->data.p_text == NULL )
+        {
+            msg_Err( p_filter, "Unable to allocate string storage" );
+            return VLC_ENOMEM;
+        }
+
+        vout_InitFormat( &p_ovl->format, VLC_FOURCC('T','E','X','T'),
+                         0, 0, 0 );
+
+        p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
+        if( p_data == NULL )
+        {
+            msg_Err( p_filter, "Unable to attach to shared memory" );
+            free( p_ovl->data.p_text );
+            p_ovl->data.p_text = NULL;
+            return VLC_ENOMEM;
+        }
+
+        memcpy( p_ovl->data.p_text, p_data, p_params->i_width );
+
+        shmdt( p_data );
+    }
+    else
+    {
+        uint8_t *p_data, *p_in;
+        size_t i_neededsize = 0;
+
+        p_ovl->data.p_pic = malloc( sizeof( picture_t ) );
+        if( p_ovl->data.p_pic == NULL )
+        {
+            msg_Err( p_filter, "Unable to allocate picture structure" );
+            return VLC_ENOMEM;
+        }
+
+        vout_InitFormat( &p_ovl->format, p_params->fourcc,
+                         p_params->i_width, p_params->i_height,
+                         VOUT_ASPECT_FACTOR );
+        if( vout_AllocatePicture( p_filter, p_ovl->data.p_pic,
+                                  p_ovl->format.i_chroma, p_params->i_width,
+                                  p_params->i_height, p_ovl->format.i_aspect ) )
+        {
+            msg_Err( p_filter, "Unable to allocate picture" );
+            free( p_ovl->data.p_pic );
+            p_ovl->data.p_pic = NULL;
+            return VLC_ENOMEM;
+        }
+
+        for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
+             ++i_plane )
+        {
+            i_neededsize += p_ovl->data.p_pic->p[i_plane].i_visible_lines *
+                            p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
+        }
+
+        if( i_neededsize > i_size )
+        {
+            msg_Err( p_filter,
+                     "Insufficient data in shared memory. need %d, got %d",
+                     i_neededsize, i_size );
+            p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
+            free( p_ovl->data.p_pic );
+            p_ovl->data.p_pic = NULL;
+            return VLC_EGENERIC;
+        }
+
+        p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
+        if( p_data == NULL )
+        {
+            msg_Err( p_filter, "Unable to attach to shared memory" );
+            p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
+            free( p_ovl->data.p_pic );
+            p_ovl->data.p_pic = NULL;
+            return VLC_ENOMEM;
+        }
+
+        p_in = p_data;
+        for( size_t i_plane = 0; i_plane < (size_t)p_ovl->data.p_pic->i_planes;
+             ++i_plane )
+        {
+            uint8_t *p_out = p_ovl->data.p_pic->p[i_plane].p_pixels;
+            for( size_t i_line = 0;
+                 i_line < (size_t)p_ovl->data.p_pic->p[i_plane].i_visible_lines;
+                 ++i_line )
+            {
+                p_filter->p_libvlc->pf_memcpy( p_out, p_in,
+                                p_ovl->data.p_pic->p[i_plane].i_visible_pitch );
+                p_out += p_ovl->data.p_pic->p[i_plane].i_pitch;
+                p_in += p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
+            }
+        }
+        shmdt( p_data );
+    }
+
+    p_sys->b_updated = p_ovl->b_active;
+
+    return VLC_SUCCESS;
+}
+
+static int exec_DeleteImage( filter_t *p_filter,
+                             const commandparams_t *p_params,
+                             commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    p_sys->b_updated = VLC_TRUE;
+
+    return ListRemove( &p_sys->overlays, p_params->i_id );
+}
+
+static int exec_EndAtomic( filter_t *p_filter,
+                           const commandparams_t *p_params,
+                           commandparams_t *p_results )
+{
+    (void)(p_params);
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    QueueTransfer( &p_sys->pending, &p_sys->atomic );
+    p_sys->b_atomic = VLC_FALSE;
+    return VLC_SUCCESS;
+}
+
+static int exec_GenImage( filter_t *p_filter,
+                          const commandparams_t *p_params,
+                          commandparams_t *p_results )
+{
+    (void)(p_params);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = OverlayCreate();
+    if( p_ovl == NULL )
+        return VLC_ENOMEM;
+
+    ssize_t i_idx = ListAdd( &p_sys->overlays, p_ovl );
+    if( i_idx < 0 )
+        return i_idx;
+
+    p_results->i_id = i_idx;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetAlpha( filter_t *p_filter,
+                          const commandparams_t *p_params,
+                          commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->i_alpha = p_ovl->i_alpha;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetPosition( filter_t *p_filter,
+                             const commandparams_t *p_params,
+                             commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->i_x = p_ovl->i_x;
+    p_results->i_y = p_ovl->i_y;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetTextAlpha( filter_t *p_filter,
+                              const commandparams_t *p_params,
+                              commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->fontstyle.i_font_alpha = p_ovl->fontstyle.i_font_alpha;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetTextColor( filter_t *p_filter,
+                              const commandparams_t *p_params,
+                              commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->fontstyle.i_font_color = p_ovl->fontstyle.i_font_color;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetTextSize( filter_t *p_filter,
+                             const commandparams_t *p_params,
+                             commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->fontstyle.i_font_size = p_ovl->fontstyle.i_font_size;
+    return VLC_SUCCESS;
+}
+
+static int exec_GetVisibility( filter_t *p_filter,
+                               const commandparams_t *p_params,
+                               commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_results->b_visible = ( p_ovl->b_active == VLC_TRUE ) ? 1 : 0;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetAlpha( filter_t *p_filter,
+                          const commandparams_t *p_params,
+                          commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->i_alpha = p_params->i_alpha;
+    p_sys->b_updated = p_ovl->b_active;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetPosition( filter_t *p_filter,
+                             const commandparams_t *p_params,
+                             commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->i_x = p_params->i_x;
+    p_ovl->i_y = p_params->i_y;
+
+    p_sys->b_updated = p_ovl->b_active;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetTextAlpha( filter_t *p_filter,
+                              const commandparams_t *p_params,
+                              commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->fontstyle.i_font_alpha = p_params->fontstyle.i_font_alpha;
+    p_sys->b_updated = p_ovl->b_active;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetTextColor( filter_t *p_filter,
+                              const commandparams_t *p_params,
+                              commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->fontstyle.i_font_color = p_params->fontstyle.i_font_color;
+    p_sys->b_updated = p_ovl->b_active;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetTextSize( filter_t *p_filter,
+                              const commandparams_t *p_params,
+                              commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->fontstyle.i_font_size = p_params->fontstyle.i_font_size;
+    p_sys->b_updated = p_ovl->b_active;
+    return VLC_SUCCESS;
+}
+
+static int exec_SetVisibility( filter_t *p_filter,
+                               const commandparams_t *p_params,
+                               commandparams_t *p_results )
+{
+    (void)(p_results);
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+
+    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
+    if( p_ovl == NULL )
+        return VLC_EGENERIC;
+
+    p_ovl->b_active = p_params->b_visible;// ? VLC_FALSE : VLC_TRUE;
+    p_sys->b_updated = VLC_TRUE;
+    return VLC_SUCCESS;
+}
+
+static int exec_StartAtomic( filter_t *p_filter,
+                             const commandparams_t *p_params,
+                             commandparams_t *p_results )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    (void)(p_params);
+    (void)(p_results);
+
+    p_sys->b_atomic = VLC_TRUE;
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Command functions
+ *****************************************************************************/
+static commanddesc_t p_commands[] =
+{
+    {   .psz_command = "DataSharedMem",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_DataSharedMem,
+        .pf_execute = exec_DataSharedMem,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "DeleteImage",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_DeleteImage,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "EndAtomic",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_None,
+        .pf_execute = exec_EndAtomic,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "GenImage",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_None,
+        .pf_execute = exec_GenImage,
+        .pf_unparse = unparse_GenImage,
+    },
+    {   .psz_command = "GetAlpha",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetAlpha,
+        .pf_unparse = unparse_GetAlpha,
+    },
+    {   .psz_command = "GetPosition",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetPosition,
+        .pf_unparse = unparse_GetPosition,
+    },
+    {   .psz_command = "GetTextAlpha",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetTextAlpha,
+        .pf_unparse = unparse_GetTextAlpha,
+    },
+    {   .psz_command = "GetTextColor",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetTextColor,
+        .pf_unparse = unparse_GetTextColor,
+    },
+    {   .psz_command = "GetTextSize",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetTextSize,
+        .pf_unparse = unparse_GetTextSize,
+    },
+    {   .psz_command = "GetVisibility",
+        .b_atomic = VLC_FALSE,
+        .pf_parser = parser_Id,
+        .pf_execute = exec_GetVisibility,
+        .pf_unparse = unparse_GetVisibility,
+    },
+    {   .psz_command = "SetAlpha",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetAlpha,
+        .pf_execute = exec_SetAlpha,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "SetPosition",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetPosition,
+        .pf_execute = exec_SetPosition,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "SetTextAlpha",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetTextAlpha,
+        .pf_execute = exec_SetTextAlpha,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "SetTextColor",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetTextColor,
+        .pf_execute = exec_SetTextColor,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "SetTextSize",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetTextSize,
+        .pf_execute = exec_SetTextSize,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "SetVisibility",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_SetVisibility,
+        .pf_execute = exec_SetVisibility,
+        .pf_unparse = unparse_default,
+    },
+    {   .psz_command = "StartAtomic",
+        .b_atomic = VLC_TRUE,
+        .pf_parser = parser_None,
+        .pf_execute = exec_StartAtomic,
+        .pf_unparse = unparse_default,
+    }
+};
+
+void RegisterCommand( filter_t *p_filter )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    size_t i_index = 0;
+
+    p_sys->i_commands = ARRAY_SIZE(p_commands);
+    p_sys->pp_commands = (commanddesc_t **) calloc( p_sys->i_commands, sizeof(commanddesc_t*) );
+    if( !p_sys->pp_commands ) return;
+    for( i_index = 0; i_index < p_sys->i_commands; i_index ++ )
+    {
+        p_sys->pp_commands[i_index] = (commanddesc_t *) malloc( sizeof(commanddesc_t) );
+        if( !p_sys->pp_commands[i_index] ) return;
+        p_sys->pp_commands[i_index]->psz_command = strdup( p_commands[i_index].psz_command );
+        p_sys->pp_commands[i_index]->b_atomic = p_commands[i_index].b_atomic;
+        p_sys->pp_commands[i_index]->pf_parser = p_commands[i_index].pf_parser;
+        p_sys->pp_commands[i_index]->pf_execute = p_commands[i_index].pf_execute;
+        p_sys->pp_commands[i_index]->pf_unparse = p_commands[i_index].pf_unparse;
+    }
+
+    msg_Dbg( p_filter, "%d commands are available", p_sys->i_commands );
+    for( size_t i_index = 0; i_index < p_sys->i_commands; i_index++ )
+        msg_Dbg( p_filter, "    %s", p_sys->pp_commands[i_index]->psz_command );
+}
+
+void UnregisterCommand( filter_t *p_filter )
+{
+    filter_sys_t *p_sys = (filter_sys_t*) p_filter->p_sys;
+    size_t i_index = 0;
+
+    for( i_index = 0; i_index < p_sys->i_commands; i_index++ )
+    {
+        free( p_sys->pp_commands[i_index]->psz_command );
+        free( p_sys->pp_commands[i_index] );
+    }
+    free( p_sys->pp_commands );
+    p_sys->pp_commands = NULL;
+    p_sys->i_commands = 0;
+}
diff --git a/modules/video_filter/dynamicoverlay/dynamicoverlay_commands.h b/modules/video_filter/dynamicoverlay/dynamicoverlay_commands.h
deleted file mode 100644 (file)
index 5dced8b..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*****************************************************************************
- * dynamicoverlay_commands.def : dynamic overlay plugin commands
- *****************************************************************************
- * Copyright (C) 2008 the VideoLAN team
- * $Id$
- *
- * Author: Søren Bøg <avacore@videolan.org>
- *         Jean-Paul Saman <jpsaman@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include <sys/shm.h>
-
-/* Commands must be sorted alphabetically.
-   I haven't found out how to implement quick sort in cpp */
-COMMAND( DataSharedMem, INT( i_id ) INT( i_width ) INT( i_height )
-         CHARS( p_fourcc, 4 ) INT( i_shmid ), , VLC_TRUE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        msg_Err( p_filter, "Invalid overlay: %d", p_params->i_id );
-        return VLC_EGENERIC;
-    }
-
-    struct shmid_ds shminfo;
-    if( shmctl( p_params->i_shmid, IPC_STAT, &shminfo ) == -1 ) {
-        msg_Err( p_filter, "Unable to access shared memory" );
-        return VLC_EGENERIC;
-    }
-    size_t i_size = shminfo.shm_segsz;
-
-    if( strncmp( p_params->p_fourcc, "TEXT", 4 ) == 0 ) {
-        if( p_params->i_height != 1 || p_params->i_width < 1 ) {
-            msg_Err( p_filter,
-                     "Invalid width and/or height. when specifing text height "
-                     "must be 1 and width the number of bytes in the string, "
-                     "including the null terminator" );
-            return VLC_EGENERIC;
-        }
-
-        if( p_params->i_width > i_size ) {
-            msg_Err( p_filter,
-                     "Insufficient data in shared memory. need %d, got %d",
-                     p_params->i_width, i_size );
-            return VLC_EGENERIC;
-        }
-
-        p_ovl->data.p_text = malloc( p_params->i_width );
-        if( p_ovl->data.p_text == NULL )
-        {
-            msg_Err( p_filter, "Unable to allocate string storage" );
-            return VLC_ENOMEM;
-        }
-
-        vout_InitFormat( &p_ovl->format, VLC_FOURCC( 'T', 'E', 'X', 'T' ), 0, 0,
-                         0 );
-
-        char *p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
-        if( p_data == NULL )
-        {
-            msg_Err( p_filter, "Unable to attach to shared memory" );
-            free( p_ovl->data.p_text );
-            p_ovl->data.p_text = NULL;
-            return VLC_ENOMEM;
-        }
-
-        memcpy( p_ovl->data.p_text, p_data, p_params->i_width );
-
-        shmdt( p_data );
-    } else {
-        p_ovl->data.p_pic = malloc( sizeof( picture_t ) );
-        if( p_ovl->data.p_pic == NULL )
-        {
-            msg_Err( p_filter, "Unable to allocate picture structure" );
-            return VLC_ENOMEM;
-        }
-
-        vout_InitFormat( &p_ovl->format, VLC_FOURCC( p_params->p_fourcc[0],
-                                                     p_params->p_fourcc[1],
-                                                     p_params->p_fourcc[2],
-                                                     p_params->p_fourcc[3] ),
-                         p_params->i_width, p_params->i_height,
-                         VOUT_ASPECT_FACTOR );
-        if( vout_AllocatePicture( p_filter, p_ovl->data.p_pic,
-                                  p_ovl->format.i_chroma, p_params->i_width,
-                                  p_params->i_height, p_ovl->format.i_aspect ) )
-        {
-            msg_Err( p_filter, "Unable to allocate picture" );
-            free( p_ovl->data.p_pic );
-            p_ovl->data.p_pic = NULL;
-            return VLC_ENOMEM;
-        }
-
-        size_t i_neededsize = 0;
-        for( size_t i_plane = 0; i_plane < p_ovl->data.p_pic->i_planes;
-             ++i_plane ) {
-            i_neededsize += p_ovl->data.p_pic->p[i_plane].i_visible_lines *
-                            p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
-        }
-        if( i_neededsize > i_size ) {
-            msg_Err( p_filter,
-                     "Insufficient data in shared memory. need %d, got %d",
-                     i_neededsize, i_size );
-            p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
-            free( p_ovl->data.p_pic );
-            p_ovl->data.p_pic = NULL;
-            return VLC_EGENERIC;
-        }
-
-        char *p_data = shmat( p_params->i_shmid, NULL, SHM_RDONLY );
-        if( p_data == NULL )
-        {
-            msg_Err( p_filter, "Unable to attach to shared memory" );
-            p_ovl->data.p_pic->pf_release( p_ovl->data.p_pic );
-            free( p_ovl->data.p_pic );
-            p_ovl->data.p_pic = NULL;
-            return VLC_ENOMEM;
-        }
-
-        char *p_in = p_data;
-        for( size_t i_plane = 0; i_plane < p_ovl->data.p_pic->i_planes;
-             ++i_plane ) {
-            char *p_out = p_ovl->data.p_pic->p[i_plane].p_pixels;
-            for( size_t i_line = 0;
-                 i_line < p_ovl->data.p_pic->p[i_plane].i_visible_lines;
-                 ++i_line ) {
-                p_filter->p_libvlc->pf_memcpy( p_out, p_in,
-                                p_ovl->data.p_pic->p[i_plane].i_visible_pitch );
-                p_out += p_ovl->data.p_pic->p[i_plane].i_pitch;
-                p_in += p_ovl->data.p_pic->p[i_plane].i_visible_pitch;
-            }
-        }
-
-        shmdt( p_data );
-    }
-
-    p_sys->b_updated = p_ovl->b_active;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( DeleteImage, INT( i_id ), , VLC_TRUE, {
-    p_sys->b_updated = VLC_TRUE;
-
-    return ListRemove( &p_sys->overlays, p_params->i_id );
-} )
-COMMAND( EndAtomic, , , VLC_FALSE, {
-    QueueTransfer( &p_sys->pending, &p_sys->atomic );
-    p_sys->b_atomic = VLC_FALSE;
-    return VLC_SUCCESS;
-} )
-COMMAND( GenImage, , INT( i_newid ), VLC_FALSE, {
-    overlay_t *p_ovl = OverlayCreate();
-    if( p_ovl == NULL ) {
-        return VLC_ENOMEM;
-    }
-
-    ssize_t i_idx = ListAdd( &p_sys->overlays, p_ovl );
-    if( i_idx < 0 ) {
-        return i_idx;
-    }
-
-    p_results->i_newid = i_idx;
-    return VLC_SUCCESS;
-} )
-COMMAND( GetAlpha, INT( i_id ), INT( i_alpha ), VLC_FALSE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_results->i_alpha = p_ovl->i_alpha;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( GetPosition, INT( i_id ), INT( i_x ) INT( i_y ), VLC_FALSE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_results->i_x = p_ovl->i_x;
-    p_results->i_y = p_ovl->i_y;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( GetVisibility, INT( i_id ), INT( i_vis ), VLC_FALSE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_results->i_vis = ( p_ovl->b_active == VLC_TRUE ) ? 1 : 0;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( SetAlpha, INT( i_id ) INT( i_alpha ), , VLC_TRUE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_ovl->i_alpha = p_params->i_alpha;
-
-    p_sys->b_updated = p_ovl->b_active;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( SetPosition, INT( i_id ) INT( i_x ) INT( i_y ), , VLC_TRUE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_ovl->i_x = p_params->i_x;
-    p_ovl->i_y = p_params->i_y;
-
-    p_sys->b_updated = p_ovl->b_active;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( SetVisibility, INT( i_id ) INT( i_vis ), , VLC_TRUE, {
-    overlay_t *p_ovl = ListGet( &p_sys->overlays, p_params->i_id );
-    if( p_ovl == NULL ) {
-        return VLC_EGENERIC;
-    }
-    p_ovl->b_active = ( p_params->i_vis == 0 ) ? VLC_FALSE : VLC_TRUE;
-
-    p_sys->b_updated = VLC_TRUE;
-
-    return VLC_SUCCESS;
-} )
-COMMAND( StartAtomic, , , VLC_FALSE, {
-    p_sys->b_atomic = VLC_TRUE;
-    return VLC_SUCCESS;
-} )
diff --git a/modules/video_filter/dynamicoverlay/dynamicoverlay_list.c b/modules/video_filter/dynamicoverlay/dynamicoverlay_list.c
new file mode 100644 (file)
index 0000000..06924fb
--- /dev/null
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * dynamicoverlay_list.h : dynamic overlay list
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Author: Søren Bøg <avacore@videolan.org>
+ *         Jean-Paul Saman <jpsaman@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc/vlc.h>
+#include <vlc_osd.h>
+
+#include <fcntl.h>
+#include "dynamicoverlay.h"
+
+/*****************************************************************************
+ * list_t: Command queue
+ *****************************************************************************/
+
+int ListInit( list_t *p_list )
+{
+    p_list->pp_head = malloc( 16 * sizeof( overlay_t * ) );
+    if( p_list->pp_head == NULL )
+        return VLC_ENOMEM;
+
+    p_list->pp_tail = p_list->pp_head + 16;
+    memset( p_list->pp_head, 0, 16 * sizeof( overlay_t * ) );
+
+    return VLC_SUCCESS;
+}
+
+int ListDestroy( list_t *p_list )
+{
+    for( overlay_t **pp_cur = p_list->pp_head;
+         pp_cur < p_list->pp_tail;
+         ++pp_cur )
+    {
+        if( *pp_cur != NULL )
+        {
+            OverlayDestroy( *pp_cur );
+            free( *pp_cur );
+        }
+    }
+    free( p_list->pp_head );
+
+    return VLC_SUCCESS;
+}
+
+ssize_t ListAdd( list_t *p_list, overlay_t *p_new )
+{
+    /* Find an available slot */
+    for( overlay_t **pp_cur = p_list->pp_head;
+         pp_cur < p_list->pp_tail;
+         ++pp_cur )
+    {
+        if( *pp_cur == NULL )
+        {
+            *pp_cur = p_new;
+            return pp_cur - p_list->pp_head;
+        }
+    }
+
+    /* Have to expand */
+    size_t i_size = p_list->pp_tail - p_list->pp_head;
+    size_t i_newsize = i_size * 2;
+    p_list->pp_head = realloc( p_list->pp_head,
+                               i_newsize * sizeof( overlay_t * ) );
+    if( p_list->pp_head == NULL )
+        return VLC_ENOMEM;
+
+    p_list->pp_tail = p_list->pp_head + i_newsize;
+    memset( p_list->pp_head + i_size, 0, i_size * sizeof( overlay_t * ) );
+    p_list->pp_head[i_size] = p_new;
+    return i_size;
+}
+
+int ListRemove( list_t *p_list, size_t i_idx )
+{
+    int ret;
+
+    if( ( i_idx >= (size_t)( p_list->pp_tail - p_list->pp_head ) ) ||
+        ( p_list->pp_head[i_idx] == NULL ) )
+    {
+        return VLC_EGENERIC;
+    }
+
+    ret = OverlayDestroy( p_list->pp_head[i_idx] );
+    free( p_list->pp_head[i_idx] );
+    p_list->pp_head[i_idx] = NULL;
+
+    return ret;
+}
+
+overlay_t *ListGet( list_t *p_list, size_t i_idx )
+{
+    if( ( i_idx >= (size_t)( p_list->pp_tail - p_list->pp_head ) ) ||
+        ( p_list->pp_head[i_idx] == NULL ) )
+    {
+        return NULL;
+    }
+    return p_list->pp_head[i_idx];
+}
+
+overlay_t *ListWalk( list_t *p_list )
+{
+    static overlay_t **pp_cur = NULL;
+
+    if( pp_cur == NULL )
+        pp_cur = p_list->pp_head;
+    else
+        pp_cur = pp_cur + 1;
+
+    for( ; pp_cur < p_list->pp_tail; ++pp_cur )
+    {
+        if( ( *pp_cur != NULL ) &&
+            ( (*pp_cur)->b_active == VLC_TRUE )&&
+            ( (*pp_cur)->format.i_chroma != VLC_FOURCC( '\0','\0','\0','\0') ) )
+        {
+            return *pp_cur;
+        }
+    }
+    pp_cur = NULL;
+    return NULL;
+}
index 4fb546af2a07bdb2e1f284559b2861d840b6858a..9fd757ad01d34f07d840d806ac59c3ad4f7f7d53 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 
 #include <vlc/vlc.h>
+#include <vlc_osd.h>
 
 #include "dynamicoverlay.h"