⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gradient.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * gradient.c : Gradient and edge detection video effects plugin for vlc ***************************************************************************** * Copyright (C) 2000-2008 the VideoLAN team * $Id: f1c57cdeefe761bdfa96ba2b255b5f1bf54c1f56 $ * * Authors: Samuel Hocevar <sam@zoy.org> *          Antoine Cellerier <dionoea -at- videolan -dot- org> * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <math.h>                                            /* sin(), cos() */#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_sout.h>#include <vlc_vout.h>#include "vlc_filter.h"#include "filter_picture.h"enum { GRADIENT, EDGE, HOUGH };/***************************************************************************** * Local prototypes *****************************************************************************/static int  Create    ( vlc_object_t * );static void Destroy   ( vlc_object_t * );static picture_t *Filter( filter_t *, picture_t * );static int GradientCallback( vlc_object_t *, char const *,                             vlc_value_t, vlc_value_t,                             void * );static void FilterGradient( filter_t *, picture_t *, picture_t * );static void FilterEdge    ( filter_t *, picture_t *, picture_t * );static void FilterHough   ( filter_t *, picture_t *, picture_t * );/***************************************************************************** * Module descriptor *****************************************************************************/#define MODE_TEXT N_("Distort mode")#define MODE_LONGTEXT N_("Distort mode, one of \"gradient\", \"edge\" and \"hough\".")#define GRADIENT_TEXT N_("Gradient image type")#define GRADIENT_LONGTEXT N_("Gradient image type (0 or 1). 0 will " \        "turn the image to white while 1 will keep colors." )#define CARTOON_TEXT N_("Apply cartoon effect")#define CARTOON_LONGTEXT N_("Apply cartoon effect. It is only used by " \    "\"gradient\" and \"edge\".")static const char *const mode_list[] = { "gradient", "edge", "hough" };static const char *const mode_list_text[] = { N_("Gradient"), N_("Edge"), N_("Hough") };#define FILTER_PREFIX "gradient-"vlc_module_begin();    set_description( N_("Gradient video filter") );    set_shortname( N_( "Gradient" ));    set_capability( "video filter2", 0 );    set_category( CAT_VIDEO );    set_subcategory( SUBCAT_VIDEO_VFILTER );    add_string( FILTER_PREFIX "mode", "gradient", NULL,                MODE_TEXT, MODE_LONGTEXT, false );        change_string_list( mode_list, mode_list_text, 0 );    add_integer_with_range( FILTER_PREFIX "type", 0, 0, 1, NULL,                GRADIENT_TEXT, GRADIENT_LONGTEXT, false );    add_bool( FILTER_PREFIX "cartoon", 1, NULL,                CARTOON_TEXT, CARTOON_LONGTEXT, false );    add_shortcut( "gradient" );    set_callbacks( Create, Destroy );vlc_module_end();static const char *const ppsz_filter_options[] = {    "mode", "type", "cartoon", NULL};/***************************************************************************** * vout_sys_t: Distort video output method descriptor ***************************************************************************** * This structure is part of the video output thread descriptor. * It describes the Distort specific properties of an output thread. *****************************************************************************/struct filter_sys_t{    int i_mode;    /* For the gradient mode */    int i_gradient_type;    bool b_cartoon;    uint32_t *p_buf32;    uint32_t *p_buf32_bis;    uint8_t *p_buf8;    /* For hough mode */    int *p_pre_hough;};/***************************************************************************** * Create: allocates Distort video thread output method ***************************************************************************** * This function allocates and initializes a Distort vout method. *****************************************************************************/static int Create( vlc_object_t *p_this ){    filter_t *p_filter = (filter_t *)p_this;    char *psz_method;    switch( p_filter->fmt_in.video.i_chroma )    {        CASE_PLANAR_YUV            break;        default:             msg_Err( p_filter, "Unsupported input chroma (%4s)",                      (char*)&(p_filter->fmt_in.video.i_chroma) );            return VLC_EGENERIC;    }    /* Allocate structure */    p_filter->p_sys = malloc( sizeof( filter_sys_t ) );    if( p_filter->p_sys == NULL )        return VLC_ENOMEM;    p_filter->pf_video_filter = Filter;    p_filter->p_sys->p_pre_hough = NULL;    config_ChainParse( p_filter, FILTER_PREFIX, ppsz_filter_options,                   p_filter->p_cfg );    if( !(psz_method =        var_CreateGetNonEmptyStringCommand( p_filter, FILTER_PREFIX "mode" )) )    {        msg_Err( p_filter, "configuration variable "                 FILTER_PREFIX "mode empty" );        p_filter->p_sys->i_mode = GRADIENT;    }    else    {        if( !strcmp( psz_method, "gradient" ) )        {            p_filter->p_sys->i_mode = GRADIENT;        }        else if( !strcmp( psz_method, "edge" ) )        {            p_filter->p_sys->i_mode = EDGE;        }        else if( !strcmp( psz_method, "hough" ) )        {            p_filter->p_sys->i_mode = HOUGH;        }        else        {            msg_Err( p_filter, "no valid gradient mode provided (%s)", psz_method );            p_filter->p_sys->i_mode = GRADIENT;        }    }    free( psz_method );    p_filter->p_sys->i_gradient_type =        var_CreateGetIntegerCommand( p_filter, FILTER_PREFIX "type" );    p_filter->p_sys->b_cartoon =        var_CreateGetBoolCommand( p_filter, FILTER_PREFIX "cartoon" );    var_AddCallback( p_filter, FILTER_PREFIX "mode",                     GradientCallback, p_filter->p_sys );    var_AddCallback( p_filter, FILTER_PREFIX "type",                     GradientCallback, p_filter->p_sys );    var_AddCallback( p_filter, FILTER_PREFIX "cartoon",                     GradientCallback, p_filter->p_sys );    p_filter->p_sys->p_buf32 = NULL;    p_filter->p_sys->p_buf32_bis = NULL;    p_filter->p_sys->p_buf8 = NULL;    return VLC_SUCCESS;}/***************************************************************************** * Destroy: destroy Distort video thread output method ***************************************************************************** * Terminate an output method created by DistortCreateOutputMethod *****************************************************************************/static void Destroy( vlc_object_t *p_this ){    filter_t *p_filter = (filter_t *)p_this;    free( p_filter->p_sys->p_buf32 );    free( p_filter->p_sys->p_buf32_bis );    free( p_filter->p_sys->p_buf8 );    free( p_filter->p_sys->p_pre_hough );    free( p_filter->p_sys );}/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Distort image, waits * until it is displayed and switch the two rendering buffers, preparing next * frame. *****************************************************************************/static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ){    picture_t *p_outpic;    if( !p_pic ) return NULL;    p_outpic = filter_NewPicture( p_filter );    if( !p_outpic )    {        picture_Release( p_pic );        return NULL;    }    switch( p_filter->p_sys->i_mode )    {        case EDGE:            FilterEdge( p_filter, p_pic, p_outpic );            break;        case GRADIENT:            FilterGradient( p_filter, p_pic, p_outpic );            break;        case HOUGH:            FilterHough( p_filter, p_pic, p_outpic );            break;        default:            break;    }    return CopyInfoAndRelease( p_outpic, p_pic );}/***************************************************************************** * Gaussian Convolution ***************************************************************************** *    Gaussian convolution ( sigma == 1.4 ) * *    |  2  4  5  4  2  |   |  2  4  4  4  2 | *    |  4  9 12  9  4  |   |  4  8 12  8  4 | *    |  5 12 15 12  5  | ~ |  4 12 16 12  4 | *    |  4  9 12  9  4  |   |  4  8 12  8  4 | *    |  2  4  5  4  2  |   |  2  4  4  4  2 | *****************************************************************************/static void GaussianConvolution( picture_t *p_inpic, uint32_t *p_smooth ){    const uint8_t *p_inpix = p_inpic->p[Y_PLANE].p_pixels;    const int i_src_pitch = p_inpic->p[Y_PLANE].i_pitch;    const int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch;    const int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines;    int x,y;    for( y = 2; y < i_num_lines - 2; y++ )    {        for( x = 2; x < i_src_visible - 2; x++ )        {            p_smooth[y*i_src_visible+x] = (uint32_t)(              /* 2 rows up */                ( p_inpix[(y-2)*i_src_pitch+x-2] )              + ((p_inpix[(y-2)*i_src_pitch+x-1]              +   p_inpix[(y-2)*i_src_pitch+x]              +   p_inpix[(y-2)*i_src_pitch+x+1])<<1 )              + ( p_inpix[(y-2)*i_src_pitch+x+2] )              /* 1 row up */              + ((p_inpix[(y-1)*i_src_pitch+x-2]              + ( p_inpix[(y-1)*i_src_pitch+x-1]<<1 )              + ( p_inpix[(y-1)*i_src_pitch+x]*3 )              + ( p_inpix[(y-1)*i_src_pitch+x+1]<<1 )              +   p_inpix[(y-1)*i_src_pitch+x+2]              /* */              +   p_inpix[y*i_src_pitch+x-2]              + ( p_inpix[y*i_src_pitch+x-1]*3 )              + ( p_inpix[y*i_src_pitch+x]<<2 )              + ( p_inpix[y*i_src_pitch+x+1]*3 )              +   p_inpix[y*i_src_pitch+x+2]              /* 1 row down */              +   p_inpix[(y+1)*i_src_pitch+x-2]              + ( p_inpix[(y+1)*i_src_pitch+x-1]<<1 )              + ( p_inpix[(y+1)*i_src_pitch+x]*3 )              + ( p_inpix[(y+1)*i_src_pitch+x+1]<<1 )              +   p_inpix[(y+1)*i_src_pitch+x+2] )<<1 )              /* 2 rows down */              + ( p_inpix[(y+2)*i_src_pitch+x-2] )              + ((p_inpix[(y+2)*i_src_pitch+x-1]              +   p_inpix[(y+2)*i_src_pitch+x]              +   p_inpix[(y+2)*i_src_pitch+x+1])<<1 )              + ( p_inpix[(y+2)*i_src_pitch+x+2] )              ) >> 6 /* 115 */;        }    }}/***************************************************************************** * FilterGradient: Sobel *****************************************************************************/static void FilterGradient( filter_t *p_filter, picture_t *p_inpic,                                                picture_t *p_outpic ){    int x, y;    const int i_src_pitch = p_inpic->p[Y_PLANE].i_pitch;    const int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch;    const int i_dst_pitch = p_outpic->p[Y_PLANE].i_pitch;    const int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines;    const uint8_t *p_inpix = p_inpic->p[Y_PLANE].p_pixels;    uint8_t *p_outpix = p_outpic->p[Y_PLANE].p_pixels;    uint32_t *p_smooth;    if( !p_filter->p_sys->p_buf32 )        p_filter->p_sys->p_buf32 =        (uint32_t *)malloc( i_num_lines * i_src_visible * sizeof(uint32_t));    p_smooth = p_filter->p_sys->p_buf32;    if( !p_smooth ) return;    if( p_filter->p_sys->b_cartoon )    {        vlc_memcpy( p_outpic->p[U_PLANE].p_pixels,            p_inpic->p[U_PLANE].p_pixels,            p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch );        vlc_memcpy( p_outpic->p[V_PLANE].p_pixels,            p_inpic->p[V_PLANE].p_pixels,            p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch );    }    else    {        vlc_memset( p_outpic->p[U_PLANE].p_pixels, 0x80,            p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch );        vlc_memset( p_outpic->p[V_PLANE].p_pixels, 0x80,            p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch );    }    GaussianConvolution( p_inpic, p_smooth );    /* Sobel gradient     | -1 0 1 |     |  1  2  1 |     | -2 0 2 | and |  0  0  0 |     | -1 0 1 |     | -1 -2 -1 | */#define FOR                                                     \    for( y = 1; y < i_num_lines - 1; y++ )                      \    {                                                           \        for( x = 1; x < i_src_visible - 1; x++ )                \        {                                                       \            const uint32_t a =                                  \            (                                                   \              abs(                                              \                 ( p_smooth[(y-1)*i_src_visible+x-1]            \                   - p_smooth[(y+1)*i_src_visible+x-1] )        \               + ( ( p_smooth[(y-1)*i_src_visible+x]            \                    - p_smooth[(y+1)*i_src_visible+x] ) <<1 )   \               + ( p_smooth[(y-1)*i_src_visible+x+1]            \                   - p_smooth[(y+1)*i_src_visible+x+1] )        \              )                                                 \            +                                                   \              abs(                                              \                 ( p_smooth[(y-1)*i_src_visible+x-1]            \                   - p_smooth[(y-1)*i_src_visible+x+1] )        \               + ( ( p_smooth[y*i_src_visible+x-1]              \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -