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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * motion_blur.c : motion blur filter for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000, 2001, 2002, 2003 the VideoLAN team
  5.  * $Id: e975efcfb581cc97b13c72cddc872b27a72cbe1c $
  6.  *
  7.  * Authors: Sigmund Augdal Helberg <dnumgis@videolan.org>
  8.  *          Antoine Cellerier <dionoea &t videolan d.t 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 <vlc_sout.h>
  33. #include <vlc_vout.h>
  34. #include <vlc_filter.h>
  35. #include "filter_picture.h"
  36. /*****************************************************************************
  37.  * Local protypes
  38.  *****************************************************************************/
  39. static int  Create       ( vlc_object_t * );
  40. static void Destroy      ( vlc_object_t * );
  41. static picture_t *Filter ( filter_t *, picture_t * );
  42. static void RenderBlur   ( filter_sys_t *, picture_t *, picture_t * );
  43. static void Copy         ( filter_t *, picture_t * );
  44. static int MotionBlurCallback( vlc_object_t *, char const *,
  45.                                vlc_value_t, vlc_value_t, void * );
  46. /*****************************************************************************
  47.  * Module descriptor
  48.  *****************************************************************************/
  49. #define FACTOR_TEXT N_("Blur factor (1-127)")
  50. #define FACTOR_LONGTEXT N_("The degree of blurring from 1 to 127.")
  51. #define FILTER_PREFIX "blur-"
  52. vlc_module_begin ()
  53.     set_shortname( N_("Motion blur") )
  54.     set_description( N_("Motion blur filter") )
  55.     set_capability( "video filter2", 0 )
  56.     set_category( CAT_VIDEO )
  57.     set_subcategory( SUBCAT_VIDEO_VFILTER )
  58.     add_integer_with_range( FILTER_PREFIX "factor", 80, 1, 127, NULL,
  59.                             FACTOR_TEXT, FACTOR_LONGTEXT, false )
  60.     add_shortcut( "blur" )
  61.     set_callbacks( Create, Destroy )
  62. vlc_module_end ()
  63. static const char *const ppsz_filter_options[] = {
  64.     "factor", NULL
  65. };
  66. /*****************************************************************************
  67.  * filter_sys_t
  68.  *****************************************************************************/
  69. struct filter_sys_t
  70. {
  71.     vlc_spinlock_t lock;
  72.     int        i_factor;
  73.     uint8_t  **pp_planes;
  74.     int        i_planes;
  75. };
  76. /*****************************************************************************
  77.  * Create
  78.  *****************************************************************************/
  79. static int Create( vlc_object_t *p_this )
  80. {
  81.     filter_t *p_filter = (filter_t *)p_this;
  82.     /* Allocate structure */
  83.     p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
  84.     if( p_filter->p_sys == NULL )
  85.         return VLC_ENOMEM;
  86.     p_filter->pf_video_filter = Filter;
  87.     config_ChainParse( p_filter, FILTER_PREFIX, ppsz_filter_options,
  88.                        p_filter->p_cfg );
  89.     p_filter->p_sys->i_factor =
  90.         var_CreateGetIntegerCommand( p_filter, FILTER_PREFIX "factor" );
  91.     vlc_spin_init( &p_filter->p_sys->lock );
  92.     var_AddCallback( p_filter, FILTER_PREFIX "factor",
  93.                      MotionBlurCallback, p_filter->p_sys );
  94.     p_filter->p_sys->pp_planes = NULL;
  95.     p_filter->p_sys->i_planes = 0;
  96.     return VLC_SUCCESS;
  97. }
  98. /*****************************************************************************
  99.  * Destroy
  100.  *****************************************************************************/
  101. static void Destroy( vlc_object_t *p_this )
  102. {
  103.     filter_t *p_filter = (filter_t *)p_this;
  104.     var_DelCallback( p_filter, FILTER_PREFIX "factor",
  105.                      MotionBlurCallback, p_filter->p_sys );
  106.     vlc_spin_destroy( &p_filter->p_sys->lock );
  107.     while( p_filter->p_sys->i_planes-- )
  108.         free( p_filter->p_sys->pp_planes[p_filter->p_sys->i_planes] );
  109.     free( p_filter->p_sys->pp_planes );
  110.     free( p_filter->p_sys );
  111. }
  112. /*****************************************************************************
  113.  * Filter
  114.  *****************************************************************************/
  115. static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
  116. {
  117.     picture_t * p_outpic;
  118.     filter_sys_t *p_sys = p_filter->p_sys;
  119.     if( !p_pic ) return NULL;
  120.     p_outpic = filter_NewPicture( p_filter );
  121.     if( !p_outpic )
  122.     {
  123.         picture_Release( p_pic );
  124.         return NULL;
  125.     }
  126.     if( !p_sys->pp_planes )
  127.     {
  128.         /* initialise our picture buffer */
  129.         int i_plane;
  130.         p_sys->i_planes = p_pic->i_planes;
  131.         p_sys->pp_planes =
  132.             (uint8_t**)malloc( p_sys->i_planes * sizeof( uint8_t * ) );
  133.         for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  134.         {
  135.             p_sys->pp_planes[i_plane] = (uint8_t*)malloc(
  136.                 p_pic->p[i_plane].i_pitch * p_pic->p[i_plane].i_visible_lines );
  137.         }
  138.         Copy( p_filter, p_pic );
  139.     }
  140.     /* Get a new picture */
  141.     RenderBlur( p_sys, p_pic, p_outpic );
  142.     Copy( p_filter, p_outpic );
  143.     return CopyInfoAndRelease( p_outpic, p_pic );
  144. }
  145. /*****************************************************************************
  146.  * RenderBlur: renders a blurred picture
  147.  *****************************************************************************/
  148. static void RenderBlur( filter_sys_t *p_sys, picture_t *p_newpic,
  149.                         picture_t *p_outpic )
  150. {
  151.     int i_plane;
  152.     int i_oldfactor = p_sys->i_factor;
  153.     int i_newfactor = 128 - i_oldfactor;
  154.     for( i_plane = 0; i_plane < p_outpic->i_planes; i_plane++ )
  155.     {
  156.         uint8_t *p_old, *p_new, *p_out, *p_out_end, *p_out_line_end;
  157.         const int i_pitch = p_outpic->p[i_plane].i_pitch;
  158.         const int i_visible_pitch = p_outpic->p[i_plane].i_visible_pitch;
  159.         const int i_visible_lines = p_outpic->p[i_plane].i_visible_lines;
  160.         p_out = p_outpic->p[i_plane].p_pixels;
  161.         p_new = p_newpic->p[i_plane].p_pixels;
  162.         p_old = p_sys->pp_planes[i_plane];
  163.         p_out_end = p_out + i_pitch * i_visible_lines;
  164.         while ( p_out < p_out_end )
  165.         {
  166.             p_out_line_end = p_out + i_visible_pitch;
  167.             while ( p_out < p_out_line_end )
  168.             {
  169.                 *p_out++ = (((*p_old++) * i_oldfactor) +
  170.                             ((*p_new++) * i_newfactor)) >> 7;
  171.             }
  172.             p_old += i_pitch - i_visible_pitch;
  173.             p_new += i_pitch - i_visible_pitch;
  174.             p_out += i_pitch - i_visible_pitch;
  175.         }
  176.     }
  177. }
  178. static void Copy( filter_t *p_filter, picture_t *p_pic )
  179. {
  180.     int i_plane;
  181.     for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
  182.     {
  183.         vlc_memcpy(
  184.             p_filter->p_sys->pp_planes[i_plane], p_pic->p[i_plane].p_pixels,
  185.             p_pic->p[i_plane].i_pitch * p_pic->p[i_plane].i_visible_lines );
  186.     }
  187. }
  188. static int MotionBlurCallback( vlc_object_t *p_this, char const *psz_var,
  189.                                vlc_value_t oldval, vlc_value_t newval,
  190.                                void *p_data )
  191. {
  192.     VLC_UNUSED(p_this); VLC_UNUSED(oldval);
  193.     filter_sys_t *p_sys = (filter_sys_t *)p_data;
  194.     if( !strcmp( psz_var, FILTER_PREFIX "factor" ) )
  195.     {
  196.         vlc_spin_lock( &p_sys->lock );
  197.         p_sys->i_factor = __MIN( 127, __MAX( 1, newval.i_int ) );
  198.         vlc_spin_unlock( &p_sys->lock );
  199.     }
  200.     return VLC_SUCCESS;
  201. }