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

📄 deinterlace.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
#if 0/* Kernel interpolation (1,-5,20,20,-5,1) * Lose a bit more details+add aliasing than edge interpol but avoid * more artifacts */static inline uint8_t clip1( int a ){    if( a <= 0 )        return 0;    else if( a >= 255 )        return 255;    else        return a;}static inline void XDeint8x8Field( uint8_t *dst, int i_dst,                                   uint8_t *src, int i_src ){    int y, x;    /* Interlaced */    for( y = 0; y < 8; y += 2 )    {        const int i_src2 = i_src*2;        memcpy( dst, src, 8 );        dst += i_dst;        for( x = 0; x < 8; x++ )        {            int pix;            pix =   1*(src[-2*i_src2+x]+src[3*i_src2+x]) +                   -5*(src[-1*i_src2+x]+src[2*i_src2+x])                  +20*(src[ 0*i_src2+x]+src[1*i_src2+x]);            dst[x] = clip1( ( pix + 16 ) >> 5 );        }        dst += 1*i_dst;        src += 2*i_src;    }}#endif/* NxN arbitray size (and then only use pixel in the NxN block) */static inline int XDeintNxNDetect( uint8_t *src, int i_src,                                   int i_height, int i_width ){    int y, x;    int ff, fr;    int fc;    /* Detect interlacing */    /* FIXME way too simple, need to be more like XDeint8x8Detect */    ff = fr = 0;    fc = 0;    for( y = 0; y < i_height - 2; y += 2 )    {        const uint8_t *s = &src[y*i_src];        for( x = 0; x < i_width; x++ )        {            fr += ssd(s[      x] - s[1*i_src+x]);            ff += ssd(s[      x] - s[2*i_src+x]);        }        if( ff < fr && fr > i_width / 2 )            fc++;    }    return fc < 2 ? false : true;}static inline void XDeintNxNFrame( uint8_t *dst, int i_dst,                                   uint8_t *src, int i_src,                                   int i_width, int i_height ){    int y, x;    /* Progressive */    for( y = 0; y < i_height; y += 2 )    {        memcpy( dst, src, i_width );        dst += i_dst;        if( y < i_height - 2 )        {            for( x = 0; x < i_width; x++ )                dst[x] = (src[x] + 2*src[1*i_src+x] + src[2*i_src+x] + 2 ) >> 2;        }        else        {            /* Blend last line */            for( x = 0; x < i_width; x++ )                dst[x] = (src[x] + src[1*i_src+x] ) >> 1;        }        dst += 1*i_dst;        src += 2*i_src;    }}static inline void XDeintNxNField( uint8_t *dst, int i_dst,                                   uint8_t *src, int i_src,                                   int i_width, int i_height ){    int y, x;    /* Interlaced */    for( y = 0; y < i_height; y += 2 )    {        memcpy( dst, src, i_width );        dst += i_dst;        if( y < i_height - 2 )        {            for( x = 0; x < i_width; x++ )                dst[x] = (src[x] + src[2*i_src+x] ) >> 1;        }        else        {            /* Blend last line */            for( x = 0; x < i_width; x++ )                dst[x] = (src[x] + src[i_src+x]) >> 1;        }        dst += 1*i_dst;        src += 2*i_src;    }}static inline void XDeintNxN( uint8_t *dst, int i_dst, uint8_t *src, int i_src,                              int i_width, int i_height ){    if( XDeintNxNDetect( src, i_src, i_width, i_height ) )        XDeintNxNField( dst, i_dst, src, i_src, i_width, i_height );    else        XDeintNxNFrame( dst, i_dst, src, i_src, i_width, i_height );}static inline int median( int a, int b, int c ){    int min = a, max =a;    if( b < min )        min = b;    else        max = b;    if( c < min )        min = c;    else if( c > max )        max = c;    return a + b + c - min - max;}/* XDeintBand8x8: */static inline void XDeintBand8x8C( uint8_t *dst, int i_dst,                                   uint8_t *src, int i_src,                                   const int i_mbx, int i_modx ){    int x;    for( x = 0; x < i_mbx; x++ )    {        int s;        if( ( s = XDeint8x8DetectC( src, i_src ) ) )        {            if( x == 0 || x == i_mbx - 1 )                XDeint8x8FieldEC( dst, i_dst, src, i_src );            else                XDeint8x8FieldC( dst, i_dst, src, i_src );        }        else        {            XDeint8x8MergeC( dst, i_dst,                             &src[0*i_src], 2*i_src,                             &src[1*i_src], 2*i_src );        }        dst += 8;        src += 8;    }    if( i_modx )        XDeintNxN( dst, i_dst, src, i_src, i_modx, 8 );}#ifdef CAN_COMPILE_MMXEXTstatic inline void XDeintBand8x8MMXEXT( uint8_t *dst, int i_dst,                                        uint8_t *src, int i_src,                                        const int i_mbx, int i_modx ){    int x;    /* Reset current line */    for( x = 0; x < i_mbx; x++ )    {        int s;        if( ( s = XDeint8x8DetectMMXEXT( src, i_src ) ) )        {            if( x == 0 || x == i_mbx - 1 )                XDeint8x8FieldEMMXEXT( dst, i_dst, src, i_src );            else                XDeint8x8FieldMMXEXT( dst, i_dst, src, i_src );        }        else        {            XDeint8x8MergeMMXEXT( dst, i_dst,                                  &src[0*i_src], 2*i_src,                                  &src[1*i_src], 2*i_src );        }        dst += 8;        src += 8;    }    if( i_modx )        XDeintNxN( dst, i_dst, src, i_src, i_modx, 8 );}#endifstatic void RenderX( picture_t *p_outpic, picture_t *p_pic ){    int i_plane;    /* Copy image and skip lines */    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )    {        const int i_mby = ( p_outpic->p[i_plane].i_visible_lines + 7 )/8 - 1;        const int i_mbx = p_outpic->p[i_plane].i_visible_pitch/8;        const int i_mody = p_outpic->p[i_plane].i_visible_lines - 8*i_mby;        const int i_modx = p_outpic->p[i_plane].i_visible_pitch - 8*i_mbx;        const int i_dst = p_outpic->p[i_plane].i_pitch;        const int i_src = p_pic->p[i_plane].i_pitch;        int y, x;        for( y = 0; y < i_mby; y++ )        {            uint8_t *dst = &p_outpic->p[i_plane].p_pixels[8*y*i_dst];            uint8_t *src = &p_pic->p[i_plane].p_pixels[8*y*i_src];#ifdef CAN_COMPILE_MMXEXT            if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )                XDeintBand8x8MMXEXT( dst, i_dst, src, i_src, i_mbx, i_modx );            else#endif                XDeintBand8x8C( dst, i_dst, src, i_src, i_mbx, i_modx );        }        /* Last line (C only)*/        if( i_mody )        {            uint8_t *dst = &p_outpic->p[i_plane].p_pixels[8*y*i_dst];            uint8_t *src = &p_pic->p[i_plane].p_pixels[8*y*i_src];            for( x = 0; x < i_mbx; x++ )            {                XDeintNxN( dst, i_dst, src, i_src, 8, i_mody );                dst += 8;                src += 8;            }            if( i_modx )                XDeintNxN( dst, i_dst, src, i_src, i_modx, i_mody );        }    }#ifdef CAN_COMPILE_MMXEXT    if( vlc_CPU() & CPU_CAPABILITY_MMXEXT )        emms();#endif}/***************************************************************************** * SendEvents: forward mouse and keyboard events to the parent p_vout *****************************************************************************/static int SendEvents( vlc_object_t *p_this, char const *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *_p_vout ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval);    vout_thread_t *p_vout = (vout_thread_t *)_p_vout;    vlc_value_t sentval = newval;    if( !strcmp( psz_var, "mouse-y" ) )    {        switch( p_vout->p_sys->i_mode )        {            case DEINTERLACE_MEAN:            case DEINTERLACE_DISCARD:                sentval.i_int *= 2;                break;        }    }    var_Set( p_vout, psz_var, sentval );    return VLC_SUCCESS;}/***************************************************************************** * FilterCallback: called when changing the deinterlace method on the fly. *****************************************************************************/static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,                           vlc_value_t oldval, vlc_value_t newval,                           void *p_data ){    VLC_UNUSED(psz_cmd); VLC_UNUSED(p_data); VLC_UNUSED(oldval);    vout_thread_t * p_vout = (vout_thread_t *)p_this;    int i_old_mode = p_vout->p_sys->i_mode;    msg_Dbg( p_vout, "using %s deinterlace mode", newval.psz_string );    vlc_mutex_lock( &p_vout->p_sys->filter_lock );    SetFilterMethod( p_vout, newval.psz_string );    switch( p_vout->render.i_chroma )    {    case VLC_FOURCC('I','4','2','2'):        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );        return VLC_SUCCESS;        break;    case VLC_FOURCC('I','4','2','0'):    case VLC_FOURCC('I','Y','U','V'):    case VLC_FOURCC('Y','V','1','2'):        switch( p_vout->p_sys->i_mode )        {        case DEINTERLACE_MEAN:        case DEINTERLACE_DISCARD:            if( ( i_old_mode == DEINTERLACE_MEAN )                || ( i_old_mode == DEINTERLACE_DISCARD ) )            {                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );                return VLC_SUCCESS;            }            break;        case DEINTERLACE_BOB:        case DEINTERLACE_BLEND:        case DEINTERLACE_LINEAR:            if( ( i_old_mode == DEINTERLACE_BOB )                || ( i_old_mode == DEINTERLACE_BLEND )                || ( i_old_mode == DEINTERLACE_LINEAR ) )            {                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );                return VLC_SUCCESS;            }            break;        }        break;    default:        break;    }    /* We need to kill the old vout */    if( p_vout->p_sys->p_vout )    {        DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );        vout_CloseAndRelease( p_vout->p_sys->p_vout );    }    /* Try to open a new video output */    p_vout->p_sys->p_vout = SpawnRealVout( p_vout );    if( p_vout->p_sys->p_vout == NULL )    {        /* Everything failed */        msg_Err( p_vout, "cannot open vout, aborting" );        vlc_mutex_unlock( &p_vout->p_sys->filter_lock );        return VLC_EGENERIC;    }    ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );    return VLC_SUCCESS;}/***************************************************************************** * SendEventsToChild: forward events to the child/children vout *****************************************************************************/static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    VLC_UNUSED(p_data); VLC_UNUSED(oldval);    vout_thread_t *p_vout = (vout_thread_t *)p_this;    var_Set( p_vout->p_sys->p_vout, psz_var, newval );    return VLC_SUCCESS;}/***************************************************************************** * video filter2 functions *****************************************************************************/static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic ){    vout_thread_t *p_vout = (vout_thread_t *)p_filter->p_sys;    picture_t *p_pic_dst;    /* Request output picture */    p_pic_dst = filter_NewPicture( p_filter );    if( p_pic_dst == NULL )        return p_pic;    switch( p_vout->p_sys->i_mode )    {        case DEINTERLACE_DISCARD:#if 0            RenderDiscard( p_vout, p_pic_dst, p_pic, 0 );#endif            msg_Err( p_vout, "discarding lines is not supported yet" );            picture_Release( p_pic_dst );            return p_pic;            break;        case DEINTERLACE_BOB:#if 0            RenderBob( p_vout, p

⌨️ 快捷键说明

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