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

📄 deinterlace.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    if( p_vout->p_sys->p_vout )        vout_CloseAndRelease( p_vout->p_sys->p_vout );}/***************************************************************************** * Destroy: destroy Deinterlace video thread output method ***************************************************************************** * Terminate an output method created by DeinterlaceCreateOutputMethod *****************************************************************************/static void Destroy( vlc_object_t *p_this ){    vout_thread_t *p_vout = (vout_thread_t *)p_this;    vlc_mutex_destroy( &p_vout->p_sys->filter_lock );    free( p_vout->p_sys );}/***************************************************************************** * Render: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to Deinterlace image, * waits until it is displayed and switch the two rendering buffers, preparing * next frame. *****************************************************************************/static void Render ( vout_thread_t *p_vout, picture_t *p_pic ){    vout_sys_t *p_sys = p_vout->p_sys;    picture_t *pp_outpic[2];    /* FIXME are they needed ? */    p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;    p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;    p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;    p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;    /* FIXME p_sys->p_vout->* should NOT be changed FIXME */    p_sys->p_vout->fmt_in.i_x_offset = p_vout->fmt_out.i_x_offset;    p_sys->p_vout->fmt_in.i_y_offset = p_vout->fmt_out.i_y_offset;    p_sys->p_vout->fmt_in.i_visible_width = p_vout->fmt_out.i_visible_width;    p_sys->p_vout->fmt_in.i_visible_height = p_vout->fmt_in.i_visible_height;    if( p_vout->p_sys->b_half_height )    {        p_sys->p_vout->fmt_in.i_y_offset /= 2;        p_sys->p_vout->fmt_in.i_visible_height /= 2;    }    if( p_vout->i_changes & VOUT_ASPECT_CHANGE )    {        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;        p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;        p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;        p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;        video_format_t fmt = p_vout->fmt_out;        if( p_vout->p_sys->b_half_height )        {            fmt.i_height /= 2; fmt.i_visible_height /= 2; fmt.i_y_offset /= 2;            fmt.i_sar_den *= 2;        }        p_sys->p_vout = vout_Request( p_vout, p_sys->p_vout, &fmt );    }    if( !p_sys->p_vout )        return;    pp_outpic[0] = pp_outpic[1] = NULL;    vlc_mutex_lock( &p_vout->p_sys->filter_lock );    /* Get a new picture */    while( ( pp_outpic[0] = vout_CreatePicture( p_vout->p_sys->p_vout,                                                0, 0, 0 ) )              == NULL )    {        if( !vlc_object_alive( p_vout ) || p_vout->b_error )        {            vlc_mutex_unlock( &p_vout->p_sys->filter_lock );            return;        }        msleep( VOUT_OUTMEM_SLEEP );    }    vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[0], p_pic->date );    /* If we are using double rate, get an additional new picture */    if( p_vout->p_sys->b_double_rate )    {        while( ( pp_outpic[1] = vout_CreatePicture( p_vout->p_sys->p_vout,                                                 0, 0, 0 ) )                  == NULL )        {            if( !vlc_object_alive( p_vout ) || p_vout->b_error )            {                vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );                vlc_mutex_unlock( &p_vout->p_sys->filter_lock );                return;            }            msleep( VOUT_OUTMEM_SLEEP );        }        /* 20ms is a bit arbitrary, but it's only for the first image we get */        if( !p_vout->p_sys->last_date )        {            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],                              p_pic->date + 20000 );        }        else        {            vout_DatePicture( p_vout->p_sys->p_vout, pp_outpic[1],                      (3 * p_pic->date - p_vout->p_sys->last_date) / 2 );        }        p_vout->p_sys->last_date = p_pic->date;    }    switch( p_vout->p_sys->i_mode )    {        case DEINTERLACE_DISCARD:            RenderDiscard( p_vout, pp_outpic[0], p_pic, 0 );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            break;        case DEINTERLACE_BOB:            RenderBob( p_vout, pp_outpic[0], p_pic, p_pic->b_top_field_first ? 0 : 1 );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            RenderBob( p_vout, pp_outpic[1], p_pic, p_pic->b_top_field_first ? 1 : 0 );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );            break;        case DEINTERLACE_LINEAR:            RenderLinear( p_vout, pp_outpic[0], p_pic, p_pic->b_top_field_first ? 0 : 1 );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            RenderLinear( p_vout, pp_outpic[1], p_pic, p_pic->b_top_field_first ? 1 : 0 );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[1] );            break;        case DEINTERLACE_MEAN:            RenderMean( p_vout, pp_outpic[0], p_pic );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            break;        case DEINTERLACE_BLEND:            RenderBlend( p_vout, pp_outpic[0], p_pic );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            break;        case DEINTERLACE_X:            RenderX( pp_outpic[0], p_pic );            vout_DisplayPicture( p_vout->p_sys->p_vout, pp_outpic[0] );            break;    }    vlc_mutex_unlock( &p_vout->p_sys->filter_lock );}/***************************************************************************** * RenderDiscard: only keep TOP or BOTTOM field, discard the other. *****************************************************************************/static void RenderDiscard( vout_thread_t *p_vout,                           picture_t *p_outpic, picture_t *p_pic, int i_field ){    int i_plane;    /* Copy image and skip lines */    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )    {        uint8_t *p_in, *p_out_end, *p_out;        int i_increment;        p_in = p_pic->p[i_plane].p_pixels                   + i_field * p_pic->p[i_plane].i_pitch;        p_out = p_outpic->p[i_plane].p_pixels;        p_out_end = p_out + p_outpic->p[i_plane].i_pitch                             * p_outpic->p[i_plane].i_visible_lines;        switch( p_vout->render.i_chroma )        {        case VLC_FOURCC('I','4','2','0'):        case VLC_FOURCC('I','Y','U','V'):        case VLC_FOURCC('Y','V','1','2'):            for( ; p_out < p_out_end ; )            {                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                p_out += p_outpic->p[i_plane].i_pitch;                p_in += 2 * p_pic->p[i_plane].i_pitch;            }            break;        case VLC_FOURCC('I','4','2','2'):            i_increment = 2 * p_pic->p[i_plane].i_pitch;            if( i_plane == Y_PLANE )            {                for( ; p_out < p_out_end ; )                {                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_out += p_outpic->p[i_plane].i_pitch;                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_out += p_outpic->p[i_plane].i_pitch;                    p_in += i_increment;                }            }            else            {                for( ; p_out < p_out_end ; )                {                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_out += p_outpic->p[i_plane].i_pitch;                    p_in += i_increment;                }            }            break;        default:            break;        }    }}/***************************************************************************** * RenderBob: renders a BOB picture - simple copy *****************************************************************************/static void RenderBob( vout_thread_t *p_vout,                       picture_t *p_outpic, picture_t *p_pic, int i_field ){    int i_plane;    /* Copy image and skip lines */    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )    {        uint8_t *p_in, *p_out_end, *p_out;        p_in = p_pic->p[i_plane].p_pixels;        p_out = p_outpic->p[i_plane].p_pixels;        p_out_end = p_out + p_outpic->p[i_plane].i_pitch                             * p_outpic->p[i_plane].i_visible_lines;        switch( p_vout->render.i_chroma )        {            case VLC_FOURCC('I','4','2','0'):            case VLC_FOURCC('I','Y','U','V'):            case VLC_FOURCC('Y','V','1','2'):                /* For BOTTOM field we need to add the first line */                if( i_field == 1 )                {                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_in += p_pic->p[i_plane].i_pitch;                    p_out += p_outpic->p[i_plane].i_pitch;                }                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;                for( ; p_out < p_out_end ; )                {                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_out += p_outpic->p[i_plane].i_pitch;                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_in += 2 * p_pic->p[i_plane].i_pitch;                    p_out += p_outpic->p[i_plane].i_pitch;                }                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                /* For TOP field we need to add the last line */                if( i_field == 0 )                {                    p_in += p_pic->p[i_plane].i_pitch;                    p_out += p_outpic->p[i_plane].i_pitch;                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                }                break;            case VLC_FOURCC('I','4','2','2'):                /* For BOTTOM field we need to add the first line */                if( i_field == 1 )                {                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                    p_in += p_pic->p[i_plane].i_pitch;                    p_out += p_outpic->p[i_plane].i_pitch;                }                p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;                if( i_plane == Y_PLANE )                {                    for( ; p_out < p_out_end ; )                    {                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                        p_out += p_outpic->p[i_plane].i_pitch;                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                        p_in += 2 * p_pic->p[i_plane].i_pitch;                        p_out += p_outpic->p[i_plane].i_pitch;                    }                }                else                {                    for( ; p_out < p_out_end ; )                    {                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                        p_out += p_outpic->p[i_plane].i_pitch;                        p_in += 2 * p_pic->p[i_plane].i_pitch;                    }                }                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                /* For TOP field we need to add the last line */                if( i_field == 0 )                {                    p_in += p_pic->p[i_plane].i_pitch;                    p_out += p_outpic->p[i_plane].i_pitch;                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );                }                break;        }    }}#define Merge p_vout->p_sys->pf_merge#define EndMerge if(p_vout->p_sys->pf_end_merge) p_vout->p_sys->pf_end_merge/***************************************************************************** * RenderLinear: BOB with linear interpolation *****************************************************************************/static void RenderLinear( vout_thread_t *p_vout,                          picture_t *p_outpic, picture_t *p_pic, int i_field ){    int i_plane;    /* Copy image and skip lines */    for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )    {        uint8_t *p_in, *p_out_end, *p_out;        p_in = p_pic->p[i_plane].p_pixels;        p_out = p_outpic->p[i_plane].p_pixels;        p_out_end = p_out + p_outpic->p[i_plane].i_pitch                             * p_outpic->p[i_plane].i_visible_lines;        /* For BOTTOM field we need to add the first line */        if( i_field == 1 )        {            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );            p_in += p_pic->p[i_plane].i_pitch;            p_out += p_outpic->p[i_plane].i_pitch;        }        p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;        for( ; p_out < p_out_end ; )        {            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );            p_out += p_outpic->p[i_plane].i_pitch;            Merge( p_out, p_in, p_in + 2 * p_pic->p[i_plane].i_pitch,                   p_pic->p[i_plane].i_pitch );            p_in += 2 * p_pic->p[i_plane].i_pitch;            p_out += p_outpic->p[i_plane].i_pitch;        }        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );        /* For TOP field we need to add the last line */        if( i_field == 0 )        {            p_in += p_pic->p[i_plane].i_pitch;            p_out += p_outpic->p[i_plane].i_pitch;            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );        }    }    EndMerge();}static void RenderMean( vout_thread_t *p_vout,                        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++ )    {        uint8_t *p_in, *p_out_end, *p_out;        p_in = p_pic->p[i_plane].p_pixels;        p_out = p_outpic->p[i_plane].p_pixels;        p_out_end = p_out + p_outpic->p[i_plane].i_pitch                             * p_outpic->p[i_plane].i_visible_lines;        /* All lines: mean value */        for( ; p_out < p_out_end ; )        {            Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,                   p_pic->p[i_plane].i_pitch );            p_out += p_outpic->p[i_plane].i_pitch;            p_in += 2 * p_pic->p[i_plane].i_pitch;        }    }    EndMerge();}static void RenderBlend( vout_thread_t *p_vout,                         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++ )    {        uint8_t *p_in, *p_out_end, *p_out;        p_in = p_pic->p[i_plane].p_pixels;        p_out = p_outpic->p[i_plane].p_pixels;        p_out_end = p_out + p_outpic->p[i_plane].i_pitch

⌨️ 快捷键说明

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