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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * screen.c: Screen capture module.
  3.  *****************************************************************************
  4.  * Copyright (C) 2004-2008 the VideoLAN team
  5.  * $Id: e70b168e28e73de7807a70069f1f642b720f6b1d $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *          Antoine Cellerier <dionoea at videolan dot org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include "screen.h"
  33. /*****************************************************************************
  34.  * Module descriptor
  35.  *****************************************************************************/
  36. #define CACHING_TEXT N_("Caching value in ms")
  37. #define CACHING_LONGTEXT N_( 
  38.     "Caching value for screen capture. "
  39.     "This value should be set in milliseconds." )
  40. #define FPS_TEXT N_("Frame rate")
  41. #define FPS_LONGTEXT N_( 
  42.     "Desired frame rate for the capture." )
  43. #ifdef WIN32
  44. #define FRAGS_TEXT N_("Capture fragment size")
  45. #define FRAGS_LONGTEXT N_( 
  46.     "Optimize the capture by fragmenting the screen in chunks " 
  47.     "of predefined height (16 might be a good value, and 0 means disabled)." )
  48. #endif
  49. #ifdef SCREEN_SUBSCREEN
  50. #define TOP_TEXT N_( "Subscreen top left corner" )
  51. #define TOP_LONGTEXT N_( 
  52.     "Top coordinate of the subscreen top left corner." )
  53. #define LEFT_TEXT N_( "Subscreen top left corner" )
  54. #define LEFT_LONGTEXT N_( 
  55.     "Left coordinate of the subscreen top left corner." )
  56. #define WIDTH_TEXT N_( "Subscreen width" )
  57. #define WIDTH_LONGTEXT N_( 
  58.     "Subscreen width" )
  59. #define HEIGHT_TEXT N_( "Subscreen height" )
  60. #define HEIGHT_LONGTEXT N_( 
  61.     "Subscreen height"  )
  62. #define FOLLOW_MOUSE_TEXT N_( "Follow the mouse" )
  63. #define FOLLOW_MOUSE_LONGTEXT N_( 
  64.     "Follow the mouse when capturing a subscreen." )
  65. #endif
  66. #ifdef SCREEN_MOUSE
  67. #define MOUSE_TEXT N_( "Mouse pointer image" )
  68. #define MOUSE_LONGTEXT N_( 
  69.     "If specifed, will use the image to draw the mouse pointer on the " 
  70.     "capture." )
  71. #endif
  72. static int  Open ( vlc_object_t * );
  73. static void Close( vlc_object_t * );
  74. #ifdef WIN32
  75. #   define SCREEN_FPS 1
  76. #else
  77. #   define SCREEN_FPS 5
  78. #endif
  79. vlc_module_begin ()
  80.     set_description( N_("Screen Input") )
  81.     set_shortname( N_("Screen" ))
  82.     set_category( CAT_INPUT )
  83.     set_subcategory( SUBCAT_INPUT_ACCESS )
  84.     add_integer( "screen-caching", DEFAULT_PTS_DELAY / 1000, NULL,
  85.         CACHING_TEXT, CACHING_LONGTEXT, true )
  86.     add_float( "screen-fps", SCREEN_FPS, 0, FPS_TEXT, FPS_LONGTEXT, true )
  87. #ifdef SCREEN_SUBSCREEN
  88.     add_integer( "screen-top", 0, NULL, TOP_TEXT, TOP_LONGTEXT, true )
  89.     add_integer( "screen-left", 0, NULL, LEFT_TEXT, LEFT_LONGTEXT, true )
  90.     add_integer( "screen-width", 0, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, true )
  91.     add_integer( "screen-height", 0, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, true )
  92.     add_bool( "screen-follow-mouse", false, NULL, FOLLOW_MOUSE_TEXT,
  93.               FOLLOW_MOUSE_LONGTEXT, true )
  94. #endif
  95. #ifdef SCREEN_MOUSE
  96.     add_file( "screen-mouse-image", "", NULL, MOUSE_TEXT, MOUSE_LONGTEXT,
  97.               true )
  98. #endif
  99. #ifdef WIN32
  100.     add_integer( "screen-fragment-size", 0, NULL, FRAGS_TEXT,
  101.         FRAGS_LONGTEXT, true )
  102. #endif
  103.     set_capability( "access_demux", 0 )
  104.     add_shortcut( "screen" )
  105.     set_callbacks( Open, Close )
  106. vlc_module_end ()
  107. /*****************************************************************************
  108.  * Local prototypes
  109.  *****************************************************************************/
  110. static int Control( demux_t *, int, va_list );
  111. static int Demux  ( demux_t * );
  112. /*****************************************************************************
  113.  * DemuxOpen:
  114.  *****************************************************************************/
  115. static int Open( vlc_object_t *p_this )
  116. {
  117.     demux_t     *p_demux = (demux_t*)p_this;
  118.     demux_sys_t *p_sys;
  119.     /* Fill p_demux field */
  120.     p_demux->pf_demux = Demux;
  121.     p_demux->pf_control = Control;
  122.     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
  123.     if( !p_sys )
  124.         return VLC_ENOMEM;
  125.     /* Update default_pts to a suitable value for screen access */
  126.     var_Create( p_demux, "screen-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  127.     p_sys->f_fps = var_CreateGetFloat( p_demux, "screen-fps" );
  128.     p_sys->i_incr = 1000000 / p_sys->f_fps;;
  129.     p_sys->i_next_date = 0;
  130. #ifdef SCREEN_SUBSCREEN
  131.     p_sys->i_top = var_CreateGetInteger( p_demux, "screen-top" );
  132.     p_sys->i_left = var_CreateGetInteger( p_demux, "screen-left" );
  133.     p_sys->i_width = var_CreateGetInteger( p_demux, "screen-width" );
  134.     p_sys->i_height = var_CreateGetInteger( p_demux, "screen-height" );
  135.     if( p_sys->i_width > 0 && p_sys->i_height > 0 )
  136.         msg_Dbg( p_demux, "capturing subscreen top: %d, left: %d, "
  137.                           "width: %d, height: %d",
  138.                           p_sys->i_top,
  139.                           p_sys->i_left,
  140.                           p_sys->i_width,
  141.                           p_sys->i_height );
  142. #endif
  143.     if( screen_InitCapture( p_demux ) != VLC_SUCCESS )
  144.     {
  145.         free( p_sys );
  146.         return VLC_EGENERIC;
  147.     }
  148.     msg_Dbg( p_demux, "screen width: %i, height: %i, depth: %i",
  149.              p_sys->fmt.video.i_width, p_sys->fmt.video.i_height,
  150.              p_sys->fmt.video.i_bits_per_pixel );
  151. #ifdef SCREEN_SUBSCREEN
  152.     if( p_sys->i_width > 0 && p_sys->i_height > 0 )
  153.     {
  154.         if( p_sys->i_left + p_sys->i_width > p_sys->fmt.video.i_width ||
  155.             p_sys->i_top + p_sys->i_height > p_sys->fmt.video.i_height )
  156.         {
  157.             msg_Err( p_demux, "subscreen region overflows the screen" );
  158.             free( p_sys );
  159.             return VLC_EGENERIC;
  160.         }
  161.         else
  162.         {
  163.             p_sys->i_screen_width = p_sys->fmt.video.i_width;
  164.             p_sys->i_screen_height = p_sys->fmt.video.i_height;
  165.             p_sys->fmt.video.i_visible_width =
  166.             p_sys->fmt.video.i_width = p_sys->i_width;
  167.             p_sys->fmt.video.i_visible_height =
  168.             p_sys->fmt.video.i_height = p_sys->i_height;
  169.             p_sys->b_follow_mouse = var_CreateGetInteger( p_demux,
  170.                                                 "screen-follow-mouse" );
  171.             if( p_sys->b_follow_mouse )
  172.                 msg_Dbg( p_demux, "mouse following enabled" );
  173.         }
  174.     }
  175. #endif
  176. #ifdef SCREEN_MOUSE
  177.     char * psz_mouse = var_CreateGetNonEmptyString( p_demux,
  178.                                                     "screen-mouse-image" );
  179.     if( psz_mouse )
  180.     {
  181.         image_handler_t *p_image;
  182.         video_format_t fmt_in, fmt_out;
  183.         msg_Dbg( p_demux, "Using %s for the mouse pointer image", psz_mouse );
  184.         memset( &fmt_in, 0, sizeof( fmt_in ) );
  185.         memset( &fmt_out, 0, sizeof( fmt_out ) );
  186.         fmt_out.i_chroma = VLC_FOURCC('R','G','B','A');
  187.         p_image = image_HandlerCreate( p_demux );
  188.         if( p_image )
  189.         {
  190.             p_sys->p_mouse =
  191.                 image_ReadUrl( p_image, psz_mouse, &fmt_in, &fmt_out );
  192.             image_HandlerDelete( p_image );
  193.         }
  194.         if( !p_sys->p_mouse )
  195.             msg_Err( p_demux, "Failed to open mouse pointer image (%s)",
  196.                      psz_mouse );
  197.         free( psz_mouse );
  198.     }
  199. #endif
  200.     p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
  201.     return VLC_SUCCESS;
  202. }
  203. /*****************************************************************************
  204.  * Close:
  205.  *****************************************************************************/
  206. static void Close( vlc_object_t *p_this )
  207. {
  208.     demux_t     *p_demux = (demux_t*)p_this;
  209.     demux_sys_t *p_sys = p_demux->p_sys;
  210.     screen_CloseCapture( p_demux );
  211. #ifdef SCREEN_MOUSE
  212.     if( p_sys->p_mouse )
  213.         picture_Release( p_sys->p_mouse );
  214. #endif
  215.     free( p_sys );
  216. }
  217. /*****************************************************************************
  218.  * Demux:
  219.  *****************************************************************************/
  220. static int Demux( demux_t *p_demux )
  221. {
  222.     demux_sys_t *p_sys = p_demux->p_sys;
  223.     block_t *p_block;
  224.     if( !p_sys->i_next_date ) p_sys->i_next_date = mdate();
  225.     /* Frame skipping if necessary */
  226.     while( mdate() >= p_sys->i_next_date + p_sys->i_incr )
  227.         p_sys->i_next_date += p_sys->i_incr;
  228.     mwait( p_sys->i_next_date );
  229.     p_block = screen_Capture( p_demux );
  230.     if( !p_block )
  231.     {
  232.         p_sys->i_next_date += p_sys->i_incr;
  233.         return 1;
  234.     }
  235.     p_block->i_dts = p_block->i_pts = p_sys->i_next_date;
  236.     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
  237.     es_out_Send( p_demux->out, p_sys->es, p_block );
  238.     p_sys->i_next_date += p_sys->i_incr;
  239.     return 1;
  240. }
  241. /*****************************************************************************
  242.  * Control:
  243.  *****************************************************************************/
  244. static int Control( demux_t *p_demux, int i_query, va_list args )
  245. {
  246.     bool *pb;
  247.     int64_t *pi64;
  248.     switch( i_query )
  249.     {
  250.         /* Special for access_demux */
  251.         case DEMUX_CAN_PAUSE:
  252.         case DEMUX_CAN_SEEK:
  253.         case DEMUX_CAN_CONTROL_PACE:
  254.             /* TODO */
  255.             pb = (bool*)va_arg( args, bool * );
  256.             *pb = false;
  257.             return VLC_SUCCESS;
  258.         case DEMUX_GET_PTS_DELAY:
  259.             pi64 = (int64_t*)va_arg( args, int64_t * );
  260.             *pi64 = (int64_t)var_GetInteger( p_demux, "screen-caching" ) *1000;
  261.             return VLC_SUCCESS;
  262.         case DEMUX_GET_TIME:
  263.             pi64 = (int64_t*)va_arg( args, int64_t * );
  264.             *pi64 = mdate();
  265.             return VLC_SUCCESS;
  266.         /* TODO implement others */
  267.         default:
  268.             return VLC_EGENERIC;
  269.     }
  270. }
  271. #ifdef SCREEN_SUBSCREEN
  272. void FollowMouse( demux_sys_t *p_sys, int i_x, int i_y )
  273. {
  274.     i_x -= p_sys->i_width/2;
  275.     if( i_x < 0 ) i_x = 0;
  276.     p_sys->i_left = __MIN( (unsigned int)i_x,
  277.     p_sys->i_screen_width - p_sys->i_width );
  278.     i_y -= p_sys->i_height/2;
  279.     if( i_y < 0 ) i_y = 0;
  280.     p_sys->i_top = __MIN( (unsigned int)i_y,
  281.     p_sys->i_screen_height - p_sys->i_height );
  282. }
  283. #endif
  284. #ifdef SCREEN_MOUSE
  285. void RenderCursor( demux_t *p_demux, int i_x, int i_y,
  286.                    uint8_t *p_dst )
  287. {
  288.     demux_sys_t *p_sys = p_demux->p_sys;
  289.     if( !p_sys->dst.i_planes )
  290.         vout_InitPicture( p_demux, &p_sys->dst,
  291.                           p_sys->fmt.video.i_chroma,
  292.                           p_sys->fmt.video.i_width,
  293.                           p_sys->fmt.video.i_height,
  294.                           p_sys->fmt.video.i_aspect );
  295.     if( !p_sys->p_blend )
  296.     {
  297.         p_sys->p_blend = vlc_object_create( p_demux, sizeof(filter_t) );
  298.         if( p_sys->p_blend )
  299.         {
  300.             es_format_Init( &p_sys->p_blend->fmt_in, VIDEO_ES,
  301.                             VLC_FOURCC('R','G','B','A') );
  302.             p_sys->p_blend->fmt_in.video = p_sys->p_mouse->format;
  303.             p_sys->p_blend->fmt_out = p_sys->fmt;
  304.             p_sys->p_blend->p_module =
  305.                 module_need( p_sys->p_blend, "video blending", NULL, false );
  306.             if( !p_sys->p_blend->p_module )
  307.             {
  308.                 msg_Err( p_demux, "Could not load video blending module" );
  309.                 vlc_object_detach( p_sys->p_blend );
  310.                 vlc_object_release( p_sys->p_blend );
  311.                 p_sys->p_blend = NULL;
  312.             }
  313.         }
  314.     }
  315.     if( p_sys->p_blend )
  316.     {
  317.         p_sys->dst.p->p_pixels = p_dst;
  318.         p_sys->p_blend->pf_video_blend( p_sys->p_blend,
  319.                                         &p_sys->dst,
  320.                                         p_sys->p_mouse,
  321. #ifdef SCREEN_SUBSCREEN
  322.                                         i_x-p_sys->i_left,
  323. #else
  324.                                         i_x,
  325. #endif
  326. #ifdef SCREEN_SUBSCREEN
  327.                                         i_y-p_sys->i_top,
  328. #else
  329.                                         i_y,
  330. #endif
  331.                                         255 );
  332.     }
  333.     else
  334.     {
  335.         picture_Release( p_sys->p_mouse );
  336.         p_sys->p_mouse = NULL;
  337.     }
  338. }
  339. #endif