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

📄 fb.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
    ioctl( p_vout->p_sys->i_tty, VT_SETMODE, &p_vout->p_sys->vt_mode );    /* Remove signal handlers */    sigaction( SIGUSR1, &p_vout->p_sys->sig_usr1, NULL );    sigaction( SIGUSR2, &p_vout->p_sys->sig_usr2, NULL );    /* Reset the keyboard state */    tcsetattr( 0, 0, &p_vout->p_sys->old_termios );    /* Return to text mode */    TextMode( p_vout->p_sys->i_tty );    /* Destroy structure */    free( p_vout->p_sys );}/***************************************************************************** * Manage: handle FB events ***************************************************************************** * This function should be called regularly by video output thread. It manages * console events. It returns a non null value on error. *****************************************************************************/static int Manage( vout_thread_t *p_vout ){#if 0    uint8_t buf;    if ( read(0, &buf, 1) == 1)    {        switch( buf )        {        case 'q':            p_vout->p_vlc->b_die = 1;            break;        default:            break;        }    }#endif    /*     * Size change     */    if( p_vout->i_changes & VOUT_SIZE_CHANGE )    {        msg_Dbg( p_vout, "reinitializing framebuffer screen" );        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;        /* Destroy XImages to change their size */        End( p_vout );        /* Recreate XImages. If SysInit failed, the thread can't go on. */        if( Init( p_vout ) )        {            msg_Err( p_vout, "cannot reinit framebuffer screen" );            return VLC_EGENERIC;        }        /* Clear screen */        memset( p_vout->p_sys->p_video, 0, p_vout->p_sys->i_page_size );#if 0        /* Tell the video output thread that it will need to rebuild YUV         * tables. This is needed since conversion buffer size may have changed */        p_vout->i_changes |= VOUT_YUV_CHANGE;#endif    }    return VLC_SUCCESS;}/***************************************************************************** * Display: displays previously rendered output ***************************************************************************** * This function send the currently rendered image to FB image, waits until * it is displayed and switch the two rendering buffers, preparing next frame. *****************************************************************************/static void Display( vout_thread_t *p_vout, picture_t *p_pic ){static int panned=0;    /* swap the two Y offsets if the drivers supports panning */    if( p_vout->p_sys->b_pan )    {        p_vout->p_sys->var_info.yoffset = 0;        /*p_vout->p_sys->var_info.yoffset = p_vout->p_sys->var_info.yres; */        /* the X offset should be 0, but who knows ...         * some other app might have played with the framebuffer */        p_vout->p_sys->var_info.xoffset = 0;if(panned < 0) {        ioctl( p_vout->p_sys->i_fd,               FBIOPAN_DISPLAY, &p_vout->p_sys->var_info );panned++;}    }}#if 0static void SetPalette( vout_thread_t *p_vout, uint16_t *red, uint16_t *green,                                               uint16_t *blue, uint16_t *transp ){    struct fb_cmap cmap = { 0, 256, red, green, blue, transp };    ioctl( p_vout->p_sys->i_fd, FBIOPUTCMAP, &cmap );}#endif/* following functions are local *//***************************************************************************** * OpenDisplay: initialize framebuffer *****************************************************************************/static int OpenDisplay( vout_thread_t *p_vout ){    char *psz_device;                             /* framebuffer device path */    struct fb_fix_screeninfo    fix_info;     /* framebuffer fix information */    /* Open framebuffer device */    if( !(psz_device = config_GetPsz( p_vout, FB_DEV_VAR )) )    {        msg_Err( p_vout, "don't know which fb device to open" );        return VLC_EGENERIC;    }    p_vout->p_sys->i_fd = open( psz_device, O_RDWR);    if( p_vout->p_sys->i_fd == -1 )    {        msg_Err( p_vout, "cannot open %s (%s)", psz_device, strerror(errno) );        free( psz_device );        return VLC_EGENERIC;    }    free( psz_device );    /* Get framebuffer device information */    if( ioctl( p_vout->p_sys->i_fd,               FBIOGET_VSCREENINFO, &p_vout->p_sys->var_info ) )    {        msg_Err( p_vout, "cannot get fb info (%s)", strerror(errno) );        close( p_vout->p_sys->i_fd );        return VLC_EGENERIC;    }    memcpy( &p_vout->p_sys->old_info, &p_vout->p_sys->var_info,            sizeof( struct fb_var_screeninfo ) );    /* Set some attributes */    p_vout->p_sys->var_info.activate = FB_ACTIVATE_NXTOPEN;    p_vout->p_sys->var_info.xoffset =  0;    p_vout->p_sys->var_info.yoffset =  0;    if( ioctl( p_vout->p_sys->i_fd,               FBIOPUT_VSCREENINFO, &p_vout->p_sys->var_info ) )    {        msg_Err( p_vout, "cannot set fb info (%s)", strerror(errno) );        close( p_vout->p_sys->i_fd );        return VLC_EGENERIC;    }    /* Get some information again, in the definitive configuration */    if( ioctl( p_vout->p_sys->i_fd, FBIOGET_FSCREENINFO, &fix_info )         || ioctl( p_vout->p_sys->i_fd,                   FBIOGET_VSCREENINFO, &p_vout->p_sys->var_info ) )    {        msg_Err( p_vout, "cannot get additional fb info (%s)",                          strerror(errno) );        /* Restore fb config */        ioctl( p_vout->p_sys->i_fd,               FBIOPUT_VSCREENINFO, &p_vout->p_sys->old_info );        close( p_vout->p_sys->i_fd );        return VLC_EGENERIC;    }    /* FIXME: if the image is full-size, it gets cropped on the left     * because of the xres / xres_virtual slight difference */    msg_Dbg( p_vout, "%ix%i (virtual %ix%i)",             p_vout->p_sys->var_info.xres, p_vout->p_sys->var_info.yres,             p_vout->p_sys->var_info.xres_virtual,             p_vout->p_sys->var_info.yres_virtual );    p_vout->p_sys->i_height = p_vout->p_sys->var_info.yres;    p_vout->p_sys->i_width  = p_vout->p_sys->var_info.xres_virtual                               ? p_vout->p_sys->var_info.xres_virtual                               : p_vout->p_sys->var_info.xres;    p_vout->p_sys->p_palette = NULL;    p_vout->p_sys->b_pan = ( fix_info.ypanstep || fix_info.ywrapstep );    switch( p_vout->p_sys->var_info.bits_per_pixel )    {    case 8:        p_vout->p_sys->p_palette = malloc( 8 * 256 * sizeof( uint16_t ) );        p_vout->p_sys->fb_cmap.start = 0;        p_vout->p_sys->fb_cmap.len = 256;        p_vout->p_sys->fb_cmap.red = p_vout->p_sys->p_palette;        p_vout->p_sys->fb_cmap.green = p_vout->p_sys->p_palette + 256 * sizeof( uint16_t );        p_vout->p_sys->fb_cmap.blue = p_vout->p_sys->p_palette + 2 * 256 * sizeof( uint16_t );        p_vout->p_sys->fb_cmap.transp = p_vout->p_sys->p_palette + 3 * 256 * sizeof( uint16_t );        /* Save the colormap */        ioctl( p_vout->p_sys->i_fd, FBIOGETCMAP, &p_vout->p_sys->fb_cmap );        p_vout->p_sys->i_bytes_per_pixel = 1;        break;    case 15:    case 16:        p_vout->p_sys->i_bytes_per_pixel = 2;        break;    case 24:        p_vout->p_sys->i_bytes_per_pixel = 3;        break;    case 32:        p_vout->p_sys->i_bytes_per_pixel = 4;        break;    default:        msg_Err( p_vout, "screen depth %d is not supported",                         p_vout->p_sys->var_info.bits_per_pixel );        /* Restore fb config */        ioctl( p_vout->p_sys->i_fd,               FBIOPUT_VSCREENINFO, &p_vout->p_sys->old_info );        close( p_vout->p_sys->i_fd );        return VLC_EGENERIC;    }    p_vout->p_sys->i_page_size = p_vout->p_sys->i_width *                p_vout->p_sys->i_height * p_vout->p_sys->i_bytes_per_pixel;    /* Map a framebuffer at the beginning */    p_vout->p_sys->p_video = mmap( 0, p_vout->p_sys->i_page_size,                                   PROT_READ | PROT_WRITE, MAP_SHARED,                                   p_vout->p_sys->i_fd, 0 );    if( p_vout->p_sys->p_video == ((void*)-1) )    {        msg_Err( p_vout, "cannot map video memory (%s)", strerror(errno) );        if( p_vout->p_sys->var_info.bits_per_pixel == 8 )        {            free( p_vout->p_sys->p_palette );        }        /* Restore fb config */        ioctl( p_vout->p_sys->i_fd,               FBIOPUT_VSCREENINFO, &p_vout->p_sys->old_info );        close( p_vout->p_sys->i_fd );        return VLC_EGENERIC;    }    msg_Dbg( p_vout, "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 video thread output method *****************************************************************************/static void CloseDisplay( vout_thread_t *p_vout ){    /* Clear display */    memset( p_vout->p_sys->p_video, 0, p_vout->p_sys->i_page_size );    /* Restore palette */    if( p_vout->p_sys->var_info.bits_per_pixel == 8 )    {        ioctl( p_vout->p_sys->i_fd,               FBIOPUTCMAP, &p_vout->p_sys->fb_cmap );        free( p_vout->p_sys->p_palette );    }    /* Restore fb config */    ioctl( p_vout->p_sys->i_fd,           FBIOPUT_VSCREENINFO, &p_vout->p_sys->old_info );    /* Close fb */    close( p_vout->p_sys->i_fd );}/***************************************************************************** * SwitchDisplay: VT change signal handler ***************************************************************************** * This function activates or deactivates the output of the thread. It is * called by the VT driver, on terminal change. *****************************************************************************/static void SwitchDisplay(int i_signal){#if 0    vout_thread_t *p_vout;    vlc_mutex_lock( &p_vout_bank->lock );    /* XXX: only test the first video output */    if( p_vout_bank->i_count )    {        p_vout = p_vout_bank->pp_vout[0];        switch( i_signal )        {        case SIGUSR1:                                /* vt has been released */            p_vout->b_active = 0;            ioctl( p_vout->p_sys->i_tty, VT_RELDISP, 1 );            break;        case SIGUSR2:                                /* vt has been acquired */            p_vout->b_active = 1;            ioctl( p_vout->p_sys->i_tty, VT_RELDISP, VT_ACTIVATE );            /* handle blanking */            vlc_mutex_lock( &p_vout->change_lock );            p_vout->i_changes |= VOUT_SIZE_CHANGE;            vlc_mutex_unlock( &p_vout->change_lock );            break;        }    }    vlc_mutex_unlock( &p_vout_bank->lock );#endif}/***************************************************************************** * TextMode and GfxMode : switch tty to text/graphic mode ***************************************************************************** * These functions toggle the tty mode. *****************************************************************************/static void TextMode( int i_tty ){    /* return to text mode */    if( -1 == ioctl(i_tty, KDSETMODE, KD_TEXT) )    {        /*msg_Err( p_vout, "failed ioctl KDSETMODE KD_TEXT" );*/    }}static void GfxMode( int i_tty ){    /* switch to graphic mode */    if( -1 == ioctl(i_tty, KDSETMODE, KD_GRAPHICS) )    {        /*msg_Err( p_vout, "failed ioctl KDSETMODE KD_GRAPHICS" );*/    }}

⌨️ 快捷键说明

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