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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * marq.c : marquee display video plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2008 the VideoLAN team
  5.  * $Id: b98b824c9c3d3d584721675cd5d8db019a0f9b4a $
  6.  *
  7.  * Authors: Mark Moriarty
  8.  *          Sigmund Augdal Helberg <dnumgis@videolan.org>
  9.  *          Antoine Cellerier <dionoea . videolan  org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #ifdef HAVE_CONFIG_H
  29. # include "config.h"
  30. #endif
  31. #include <vlc_common.h>
  32. #include <vlc_plugin.h>
  33. #include <vlc_vout.h>
  34. #include "vlc_filter.h"
  35. #include "vlc_block.h"
  36. #include "vlc_osd.h"
  37. #include "vlc_strings.h"
  38. /*****************************************************************************
  39.  * Local prototypes
  40.  *****************************************************************************/
  41. static int  CreateFilter ( vlc_object_t * );
  42. static void DestroyFilter( vlc_object_t * );
  43. static subpicture_t *Filter( filter_t *, mtime_t );
  44. static int MarqueeCallback( vlc_object_t *p_this, char const *psz_var,
  45.                             vlc_value_t oldval, vlc_value_t newval,
  46.                             void *p_data );
  47. static const int pi_color_values[] = {
  48.                0xf0000000, 0x00000000, 0x00808080, 0x00C0C0C0,
  49.                0x00FFFFFF, 0x00800000, 0x00FF0000, 0x00FF00FF, 0x00FFFF00,
  50.                0x00808000, 0x00008000, 0x00008080, 0x0000FF00, 0x00800080,
  51.                0x00000080, 0x000000FF, 0x0000FFFF};
  52. static const char *const ppsz_color_descriptions[] = {
  53.                N_("Default"), N_("Black"), N_("Gray"),
  54.                N_("Silver"), N_("White"), N_("Maroon"), N_("Red"),
  55.                N_("Fuchsia"), N_("Yellow"), N_("Olive"), N_("Green"),
  56.                N_("Teal"), N_("Lime"), N_("Purple"), N_("Navy"), N_("Blue"),
  57.                N_("Aqua") };
  58. /*****************************************************************************
  59.  * filter_sys_t: marquee filter descriptor
  60.  *****************************************************************************/
  61. struct filter_sys_t
  62. {
  63.     vlc_mutex_t lock;
  64.     int i_xoff, i_yoff;  /* offsets for the display string in the video window */
  65.     int i_pos; /* permit relative positioning (top, bottom, left, right, center) */
  66.     int i_timeout;
  67.     char *psz_marquee;    /* marquee string */
  68.     text_style_t *p_style; /* font control */
  69.     mtime_t last_time;
  70.     mtime_t i_refresh;
  71.     bool b_need_update;
  72. };
  73. #define MSG_TEXT N_("Text")
  74. #define MSG_LONGTEXT N_( 
  75.     "Marquee text to display. " 
  76.     "(Available format strings: " 
  77.     "Time related: %Y = year, %m = month, %d = day, %H = hour, " 
  78.     "%M = minute, %S = second, ... " 
  79.     "Meta data related: $a = artist, $b = album, $c = copyright, " 
  80.     "$d = description, $e = encoded by, $g = genre, " 
  81.     "$l = language, $n = track num, $p = now playing, " 
  82.     "$r = rating, $s = subtitles language, $t = title, "
  83.     "$u = url, $A = date, " 
  84.     "$B = audio bitrate (in kb/s), $C = chapter," 
  85.     "$D = duration, $F = full name with path, $I = title, "
  86.     "$L = time left, " 
  87.     "$N = name, $O = audio language, $P = position (in %), $R = rate, " 
  88.     "$S = audio sample rate (in kHz), " 
  89.     "$T = time, $U = publisher, $V = volume, $_ = new line) ")
  90. #define POSX_TEXT N_("X offset")
  91. #define POSX_LONGTEXT N_("X offset, from the left screen edge." )
  92. #define POSY_TEXT N_("Y offset")
  93. #define POSY_LONGTEXT N_("Y offset, down from the top." )
  94. #define TIMEOUT_TEXT N_("Timeout")
  95. #define TIMEOUT_LONGTEXT N_("Number of milliseconds the marquee must remain " 
  96.                             "displayed. Default value is " 
  97.                             "0 (remains forever).")
  98. #define REFRESH_TEXT N_("Refresh period in ms")
  99. #define REFRESH_LONGTEXT N_("Number of milliseconds between string updates. " 
  100.                             "This is mainly usefull when using meta data " 
  101.                             "or time format string sequences.")
  102. #define OPACITY_TEXT N_("Opacity")
  103. #define OPACITY_LONGTEXT N_("Opacity (inverse of transparency) of " 
  104.     "overlayed text. 0 = transparent, 255 = totally opaque. " )
  105. #define SIZE_TEXT N_("Font size, pixels")
  106. #define SIZE_LONGTEXT N_("Font size, in pixels. Default is -1 (use default " 
  107.     "font size)." )
  108. #define COLOR_TEXT N_("Color")
  109. #define COLOR_LONGTEXT N_("Color of the text that will be rendered on "
  110.     "the video. This must be an hexadecimal (like HTML colors). The first two "
  111.     "chars are for red, then green, then blue. #000000 = black, #FF0000 = red,"
  112.     " #00FF00 = green, #FFFF00 = yellow (red + green), #FFFFFF = white" )
  113. #define POS_TEXT N_("Marquee position")
  114. #define POS_LONGTEXT N_( 
  115.   "You can enforce the marquee position on the video " 
  116.   "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " 
  117.   "also use combinations of these values, eg 6 = top-right).")
  118. static const int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
  119. static const char *const ppsz_pos_descriptions[] =
  120.      { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
  121.      N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
  122. #define CFG_PREFIX "marq-"
  123. /*****************************************************************************
  124.  * Module descriptor
  125.  *****************************************************************************/
  126. vlc_module_begin ()
  127.     set_capability( "sub filter", 0 )
  128.     set_shortname( N_("Marquee" ))
  129.     set_callbacks( CreateFilter, DestroyFilter )
  130.     set_category( CAT_VIDEO )
  131.     set_subcategory( SUBCAT_VIDEO_SUBPIC )
  132.     add_string( CFG_PREFIX "marquee", "VLC", NULL, MSG_TEXT, MSG_LONGTEXT,
  133.                 false )
  134.     set_section( N_("Position"), NULL )
  135.     add_integer( CFG_PREFIX "x", 0, NULL, POSX_TEXT, POSX_LONGTEXT, true )
  136.     add_integer( CFG_PREFIX "y", 0, NULL, POSY_TEXT, POSY_LONGTEXT, true )
  137.     add_integer( CFG_PREFIX "position", -1, NULL, POS_TEXT, POS_LONGTEXT, false )
  138.         change_integer_list( pi_pos_values, ppsz_pos_descriptions, NULL )
  139.     set_section( N_("Font"), NULL )
  140.     /* 5 sets the default to top [1] left [4] */
  141.     add_integer_with_range( CFG_PREFIX "opacity", 255, 0, 255, NULL,
  142.         OPACITY_TEXT, OPACITY_LONGTEXT, false )
  143.     add_integer( CFG_PREFIX "color", 0xFFFFFF, NULL, COLOR_TEXT, COLOR_LONGTEXT,
  144.                  false )
  145.         change_integer_list( pi_color_values, ppsz_color_descriptions, NULL )
  146.     add_integer( CFG_PREFIX "size", -1, NULL, SIZE_TEXT, SIZE_LONGTEXT,
  147.                  false )
  148.     set_section( N_("Misc"), NULL )
  149.     add_integer( CFG_PREFIX "timeout", 0, NULL, TIMEOUT_TEXT, TIMEOUT_LONGTEXT,
  150.                  false )
  151.     add_integer( CFG_PREFIX "refresh", 1000, NULL, REFRESH_TEXT,
  152.                  REFRESH_LONGTEXT, false )
  153.     set_description( N_("Marquee display") )
  154.     add_shortcut( "time" )
  155.     add_obsolete_string( "time-format" )
  156.     add_obsolete_string( "time-x" )
  157.     add_obsolete_string( "time-y" )
  158.     add_obsolete_string( "time-position" )
  159.     add_obsolete_string( "time-opacity" )
  160.     add_obsolete_string( "time-color" )
  161.     add_obsolete_string( "time-size" )
  162. vlc_module_end ()
  163. static const char *const ppsz_filter_options[] = {
  164.     "marquee", "x", "y", "position", "color", "size", "timeout", "refresh",
  165.     NULL
  166. };
  167. /*****************************************************************************
  168.  * CreateFilter: allocates marquee video filter
  169.  *****************************************************************************/
  170. static int CreateFilter( vlc_object_t *p_this )
  171. {
  172.     filter_t *p_filter = (filter_t *)p_this;
  173.     filter_sys_t *p_sys;
  174.     /* Allocate structure */
  175.     p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
  176.     if( p_sys == NULL )
  177.         return VLC_ENOMEM;
  178.     vlc_mutex_init( &p_sys->lock );
  179.     p_sys->p_style = malloc( sizeof( text_style_t ) );
  180.     memcpy( p_sys->p_style, &default_text_style, sizeof( text_style_t ) );
  181.     config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
  182.                        p_filter->p_cfg );
  183. #define CREATE_VAR( stor, type, var ) 
  184.     p_sys->stor = var_CreateGet##type##Command( p_filter, var ); 
  185.     var_AddCallback( p_filter, var, MarqueeCallback, p_sys );
  186.     p_sys->b_need_update = true;
  187.     CREATE_VAR( i_xoff, Integer, "marq-x" );
  188.     CREATE_VAR( i_yoff, Integer, "marq-y" );
  189.     CREATE_VAR( i_timeout,Integer, "marq-timeout" );
  190.     p_sys->i_refresh = 1000 * var_CreateGetIntegerCommand( p_filter,
  191.                                                            "marq-refresh" );
  192.     var_AddCallback( p_filter, "marq-refresh", MarqueeCallback, p_sys );
  193.     CREATE_VAR( i_pos, Integer, "marq-position" );
  194.     CREATE_VAR( psz_marquee, String, "marq-marquee" );
  195.     p_sys->p_style->i_font_alpha = 255 - var_CreateGetIntegerCommand( p_filter,
  196.                                                             "marq-opacity" );
  197.     var_AddCallback( p_filter, "marq-opacity", MarqueeCallback, p_sys );
  198.     CREATE_VAR( p_style->i_font_color, Integer, "marq-color" );
  199.     CREATE_VAR( p_style->i_font_size, Integer, "marq-size" );
  200.     /* Misc init */
  201.     p_filter->pf_sub_filter = Filter;
  202.     p_sys->last_time = 0;
  203.     return VLC_SUCCESS;
  204. }
  205. /*****************************************************************************
  206.  * DestroyFilter: destroy marquee video filter
  207.  *****************************************************************************/
  208. static void DestroyFilter( vlc_object_t *p_this )
  209. {
  210.     filter_t *p_filter = (filter_t *)p_this;
  211.     filter_sys_t *p_sys = p_filter->p_sys;
  212.     /* Delete the marquee variables */
  213. #define DEL_VAR(var) 
  214.     var_DelCallback( p_filter, var, MarqueeCallback, p_sys ); 
  215.     var_Destroy( p_filter, var );
  216.     DEL_VAR( "marq-x" );
  217.     DEL_VAR( "marq-y" );
  218.     DEL_VAR( "marq-timeout" );
  219.     DEL_VAR( "marq-refresh" );
  220.     DEL_VAR( "marq-position" );
  221.     DEL_VAR( "marq-marquee" );
  222.     DEL_VAR( "marq-opacity" );
  223.     DEL_VAR( "marq-color" );
  224.     DEL_VAR( "marq-size" );
  225.     vlc_mutex_destroy( &p_sys->lock );
  226.     free( p_sys->p_style );
  227.     free( p_sys->psz_marquee );
  228.     free( p_sys );
  229. }
  230. /****************************************************************************
  231.  * Filter: the whole thing
  232.  ****************************************************************************
  233.  * This function outputs subpictures at regular time intervals.
  234.  ****************************************************************************/
  235. static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
  236. {
  237.     filter_sys_t *p_sys = p_filter->p_sys;
  238.     subpicture_t *p_spu = NULL;
  239.     video_format_t fmt;
  240.     vlc_mutex_lock( &p_sys->lock );
  241.     if( p_sys->last_time + p_sys->i_refresh > date )
  242.         goto out;
  243.     if( p_sys->b_need_update == false )
  244.         goto out;
  245.     p_spu = filter_NewSubpicture( p_filter );
  246.     if( !p_spu )
  247.         goto out;
  248.     memset( &fmt, 0, sizeof(video_format_t) );
  249.     fmt.i_chroma = VLC_FOURCC('T','E','X','T');
  250.     fmt.i_aspect = 0;
  251.     fmt.i_width = fmt.i_height = 0;
  252.     fmt.i_x_offset = 0;
  253.     fmt.i_y_offset = 0;
  254.     p_spu->p_region = subpicture_region_New( &fmt );
  255.     if( !p_spu->p_region )
  256.     {
  257.         p_filter->pf_sub_buffer_del( p_filter, p_spu );
  258.         p_spu = NULL;
  259.         goto out;
  260.     }
  261.     p_sys->last_time = date;
  262.     if( !strchr( p_sys->psz_marquee, '%' )
  263.      && !strchr( p_sys->psz_marquee, '$' ) )
  264.         p_sys->b_need_update = false;
  265.     p_spu->p_region->psz_text = str_format( p_filter, p_sys->psz_marquee );
  266.     p_spu->i_start = date;
  267.     p_spu->i_stop  = p_sys->i_timeout == 0 ? 0 : date + p_sys->i_timeout * 1000;
  268.     p_spu->b_ephemer = true;
  269.     /*  where to locate the string: */
  270.     if( p_sys->i_pos < 0 )
  271.     {   /*  set to an absolute xy */
  272.         p_spu->p_region->i_align = OSD_ALIGN_LEFT | OSD_ALIGN_TOP;
  273.         p_spu->b_absolute = true;
  274.     }
  275.     else
  276.     {   /* set to one of the 9 relative locations */
  277.         p_spu->p_region->i_align = p_sys->i_pos;
  278.         p_spu->b_absolute = false;
  279.     }
  280.     p_spu->p_region->i_x = p_sys->i_xoff;
  281.     p_spu->p_region->i_y = p_sys->i_yoff;
  282.     p_spu->p_region->p_style = p_sys->p_style;
  283. out:
  284.     vlc_mutex_unlock( &p_sys->lock );
  285.     return p_spu;
  286. }
  287. /**********************************************************************
  288.  * Callback to update params on the fly
  289.  **********************************************************************/
  290. static int MarqueeCallback( vlc_object_t *p_this, char const *psz_var,
  291.                             vlc_value_t oldval, vlc_value_t newval,
  292.                             void *p_data )
  293. {
  294.     filter_sys_t *p_sys = (filter_sys_t *) p_data;
  295.     VLC_UNUSED(oldval);
  296.     VLC_UNUSED(p_this);
  297.     vlc_mutex_lock( &p_sys->lock );
  298.     if( !strncmp( psz_var, "marq-marquee", 7 ) )
  299.     {
  300.         free( p_sys->psz_marquee );
  301.         p_sys->psz_marquee = strdup( newval.psz_string );
  302.     }
  303.     else if ( !strncmp( psz_var, "marq-x", 6 ) )
  304.     {
  305.         p_sys->i_xoff = newval.i_int;
  306.     }
  307.     else if ( !strncmp( psz_var, "marq-y", 6 ) )
  308.     {
  309.         p_sys->i_yoff = newval.i_int;
  310.     }
  311.     else if ( !strncmp( psz_var, "marq-color", 8 ) )  /* "marq-col" */
  312.     {
  313.         p_sys->p_style->i_font_color = newval.i_int;
  314.     }
  315.     else if ( !strncmp( psz_var, "marq-opacity", 8 ) ) /* "marq-opa" */
  316.     {
  317.         p_sys->p_style->i_font_alpha = 255 - newval.i_int;
  318.     }
  319.     else if ( !strncmp( psz_var, "marq-size", 6 ) )
  320.     {
  321.         p_sys->p_style->i_font_size = newval.i_int;
  322.     }
  323.     else if ( !strncmp( psz_var, "marq-timeout", 12 ) )
  324.     {
  325.         p_sys->i_timeout = newval.i_int;
  326.     }
  327.     else if ( !strncmp( psz_var, "marq-refresh", 12 ) )
  328.     {
  329.         p_sys->i_refresh = newval.i_int * 1000;
  330.     }
  331.     else if ( !strncmp( psz_var, "marq-position", 8 ) )
  332.     /* willing to accept a match against marq-pos */
  333.     {
  334.         p_sys->i_pos = newval.i_int;
  335.         p_sys->i_xoff = -1;       /* force to relative positioning */
  336.     }
  337.     p_sys->b_need_update = true;
  338.     vlc_mutex_unlock( &p_sys->lock );
  339.     return VLC_SUCCESS;
  340. }