X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fscreen%2Fscreen.c;h=73a279e1d962cf89ddac49aaa7c6e021de463dc6;hb=1a459c1ccb0d617580ec97bae992f01a799a5e9b;hp=e86eac52d845ca4ec7e8fbb4a5f13bf75be3ba77;hpb=df61d33b06e2b3cbbe746b2f5a9bea5b370c24ff;p=vlc diff --git a/modules/access/screen/screen.c b/modules/access/screen/screen.c index e86eac52d8..73a279e1d9 100644 --- a/modules/access/screen/screen.c +++ b/modules/access/screen/screen.c @@ -1,10 +1,11 @@ /***************************************************************************** * screen.c: Screen capture module. ***************************************************************************** - * Copyright (C) 2004 the VideoLAN team + * Copyright (C) 2004-2008 the VideoLAN team * $Id$ * * Authors: Gildas Bazin + * Antoine Cellerier * * 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 @@ -17,8 +18,8 @@ * 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. + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -29,16 +30,14 @@ # include "config.h" #endif -#include +#include +#include +#include /* module_need for "video blending" */ #include "screen.h" /***************************************************************************** * Module descriptor *****************************************************************************/ -#define CACHING_TEXT N_("Caching value in ms") -#define CACHING_LONGTEXT N_( \ - "Caching value for screen capture. "\ - "This value should be set in milliseconds." ) #define FPS_TEXT N_("Frame rate") #define FPS_LONGTEXT N_( \ "Desired frame rate for the capture." ) @@ -50,6 +49,31 @@ "of predefined height (16 might be a good value, and 0 means disabled)." ) #endif +#ifdef SCREEN_SUBSCREEN +#define TOP_TEXT N_( "Subscreen top left corner" ) +#define TOP_LONGTEXT N_( \ + "Top coordinate of the subscreen top left corner." ) + +#define LEFT_TEXT N_( "Subscreen top left corner" ) +#define LEFT_LONGTEXT N_( \ + "Left coordinate of the subscreen top left corner." ) + +#define WIDTH_TEXT N_( "Subscreen width" ) + +#define HEIGHT_TEXT N_( "Subscreen height" ) + +#define FOLLOW_MOUSE_TEXT N_( "Follow the mouse" ) +#define FOLLOW_MOUSE_LONGTEXT N_( \ + "Follow the mouse when capturing a subscreen." ) +#endif + +#ifdef SCREEN_MOUSE +#define MOUSE_TEXT N_( "Mouse pointer image" ) +#define MOUSE_LONGTEXT N_( \ + "If specified, will use the image to draw the mouse pointer on the " \ + "capture." ) +#endif + static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); @@ -59,25 +83,36 @@ static void Close( vlc_object_t * ); # define SCREEN_FPS 5 #endif -vlc_module_begin(); - set_description( _("Screen Input") ); - set_shortname( _("Screen" )); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACCESS ); +vlc_module_begin () + set_description( N_("Screen Input") ) + set_shortname( N_("Screen" )) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_ACCESS ) + + add_float( "screen-fps", SCREEN_FPS, FPS_TEXT, FPS_LONGTEXT, false ) + +#ifdef SCREEN_SUBSCREEN + add_integer( "screen-top", 0, TOP_TEXT, TOP_LONGTEXT, true ) + add_integer( "screen-left", 0, LEFT_TEXT, LEFT_LONGTEXT, true ) + add_integer( "screen-width", 0, WIDTH_TEXT, WIDTH_TEXT, true ) + add_integer( "screen-height", 0, HEIGHT_TEXT, HEIGHT_TEXT, true ) + + add_bool( "screen-follow-mouse", false, FOLLOW_MOUSE_TEXT, + FOLLOW_MOUSE_LONGTEXT, false ) +#endif - add_integer( "screen-caching", DEFAULT_PTS_DELAY / 1000, NULL, - CACHING_TEXT, CACHING_LONGTEXT, true ); - add_float( "screen-fps", SCREEN_FPS, 0, FPS_TEXT, FPS_LONGTEXT, true ); +#ifdef SCREEN_MOUSE + add_loadfile( "screen-mouse-image", "", MOUSE_TEXT, MOUSE_LONGTEXT, true ) +#endif #ifdef WIN32 - add_integer( "screen-fragment-size", 0, NULL, FRAGS_TEXT, - FRAGS_LONGTEXT, true ); + add_integer( "screen-fragment-size", 0, FRAGS_TEXT, FRAGS_LONGTEXT, true ) #endif - set_capability( "access_demux", 0 ); - add_shortcut( "screen" ); - set_callbacks( Open, Close ); -vlc_module_end(); + set_capability( "access_demux", 0 ) + add_shortcut( "screen" ) + set_callbacks( Open, Close ) +vlc_module_end () /***************************************************************************** * Local prototypes @@ -92,23 +127,32 @@ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; - vlc_value_t val; /* Fill p_demux field */ p_demux->pf_demux = Demux; p_demux->pf_control = Control; - p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); - memset( p_sys, 0, sizeof( demux_sys_t ) ); - - /* Update default_pts to a suitable value for screen access */ - var_Create( p_demux, "screen-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); + p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; - var_Create( p_demux, "screen-fps", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT ); - var_Get( p_demux, "screen-fps", &val ); - p_sys->f_fps = val.f_float; - p_sys->i_incr = 1000000 / val.f_float; + p_sys->f_fps = var_CreateGetFloat( p_demux, "screen-fps" ); + p_sys->i_incr = 1000000 / p_sys->f_fps;; p_sys->i_next_date = 0; +#ifdef SCREEN_SUBSCREEN + p_sys->i_top = var_CreateGetInteger( p_demux, "screen-top" ); + p_sys->i_left = var_CreateGetInteger( p_demux, "screen-left" ); + p_sys->i_width = var_CreateGetInteger( p_demux, "screen-width" ); + p_sys->i_height = var_CreateGetInteger( p_demux, "screen-height" ); + if( p_sys->i_width > 0 && p_sys->i_height > 0 ) + msg_Dbg( p_demux, "capturing subscreen top: %d, left: %d, " + "width: %d, height: %d", + p_sys->i_top, + p_sys->i_left, + p_sys->i_width, + p_sys->i_height ); +#endif + if( screen_InitCapture( p_demux ) != VLC_SUCCESS ) { free( p_sys ); @@ -119,6 +163,57 @@ static int Open( vlc_object_t *p_this ) p_sys->fmt.video.i_width, p_sys->fmt.video.i_height, p_sys->fmt.video.i_bits_per_pixel ); +#ifdef SCREEN_SUBSCREEN + if( p_sys->i_width > 0 && p_sys->i_height > 0 ) + { + if( p_sys->i_left + p_sys->i_width > p_sys->fmt.video.i_width || + p_sys->i_top + p_sys->i_height > p_sys->fmt.video.i_height ) + { + msg_Err( p_demux, "subscreen region overflows the screen" ); + free( p_sys ); + return VLC_EGENERIC; + } + else + { + p_sys->i_screen_width = p_sys->fmt.video.i_width; + p_sys->i_screen_height = p_sys->fmt.video.i_height; + p_sys->fmt.video.i_visible_width = + p_sys->fmt.video.i_width = p_sys->i_width; + p_sys->fmt.video.i_visible_height = + p_sys->fmt.video.i_height = p_sys->i_height; + p_sys->b_follow_mouse = var_CreateGetInteger( p_demux, + "screen-follow-mouse" ); + if( p_sys->b_follow_mouse ) + msg_Dbg( p_demux, "mouse following enabled" ); + } + } +#endif + +#ifdef SCREEN_MOUSE + char * psz_mouse = var_CreateGetNonEmptyString( p_demux, + "screen-mouse-image" ); + if( psz_mouse ) + { + image_handler_t *p_image; + video_format_t fmt_in, fmt_out; + msg_Dbg( p_demux, "Using %s for the mouse pointer image", psz_mouse ); + memset( &fmt_in, 0, sizeof( fmt_in ) ); + memset( &fmt_out, 0, sizeof( fmt_out ) ); + fmt_out.i_chroma = VLC_CODEC_RGBA; + p_image = image_HandlerCreate( p_demux ); + if( p_image ) + { + p_sys->p_mouse = + image_ReadUrl( p_image, psz_mouse, &fmt_in, &fmt_out ); + image_HandlerDelete( p_image ); + } + if( !p_sys->p_mouse ) + msg_Err( p_demux, "Failed to open mouse pointer image (%s)", + psz_mouse ); + free( psz_mouse ); + } +#endif + p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt ); return VLC_SUCCESS; @@ -133,6 +228,10 @@ static void Close( vlc_object_t *p_this ) demux_sys_t *p_sys = p_demux->p_sys; screen_CloseCapture( p_demux ); +#ifdef SCREEN_MOUSE + if( p_sys->p_mouse ) + picture_Release( p_sys->p_mouse ); +#endif free( p_sys ); } @@ -189,7 +288,13 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) case DEMUX_GET_PTS_DELAY: pi64 = (int64_t*)va_arg( args, int64_t * ); - *pi64 = (int64_t)var_GetInteger( p_demux, "screen-caching" ) *1000; + *pi64 = INT64_C(1000) + * var_InheritInteger( p_demux, "live-caching" ); + return VLC_SUCCESS; + + case DEMUX_GET_TIME: + pi64 = (int64_t*)va_arg( args, int64_t * ); + *pi64 = mdate(); return VLC_SUCCESS; /* TODO implement others */ @@ -197,3 +302,75 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) return VLC_EGENERIC; } } + +#ifdef SCREEN_SUBSCREEN +void FollowMouse( demux_sys_t *p_sys, int i_x, int i_y ) +{ + i_x -= p_sys->i_width/2; + if( i_x < 0 ) i_x = 0; + p_sys->i_left = __MIN( (unsigned int)i_x, + p_sys->i_screen_width - p_sys->i_width ); + + i_y -= p_sys->i_height/2; + if( i_y < 0 ) i_y = 0; + p_sys->i_top = __MIN( (unsigned int)i_y, + p_sys->i_screen_height - p_sys->i_height ); +} +#endif + +#ifdef SCREEN_MOUSE +void RenderCursor( demux_t *p_demux, int i_x, int i_y, + uint8_t *p_dst ) +{ + demux_sys_t *p_sys = p_demux->p_sys; + if( !p_sys->dst.i_planes ) + picture_Setup( &p_sys->dst, + p_sys->fmt.video.i_chroma, + p_sys->fmt.video.i_width, + p_sys->fmt.video.i_height, + p_sys->fmt.video.i_sar_num, + p_sys->fmt.video.i_sar_den ); + if( !p_sys->p_blend ) + { + p_sys->p_blend = vlc_object_create( p_demux, sizeof(filter_t) ); + if( p_sys->p_blend ) + { + es_format_Init( &p_sys->p_blend->fmt_in, VIDEO_ES, + VLC_CODEC_RGBA ); + p_sys->p_blend->fmt_in.video = p_sys->p_mouse->format; + p_sys->p_blend->fmt_out = p_sys->fmt; + p_sys->p_blend->p_module = + module_need( p_sys->p_blend, "video blending", NULL, false ); + if( !p_sys->p_blend->p_module ) + { + msg_Err( p_demux, "Could not load video blending module" ); + vlc_object_release( p_sys->p_blend ); + p_sys->p_blend = NULL; + } + } + } + if( p_sys->p_blend ) + { + p_sys->dst.p->p_pixels = p_dst; + p_sys->p_blend->pf_video_blend( p_sys->p_blend, + &p_sys->dst, + p_sys->p_mouse, +#ifdef SCREEN_SUBSCREEN + i_x-p_sys->i_left, +#else + i_x, +#endif +#ifdef SCREEN_SUBSCREEN + i_y-p_sys->i_top, +#else + i_y, +#endif + 255 ); + } + else + { + picture_Release( p_sys->p_mouse ); + p_sys->p_mouse = NULL; + } +} +#endif