[vlc-devel] [PATCH 1/3] VHS: VHS style video filter

Jean-Baptiste Kempf jb at videolan.org
Thu Aug 15 13:49:55 CEST 2013


Applied, with the same manipulations

Le 26/07/2013 19:56, Vianney Boyer a écrit :
>
>
> Hi,
>
> You'll find below and in 2 additional patches the vhs video filter
> modified as per your comments.
>
> It has to be applied after freeze patch and oldmovie patch set
>
>
> Regards
>
> Vianney
>
>
> ---
>   modules/video_filter/vhs.c | 540
> +++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 540 insertions(+)
>   create mode 100644 modules/video_filter/vhs.c
>
> diff --git a/modules/video_filter/vhs.c b/modules/video_filter/vhs.c
> new file mode 100644
> index 0000000..cd1c450
> --- /dev/null
> +++ b/modules/video_filter/vhs.c
> @@ -0,0 +1,540 @@
> +/*****************************************************************************
> + * vhs.c : VHS effect video filter
> +
> *****************************************************************************
> + * Copyright (C) 2013      Vianney Boyer
> + * $Id$
> + *
> + * Authors: Vianney Boyer <vlcvboyer -at- gmail -dot- com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser 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 <vlc_common.h>
> +#include <vlc_plugin.h>
> +#include <vlc_filter.h>
> +#include <vlc_rand.h>
> +#include <vlc_mtime.h>
> +
> +#include "filter_picture.h"
> +
> +#ifndef TIME_UNIT_PER_S
> +#   define TIME_UNIT_PER_S ( ((int64_t) 1) << 32 )
> +#endif
> +
> +static inline int64_t MOD(int64_t a, int64_t b) {
> +    return ( ( a % b ) + b ) % b; }
> +
> +#define MAX_BLUE_RED_LINES 100
> +
> +typedef struct {
> +    int32_t  i_offset;
> +    uint16_t i_intensity;
> +    bool     b_blue_red;
> +    uint64_t i_stop_trigger;
> +} blue_red_line_t;
> +
> +struct filter_sys_t {
> +
> +    /* general data */
> +    bool b_init;
> +    int32_t  i_planes;
> +    int32_t *i_height; /* note: each plane may have different dimensions */
> +    int32_t *i_width;
> +    int32_t *i_visible_pitch;
> +    uint64_t i_start_time;
> +    uint64_t i_last_time;
> +    uint64_t i_cur_time;
> +
> +    /* sliding & offset effect */
> +    int32_t  i_phase_speed;
> +    int32_t  i_phase_ofs;
> +    int32_t  i_offset_ofs;
> +    int32_t  i_sliding_ofs;
> +    int32_t  i_sliding_speed;
> +    uint64_t i_offset_trigger;
> +    uint64_t i_sliding_trigger;
> +    uint64_t i_sliding_stop_trig;
> +    bool     i_sliding_type_duplicate;
> +
> +    /* blue red lines effect */
> +    uint64_t i_BR_line_trigger;
> +    blue_red_line_t *p_BR_lines[MAX_BLUE_RED_LINES];
> +
> +};
> +
> +/*****************************************************************************
> + * Prototypes
> +
> *****************************************************************************/
> +
> +picture_t *Filter( filter_t *, picture_t * );
> +
> +int  vhs_allocate_data( filter_t *, picture_t * );
> +void vhs_free_allocated_data( filter_t * );
> +
> +int  vhs_blue_red_line_effect( filter_t *, picture_t * );
> +void vhs_blue_red_dots_effect( filter_t *, picture_t * );
> +int  vhs_sliding_effect( filter_t *, picture_t * );
> +
> +int  vhs_sliding_effect_apply( filter_t *, picture_t * );
> +
> +/*****************************************************************************
> + * Module descriptor
> +
> *****************************************************************************/
> +
> +int  Open ( vlc_object_t * );
> +void Close( vlc_object_t * );
> +
> +vlc_module_begin()
> +    set_description( N_("VHS movie effect video filter") )
> +    set_shortname(   N_("VHS movie" ) )
> +    set_capability( "video filter2", 0 )
> +    set_category( CAT_VIDEO )
> +    set_subcategory( SUBCAT_VIDEO_VFILTER )
> +
> +    set_callbacks( Open, Close )
> +vlc_module_end()
> +
> +/**
> + * Open the filter
> + */
> +int Open( vlc_object_t *p_this )
> +{
> +    filter_t *p_filter = (filter_t*)p_this;
> +    filter_sys_t *p_sys;
> +
> +    /* Assert video in match with video out */
> +    if( !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) ) {
> +        msg_Err( p_filter, "Input and output format does not match" );
> +        return VLC_EGENERIC;
> +    }
> +
> +    /* Reject 0 bpp and unsupported chroma */
> +    const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma;
> +    const vlc_chroma_description_t *p_chroma =
> +        vlc_fourcc_GetChromaDescription( p_filter->fmt_in.video.i_chroma );
> +    if( !p_chroma || p_chroma->pixel_size == 0
> +        || p_chroma->plane_count < 3 || p_chroma->pixel_size > 1
> +        || !vlc_fourcc_IsYUV( fourcc ) )
> +    {
> +        msg_Err( p_filter, "Unsupported chroma (%4.4s)", (char*)&fourcc );
> +        return VLC_EGENERIC;
> +    }
> +
> +    /* Allocate structure */
> +    p_filter->p_sys = p_sys = calloc(1, sizeof(*p_sys) );
> +    if( unlikely( !p_sys ) )
> +        return VLC_ENOMEM;
> +
> +    /* init data */
> +    p_filter->pf_video_filter = Filter;
> +    p_sys->i_start_time = p_sys->i_cur_time = p_sys->i_last_time =
> NTPtime64();
> +
> +    return VLC_SUCCESS;
> +}
> +
> +/**
> + * Close the filter
> + */
> +void Close( vlc_object_t *p_this ) {
> +    filter_t *p_filter = (filter_t*)p_this;
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    /* Free allocated memory */
> +    vhs_free_allocated_data( p_filter );
> +    free( p_sys );
> +}
> +
> +/**
> + * Filter a picture
> + */
> +picture_t *Filter( filter_t *p_filter, picture_t *p_pic_in ) {
> +    if( unlikely( !p_pic_in || !p_filter) )
> +        return NULL;
> +
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    picture_t *p_pic_out = filter_NewPicture( p_filter );
> +    if( unlikely( !p_pic_out ) ) {
> +        picture_Release( p_pic_in );
> +        return NULL;
> +    }
> +
> +   /*
> +    * manage time
> +    */
> +    p_sys->i_last_time = p_sys->i_cur_time;
> +    p_sys->i_cur_time = NTPtime64();
> +
> +   /*
> +    * allocate data
> +    */
> +    if ( unlikely( !p_sys->b_init ) )
> +        if ( unlikely( vhs_allocate_data( p_filter, p_pic_in ) !=
> VLC_SUCCESS ) ) {
> +            picture_Release( p_pic_in );
> +            return NULL;
> +        }
> +    p_sys->b_init = true;
> +
> +   /*
> +    * preset output pic: raw copy src to dst
> +    */
> +    picture_CopyPixels(p_pic_out, p_pic_in);
> +
> +   /*
> +    * apply effects on picture
> +    */
> +    if ( unlikely( vhs_blue_red_line_effect( p_filter, p_pic_out ) !=
> VLC_SUCCESS ) )
> +        return CopyInfoAndRelease( p_pic_out, p_pic_in );
> +
> +    if ( unlikely( vhs_sliding_effect(p_filter, p_pic_out ) !=
> VLC_SUCCESS ) )
> +        return CopyInfoAndRelease( p_pic_out, p_pic_in );
> +
> +    vhs_blue_red_dots_effect( p_filter, p_pic_out );
> +
> +    return CopyInfoAndRelease( p_pic_out, p_pic_in );
> +}
> +
> +/*
> + * Allocate data
> + */
> +int vhs_allocate_data( filter_t *p_filter, picture_t *p_pic_in ) {
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    vhs_free_allocated_data( p_filter );
> +
> +   /*
> +    * take into account different characteristics for each plane
> +    */
> +    p_sys->i_planes = p_pic_in->i_planes;
> +    p_sys->i_height = calloc( p_sys->i_planes, sizeof(int32_t) );
> +    p_sys->i_width  = calloc( p_sys->i_planes, sizeof(int32_t) );
> +    p_sys->i_visible_pitch = calloc( p_sys->i_planes, sizeof(int32_t) );
> +
> +    if( unlikely( !p_sys->i_height || !p_sys->i_width ||
> !p_sys->i_visible_pitch ) ) {
> +        vhs_free_allocated_data( p_filter );
> +        return VLC_ENOMEM;
> +    }
> +
> +    for ( int32_t i_p = 0; i_p < p_sys->i_planes; i_p++) {
> +        p_sys->i_visible_pitch [i_p] = (int)
> p_pic_in->p[i_p].i_visible_pitch;
> +        p_sys->i_height[i_p] = (int) p_pic_in->p[i_p].i_visible_lines;
> +        p_sys->i_width [i_p] = (int) p_pic_in->p[i_p].i_visible_pitch /
> p_pic_in->p[i_p].i_pixel_pitch;
> +    }
> +    return VLC_SUCCESS;
> +}
> +
> +/**
> + * Free allocated data
> + */
> +void vhs_free_allocated_data( filter_t *p_filter ) {
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    for ( uint32_t i_b = 0; i_b < MAX_BLUE_RED_LINES; i_b++ )
> +        FREENULL( p_sys->p_BR_lines[i_b] );
> +
> +    p_sys->i_planes = 0;
> +    FREENULL( p_sys->i_height );
> +    FREENULL( p_sys->i_width );
> +    FREENULL( p_sys->i_visible_pitch );
> +}
> +
> +
> +/**
> + * Horizontal blue or red lines random management and effect
> + */
> +int vhs_blue_red_line_effect( filter_t *p_filter, picture_t *p_pic_out ) {
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +#define BR_LINES_GENERATOR_PERIOD ( TIME_UNIT_PER_S * 50 )
> +#define BR_LINES_DURATION         ( TIME_UNIT_PER_S * 1/50 )
> +
> +    /* generate new blue or red lines */
> +    if ( p_sys->i_BR_line_trigger <= p_sys->i_cur_time ) {
> +        for ( uint32_t i_b = 0; i_b < MAX_BLUE_RED_LINES; i_b++ )
> +            if (p_sys->p_BR_lines[i_b] == NULL) {
> +                /* allocate data */
> +                p_sys->p_BR_lines[i_b] = calloc( 1,
> sizeof(blue_red_line_t) );
> +                if ( unlikely( !p_sys->p_BR_lines[i_b] ) )
> +                    return VLC_ENOMEM;
> +
> +                /* set random parameters */
> +                p_sys->p_BR_lines[i_b]->i_offset = (unsigned)vlc_mrand48()
> +                                                 % __MAX( 1,
> p_sys->i_height[Y_PLANE] - 10 )
> +                                                 + 5;
> +
> +                p_sys->p_BR_lines[i_b]->b_blue_red =
> (unsigned)vlc_mrand48() & 0x01;
> +
> +                p_sys->p_BR_lines[i_b]->i_stop_trigger = p_sys->i_cur_time
> +                                                       +
> (uint64_t)vlc_mrand48() % BR_LINES_DURATION
> +                                                       +
> BR_LINES_DURATION / 2;
> +
> +                break;
> +            }
> +        p_sys->i_BR_line_trigger = p_sys->i_cur_time
> +                                 + (uint64_t)vlc_mrand48() %
> BR_LINES_GENERATOR_PERIOD
> +                                 + BR_LINES_GENERATOR_PERIOD / 2;
> +    }
> +
> +
> +    /* manage and apply current blue/red lines */
> +    for ( uint8_t i_b = 0; i_b < MAX_BLUE_RED_LINES; i_b++ )
> +        if ( p_sys->p_BR_lines[i_b] ) {
> +            /* remove outdated ones */
> +            if ( p_sys->p_BR_lines[i_b]->i_stop_trigger <=
> p_sys->i_cur_time ) {
> +                FREENULL( p_sys->p_BR_lines[i_b] );
> +                continue;
> +            }
> +
> +            /* otherwise apply */
> +            for ( int32_t i_p=0; i_p < p_sys->i_planes; i_p++ ) {
> +                uint32_t i_pix_ofs = p_sys->p_BR_lines[i_b]->i_offset
> +                                   * p_pic_out->p[i_p].i_visible_lines
> +                                   / p_sys->i_height[Y_PLANE]
> +                                   * p_pic_out->p[i_p].i_pitch;
> +
> +                switch ( i_p ) {
> +                  case Y_PLANE:
> +                    memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs], 127,
> + p_pic_out->p[i_p].i_visible_pitch);
> +                    break;
> +                  case U_PLANE:
> +                    memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs],
> + (p_sys->p_BR_lines[i_b]->b_blue_red?255:0),
> + p_pic_out->p[i_p].i_visible_pitch);
> +                    break;
> +                  case V_PLANE:
> +                    memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs],
> + (p_sys->p_BR_lines[i_b]->b_blue_red?0:255),
> + p_pic_out->p[i_p].i_visible_pitch);
> +                    break;
> +                }
> +
> +            }
> +        }
> +    return VLC_SUCCESS;
> +}
> +
> +/**
> + * insert randomly blue and red dots on the picture
> + */
> +void vhs_blue_red_dots_effect( filter_t *p_filter, picture_t *p_pic_out ) {
> +#define BR_DOTS_RATIO 10000
> +
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    for ( int32_t i_dots = 0;
> +          i_dots < p_sys->i_width[Y_PLANE] * p_sys->i_height[Y_PLANE] /
> BR_DOTS_RATIO;
> +          i_dots++) {
> +
> +        uint32_t i_length = (unsigned)vlc_mrand48()
> +                          % __MAX( 1, p_sys->i_width[Y_PLANE] / 30 ) + 1;
> +
> +        uint16_t i_x = (unsigned)vlc_mrand48()
> +                     % __MAX( 1, p_sys->i_width[Y_PLANE] - i_length );
> +        uint16_t i_y = (unsigned)vlc_mrand48() % p_sys->i_height[Y_PLANE];
> +        bool b_color = ( ( (unsigned)vlc_mrand48() % 2 ) == 0);
> +
> +        for ( int32_t i_p = 0; i_p < p_sys->i_planes; i_p++ ) {
> +            uint32_t i_pix_ofs = i_y
> +                               * p_pic_out->p[i_p].i_visible_lines
> +                               / p_sys->i_height[Y_PLANE]
> +                               * p_pic_out->p[i_p].i_pitch
> +                               + i_x
> +                               * p_pic_out->p[i_p].i_pixel_pitch;
> +
> +            uint32_t i_length_in_plane = i_length
> +                                       * p_pic_out->p[i_p].i_visible_pitch
> +                                       /
> p_pic_out->p[Y_PLANE].i_visible_pitch;
> +
> +            switch ( i_p ) {
> +              case Y_PLANE:
> +                memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs], 127,
> +                        i_length_in_plane );
> +                break;
> +              case U_PLANE:
> +                memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs],
> +                        (b_color?255:0),
> +                        i_length_in_plane );
> +                break;
> +              case V_PLANE:
> +                memset( &p_pic_out->p[i_p].p_pixels[i_pix_ofs],
> +                        (b_color?0:255),
> +                        i_length_in_plane );
> +                break;
> +            }
> +        }
> +    }
> +}
> +
> +/**
> +* sliding effects
> +*/
> +int vhs_sliding_effect( filter_t *p_filter, picture_t *p_pic_out ) {
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    /**
> +    * one shot offset section
> +    */
> +
> +#define OFFSET_AVERAGE_PERIOD   (10 * TIME_UNIT_PER_S)
> +
> +    /* start trigger to be (re)initialized */
> +    if ( p_sys->i_offset_trigger == 0
> +         || p_sys->i_sliding_speed != 0 ) { /* do not mix sliding and
> offset */
> +
> +        /* random trigger for offset effect */
> +        p_sys->i_offset_trigger = p_sys->i_cur_time
> +                                + ((uint64_t) vlc_mrand48() ) %
> OFFSET_AVERAGE_PERIOD
> +                                + OFFSET_AVERAGE_PERIOD / 2;
> +        p_sys->i_offset_ofs = 0;
> +    } else if (p_sys->i_offset_trigger <= p_sys->i_cur_time) {
> +        /* trigger for offset effect occurs */
> +        p_sys->i_offset_trigger = 0;
> +        p_sys->i_offset_ofs = (uint32_t)vlc_mrand48()
> +                            % p_sys->i_height[Y_PLANE];
> +    }
> +    else
> +        p_sys->i_offset_ofs = 0;
> +
> +
> +    /**
> +    * phase section
> +    */
> +
> +#define MAX_PHASE_OFS (p_sys->i_height[Y_PLANE]*100/15)
> +
> +    p_sys->i_phase_speed += MOD( (int32_t)vlc_mrand48(), 3) - 1;
> +    p_sys->i_phase_ofs   += p_sys->i_phase_speed;
> +    p_sys->i_phase_ofs    = VLC_CLIP( p_sys->i_phase_ofs,
> -MAX_PHASE_OFS, +MAX_PHASE_OFS);
> +    if ( abs( p_sys->i_phase_ofs ) >= MAX_PHASE_OFS )
> +        p_sys->i_phase_speed = 0;
> +
> +
> +    /**
> +    * sliding section
> +    */
> +
> +#define SLIDING_AVERAGE_PERIOD   (20 * TIME_UNIT_PER_S)
> +#define SLIDING_AVERAGE_DURATION ( 3 * TIME_UNIT_PER_S)
> +
> +    /* start trigger to be (re)initialized */
> +    if ( ( p_sys->i_sliding_stop_trig  == 0 ) &&
> +         ( p_sys->i_sliding_trigger    == 0 ) &&
> +         ( p_sys->i_sliding_speed      == 0 ) ) {
> +
> +        /* random trigger which enable sliding effect */
> +        p_sys->i_sliding_trigger = p_sys->i_cur_time
> +                                 + (uint64_t)vlc_mrand48() %
> SLIDING_AVERAGE_PERIOD
> +                                 + SLIDING_AVERAGE_PERIOD / 2;
> +    }
> +
> +    /* start trigger just occurs */
> +    else if ( ( p_sys->i_sliding_stop_trig  == 0 ) &&
> +              ( p_sys->i_sliding_trigger    <= p_sys->i_cur_time ) &&
> +              ( p_sys->i_sliding_speed      == 0 ) ) {
> +
> +        /* init sliding parameters */
> +        p_sys->i_sliding_trigger = 0;
> +        p_sys->i_sliding_stop_trig = p_sys->i_cur_time
> +                                   + (uint64_t)vlc_mrand48() %
> SLIDING_AVERAGE_DURATION
> +                                   + SLIDING_AVERAGE_DURATION / 2;
> +        p_sys->i_sliding_ofs = 0;
> +        /* note: sliding speed unit = image per 100 s */
> +        p_sys->i_sliding_speed = MOD( (int32_t)vlc_mrand48(), 1001 ) - 500;
> +        p_sys->i_sliding_type_duplicate = (unsigned)vlc_mrand48() & 0x01;
> +    }
> +
> +    /* stop trigger disabling sliding effect occurs */
> +    else if ( ( p_sys->i_sliding_stop_trig  <= p_sys->i_cur_time )
> +              && ( p_sys->i_sliding_trigger == 0 ) ) {
> +
> +        /* first increase speed to ensure we will stop sliding on plain
> pict */
> +        if ( abs( p_sys->i_sliding_speed ) < 5 )
> +            p_sys->i_sliding_speed += 1;
> +
> +        /* check if offset is close to 0 and then ready to stop */
> +        if ( abs( p_sys->i_sliding_ofs ) < abs( p_sys->i_sliding_speed
> +             * p_sys->i_height[Y_PLANE]
> +             * ( p_sys->i_cur_time - p_sys->i_last_time ) /
> TIME_UNIT_PER_S )
> +             || abs( p_sys->i_sliding_ofs ) < p_sys->i_height[Y_PLANE]
> * 100 / 20 ) {
> +
> +            /* reset sliding parameters */
> +            p_sys->i_sliding_ofs = p_sys->i_sliding_speed = 0;
> +            p_sys->i_sliding_trigger = p_sys->i_sliding_stop_trig = 0;
> +            p_sys->i_sliding_type_duplicate = false;
> +        }
> +    }
> +
> +    /* update offset */
> +    p_sys->i_sliding_ofs = MOD( p_sys->i_sliding_ofs
> +                                + p_sys->i_sliding_speed *
> p_sys->i_height[Y_PLANE]
> +                                * ( p_sys->i_cur_time - p_sys->i_last_time)
> +                                / TIME_UNIT_PER_S,
> +                                p_sys->i_height[Y_PLANE] * 100 );
> +
> +    return vhs_sliding_effect_apply( p_filter, p_pic_out );
> +}
> +
> +/**
> +* apply both sliding and offset effect
> +*/
> +int vhs_sliding_effect_apply( filter_t *p_filter, picture_t *p_pic_out )
> +{
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +
> +    for ( uint8_t i_p = 0; i_p < p_pic_out->i_planes; i_p++ ) {
> +        /* first allocate temporary buffer for swap operation */
> +        uint8_t *p_temp_buf;
> +        if ( !p_sys->i_sliding_type_duplicate ) {
> +            p_temp_buf= calloc( p_pic_out->p[i_p].i_lines
> +                                * p_pic_out->p[i_p].i_pitch,
> sizeof(uint8_t) );
> +            if ( unlikely( !p_temp_buf ) )
> +                return VLC_ENOMEM;
> +            memcpy( p_temp_buf, p_pic_out->p[i_p].p_pixels,
> +                    p_pic_out->p[i_p].i_lines *
> p_pic_out->p[i_p].i_pitch );
> +        }
> +        else
> +            p_temp_buf = p_pic_out->p[i_p].p_pixels;
> +
> +        /* copy lines to output_pic */
> +        for ( int32_t i_y = 0; i_y < p_pic_out->p[i_p].i_visible_lines;
> i_y++ )
> +        {
> +            int32_t i_ofs = p_sys->i_offset_ofs + p_sys->i_sliding_ofs;
> +
> +            if ( ( p_sys->i_sliding_speed == 0 ) ||
> !p_sys->i_sliding_type_duplicate )
> +                i_ofs += p_sys->i_phase_ofs;
> +
> +            i_ofs  = MOD( i_ofs / 100, p_sys->i_height[Y_PLANE] );
> +            i_ofs *= p_pic_out->p[i_p].i_visible_lines;
> +            i_ofs /= p_sys->i_height[Y_PLANE];
> +
> +            memcpy( &p_pic_out->p[i_p].p_pixels[ i_y *
> p_pic_out->p[i_p].i_pitch ],
> +                    &p_temp_buf[ ( ( i_y + i_ofs ) %
> p_pic_out->p[i_p].i_visible_lines ) * p_pic_out->p[i_p].i_pitch ],
> +                    p_pic_out->p[i_p].i_visible_pitch );
> +        }
> +        if ( !p_sys->i_sliding_type_duplicate )
> +            free(p_temp_buf);
> +    }
> +
> +    return VLC_SUCCESS;
> +}
> --
> 1.8.1.2
>
>
>
>
> Le 25/07/2013 13:41, Jean-Baptiste Kempf a écrit :
>> On 25 Jul, Vianney Boyer wrote :
>>> New video filter showing the video like an old VHS tape
>> Mostly the same remarks as the previous ones.
>>
>
>
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel
>


-- 
Jean-Baptiste Kempf
http://www.jbkempf.com/ - +33 672 704 734
Sent from my Electronic Device



More information about the vlc-devel mailing list