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

📄 fbosd.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    p_sys->i_fd = open( psz_device, O_RDWR );    if( p_sys->i_fd == -1 )    {        msg_Err( p_intf, "cannot open %s (%s)", psz_device, strerror(errno) );        free( psz_device );        return VLC_EGENERIC;    }    free( psz_device );    /* Get framebuffer device information */    if( ioctl( p_sys->i_fd, FBIOGET_VSCREENINFO, &p_sys->var_info ) )    {        msg_Err( p_intf, "cannot get fb info (%s)", strerror(errno) );        close( p_sys->i_fd );        return VLC_EGENERIC;    }    /* Get some info on the framebuffer itself */    if( ioctl( p_sys->i_fd, FBIOGET_FSCREENINFO, &fix_info ) == 0 )    {        p_sys->i_width = p_sys->fmt_out.i_width = p_sys->var_info.xres;        p_sys->i_height = p_sys->fmt_out.i_height = p_sys->var_info.yres;    }    /* FIXME: if the image is full-size, it gets cropped on the left     * because of the xres / xres_virtual slight difference */    msg_Dbg( p_intf, "%ix%i (virtual %ix%i)",             p_sys->var_info.xres, p_sys->var_info.yres,             p_sys->var_info.xres_virtual,             p_sys->var_info.yres_virtual );    p_sys->fmt_out.i_width = p_sys->i_width;    p_sys->fmt_out.i_height = p_sys->i_height;    p_sys->p_palette = NULL;    p_sys->b_pan = ( fix_info.ypanstep || fix_info.ywrapstep );    switch( p_sys->var_info.bits_per_pixel )    {    case 8:        p_sys->p_palette = malloc( 8 * 256 * sizeof( uint16_t ) );        if( !p_sys->p_palette )        {            close( p_sys->i_fd );            return VLC_ENOMEM;        }        p_sys->fb_cmap.start = 0;        p_sys->fb_cmap.len = 256;        p_sys->fb_cmap.red = p_sys->p_palette;        p_sys->fb_cmap.green  = p_sys->p_palette + 256 * sizeof( uint16_t );        p_sys->fb_cmap.blue   = p_sys->p_palette + 2 * 256 * sizeof( uint16_t );        p_sys->fb_cmap.transp = p_sys->p_palette + 3 * 256 * sizeof( uint16_t );        /* Save the colormap */        ioctl( p_sys->i_fd, FBIOGETCMAP, &p_sys->fb_cmap );        p_sys->i_bytes_per_pixel = 1;        break;    case 15:    case 16:        p_sys->i_bytes_per_pixel = 2;        break;    case 24:        p_sys->i_bytes_per_pixel = 3;        break;    case 32:        p_sys->i_bytes_per_pixel = 4;        break;    default:        msg_Err( p_intf, "screen depth %d is not supported",                         p_sys->var_info.bits_per_pixel );        close( p_sys->i_fd );        return VLC_EGENERIC;    }    p_sys->i_page_size = p_sys->i_width * p_sys->i_height                         * p_sys->i_bytes_per_pixel;    msg_Dbg( p_intf, "framebuffer type=%d, visual=%d, ypanstep=%d, "             "ywrap=%d, accel=%d", fix_info.type, fix_info.visual,             fix_info.ypanstep, fix_info.ywrapstep, fix_info.accel );    return VLC_SUCCESS;}/***************************************************************************** * CloseDisplay: terminate FB interface thread *****************************************************************************/static void CloseDisplay( intf_thread_t *p_intf ){    intf_sys_t *p_sys = (intf_sys_t *) p_intf;    /* Restore palette */    if( p_sys->var_info.bits_per_pixel == 8 )    {        ioctl( p_sys->i_fd, FBIOPUTCMAP, &p_sys->fb_cmap );        free( p_sys->p_palette );        p_sys->p_palette = NULL;    }    /* Close fb */    close( p_sys->i_fd );}static void Render( intf_thread_t *p_intf, struct fbosd_render_t *render ){    intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;    if( render->i_state != FBOSD_STATE_RENDER ) return;    if( !render->psz_string ) return;    if( render->i_type == FBOSD_RENDER_IMAGE )    {        picture_t *p_pic;        p_pic = LoadImage( p_intf, &p_sys->fmt_out, render->psz_string );        if( p_pic )        {            RenderPicture( p_intf, render->i_x, render->i_y,                           p_pic, p_sys->p_overlay );            picture_Release( p_pic );        }    }    else if( render->i_type == FBOSD_RENDER_TEXT )    {        picture_t *p_text;#if defined(FBOSD_BLENDING)        video_format_t fmt_in;        memset( &fmt_in, 0, sizeof(video_format_t) );        p_text = RenderText( p_intf, render->psz_string, &render->text_style,                             &fmt_in );        if( p_text )        {            BlendPicture( p_intf, &fmt_in, &p_sys->fmt_out,                          p_text, p_sys->p_overlay );            msg_Dbg( p_intf, "releasing picture" );            DeAllocatePicture( VLC_OBJECT( p_intf ), p_text, &fmt_in );        }#else        p_text = RenderText( p_intf, render->psz_string, &render->text_style,                             &p_sys->fmt_out );        if( p_text )        {            RenderPicture( p_intf, render->i_x, render->i_y,                           p_text, p_sys->p_overlay );            picture_Release( p_text );        }#endif    }}static void RenderClear( intf_thread_t *p_intf, struct fbosd_render_t *render ){    intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;    vlc_memcpy( &render->text_style, &default_text_style,                sizeof( text_style_t ) );    free( render->psz_string );    render->psz_string = NULL;    render->i_x = p_sys->i_x;    render->i_y = p_sys->i_y;    render->i_pos = p_sys->i_pos;    render->i_alpha = p_sys->i_alpha;    render->b_absolute = p_sys->b_absolute;    render->i_state = FBOSD_STATE_FREE;}static bool isRendererReady( intf_thread_t *p_intf ){    intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;    int i;    /* Check if there are more items to render */    for( i = 0; i < FBOSD_RENDER_MAX; i++ )    {        if( p_sys->render[i].i_state == FBOSD_STATE_RESERVED )            return false;    }    return true;}/***************************************************************************** * Run: thread ***************************************************************************** * This part of the interface is in a separate thread so that we can call * exec() from within it without annoying the rest of the program. *****************************************************************************/static void Run( intf_thread_t *p_intf ){    intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;    while( !intf_ShouldDie( p_intf ) )    {        int i;        /* Is there somthing to render? */        for( i = 0; i < FBOSD_RENDER_MAX; i++ )        {            if( p_sys->render[i].i_state == FBOSD_STATE_RENDER )            {                Render( p_intf, &p_sys->render[i] );                RenderClear( p_intf, &p_sys->render[i] );            }        }        if( p_sys->b_clear )        {            SetOverlayTransparency( p_intf, true );            var_SetString( p_intf, "fbosd-image", "" );            var_SetString( p_intf, "fbosd-text", "" );            p_sys->b_clear = false;            p_sys->b_need_update = true;        }        if( p_sys->b_need_update && p_sys->p_overlay &&            isRendererReady( p_intf ) )        {            int ret;#if defined(FBOSD_BLENDING)            /* Reverse alpha channel to work around FPGA bug */            InvertAlpha( p_intf, &p_sys->p_overlay, p_sys->fmt_out );#endif            ret = write( p_sys->i_fd, p_sys->p_overlay->p[0].p_pixels,                         p_sys->i_page_size );            if( ret < 0 )                msg_Err( p_intf, "unable to write to overlay" );            lseek( p_sys->i_fd, 0, SEEK_SET );            /* clear the picture */            memset( p_sys->p_overlay->p[0].p_pixels, 0xFF, p_sys->i_page_size );            p_sys->b_need_update = false;        }        if( vlc_CPU() & CPU_CAPABILITY_FPU )            msleep( INTF_IDLE_SLEEP );        else            msleep( 500 );    }    End( p_intf );}static int OverlayCallback( vlc_object_t *p_this, char const *psz_cmd,                 vlc_value_t oldval, vlc_value_t newval, void *p_data ){    intf_thread_t *p_intf = (intf_thread_t *) p_this;    intf_sys_t *p_sys = (intf_sys_t*) p_intf->p_sys;    VLC_UNUSED(oldval); VLC_UNUSED(p_data);    if( !strncmp( psz_cmd, "fbosd-display", 13 ) )    {        p_sys->b_need_update = true;    }    else if( !strncmp( psz_cmd, "fbosd-clear", 11 ) )    {        int i;        /* Clear the entire render list */        for( i = 0; i < FBOSD_RENDER_MAX; i++ )        {            RenderClear( p_intf, &p_sys->render[i] );        }        p_sys->b_clear = true;    }    else if( !strncmp( psz_cmd, "fbosd-render", 12 ) )    {        int i;        /* Are we already busy with on slot ? */        for( i = 0; i < FBOSD_RENDER_MAX; i++ )        {            if( p_sys->render[i].i_state == FBOSD_STATE_RESERVED )            {                p_sys->render[i].i_state = FBOSD_STATE_RENDER;                break;            }        }    }    else    {        int i;        /* Are we already busy with on slot ? */        for( i = 0; i < FBOSD_RENDER_MAX; i++ )        {            if( p_sys->render[i].i_state == FBOSD_STATE_RESERVED )                break;        }        /* No, then find first FREE slot */        if( p_sys->render[i].i_state != FBOSD_STATE_RESERVED )        {            for( i = 0; i < FBOSD_RENDER_MAX; i++ )            {                if( p_sys->render[i].i_state == FBOSD_STATE_FREE )                    break;            }            if( p_sys->render[i].i_state != FBOSD_STATE_FREE )            {                msg_Warn( p_this, "render space depleated" );                return VLC_SUCCESS;            }        }        /* Found a free slot */        p_sys->render[i].i_state = FBOSD_STATE_RESERVED;        if( !strncmp( psz_cmd, "fbosd-image", 11 ) )        {            free( p_sys->render[i].psz_string );            p_sys->render[i].psz_string = strdup( newval.psz_string );            p_sys->render[i].i_type = FBOSD_RENDER_IMAGE;        }        else if( !strncmp( psz_cmd, "fbosd-text", 10 ) )        {            free( p_sys->render[i].psz_string );            p_sys->render[i].psz_string = strdup( newval.psz_string );            p_sys->render[i].i_type = FBOSD_RENDER_TEXT;        }        else if( !strncmp( psz_cmd, "fbosd-x", 7 ) )        {            p_sys->render[i].b_absolute = false;            p_sys->render[i].i_x = (newval.i_int < p_sys->i_width) ?                                    newval.i_int : p_sys->i_width;        }        else if( !strncmp( psz_cmd, "fbosd-y", 7 ) )        {            p_sys->render[i].b_absolute = false;            p_sys->render[i].i_y = (newval.i_int < p_sys->i_height) ?                                    newval.i_int : p_sys->i_height;        }        else if( !strncmp( psz_cmd, "fbosd-position", 14 ) )        {            p_sys->render[i].b_absolute = true;            p_sys->render[i].i_pos = newval.i_int;        }        else if( !strncmp( psz_cmd, "fbosd-font-size", 15 ) )        {            p_sys->render[i].text_style.i_font_size = newval.i_int;        }        else if( !strncmp( psz_cmd, "fbosd-font-color", 16 ) )        {            p_sys->render[i].text_style.i_font_color = newval.i_int;        }        else if( !strncmp( psz_cmd, "fbosd-font-opacity", 18 ) )        {            p_sys->render[i].text_style.i_font_alpha = 255 - newval.i_int;        }        else if( !strncmp( psz_cmd, "fbosd-alpha", 11 ) )        {            p_sys->render[i].i_alpha = newval.i_int;        }    }    return VLC_SUCCESS;}

⌨️ 快捷键说明

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