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

📄 erase.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
}/***************************************************************************** * FilterErase *****************************************************************************/static void FilterErase( filter_t *p_filter, picture_t *p_inpic,                                             picture_t *p_outpic ){    filter_sys_t *p_sys = p_filter->p_sys;    int i_plane;    const int i_mask_pitch = p_sys->p_mask->A_PITCH;    const int i_mask_visible_pitch = p_sys->p_mask->p[A_PLANE].i_visible_pitch;    const int i_mask_visible_lines = p_sys->p_mask->p[A_PLANE].i_visible_lines;    for( i_plane = 0; i_plane < p_inpic->i_planes; i_plane++ )    {        const int i_pitch = p_inpic->p[i_plane].i_pitch;        const int i_2pitch = i_pitch<<1;        const int i_visible_pitch = p_inpic->p[i_plane].i_visible_pitch;        const int i_lines = p_inpic->p[i_plane].i_lines;        const int i_visible_lines = p_inpic->p[i_plane].i_visible_lines;        uint8_t *p_inpix = p_inpic->p[i_plane].p_pixels;        uint8_t *p_outpix = p_outpic->p[i_plane].p_pixels;        uint8_t *p_mask = p_sys->p_mask->A_PIXELS;        int i_x = p_sys->i_x,            i_y = p_sys->i_y;        int x, y;        int i_height = i_mask_visible_lines;        int i_width  = i_mask_visible_pitch;        const bool b_line_factor = ( i_plane /* U_PLANE or V_PLANE */ &&            !( p_inpic->format.i_chroma == VLC_FOURCC('I','4','2','2')            || p_inpic->format.i_chroma == VLC_FOURCC('J','4','2','2') ) );        if( i_plane ) /* U_PLANE or V_PLANE */        {            i_width  >>= 1;            i_x      >>= 1;        }        if( b_line_factor )        {            i_height >>= 1;            i_y      >>= 1;        }        i_height = __MIN( i_visible_lines - i_y, i_height );        i_width  = __MIN( i_visible_pitch - i_x, i_width  );        /* Copy original pixel buffer */        vlc_memcpy( p_outpix, p_inpix, i_pitch * i_lines );        /* Horizontal linear interpolation of masked areas */        p_outpix = p_outpic->p[i_plane].p_pixels + i_y*i_pitch + i_x;        for( y = 0; y < i_height;             y++, p_mask += i_mask_pitch, p_outpix += i_pitch )        {            uint8_t prev, next = 0;            int prev_x = -1, next_x = -2;            int quot = 0;            /* Find a suitable value for the previous color to use when             * interpoling a masked pixel's value */            if( i_x )            {                /* There are pixels before current position on the same line.                 * Use those */                prev = *(p_outpix-1);            }            else if( y || i_y )            {                /* This is the first pixel on a line but there other lines                 * above us. Use the pixel right above */                prev = *(p_outpix-i_pitch);            }            else            {                /* We're in the upper left corner. This sucks. We can't use                 * any previous value, so we'll use a dummy one. In most                 * cases this dummy value will be fixed later on in the                 * algorithm */                prev = 0xff;            }            for( x = 0; x < i_width; x++ )            {                if( p_mask[i_plane?x<<1:x] > 127 )                {                    /* This is a masked pixel */                    if( next_x <= prev_x )                    {                        int x0;                        /* Look for the next non masked pixel on the same                         * line (inside the mask's bounding box) */                        for( x0 = x; x0 < i_width; x0++ )                        {                            if( p_mask[i_plane?x0<<1:x0] <= 127 )                            {                                /* We found an unmasked pixel. Victory! */                                next_x = x0;                                next = p_outpix[x0];                                break;                            }                        }                        if( next_x <= prev_x )                        {                            /* We didn't find an unmasked pixel yet. Try                             * harder */                            if( x0 == x ) x0++;                            if( x0 < i_visible_pitch )                            {                                /* If we didn't find a non masked pixel on the                                 * same line inside the mask's bounding box,                                 * use the next pixel on the line (except if                                 * it doesn't exist) */                                next_x = x0;                                next = p_outpix[x0];                            }                            else                            {                                /* The last pixel on the line is masked,                                 * so we'll use the "prev" value. A better                                 * approach would be to use unmasked pixels                                 * at the end of adjacent lines */                                next_x = x0;                                next = prev;                            }                        }                        if( !( i_x || y || i_y ) )                            /* We were unable to find a suitable value for                             * the previous color (which means that we are                             * on the first line in the upper left corner)                             */                            prev = next;                        /* Divide only once instead of next_x-prev_x-1 times */                        quot = ((next-prev)<<16)/(next_x-prev_x);                    }                    /* Interpolate new value, and round correctly */                    p_outpix[x] = prev + (((x-prev_x)*quot+(1<<16))>>16);                }                else                {                    /* This pixel isn't masked. It's thus suitable as a                     * previous color for the next interpolation */                    prev = p_outpix[x];                    prev_x = x;                }            }        }        /* Vertical bluring */        p_mask = p_sys->p_mask->A_PIXELS;        i_height = b_line_factor ? i_mask_visible_lines>>1                                 : i_mask_visible_lines;        /* Make sure that we stop at least 2 lines before the picture's end         * (since our bluring algorithm uses the 2 next lines) */        i_height = __MIN( i_visible_lines - i_y - 2, i_height );        /* Make sure that we start at least 2 lines from the top (since our         * bluring algorithm uses the 2 previous lines) */        y = __MAX(i_y,2);        p_outpix = p_outpic->p[i_plane].p_pixels + (i_y+y)*i_pitch + i_x;        for( ; y < i_height; y++, p_mask += i_mask_pitch, p_outpix += i_pitch )        {            for( x = 0; x < i_width; x++ )            {                if( p_mask[i_plane?x<<1:x] > 127 )                {                    /* Ugly bluring function */                    p_outpix[x] =                        ( (p_outpix[x-i_2pitch]<<1)       /* 2 */                        + (p_outpix[x-i_pitch ]<<2)       /* 4 */                        + (p_outpix[x         ]<<2)       /* 4 */                        + (p_outpix[x+i_pitch ]<<2)       /* 4 */                        + (p_outpix[x+i_2pitch]<<1) )>>4; /* 2 */                }            }        }    }}static int EraseCallback( vlc_object_t *p_this, char const *psz_var,                          vlc_value_t oldval, vlc_value_t newval, void *p_data ){    VLC_UNUSED(oldval);    filter_sys_t *p_sys = (filter_sys_t *)p_data;    if( !strcmp( psz_var, CFG_PREFIX "x" ) )    {        vlc_mutex_lock( &p_sys->lock );        p_sys->i_x = newval.i_int;        vlc_mutex_unlock( &p_sys->lock );    }    else if( !strcmp( psz_var, CFG_PREFIX "y" ) )    {        vlc_mutex_lock( &p_sys->lock );        p_sys->i_y = newval.i_int;        vlc_mutex_unlock( &p_sys->lock );    }    else if( !strcmp( psz_var, CFG_PREFIX "mask" ) )    {        vlc_mutex_lock( &p_sys->lock );        LoadMask( (filter_t*)p_this, newval.psz_string );        vlc_mutex_unlock( &p_sys->lock );    }    else    {        msg_Warn( p_this, "Unknown callback command." );    }    return VLC_SUCCESS;}

⌨️ 快捷键说明

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