コード例 #1
0
/*****************************************************************************
 * PostprocPict
 *****************************************************************************/
static picture_t *PostprocPict( filter_t *p_filter, picture_t *p_pic )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    const uint8_t *src[3];
    uint8_t *dst[3];
    int i_plane;
    int i_src_stride[3], i_dst_stride[3];

    picture_t *p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* Lock to prevent issues if pp_mode is changed */
    vlc_mutex_lock( &p_sys->lock );
    if( !p_sys->pp_mode )
    {
        vlc_mutex_unlock( &p_sys->lock );
        picture_CopyPixels( p_outpic, p_pic );
        return CopyInfoAndRelease( p_outpic, p_pic );
    }


    for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
    {
        src[i_plane] = p_pic->p[i_plane].p_pixels;
        dst[i_plane] = p_outpic->p[i_plane].p_pixels;

        /* I'm not sure what happens if i_pitch != i_visible_pitch ...
         * at least it shouldn't crash. */
        i_src_stride[i_plane] = p_pic->p[i_plane].i_pitch;
        i_dst_stride[i_plane] = p_outpic->p[i_plane].i_pitch;
    }

    if( !p_pic->p_q && p_sys->b_had_matrix )
    {
        msg_Warn( p_filter, "Quantification table was not set by video decoder. Postprocessing won't look good." );
        p_sys->b_had_matrix = false;
    }
    else if( p_pic->p_q )
    {
        p_sys->b_had_matrix = true;
    }

    pp_postprocess( src, i_src_stride, dst, i_dst_stride,
                    p_filter->fmt_in.video.i_width,
                    p_filter->fmt_in.video.i_height,
                    p_pic->p_q, p_pic->i_qstride,
                    p_sys->pp_mode, p_sys->pp_context,
                    p_pic->i_qtype == QTYPE_MPEG2 ? PP_PICT_TYPE_QP2 : 0 );
    vlc_mutex_unlock( &p_sys->lock );

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #2
0
ファイル: motionblur.c プロジェクト: banketree/faplayer
/*****************************************************************************
 * Filter
 *****************************************************************************/
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    picture_t * p_outpic;
    filter_sys_t *p_sys = p_filter->p_sys;

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    if( p_sys->b_first )
    {
        picture_CopyPixels( p_sys->p_tmp, p_pic );
        p_sys->b_first = false;
    }

    /* Get a new picture */
    RenderBlur( p_sys, p_pic, p_outpic );

    picture_CopyPixels( p_sys->p_tmp, p_outpic );

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #3
0
ファイル: sharpen.c プロジェクト: IAPark/vlc
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    picture_t *p_outpic;
    const int v1 = -1;
    const int v2 = 3; /* 2^3 = 8 */
    const unsigned i_visible_lines = p_pic->p[Y_PLANE].i_visible_lines;
    const unsigned i_visible_pitch = p_pic->p[Y_PLANE].i_visible_pitch;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    if (!IS_YUV_420_10BITS(p_pic->format.i_chroma))
        SHARPEN_FRAME(255, uint8_t);
    else
        SHARPEN_FRAME(1023, uint16_t);

    plane_CopyPixels( &p_outpic->p[U_PLANE], &p_pic->p[U_PLANE] );
    plane_CopyPixels( &p_outpic->p[V_PLANE], &p_pic->p[V_PLANE] );

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #4
0
ファイル: anaglyph.c プロジェクト: RicoP/vlcfork
static picture_t *Filter(filter_t *p_filter, picture_t *p_pic)
{
    filter_sys_t *p_sys = p_filter->p_sys;

    if (!p_pic)
        return NULL;

    picture_t *p_outpic = filter_NewPicture(p_filter);
    if (!p_outpic)
    {
        picture_Release(p_pic);
        return NULL;
    }

    switch (p_pic->format.i_chroma)
    {
        case VLC_CODEC_I420:
        case VLC_CODEC_J420:
        case VLC_CODEC_YV12:
            combine_side_by_side_yuv420(p_pic, p_outpic,
                                        p_sys->left, p_sys->right);
            break;

        default:
            msg_Warn(p_filter, "Unsupported input chroma (%4.4s)",
                     (char*)&(p_pic->format.i_chroma));
            picture_Release(p_pic);
            return NULL;
    }

    return CopyInfoAndRelease(p_outpic, p_pic);
}
コード例 #5
0
/*****************************************************************************
 * Render: displays previously rendered output
 *****************************************************************************
 * This function send the currently rendered image to adjust modified 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;
    filter_sys_t *p_sys = p_filter->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    int i_simthres = p_sys->i_simthres;
    int i_satthres = p_sys->i_satthres;
    int i_color = p_sys->i_color;
    vlc_mutex_unlock( &p_sys->lock );

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* Copy the Y plane */
    plane_CopyPixels( &p_outpic->p[Y_PLANE], &p_pic->p[Y_PLANE] );

    /*
     * Do the U and V planes
     */
    int refu, refv, reflength;
    GetReference( &refu, &refv, &reflength, i_color );

    for( int y = 0; y < p_pic->p[U_PLANE].i_visible_lines; y++ )
    {
        uint8_t *p_src_u = &p_pic->p[U_PLANE].p_pixels[y * p_pic->p[U_PLANE].i_pitch];
        uint8_t *p_src_v = &p_pic->p[V_PLANE].p_pixels[y * p_pic->p[V_PLANE].i_pitch];
        uint8_t *p_dst_u = &p_outpic->p[U_PLANE].p_pixels[y * p_outpic->p[U_PLANE].i_pitch];
        uint8_t *p_dst_v = &p_outpic->p[V_PLANE].p_pixels[y * p_outpic->p[V_PLANE].i_pitch];

        for( int x = 0; x < p_pic->p[U_PLANE].i_visible_pitch; x++ )
        {
            if( IsSimilar( *p_src_u - 0x80, *p_src_v - 0x80,
                           refu, refv, reflength,
                           i_satthres, i_simthres ) )

            {
                *p_dst_u++ = *p_src_u;
                *p_dst_v++ = *p_src_v;
            }
            else
            {
                *p_dst_u++ = 0x80;
                *p_dst_v++ = 0x80;
            }
            p_src_u++;
            p_src_v++;
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #6
0
/*****************************************************************************
 * Filter: displays previously rendered output
 *****************************************************************************
 * This function send the currently rendered image to the internal opencv
 * filter for processing.
 *****************************************************************************/
static picture_t* Filter( filter_t* p_filter, picture_t* p_pic )
{
    picture_t* p_outpic = filter_NewPicture( p_filter );
    if( p_outpic == NULL ) {
        msg_Err( p_filter, "couldn't get a p_outpic!" );
        picture_Release( p_pic );
        return NULL;
    }

    video_format_t fmt_out;

    // Make a copy if we want to show the original input
    if (p_filter->p_sys->i_wrapper_output == VINPUT)
        picture_Copy( p_outpic, p_pic );

    VlcPictureToIplImage( p_filter, p_pic );
    // Pass the image (as a pointer to the first IplImage*) to the
    // internal OpenCV filter for processing.
    p_filter->p_sys->p_opencv->pf_video_filter( p_filter->p_sys->p_opencv, (picture_t*)&(p_filter->p_sys->p_cv_image[0]) );

    if(p_filter->p_sys->i_wrapper_output == PROCESSED) {
        // Processed video
        if( (p_filter->p_sys->p_proc_image) &&
            (p_filter->p_sys->p_proc_image->i_planes > 0) &&
            (p_filter->p_sys->i_internal_chroma != CINPUT) ) {
            //p_filter->p_sys->p_proc_image->format.i_chroma = VLC_CODEC_RGB24;

            memset( &fmt_out, 0, sizeof(video_format_t) );
            fmt_out = p_pic->format;
            //picture_Release( p_outpic );

            /*
             * We have to copy out the image from image_Convert(), otherwise
             * you leak pictures for some reason:
             * main video output error: pictures leaked, trying to workaround
             */
            picture_t* p_outpic_tmp = image_Convert(
                        p_filter->p_sys->p_image,
                        p_filter->p_sys->p_proc_image,
                        &(p_filter->p_sys->p_proc_image->format),
                        &fmt_out );

            picture_CopyPixels( p_outpic, p_outpic_tmp );
            CopyInfoAndRelease( p_outpic, p_outpic_tmp );
        } else if( p_filter->p_sys->i_internal_chroma == CINPUT ) {
            picture_CopyPixels( p_outpic, p_filter->p_sys->p_proc_image );
            picture_CopyProperties( p_outpic, p_filter->p_sys->p_proc_image );
        }
    }

    ReleaseImages( p_filter );
    picture_Release( p_pic );

#ifndef NDEBUG
    msg_Dbg( p_filter, "Filter() done" );
#endif

    if( p_filter->p_sys->i_wrapper_output != NONE ) {
        return p_outpic;
    } else { // NONE
        picture_Release( p_outpic );
        return NULL;
    }
}
コード例 #7
0
ファイル: gaussianblur.c プロジェクト: 0xheart0/vlc
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    picture_t *p_outpic;
    filter_sys_t *p_sys = p_filter->p_sys;
    const int i_dim = p_sys->i_dim;
    type_t *pt_buffer;
    type_t *pt_scale;
    const type_t *pt_distribution = p_sys->pt_distribution;

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }
    if( !p_sys->pt_buffer )
    {
        p_sys->pt_buffer = realloc_or_free( p_sys->pt_buffer,
                               p_pic->p[Y_PLANE].i_visible_lines *
                               p_pic->p[Y_PLANE].i_pitch * sizeof( type_t ) );
    }

    pt_buffer = p_sys->pt_buffer;
    if( !p_sys->pt_scale )
    {
        const int i_visible_lines = p_pic->p[Y_PLANE].i_visible_lines;
        const int i_visible_pitch = p_pic->p[Y_PLANE].i_visible_pitch;
        const int i_pitch = p_pic->p[Y_PLANE].i_pitch;

        p_sys->pt_scale = xmalloc( i_visible_lines * i_pitch * sizeof( type_t ) );
        pt_scale = p_sys->pt_scale;

        for( int i_line = 0; i_line < i_visible_lines; i_line++ )
        {
            for( int i_col = 0; i_col < i_visible_pitch; i_col++ )
            {
                type_t t_value = 0;

                for( int y = __MAX( -i_dim, -i_line );
                     y <= __MIN( i_dim, i_visible_lines - i_line - 1 );
                     y++ )
                {
                    for( int x = __MAX( -i_dim, -i_col );
                         x <= __MIN( i_dim, i_visible_pitch - i_col + 1 );
                         x++ )
                    {
                        t_value += pt_distribution[y+i_dim] *
                                   pt_distribution[x+i_dim];
                    }
                }
                pt_scale[i_line*i_pitch+i_col] = t_value;
            }
        }
    }

    pt_scale = p_sys->pt_scale;
    for( int i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
    {

        uint8_t *p_in = p_pic->p[i_plane].p_pixels;
        uint8_t *p_out = p_outpic->p[i_plane].p_pixels;

        const int i_visible_lines = p_pic->p[i_plane].i_visible_lines;
        const int i_visible_pitch = p_pic->p[i_plane].i_visible_pitch;
        const int i_in_pitch = p_pic->p[i_plane].i_pitch;

        const int x_factor = p_pic->p[Y_PLANE].i_visible_pitch/i_visible_pitch-1;
        const int y_factor = p_pic->p[Y_PLANE].i_visible_lines/i_visible_lines-1;

        for( int i_line = 0; i_line < i_visible_lines; i_line++ )
        {
            for( int i_col = 0; i_col < i_visible_pitch; i_col++ )
            {
                type_t t_value = 0;
                const int c = i_line*i_in_pitch+i_col;
                for( int x = __MAX( -i_dim, -i_col*(x_factor+1) );
                     x <= __MIN( i_dim, (i_visible_pitch - i_col)*(x_factor+1) + 1 );
                     x++ )
                {
                    t_value += pt_distribution[x+i_dim] *
                               p_in[c+(x>>x_factor)];
                }
                pt_buffer[c] = t_value;
            }
        }
        for( int i_line = 0; i_line < i_visible_lines; i_line++ )
        {
            for( int i_col = 0; i_col < i_visible_pitch; i_col++ )
            {
                type_t t_value = 0;
                const int c = i_line*i_in_pitch+i_col;
                for( int y = __MAX( -i_dim, (-i_line)*(y_factor+1) );
                     y <= __MIN( i_dim, (i_visible_lines - i_line)*(y_factor+1) - 1 );
                     y++ )
                {
                    t_value += pt_distribution[y+i_dim] *
                               pt_buffer[c+(y>>y_factor)*i_in_pitch];
                }

                const type_t t_scale = pt_scale[(i_line<<y_factor)*(i_in_pitch<<x_factor)+(i_col<<x_factor)];
                p_out[i_line * p_outpic->p[i_plane].i_pitch + i_col] = (uint8_t)(t_value / t_scale); // FIXME wouldn't it be better to round instead of trunc ?
            }
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #8
0
ファイル: croppadd.c プロジェクト: qdk0901/vlc
/****************************************************************************
 * Filter: the whole thing
 ****************************************************************************/
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    picture_t *p_outpic;
    int i_width, i_height, i_xcrop, i_ycrop,
        i_outwidth, i_outheight, i_xpadd, i_ypadd;

    const int p_padd_color[] = { 0x00, 0x80, 0x80, 0xff };

    if( !p_pic ) return NULL;

    /* Request output picture */
    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    for( int i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
    /* p_pic and p_outpic have the same chroma/number of planes but that's
     * about it. */
    {
        plane_t *p_plane = p_pic->p+i_plane;
        plane_t *p_outplane = p_outpic->p+i_plane;
        uint8_t *p_in = p_plane->p_pixels;
        uint8_t *p_out = p_outplane->p_pixels;
        int i_pixel_pitch = p_plane->i_pixel_pitch;
        int i_padd_color = i_plane > 3 ? p_padd_color[0]
                                       : p_padd_color[i_plane];

        /* These assignments assume that the first plane always has
         * a width and height equal to the picture's */
        i_width =     ( ( p_filter->fmt_in.video.i_visible_width
                          - p_sys->i_cropleft - p_sys->i_cropright )
                        * p_plane->i_visible_pitch )
                      / p_pic->p->i_visible_pitch;
        i_height =    ( ( p_filter->fmt_in.video.i_visible_height
                          - p_sys->i_croptop - p_sys->i_cropbottom )
                        * p_plane->i_visible_lines )
                      / p_pic->p->i_visible_lines;
        i_xcrop =     ( p_sys->i_cropleft * p_plane->i_visible_pitch)
                      / p_pic->p->i_visible_pitch;
        i_ycrop =     ( p_sys->i_croptop * p_plane->i_visible_lines)
                      / p_pic->p->i_visible_lines;
        i_outwidth =  ( p_filter->fmt_out.video.i_visible_width
                        * p_outplane->i_visible_pitch )
                      / p_outpic->p->i_visible_pitch;
        i_outheight = ( p_filter->fmt_out.video.i_visible_height
                        * p_outplane->i_visible_lines )
                      / p_outpic->p->i_visible_lines;
        i_xpadd =     ( p_sys->i_paddleft * p_outplane->i_visible_pitch )
                      / p_outpic->p->i_visible_pitch;
        i_ypadd =     ( p_sys->i_paddtop * p_outplane->i_visible_lines )
                       / p_outpic->p->i_visible_lines;

        /* Crop the top */
        p_in += i_ycrop * p_plane->i_pitch;

        /* Padd on the top */
        memset( p_out, i_padd_color, i_ypadd * p_outplane->i_pitch );
        p_out += i_ypadd * p_outplane->i_pitch;

        for( int i_line = 0; i_line < i_height; i_line++ )
        {
            uint8_t *p_in_next = p_in + p_plane->i_pitch;
            uint8_t *p_out_next = p_out + p_outplane->i_pitch;

            /* Crop on the left */
            p_in += i_xcrop * i_pixel_pitch;

            /* Padd on the left */
            memset( p_out, i_padd_color, i_xpadd * i_pixel_pitch );
            p_out += i_xpadd * i_pixel_pitch;

            /* Copy the image and crop on the right */
            memcpy( p_out, p_in, i_width * i_pixel_pitch );
            p_out += i_width * i_pixel_pitch;
            p_in += i_width * i_pixel_pitch;

            /* Padd on the right */
            memset( p_out, i_padd_color,
                        ( i_outwidth - i_xpadd - i_width ) * i_pixel_pitch );

            /* Got to begining of the next line */
            p_in = p_in_next;
            p_out = p_out_next;
        }

        /* Padd on the bottom */
        memset( p_out, i_padd_color,
                 ( i_outheight - i_ypadd - i_height ) * p_outplane->i_pitch );
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #9
0
ファイル: adjust.c プロジェクト: 371816210/vlc_vlc
/*****************************************************************************
 * Run the filter on a Packed YUV picture
 *****************************************************************************/
static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_pic )
{
    int pi_luma[256];
    int pi_gamma[256];

    picture_t *p_outpic;
    uint8_t *p_in, *p_in_end, *p_line_end;
    uint8_t *p_out;
    int i_y_offset, i_u_offset, i_v_offset;

    int i_pitch, i_visible_pitch;

    bool b_thres;
    double  f_hue;
    double  f_gamma;
    int32_t i_cont, i_lum;
    int i_sat, i_sin, i_cos, i_x, i_y;
    int i;

    filter_sys_t *p_sys = p_filter->p_sys;

    if( !p_pic ) return NULL;

    i_pitch = p_pic->p->i_pitch;
    i_visible_pitch = p_pic->p->i_visible_pitch;

    if( GetPackedYuvOffsets( p_pic->format.i_chroma, &i_y_offset,
                             &i_u_offset, &i_v_offset ) != VLC_SUCCESS )
    {
        msg_Warn( p_filter, "Unsupported input chroma (%4.4s)",
                  (char*)&(p_pic->format.i_chroma) );

        picture_Release( p_pic );
        return NULL;
    }

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        msg_Warn( p_filter, "can't get output picture" );

        picture_Release( p_pic );
        return NULL;
    }

    /* Get variables */
    vlc_mutex_lock( &p_sys->lock );
    i_cont = (int)( p_sys->f_contrast * 255 );
    i_lum = (int)( (p_sys->f_brightness - 1.0)*255 );
    f_hue = (float)( p_sys->i_hue * M_PI / 180 );
    i_sat = (int)( p_sys->f_saturation * 256 );
    f_gamma = 1.0 / p_sys->f_gamma;
    b_thres = p_sys->b_brightness_threshold;
    vlc_mutex_unlock( &p_sys->lock );

    /*
     * Threshold mode drops out everything about luma, contrast and gamma.
     */
    if( !b_thres )
    {

        /* Contrast is a fast but kludged function, so I put this gap to be
         * cleaner :) */
        i_lum += 128 - i_cont / 2;

        /* Fill the gamma lookup table */
        for( i = 0 ; i < 256 ; i++ )
        {
          pi_gamma[ i ] = clip_uint8_vlc( pow(i / 255.0, f_gamma) * 255.0);
        }

        /* Fill the luma lookup table */
        for( i = 0 ; i < 256 ; i++ )
        {
            pi_luma[ i ] = pi_gamma[clip_uint8_vlc( i_lum + i_cont * i / 256)];
        }
    }
    else
    {
        /*
         * We get luma as threshold value: the higher it is, the darker is
         * the image. Should I reverse this?
         */
        for( i = 0 ; i < 256 ; i++ )
        {
            pi_luma[ i ] = (i < i_lum) ? 0 : 255;
        }

        /*
         * Desaturates image to avoid that strange yellow halo...
         */
        i_sat = 0;
    }

    /*
     * Do the Y plane
     */

    p_in = p_pic->p->p_pixels + i_y_offset;
    p_in_end = p_in + p_pic->p->i_visible_lines * p_pic->p->i_pitch - 8 * 4;

    p_out = p_outpic->p->p_pixels + i_y_offset;

    for( ; p_in < p_in_end ; )
    {
        p_line_end = p_in + i_visible_pitch - 8 * 4;

        for( ; p_in < p_line_end ; )
        {
            /* Do 8 pixels at a time */
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
        }

        p_line_end += 8 * 4;

        for( ; p_in < p_line_end ; )
        {
            *p_out = pi_luma[ *p_in ]; p_in += 2; p_out += 2;
        }

        p_in += i_pitch - p_pic->p->i_visible_pitch;
        p_out += i_pitch - p_outpic->p->i_visible_pitch;
    }

    /*
     * Do the U and V planes
     */

    i_sin = sin(f_hue) * 256;
    i_cos = cos(f_hue) * 256;

    i_x = ( cos(f_hue) + sin(f_hue) ) * 32768;
    i_y = ( cos(f_hue) - sin(f_hue) ) * 32768;

    if ( i_sat > 256 )
    {
        if ( p_sys->pf_process_sat_hue_clip( p_pic, p_outpic, i_sin, i_cos, i_sat,
                                             i_x, i_y ) != VLC_SUCCESS )
        {
            /* Currently only one error can happen in the function, but if there
             * will be more of them, this message must go away */
            msg_Warn( p_filter, "Unsupported input chroma (%4.4s)",
                      (char*)&(p_pic->format.i_chroma) );
            picture_Release( p_pic );
            return NULL;
        }
    }
    else
    {
        if ( p_sys->pf_process_sat_hue( p_pic, p_outpic, i_sin, i_cos, i_sat,
                                        i_x, i_y ) != VLC_SUCCESS )
        {
            /* Currently only one error can happen in the function, but if there
             * will be more of them, this message must go away */
            msg_Warn( p_filter, "Unsupported input chroma (%4.4s)",
                      (char*)&(p_pic->format.i_chroma) );
            picture_Release( p_pic );
            return NULL;
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #10
0
ファイル: adjust.c プロジェクト: 371816210/vlc_vlc
/*****************************************************************************
 * Run the filter on a Planar YUV picture
 *****************************************************************************/
static picture_t *FilterPlanar( filter_t *p_filter, picture_t *p_pic )
{
    int pi_luma[256];
    int pi_gamma[256];

    picture_t *p_outpic;
    uint8_t *p_in, *p_in_end, *p_line_end;
    uint8_t *p_out;

    bool b_thres;
    double  f_hue;
    double  f_gamma;
    int32_t i_cont, i_lum;
    int i_sat, i_sin, i_cos, i_x, i_y;
    int i;

    filter_sys_t *p_sys = p_filter->p_sys;

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* Get variables */
    vlc_mutex_lock( &p_sys->lock );
    i_cont = (int)( p_sys->f_contrast * 255 );
    i_lum = (int)( (p_sys->f_brightness - 1.0)*255 );
    f_hue = (float)( p_sys->i_hue * M_PI / 180 );
    i_sat = (int)( p_sys->f_saturation * 256 );
    f_gamma = 1.0 / p_sys->f_gamma;
    b_thres = p_sys->b_brightness_threshold;
    vlc_mutex_unlock( &p_sys->lock );

    /*
     * Threshold mode drops out everything about luma, contrast and gamma.
     */
    if( !b_thres )
    {

        /* Contrast is a fast but kludged function, so I put this gap to be
         * cleaner :) */
        i_lum += 128 - i_cont / 2;

        /* Fill the gamma lookup table */
        for( i = 0 ; i < 256 ; i++ )
        {
            pi_gamma[ i ] = clip_uint8_vlc( pow(i / 255.0, f_gamma) * 255.0);
        }

        /* Fill the luma lookup table */
        for( i = 0 ; i < 256 ; i++ )
        {
            pi_luma[ i ] = pi_gamma[clip_uint8_vlc( i_lum + i_cont * i / 256)];
        }
    }
    else
    {
        /*
         * We get luma as threshold value: the higher it is, the darker is
         * the image. Should I reverse this?
         */
        for( i = 0 ; i < 256 ; i++ )
        {
            pi_luma[ i ] = (i < i_lum) ? 0 : 255;
        }

        /*
         * Desaturates image to avoid that strange yellow halo...
         */
        i_sat = 0;
    }

    /*
     * Do the Y plane
     */

    p_in = p_pic->p[Y_PLANE].p_pixels;
    p_in_end = p_in + p_pic->p[Y_PLANE].i_visible_lines
                      * p_pic->p[Y_PLANE].i_pitch - 8;

    p_out = p_outpic->p[Y_PLANE].p_pixels;

    for( ; p_in < p_in_end ; )
    {
        p_line_end = p_in + p_pic->p[Y_PLANE].i_visible_pitch - 8;

        for( ; p_in < p_line_end ; )
        {
            /* Do 8 pixels at a time */
            *p_out++ = pi_luma[ *p_in++ ]; *p_out++ = pi_luma[ *p_in++ ];
            *p_out++ = pi_luma[ *p_in++ ]; *p_out++ = pi_luma[ *p_in++ ];
            *p_out++ = pi_luma[ *p_in++ ]; *p_out++ = pi_luma[ *p_in++ ];
            *p_out++ = pi_luma[ *p_in++ ]; *p_out++ = pi_luma[ *p_in++ ];
        }

        p_line_end += 8;

        for( ; p_in < p_line_end ; )
        {
            *p_out++ = pi_luma[ *p_in++ ];
        }

        p_in += p_pic->p[Y_PLANE].i_pitch
              - p_pic->p[Y_PLANE].i_visible_pitch;
        p_out += p_outpic->p[Y_PLANE].i_pitch
               - p_outpic->p[Y_PLANE].i_visible_pitch;
    }

    /*
     * Do the U and V planes
     */

    i_sin = sin(f_hue) * 256;
    i_cos = cos(f_hue) * 256;

    i_x = ( cos(f_hue) + sin(f_hue) ) * 32768;
    i_y = ( cos(f_hue) - sin(f_hue) ) * 32768;

    if ( i_sat > 256 )
    {
        /* Currently no errors are implemented in the function, if any are added
         * check them here */
        p_sys->pf_process_sat_hue_clip( p_pic, p_outpic, i_sin, i_cos, i_sat,
                                        i_x, i_y );
    }
    else
    {
        /* Currently no errors are implemented in the function, if any are added
         * check them here */
        p_sys->pf_process_sat_hue( p_pic, p_outpic, i_sin, i_cos, i_sat,
                                        i_x, i_y );
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #11
0
ファイル: colorthres.c プロジェクト: 0xheart0/vlc
static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_pic )
{
    picture_t *p_outpic;
    filter_sys_t *p_sys = p_filter->p_sys;
    int i_simthres = atomic_load( &p_sys->i_simthres );
    int i_satthres = atomic_load( &p_sys->i_satthres );
    int i_color = atomic_load( &p_sys->i_color );

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    int i_y_offset, i_u_offset, i_v_offset;
    int i_ret = GetPackedYuvOffsets( p_filter->fmt_in.video.i_chroma,
                                     &i_y_offset, &i_u_offset, &i_v_offset );
    if( i_ret == VLC_EGENERIC )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /*
     * Copy Y and do the U and V planes
     */
    int refu, refv, reflength;
    GetReference( &refu, &refv, &reflength, i_color );

    for( int y = 0; y < p_pic->p->i_visible_lines; y++ )
    {
        uint8_t *p_src = &p_pic->p->p_pixels[y * p_pic->p->i_pitch];
        uint8_t *p_dst = &p_outpic->p->p_pixels[y * p_outpic->p->i_pitch];

        for( int x = 0; x < p_pic->p->i_visible_pitch / 4; x++ )
        {
            p_dst[i_y_offset + 0] = p_src[i_y_offset + 0];
            p_dst[i_y_offset + 2] = p_src[i_y_offset + 2];

            if( IsSimilar( p_src[i_u_offset] - 0x80, p_src[i_v_offset] - 0x80,
                           refu, refv, reflength,
                           i_satthres, i_simthres ) )
            {
                p_dst[i_u_offset] = p_src[i_u_offset];
                p_dst[i_v_offset] = p_src[i_v_offset];
            }
            else
            {
                p_dst[i_u_offset] = 0x80;
                p_dst[i_v_offset] = 0x80;
            }

            p_dst += 4;
            p_src += 4;
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #12
0
ファイル: psychedelic.c プロジェクト: FLYKingdom/vlc
/*****************************************************************************
 * 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;

    unsigned int w, h;
    int x,y;
    uint8_t u,v;

    picture_t *p_converted;
    video_format_t fmt_out;
    memset( &fmt_out, 0, sizeof(video_format_t) );
    fmt_out.p_palette = NULL;

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    if( !p_filter->p_sys->p_image )
        p_filter->p_sys->p_image = image_HandlerCreate( p_filter );

    /* chrominance */
    u = p_filter->p_sys->u;
    v = p_filter->p_sys->v;
    for( y = 0; y<p_outpic->p[U_PLANE].i_lines; y++)
    {
        vlc_memset(
                p_outpic->p[U_PLANE].p_pixels+y*p_outpic->p[U_PLANE].i_pitch,
                u, p_outpic->p[U_PLANE].i_pitch );
        vlc_memset(
                p_outpic->p[V_PLANE].p_pixels+y*p_outpic->p[V_PLANE].i_pitch,
                v, p_outpic->p[V_PLANE].i_pitch );
        if( v == 0 && u != 0 )
            u --;
        else if( u == 0xff )
            v --;
        else if( v == 0xff )
            u ++;
        else if( u == 0 )
            v ++;
    }

    /* luminance */
    vlc_memcpy( p_outpic->p[Y_PLANE].p_pixels, p_pic->p[Y_PLANE].p_pixels,
                p_outpic->p[Y_PLANE].i_lines * p_outpic->p[Y_PLANE].i_pitch );

    /* image visualization */
    fmt_out = p_filter->fmt_out.video;
    fmt_out.i_width = p_filter->fmt_out.video.i_width*p_filter->p_sys->scale/150;
    fmt_out.i_height = p_filter->fmt_out.video.i_height*p_filter->p_sys->scale/150;
    p_converted = image_Convert( p_filter->p_sys->p_image, p_pic,
                                 &(p_pic->format), &fmt_out );

    if( p_converted )
    {
#define copyimage( plane, b ) \
        for( y=0; y<p_converted->p[plane].i_visible_lines; y++) { \
        for( x=0; x<p_converted->p[plane].i_visible_pitch; x++) { \
            int nx, ny; \
            if( p_filter->p_sys->yinc == 1 ) \
                ny= y; \
            else \
                ny = p_converted->p[plane].i_visible_lines-y; \
            if( p_filter->p_sys->xinc == 1 ) \
                nx = x; \
            else \
                nx = p_converted->p[plane].i_visible_pitch-x; \
            p_outpic->p[plane].p_pixels[(p_filter->p_sys->x*b+nx)+(ny+p_filter->p_sys->y*b)*p_outpic->p[plane].i_pitch ] = p_converted->p[plane].p_pixels[y*p_converted->p[plane].i_pitch+x]; \
        } }
        copyimage( Y_PLANE, 2 );
        copyimage( U_PLANE, 1 );
        copyimage( V_PLANE, 1 );
#undef copyimage

        picture_Release( p_converted );
    }
    else
    {
        msg_Err( p_filter, "Image scaling failed miserably." );
    }

    p_filter->p_sys->x += p_filter->p_sys->xinc;
    p_filter->p_sys->y += p_filter->p_sys->yinc;

    p_filter->p_sys->scale += p_filter->p_sys->scaleinc;
    if( p_filter->p_sys->scale >= 50 ) p_filter->p_sys->scaleinc = -1;
    if( p_filter->p_sys->scale <= 1 ) p_filter->p_sys->scaleinc = 1;

    w = p_filter->fmt_out.video.i_width*p_filter->p_sys->scale/150;
    h = p_filter->fmt_out.video.i_height*p_filter->p_sys->scale/150;
    if( p_filter->p_sys->x*2 + w >= p_filter->fmt_out.video.i_width )
        p_filter->p_sys->xinc = -1;
    if( p_filter->p_sys->x <= 0 )
        p_filter->p_sys->xinc = 1;

    if( p_filter->p_sys->x*2 + w >= p_filter->fmt_out.video.i_width )
        p_filter->p_sys->x = (p_filter->fmt_out.video.i_width-w)/2;
    if( p_filter->p_sys->y*2 + h >= p_filter->fmt_out.video.i_height )
        p_filter->p_sys->y = (p_filter->fmt_out.video.i_height-h)/2;

    if( p_filter->p_sys->y*2 + h >= p_filter->fmt_out.video.i_height )
        p_filter->p_sys->yinc = -1;
    if( p_filter->p_sys->y <= 0 )
        p_filter->p_sys->yinc = 1;

    for( y = 0; y< 16; y++ )
    {
        if( p_filter->p_sys->v == 0 && p_filter->p_sys->u != 0 )
            p_filter->p_sys->u -= 1;
        else if( p_filter->p_sys->u == 0xff )
            p_filter->p_sys->v -= 1;
        else if( p_filter->p_sys->v == 0xff )
            p_filter->p_sys->u += 1;
        else if( p_filter->p_sys->u == 0 )
            p_filter->p_sys->v += 1;
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #13
0
ファイル: invert.c プロジェクト: 0xheart0/vlc
/*****************************************************************************
 * Render: displays previously rendered output
 *****************************************************************************
 * This function send the currently rendered image to Invert 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;
    int i_planes;

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        msg_Warn( p_filter, "can't get output picture" );
        picture_Release( p_pic );
        return NULL;
    }

    if( p_pic->format.i_chroma == VLC_CODEC_YUVA )
    {
        /* We don't want to invert the alpha plane */
        i_planes = p_pic->i_planes - 1;
        memcpy(
            p_outpic->p[A_PLANE].p_pixels, p_pic->p[A_PLANE].p_pixels,
            p_pic->p[A_PLANE].i_pitch *  p_pic->p[A_PLANE].i_lines );
    }
    else
    {
        i_planes = p_pic->i_planes;
    }

    for( int i_index = 0 ; i_index < i_planes ; i_index++ )
    {
        uint8_t *p_in, *p_in_end, *p_line_end, *p_out;

        p_in = p_pic->p[i_index].p_pixels;
        p_in_end = p_in + p_pic->p[i_index].i_visible_lines
                           * p_pic->p[i_index].i_pitch;

        p_out = p_outpic->p[i_index].p_pixels;

        while( p_in < p_in_end )
        {
            uint64_t *p_in64, *p_out64;

            p_line_end = p_in + p_pic->p[i_index].i_visible_pitch - 64;

            p_in64 = (uint64_t*)p_in;
            p_out64 = (uint64_t*)p_out;

            while( p_in64 < (uint64_t *)p_line_end )
            {
                /* Do 64 pixels at a time */
                *p_out64++ = ~*p_in64++; *p_out64++ = ~*p_in64++;
                *p_out64++ = ~*p_in64++; *p_out64++ = ~*p_in64++;
                *p_out64++ = ~*p_in64++; *p_out64++ = ~*p_in64++;
                *p_out64++ = ~*p_in64++; *p_out64++ = ~*p_in64++;
            }

            p_in = (uint8_t*)p_in64;
            p_out = (uint8_t*)p_out64;
            p_line_end += 64;

            while( p_in < p_line_end )
            {
                *p_out++ = ~( *p_in++ );
            }

            p_in += p_pic->p[i_index].i_pitch
                     - p_pic->p[i_index].i_visible_pitch;
            p_out += p_outpic->p[i_index].i_pitch
                     - p_outpic->p[i_index].i_visible_pitch;
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #14
0
ファイル: puzzle.c プロジェクト: qdk0901/vlc
/**
 * Filter a picture
 */
picture_t *Filter( filter_t *p_filter, picture_t *p_pic_in ) {
    if( !p_pic_in || !p_filter) return NULL;

    const video_format_t  *p_fmt_in = &p_filter->fmt_in.video;
    filter_sys_t *p_sys = p_filter->p_sys;

    picture_t *p_pic_out = filter_NewPicture( p_filter );
    if( !p_pic_out ) {
        picture_Release( p_pic_in );
        return NULL;
    }

    int i_ret = 0;
    p_sys->b_bake_request = false;

    if ((p_sys->pi_order == NULL) || (p_sys->ps_desk_planes == NULL) || (p_sys->ps_pict_planes == NULL)  || (p_sys->ps_puzzle_array == NULL) || (p_sys->ps_pieces == NULL))
        p_sys->b_init = false;

    if ((p_sys->ps_pieces_shapes == NULL) && p_sys->s_current_param.b_advanced && (p_sys->s_current_param.i_shape_size != 0))
        p_sys->b_init = false;

    /* assert initialized & allocated data match with current frame characteristics */
    if ( p_sys->s_allocated.i_planes != p_pic_out->i_planes)
        p_sys->b_init = false;
    p_sys->s_current_param.i_planes = p_pic_out->i_planes;
    if (p_sys->ps_pict_planes != NULL) {
        for (uint8_t i_plane = 0; i_plane < p_sys->s_allocated.i_planes; i_plane++) {
            if ( (p_sys->ps_pict_planes[i_plane].i_lines != p_pic_in->p[i_plane].i_visible_lines)
                    || (p_sys->ps_pict_planes[i_plane].i_width != p_pic_in->p[i_plane].i_visible_pitch / p_pic_in->p[i_plane].i_pixel_pitch)
                    || (p_sys->ps_desk_planes[i_plane].i_lines != p_pic_out->p[i_plane].i_visible_lines)
                    || (p_sys->ps_desk_planes[i_plane].i_width != p_pic_out->p[i_plane].i_visible_pitch / p_pic_out->p[i_plane].i_pixel_pitch) )
                p_sys->b_init = false;
        }
    }

    p_sys->s_current_param.i_pict_width  = (int) p_pic_in->p[0].i_visible_pitch / p_pic_in->p[0].i_pixel_pitch;
    p_sys->s_current_param.i_pict_height = (int) p_pic_in->p[0].i_visible_lines;
    p_sys->s_current_param.i_desk_width  = (int) p_pic_out->p[0].i_visible_pitch / p_pic_out->p[0].i_pixel_pitch;
    p_sys->s_current_param.i_desk_height = (int) p_pic_out->p[0].i_visible_lines;

    /* assert no mismatch between sizes */
    if (    p_sys->s_current_param.i_pict_width  != p_sys->s_current_param.i_desk_width
         || p_sys->s_current_param.i_pict_height != p_sys->s_current_param.i_desk_height
         || p_sys->s_current_param.i_pict_width  != (int) p_fmt_in->i_visible_width
         || p_sys->s_current_param.i_pict_height != (int) p_fmt_in->i_visible_height ) {
        picture_Release(p_pic_in);
        picture_Release(p_pic_out);
        return NULL;
    }

    vlc_mutex_lock( &p_sys->lock );

    /* check if we have to compute initial data */
    if ( p_sys->b_change_param || p_sys->b_bake_request || !p_sys->b_init ) {
        if ( p_sys->s_allocated.i_rows != p_sys->s_new_param.i_rows
                || p_sys->s_allocated.i_cols != p_sys->s_new_param.i_cols
                || p_sys->s_allocated.i_rotate != p_sys->s_new_param.i_rotate
                || p_sys->s_allocated.i_mode != p_sys->s_new_param.i_mode
                || p_sys->b_bake_request  || !p_sys->b_init )
        {
            p_sys->b_bake_request = true;
            p_sys->b_init = false;
            p_sys->b_shuffle_rqst = true;
            p_sys->b_shape_init = false;
        }

        if ( p_sys->s_current_param.i_border != p_sys->s_new_param.i_border
                || p_sys->s_current_param.i_shape_size != p_sys->s_new_param.i_shape_size )
        {
            p_sys->b_bake_request = true;
            p_sys->b_shape_init = false;
        }

        /* depending on the game selected, set associated internal flags */
        switch ( p_sys->s_new_param.i_mode )
        {
          case 0:  /* jigsaw puzzle */
            p_sys->s_new_param.b_advanced    = true;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = false;
            break;
          case 1:  /* sliding puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = true;
            p_sys->s_new_param.b_near        = true;
            break;
          case 2:  /* swap puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = true;
            break;
          case 3:  /* exchange puzzle */
            p_sys->s_new_param.b_advanced    = false;
            p_sys->s_new_param.b_blackslot   = false;
            p_sys->s_new_param.b_near        = false;
            break;
        }
        p_sys->s_current_param.i_mode = p_sys->s_new_param.i_mode;

        if ( p_sys->s_current_param.b_blackslot != p_sys->s_new_param.b_blackslot
                && p_sys->i_selected == NO_PCE
                && p_sys->s_current_param.b_blackslot )
            p_sys->i_selected = 0;

        if ( p_sys->s_current_param.i_auto_shuffle_speed != p_sys->s_new_param.i_auto_shuffle_speed )
            p_sys->i_auto_shuffle_countdown_val = init_countdown(p_sys->s_new_param.i_auto_shuffle_speed);

        if ( p_sys->s_current_param.i_auto_solve_speed != p_sys->s_new_param.i_auto_solve_speed )
            p_sys->i_auto_solve_countdown_val = init_countdown(p_sys->s_current_param.i_auto_solve_speed);

        p_sys->s_current_param.i_rows       = p_sys->s_new_param.i_rows;
        p_sys->s_current_param.i_cols       = p_sys->s_new_param.i_cols;
        p_sys->s_current_param.i_pieces_nbr = p_sys->s_current_param.i_rows * p_sys->s_current_param.i_cols;
        p_sys->s_current_param.b_advanced   = p_sys->s_new_param.b_advanced;
        if (!p_sys->s_new_param.b_advanced) {
            p_sys->s_current_param.b_blackslot   = p_sys->s_new_param.b_blackslot;
            p_sys->s_current_param.b_near        = p_sys->s_new_param.b_near || p_sys->s_new_param.b_blackslot;
            p_sys->s_current_param.i_border      = 0;
            p_sys->s_current_param.b_preview     = false;
            p_sys->s_current_param.i_preview_size= 0;
            p_sys->s_current_param.i_shape_size  = 0;
            p_sys->s_current_param.i_auto_shuffle_speed  = 0;
            p_sys->s_current_param.i_auto_solve_speed    = 0;
            p_sys->s_current_param.i_rotate      = 0;
        }
        else
        {
            p_sys->s_current_param.b_blackslot = false;
            p_sys->s_current_param.b_near      = false;
            p_sys->s_current_param.i_border    = p_sys->s_new_param.i_border;
            p_sys->s_current_param.b_preview   = p_sys->s_new_param.b_preview;
            p_sys->s_current_param.i_preview_size        = p_sys->s_new_param.i_preview_size;
            p_sys->s_current_param.i_shape_size          = p_sys->s_new_param.i_shape_size;
            p_sys->s_current_param.i_auto_shuffle_speed  = p_sys->s_new_param.i_auto_shuffle_speed;
            p_sys->s_current_param.i_auto_solve_speed    = p_sys->s_new_param.i_auto_solve_speed;
            p_sys->s_current_param.i_rotate     = p_sys->s_new_param.i_rotate;
        }
        p_sys->b_change_param = false;
    }

    vlc_mutex_unlock( &p_sys->lock );

    /* generate initial puzzle data when needed */
    if ( p_sys->b_bake_request ) {
        if (!p_sys->b_shuffle_rqst) {
            /* here we have to keep the same position
             * we have to save locations before generating new data
             */
            save_game_t *ps_save_game = puzzle_save(p_filter);
            if (!ps_save_game)
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
            i_ret = puzzle_bake( p_filter, p_pic_out, p_pic_in );
            if ( i_ret != VLC_SUCCESS )
            {
                free(ps_save_game->ps_pieces);
                free(ps_save_game);
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
            }
            puzzle_load( p_filter, ps_save_game);
            free(ps_save_game->ps_pieces);
            free(ps_save_game);
        }
        else {
            i_ret = puzzle_bake( p_filter, p_pic_out, p_pic_in );
            if ( i_ret != VLC_SUCCESS )
                return CopyInfoAndRelease( p_pic_out, p_pic_in );
        }
    }

    /* shuffle the desk and generate pieces data  */
    if ( p_sys->b_shuffle_rqst && p_sys->b_init ) {
        i_ret = puzzle_bake_piece ( p_filter );
        if (i_ret != VLC_SUCCESS)
            return CopyInfoAndRelease( p_pic_out, p_pic_in );
    }

    /* preset output pic */
    if ( !p_sys->b_bake_request && !p_sys->b_shuffle_rqst && p_sys->b_init && !p_sys->b_finished )
        puzzle_preset_desk_background(p_pic_out, 0, 127, 127);
    else {
        /* copy src to dst during init & bake process */
        for( uint8_t i_plane = 0; i_plane < p_pic_out->i_planes; i_plane++ )
            memcpy( p_pic_out->p[i_plane].p_pixels, p_pic_in->p[i_plane].p_pixels,
                p_pic_in->p[i_plane].i_pitch * (int32_t) p_pic_in->p[i_plane].i_visible_lines );
    }

    vlc_mutex_lock( &p_sys->pce_lock );

    /* manage the game, adjust locations, groups and regenerate some corrupted data if any */
    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 4 )
                             && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                             && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        puzzle_solve_pces_accuracy( p_filter );
    }

    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 4 )
                             && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                             && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        puzzle_solve_pces_group( p_filter );
    }

    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
            && p_sys->s_current_param.b_advanced )
        puzzle_count_pce_group( p_filter);
    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
            && p_sys->s_current_param.b_advanced ) {
        i_ret = puzzle_sort_layers( p_filter);
        if (i_ret != VLC_SUCCESS)
        {
            vlc_mutex_unlock( &p_sys->pce_lock );
            return CopyInfoAndRelease( p_pic_out, p_pic_in );
        }
    }

    for (uint32_t i = 0; i < __MAX( 4, p_sys->s_allocated.i_pieces_nbr / 24 )
                            && ( !p_sys->b_bake_request && !p_sys->b_mouse_drag
                            && p_sys->b_init && p_sys->s_current_param.b_advanced ); i++)
    {
        p_sys->i_calc_corn_loop++;
        p_sys->i_calc_corn_loop %= p_sys->s_allocated.i_pieces_nbr;
        puzzle_calculate_corners( p_filter, p_sys->i_calc_corn_loop );
    }

    /* computer moves some piece depending on auto_solve and auto_shuffle param */
    if ( !p_sys->b_bake_request && !p_sys->b_mouse_drag && p_sys->b_init
             && p_sys->ps_puzzle_array != NULL && p_sys->s_current_param.b_advanced )
    {
        puzzle_auto_shuffle( p_filter );
        puzzle_auto_solve( p_filter );
    }

    vlc_mutex_unlock( &p_sys->pce_lock );

    /* draw output pic */
    if ( !p_sys->b_bake_request && p_sys->b_init  && p_sys->ps_puzzle_array != NULL ) {

        puzzle_draw_borders(p_filter, p_pic_in, p_pic_out);

        p_sys->i_pointed_pce = NO_PCE;
        puzzle_draw_pieces(p_filter, p_pic_in, p_pic_out);

        /* when puzzle_draw_pieces() has not updated p_sys->i_pointed_pce,
         * use puzzle_find_piece to define the piece pointed by the mouse
         */
        if (p_sys->i_pointed_pce == NO_PCE)
            p_sys->i_mouse_drag_pce = puzzle_find_piece( p_filter, p_sys->i_mouse_x, p_sys->i_mouse_y, -1);
        else
            p_sys->i_mouse_drag_pce = p_sys->i_pointed_pce;

        if (p_sys->s_current_param.b_preview )
            puzzle_draw_preview(p_filter, p_pic_in, p_pic_out);

        /* highlight the selected piece when not playing jigsaw mode */
        if ( p_sys->i_selected != NO_PCE && !p_sys->s_current_param.b_blackslot
                && !p_sys->s_current_param.b_advanced )
        {
            int32_t c = (p_sys->i_selected % p_sys->s_allocated.i_cols);
            int32_t r = (p_sys->i_selected / p_sys->s_allocated.i_cols);

            puzzle_draw_rectangle(p_pic_out,
                p_sys->ps_puzzle_array[r][c][0].i_x,
                p_sys->ps_puzzle_array[r][c][0].i_y,
                p_sys->ps_puzzle_array[r][c][0].i_width,
                p_sys->ps_puzzle_array[r][c][0].i_lines,
                255, 127, 127);
        }

        /* draw the blackslot when playing sliding puzzle mode */
        if ( p_sys->i_selected != NO_PCE && p_sys->s_current_param.b_blackslot
                && !p_sys->s_current_param.b_advanced )
        {
            int32_t c = (p_sys->i_selected % p_sys->s_allocated.i_cols);
            int32_t r = (p_sys->i_selected / p_sys->s_allocated.i_cols);

            puzzle_fill_rectangle(p_pic_out,
                p_sys->ps_puzzle_array[r][c][0].i_x,
                p_sys->ps_puzzle_array[r][c][0].i_y,
                p_sys->ps_puzzle_array[r][c][0].i_width,
                p_sys->ps_puzzle_array[r][c][0].i_lines,
                0, 127, 127);
        }

        /* Draw the 'puzzle_shuffle' button if the puzzle is finished */
        if ( p_sys->b_finished )
            puzzle_draw_sign(p_pic_out, 0, 0, SHUFFLE_WIDTH, SHUFFLE_LINES, ppsz_shuffle_button, false);

        /* draw an arrow at mouse pointer to indicate current action (rotation...) */
        if ((p_sys->i_mouse_drag_pce != NO_PCE) && !p_sys->b_mouse_drag
                && !p_sys->b_finished && p_sys->s_current_param.b_advanced )
        {
            vlc_mutex_lock( &p_sys->pce_lock );

            int32_t i_delta_x;

            if (p_sys->s_current_param.i_rotate != 3)
                i_delta_x = 0;
            else if ( (p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_actual_angle & 1) == 0)
                i_delta_x = p_sys->ps_desk_planes[0].i_pce_max_width / 6;
            else
                i_delta_x = p_sys->ps_desk_planes[0].i_pce_max_lines / 6;

            if (p_sys->s_current_param.i_rotate == 0)
                p_sys->i_mouse_action = 0;
            else if (p_sys->s_current_param.i_rotate == 1)
                p_sys->i_mouse_action = 2;
            else if ( p_sys->i_mouse_x >= ( p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_center_x + i_delta_x) )
                p_sys->i_mouse_action = -1;  /* rotate counterclockwise */
            else if ( p_sys->i_mouse_x <= ( p_sys->ps_pieces[p_sys->i_mouse_drag_pce].i_center_x - i_delta_x) )
                p_sys->i_mouse_action = +1;
            else
                p_sys->i_mouse_action = 4;   /* center click: only mirror */

            if ( p_sys->i_mouse_action == +1 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_rot_arrow_sign, false);
            else if ( p_sys->i_mouse_action == -1 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_rot_arrow_sign, true);
            else if ( p_sys->i_mouse_action == 4 )
                puzzle_draw_sign(p_pic_out, p_sys->i_mouse_x - ARROW_WIDTH,
                                 p_sys->i_mouse_y, ARROW_WIDTH, ARROW_LINES, ppsz_mir_arrow_sign, false);

            vlc_mutex_unlock( &p_sys->pce_lock );
        }
    }

    return CopyInfoAndRelease( p_pic_out, p_pic_in );
}
コード例 #15
0
ファイル: puzzle.c プロジェクト: paa/vlc
/**
 * Filter a picture
 */
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    picture_t *p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* */
    vlc_mutex_lock( &p_sys->lock );
    if( p_sys->b_change )
    {
        p_sys->i_rows      = p_sys->change.i_rows;
        p_sys->i_cols      = p_sys->change.i_cols;
        p_sys->b_blackslot = p_sys->change.b_blackslot;
        p_sys->b_change = false;

        Shuffle( p_sys );
    }
    vlc_mutex_unlock( &p_sys->lock );

    /* */
    const int i_rows = p_sys->i_rows;
    const int i_cols = p_sys->i_cols;

    /* Draw each piece of the puzzle at the right place */
    for( int i_plane = 0; i_plane < p_outpic->i_planes; i_plane++ )
    {
        const plane_t *p_in = &p_pic->p[i_plane];
        plane_t *p_out = &p_outpic->p[i_plane];

        for( int i = 0; i < i_cols * i_rows; i++ )
        {
            int i_piece_height = p_out->i_visible_lines / i_rows;
            int i_piece_width  = p_out->i_visible_pitch / i_cols;

            int i_col = (i % i_cols) * i_piece_width;
            int i_row = (i / i_cols) * i_piece_height;
            int i_last_row = i_row + i_piece_height;

            int i_ocol = (p_sys->pi_order[i] % i_cols) * i_piece_width;
            int i_orow = (p_sys->pi_order[i] / i_cols) * i_piece_height;

            if( p_sys->b_blackslot && !p_sys->b_finished && i == p_sys->i_selected )
            {
                uint8_t color = ( i_plane == Y_PLANE ? 0x0 : 0x80 );
                for( int r = i_row; r < i_last_row; r++ )
                {
                    memset( p_out->p_pixels + r * p_out->i_pitch + i_col,
                            color, i_piece_width );
                }
            }
            else
            {
                for( int r = i_row, or = i_orow; r < i_last_row; r++, or++ )
                {
                    memcpy( p_out->p_pixels + r * p_out->i_pitch + i_col,
                            p_in->p_pixels + or * p_in->i_pitch  + i_ocol,
                            i_piece_width );
                }
            }

            /* Draw the borders of the selected slot */
            if( i_plane == 0 && !p_sys->b_blackslot && p_sys->i_selected == i )
            {
                memset( p_out->p_pixels + i_row * p_out->i_pitch + i_col,
                        0xff, i_piece_width );
                for( int r = i_row; r < i_last_row; r++ )
                {
                    p_out->p_pixels[r * p_out->i_pitch + i_col + 0             + 0 ] = 0xff;
                    p_out->p_pixels[r * p_out->i_pitch + i_col + i_piece_width - 1 ] = 0xff;
                }
                memset( p_out->p_pixels + (i_last_row - 1) * p_out->i_pitch + i_col,
                        0xff, i_piece_width );
            }
        }
    }

    /* Draw the 'Shuffle' button if the puzzle is finished */
    if( p_sys->b_finished )
    {
        plane_t *p_out = &p_outpic->p[Y_PLANE];
        for( int i = 0; i < SHUFFLE_HEIGHT; i++ )
        {
            for( int j = 0; j < SHUFFLE_WIDTH; j++ )
            {
                if( shuffle_button[i][j] == '.' )
                   p_out->p_pixels[ i * p_out->i_pitch + j ] = 0xff;
            }
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #16
0
/*****************************************************************************
 * Render: displays previously rendered output
 *****************************************************************************
 * This function send the currently rendered image to Invert 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;
    int i, j;
    uint8_t *p_src = NULL;
    uint8_t *p_out = NULL;
    int i_src_pitch;
    int i_out_pitch;
    int pix;
    const int v1 = -1;
    const int v2 = 3; /* 2^3 = 8 */

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* process the Y plane */
    p_src = p_pic->p[Y_PLANE].p_pixels;
    p_out = p_outpic->p[Y_PLANE].p_pixels;
    i_src_pitch = p_pic->p[Y_PLANE].i_pitch;
    i_out_pitch = p_outpic->p[Y_PLANE].i_pitch;

    /* perform convolution only on Y plane. Avoid border line. */
    vlc_mutex_lock( &p_filter->p_sys->lock );
    for( i = 0; i < p_pic->p[Y_PLANE].i_visible_lines; i++ )
    {
        if( (i == 0) || (i == p_pic->p[Y_PLANE].i_visible_lines - 1) )
        {
            for( j = 0; j < p_pic->p[Y_PLANE].i_visible_pitch; j++ )
                p_out[i * i_out_pitch + j] = clip( p_src[i * i_src_pitch + j] );
            continue ;
        }
        for( j = 0; j < p_pic->p[Y_PLANE].i_visible_pitch; j++ )
        {
            if( (j == 0) || (j == p_pic->p[Y_PLANE].i_visible_pitch - 1) )
            {
                p_out[i * i_out_pitch + j] = p_src[i * i_src_pitch + j];
                continue ;
            }

            pix = (p_src[(i - 1) * i_src_pitch + j - 1] * v1) +
                  (p_src[(i - 1) * i_src_pitch + j    ] * v1) +
                  (p_src[(i - 1) * i_src_pitch + j + 1] * v1) +
                  (p_src[(i    ) * i_src_pitch + j - 1] * v1) +
                  (p_src[(i    ) * i_src_pitch + j    ] << v2) +
                  (p_src[(i    ) * i_src_pitch + j + 1] * v1) +
                  (p_src[(i + 1) * i_src_pitch + j - 1] * v1) +
                  (p_src[(i + 1) * i_src_pitch + j    ] * v1) +
                  (p_src[(i + 1) * i_src_pitch + j + 1] * v1);

           pix = pix >= 0 ? clip(pix) : -clip(pix * -1);
           p_out[i * i_out_pitch + j] = clip( p_src[i * i_src_pitch + j] +
               p_filter->p_sys->tab_precalc[pix + 256] );
        }
    }
    vlc_mutex_unlock( &p_filter->p_sys->lock );

    plane_CopyPixels( &p_outpic->p[U_PLANE], &p_pic->p[U_PLANE] );
    plane_CopyPixels( &p_outpic->p[V_PLANE], &p_pic->p[V_PLANE] );

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #17
0
ファイル: puzzle.c プロジェクト: Kafay/vlc
/**
 * Filter a picture
 */
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    filter_sys_t *p_sys = p_filter->p_sys;

    picture_t *p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    /* */
    vlc_mutex_lock( &p_sys->lock );
    if( p_sys->b_change )
    {
        p_sys->i_rows      = p_sys->change.i_rows;
        p_sys->i_cols      = p_sys->change.i_cols;
        p_sys->b_blackslot = p_sys->change.b_blackslot;
        p_sys->b_change = false;

        Shuffle( p_sys );
    }
    vlc_mutex_unlock( &p_sys->lock );

    /* */
    const int i_rows = p_sys->i_rows;
    const int i_cols = p_sys->i_cols;

    /* */
    for( int i_plane = 0; i_plane < p_outpic->i_planes; i_plane++ )
    {
        const plane_t *p_in = &p_pic->p[i_plane];
        const int i_pitch = p_in->i_pitch;
        plane_t *p_out = &p_outpic->p[i_plane];

        for( int i = 0; i < i_cols * i_rows; i++ )
        {
            int i_col = i % i_cols;
            int i_row = i / i_cols;
            int i_ocol = p_sys->pi_order[i] % i_cols;
            int i_orow = p_sys->pi_order[i] / i_cols;
            int i_last_row = i_row + 1;
            i_orow *= p_in->i_lines / i_rows;
            i_row *= p_in->i_lines / i_rows;
            i_last_row *= p_in->i_lines / i_rows;

            if( p_sys->b_blackslot && p_sys->b_finished && i == p_sys->i_selected )
            {
                uint8_t color = ( i_plane == Y_PLANE ? 0x0 : 0x80 );
                for( ; i_row < i_last_row; i_row++, i_orow++ )
                {
                    memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols,
                            color, i_pitch / i_cols );
                }
            }
            else
            {
                for( ; i_row < i_last_row; i_row++, i_orow++ )
                {
                    memcpy( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols,
                            p_in->p_pixels + i_orow * i_pitch + i_ocol * i_pitch / i_cols,
                            i_pitch / i_cols );
                }
            }
        }
    }

    if( p_sys->i_selected != -1 && !p_sys->b_blackslot )
    {
        const plane_t *p_in = &p_pic->p[Y_PLANE];
        const int i_pitch = p_in->i_pitch;
        plane_t *p_out = &p_outpic->p[Y_PLANE];

        int i_col = p_sys->i_selected % i_cols;
        int i_row = p_sys->i_selected / i_cols;
        int i_last_row = i_row + 1;
        i_row *= p_in->i_lines / i_rows;
        i_last_row *= p_in->i_lines / i_rows;
        memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols,
                0xff, i_pitch / i_cols );
        for( ; i_row < i_last_row; i_row++ )
        {
            p_out->p_pixels[   i_row * i_pitch
                             + i_col * i_pitch / i_cols ] = 0xff;
            p_out->p_pixels[ i_row * i_pitch
                             + (i_col+1) * i_pitch / i_cols - 1 ] = 0xff;
        }
        i_row--;
        memset( p_out->p_pixels + i_row * i_pitch + i_col * i_pitch / i_cols,
                0xff, i_pitch / i_cols );
    }

    if( p_sys->b_finished )
    {
        plane_t *p_out = &p_outpic->p[Y_PLANE];
        for( int i = 0; i < SHUFFLE_HEIGHT; i++ )
        {
            for( int j = 0; j < SHUFFLE_WIDTH; j++ )
            {
                if( shuffle_button[i][j] == '.' )
                   p_out->p_pixels[ i * p_out->i_pitch + j ] = 0xff;
            }
        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #18
0
ファイル: ripple.c プロジェクト: orewatakesi/VLC-for-VS2010
/*****************************************************************************
 * 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;
    int i_index;
    double f_angle;
    mtime_t new_date = mdate();

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    p_filter->p_sys->f_angle -= (p_filter->p_sys->last_date - new_date) / 100000.0;
    p_filter->p_sys->last_date = new_date;
    f_angle = p_filter->p_sys->f_angle;

    for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
    {
        int i_line, i_first_line, i_num_lines, i_offset, i_pixel_pitch,
            i_visible_pixels;
        uint8_t black_pixel;
        uint8_t *p_in, *p_out;

        black_pixel = ( p_pic->i_planes > 1 && i_index == Y_PLANE ) ? 0x00
                      : 0x80;

        i_num_lines = p_pic->p[i_index].i_visible_lines;
        i_pixel_pitch = p_pic->p[i_index].i_pixel_pitch;
        switch( p_filter->fmt_in.video.i_chroma )
        {
            CASE_PACKED_YUV_422
            // Quick hack to fix u/v inversion occuring with 2 byte pixel pitch
            i_pixel_pitch *= 2;
            break;
        }

        i_visible_pixels = p_pic->p[i_index].i_visible_pitch/i_pixel_pitch;

        i_first_line = i_num_lines * 4 / 5;

        p_in = p_pic->p[i_index].p_pixels;
        p_out = p_outpic->p[i_index].p_pixels;

        for( i_line = 0 ; i_line < i_first_line ; i_line++ )
        {
            memcpy( p_out, p_in, p_pic->p[i_index].i_visible_pitch );
            p_in += p_pic->p[i_index].i_pitch;
            p_out += p_outpic->p[i_index].i_pitch;
        }

        /* Ok, we do 3 times the sin() calculation for each line. So what ? */
        for( i_line = i_first_line ; i_line < i_num_lines ; i_line++ )
        {
            /* Calculate today's offset, don't go above 1/20th of the screen */
            i_offset = (int)( (double)(i_visible_pixels)
                              * sin( f_angle + 2.0 * (double)i_line
                                     / (double)( 1 + i_line
                                                 - i_first_line) )
                              * (double)(i_line - i_first_line)
                              / (double)i_num_lines
                              / 8.0 )*i_pixel_pitch;

            if( i_offset )
            {
                if( i_offset < 0 )
                {
                    memcpy( p_out, p_in - i_offset,
                            p_pic->p[i_index].i_visible_pitch + i_offset );
                    p_in -= p_pic->p[i_index].i_pitch;
                    p_out += p_outpic->p[i_index].i_pitch;
                    memset( p_out + i_offset, black_pixel, -i_offset );
                }
                else
                {
                    memcpy( p_out + i_offset, p_in,
                            p_pic->p[i_index].i_visible_pitch - i_offset );
                    memset( p_out, black_pixel, i_offset );
                    p_in -= p_pic->p[i_index].i_pitch;
                    p_out += p_outpic->p[i_index].i_pitch;
                }
            }
            else
            {
                memcpy( p_out, p_in, p_pic->p[i_index].i_visible_pitch );
                p_in -= p_pic->p[i_index].i_pitch;
                p_out += p_outpic->p[i_index].i_pitch;
            }

        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}
コード例 #19
0
ファイル: wave.c プロジェクト: Kafay/vlc
/*****************************************************************************
 * 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;
    int i_index;
    double f_angle;
    mtime_t new_date = mdate();

    if( !p_pic ) return NULL;

    p_outpic = filter_NewPicture( p_filter );
    if( !p_outpic )
    {
        picture_Release( p_pic );
        return NULL;
    }

    p_filter->p_sys->f_angle += (new_date - p_filter->p_sys->last_date) / 200000.0;
    p_filter->p_sys->last_date = new_date;
    f_angle = p_filter->p_sys->f_angle;

    for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ )
    {
        int i_line, i_num_lines, i_visible_pitch, i_pixel_pitch, i_offset,
            i_visible_pixels;
        uint8_t black_pixel;
        uint8_t *p_in, *p_out;

        p_in = p_pic->p[i_index].p_pixels;
        p_out = p_outpic->p[i_index].p_pixels;

        i_num_lines = p_pic->p[i_index].i_visible_lines;
        i_visible_pitch = p_pic->p[i_index].i_visible_pitch;
        i_pixel_pitch = p_pic->p[i_index].i_pixel_pitch;
        i_visible_pixels = i_visible_pitch/i_pixel_pitch;

        black_pixel = ( p_pic->i_planes > 1 && i_index == Y_PLANE ) ? 0x00
                                                                    : 0x80;

        /* Ok, we do 3 times the sin() calculation for each line. So what ? */
        for( i_line = 0 ; i_line < i_num_lines ; i_line++ )
        {
            /* Calculate today's offset, don't go above 1/20th of the screen */
            i_offset = (int)( (double)(i_visible_pixels)
                         * sin( f_angle + 10.0 * (double)i_line
                                               / (double)i_num_lines )
                         / 20.0 )*i_pixel_pitch;

            if( i_offset )
            {
                if( i_offset < 0 )
                {
                    vlc_memcpy( p_out, p_in - i_offset,
                                i_visible_pitch + i_offset );
                    p_in += p_pic->p[i_index].i_pitch;
                    p_out += p_outpic->p[i_index].i_pitch;
                    vlc_memset( p_out + i_offset, black_pixel, -i_offset );
                }
                else
                {
                    vlc_memcpy( p_out + i_offset, p_in,
                                i_visible_pitch - i_offset );
                    vlc_memset( p_out, black_pixel, i_offset );
                    p_in += p_pic->p[i_index].i_pitch;
                    p_out += p_outpic->p[i_index].i_pitch;
                }
            }
            else
            {
                vlc_memcpy( p_out, p_in, i_visible_pitch );
                p_in += p_pic->p[i_index].i_pitch;
                p_out += p_outpic->p[i_index].i_pitch;
            }

        }
    }

    return CopyInfoAndRelease( p_outpic, p_pic );
}