dynamicoverlay_commands.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:29k
源码类别:

midi

开发平台:

Unix_Linux

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