📄 fb.c
字号:
/***************************************************************************** * fb.c : framebuffer plugin for vlc ***************************************************************************** * Copyright (C) 2000, 2001 the VideoLAN team * $Id: 95ea2fe1a317b5df5284080e885488a52eb07b65 $ * * Authors: Samuel Hocevar <sam@zoy.org> * Jean-Paul Saman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <errno.h> /* ENOMEM */#include <signal.h> /* SIGUSR1, SIGUSR2 */#include <fcntl.h> /* open() */#include <unistd.h> /* close() */#include <termios.h> /* struct termios */#include <sys/ioctl.h>#include <sys/mman.h> /* mmap() */#include <linux/fb.h>#include <linux/vt.h> /* VT_* */#include <linux/kd.h> /* KD* */#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_vout.h>/***************************************************************************** * Local prototypes *****************************************************************************/static int Create ( vlc_object_t * );static void Destroy ( vlc_object_t * );static int Init ( vout_thread_t * );static void End ( vout_thread_t * );static int Manage ( vout_thread_t * );static void Display ( vout_thread_t *, picture_t * );static int Control ( vout_thread_t *, int, va_list );static int NewPicture ( vout_thread_t *, picture_t * );static void FreePicture ( vout_thread_t *, picture_t * );static int OpenDisplay ( vout_thread_t * );static void CloseDisplay ( vout_thread_t * );static void SwitchDisplay ( int i_signal );static void TextMode ( int i_tty );static void GfxMode ( int i_tty );#define MAX_DIRECTBUFFERS 1/***************************************************************************** * Module descriptor *****************************************************************************/#define FB_DEV_VAR "fbdev"#define DEVICE_TEXT N_("Framebuffer device")#define DEVICE_LONGTEXT N_( \ "Framebuffer device to use for rendering (usually /dev/fb0).")#define TTY_TEXT N_("Run fb on current tty.")#define TTY_LONGTEXT N_( \ "Run framebuffer on current TTY device (default enabled). " \ "(disable tty handling with caution)" )#define CHROMA_TEXT N_("Chroma used.")#define CHROMA_LONGTEXT N_( \ "Force use of a specific chroma for output. Default is I420." )#define ASPECT_RATIO_TEXT N_("Video aspect ratio")#define ASPECT_RATIO_LONGTEXT N_( \ "Aspect ratio of the video image (4:3, 16:9). Default is square pixels." )#define FB_MODE_TEXT N_("Framebuffer resolution to use.")#define FB_MODE_LONGTEXT N_( \ "Select the resolution for the framebuffer. Currently it supports " \ "the values 0=QCIF 1=CIF 2=NTSC 3=PAL, 4=auto (default 4=auto)" )#define HW_ACCEL_TEXT N_("Framebuffer uses hw acceleration.")#define HW_ACCEL_LONGTEXT N_( \ "If your framebuffer supports hardware acceleration or does double buffering " \ "in hardware then you must disable this option. It then does double buffering " \ "in software." )vlc_module_begin(); set_shortname( "Framebuffer" ); set_category( CAT_VIDEO ); set_subcategory( SUBCAT_VIDEO_VOUT ); add_file( FB_DEV_VAR, "/dev/fb0", NULL, DEVICE_TEXT, DEVICE_LONGTEXT, false ); add_bool( "fb-tty", 1, NULL, TTY_TEXT, TTY_LONGTEXT, true ); add_string( "fb-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true ); add_string( "fb-aspect-ratio", NULL, NULL, ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, true ); add_integer( "fb-mode", 4, NULL, FB_MODE_TEXT, FB_MODE_LONGTEXT, true ); add_bool( "fb-hw-accel", true, NULL, HW_ACCEL_TEXT, HW_ACCEL_LONGTEXT, true ); set_description( N_("GNU/Linux console framebuffer video output") ); set_capability( "video output", 30 ); set_callbacks( Create, Destroy );vlc_module_end();/***************************************************************************** * vout_sys_t: video output framebuffer method descriptor ***************************************************************************** * This structure is part of the video output thread descriptor. * It describes the FB specific properties of an output thread. *****************************************************************************/struct vout_sys_t{ /* System information */ int i_tty; /* tty device handle */ bool b_tty; struct termios old_termios; /* Original configuration information */ struct sigaction sig_usr1; /* USR1 previous handler */ struct sigaction sig_usr2; /* USR2 previous handler */ struct vt_mode vt_mode; /* previous VT mode */ /* Framebuffer information */ int i_fd; /* device handle */ struct fb_var_screeninfo old_info; /* original mode information */ struct fb_var_screeninfo var_info; /* current mode information */ bool b_pan; /* does device supports panning ? */ struct fb_cmap fb_cmap; /* original colormap */ uint16_t *p_palette; /* original palette */ bool b_hw_accel; /* has hardware support */ /* Video information */ uint32_t i_width; uint32_t i_height; int i_aspect; int i_bytes_per_pixel; bool b_auto; /* Automatically adjust video size to fb size */ vlc_fourcc_t i_chroma; /* Video memory */ uint8_t *p_video; /* base adress */ size_t i_page_size; /* page size */};struct picture_sys_t{ uint8_t * p_data; /* base adress */};/***************************************************************************** * Create: allocates FB video thread output method ***************************************************************************** * This function allocates and initializes a FB vout method. *****************************************************************************/static int Create( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_sys_t *p_sys; char *psz_chroma; char *psz_aspect; int i_mode; struct sigaction sig_tty; /* sigaction for tty change */ struct vt_mode vt_mode; /* vt current mode */ struct termios new_termios; /* Allocate instance and initialize some members */ p_vout->p_sys = p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) return VLC_ENOMEM; memset( p_sys, 0, sizeof(vout_sys_t) ); p_vout->pf_init = Init; p_vout->pf_end = End; p_vout->pf_manage = Manage; p_vout->pf_render = NULL; p_vout->pf_display = Display; p_vout->pf_control = Control; /* Does the framebuffer uses hw acceleration? */ p_sys->b_hw_accel = var_CreateGetBool( p_vout, "fb-hw-accel" ); /* Set tty and fb devices */ p_sys->i_tty = 0; /* 0 == /dev/tty0 == current console */ p_sys->b_tty = var_CreateGetBool( p_vout, "fb-tty" );#ifndef WIN32#if defined(HAVE_ISATTY) /* Check that stdin is a TTY */ if( p_sys->b_tty && !isatty( 0 ) ) { msg_Warn( p_vout, "fd 0 is not a TTY" ); return VLC_EGENERIC; } else { msg_Warn( p_vout, "disabling tty handling, use with caution because " "there is no way to return to the tty." ); }#endif#endif psz_chroma = var_CreateGetNonEmptyString( p_vout, "fb-chroma" ); if( psz_chroma ) { if( strlen( psz_chroma ) == 4 ) { p_sys->i_chroma = VLC_FOURCC( psz_chroma[0], psz_chroma[1], psz_chroma[2], psz_chroma[3] ); msg_Dbg( p_vout, "forcing chroma '%s'", psz_chroma ); } else { msg_Warn( p_vout, "invalid chroma (%s), using defaults.", psz_chroma ); } free( psz_chroma ); psz_chroma = NULL; } p_sys->i_aspect = -1; psz_aspect = var_CreateGetNonEmptyString( p_vout, "fb-aspect-ratio" ); if( psz_aspect ) { char *psz_parser = strchr( psz_aspect, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; p_sys->i_aspect = ( atoi( psz_aspect ) * VOUT_ASPECT_FACTOR ) / atoi( psz_parser ); } msg_Dbg( p_vout, "using aspect ratio %d:%d", atoi( psz_aspect ), atoi( psz_parser ) ); free( psz_aspect ); psz_aspect = NULL; } p_sys->b_auto = false; i_mode = var_CreateGetInteger( p_vout, "fb-mode" ); switch( i_mode ) { case 0: /* QCIF */ p_sys->i_width = 176; p_sys->i_height = 144; break; case 1: /* CIF */ p_sys->i_width = 352; p_sys->i_height = 288; break; case 2: /* NTSC */ p_sys->i_width = 640; p_sys->i_height = 480; break; case 3: /* PAL */ p_sys->i_width = 704; p_sys->i_height = 576; break; case 4: default: p_sys->b_auto = true; break; } /* tty handling */ if( p_sys->b_tty ) { GfxMode( p_sys->i_tty ); /* Set keyboard settings */ if( tcgetattr(0, &p_vout->p_sys->old_termios) == -1 ) { msg_Err( p_vout, "tcgetattr failed" ); } if( tcgetattr(0, &new_termios) == -1 ) { msg_Err( p_vout, "tcgetattr failed" ); } /* new_termios.c_lflag &= ~ (ICANON | ISIG); new_termios.c_lflag |= (ECHO | ECHOCTL); */ new_termios.c_lflag &= ~ (ICANON); new_termios.c_lflag &= ~(ECHO | ECHOCTL); new_termios.c_iflag = 0; new_termios.c_cc[VMIN] = 1; new_termios.c_cc[VTIME] = 0; if( tcsetattr(0, TCSAFLUSH, &new_termios) == -1 ) { msg_Err( p_vout, "tcsetattr failed" ); } ioctl( p_sys->i_tty, VT_RELDISP, VT_ACKACQ ); /* Set-up tty signal handler to be aware of tty changes */ memset( &sig_tty, 0, sizeof( sig_tty ) ); sig_tty.sa_handler = SwitchDisplay; sigemptyset( &sig_tty.sa_mask ); if( sigaction( SIGUSR1, &sig_tty, &p_vout->p_sys->sig_usr1 ) || sigaction( SIGUSR2, &sig_tty, &p_vout->p_sys->sig_usr2 ) ) { msg_Err( p_vout, "cannot set signal handler (%m)" ); tcsetattr(0, 0, &p_vout->p_sys->old_termios); TextMode( p_sys->i_tty ); free( p_vout->p_sys ); return VLC_EGENERIC; } /* Set-up tty according to new signal handler */ if( -1 == ioctl( p_sys->i_tty, VT_GETMODE, &p_vout->p_sys->vt_mode ) ) { msg_Err( p_vout, "cannot get terminal mode (%m)" ); sigaction( SIGUSR1, &p_vout->p_sys->sig_usr1, NULL ); sigaction( SIGUSR2, &p_vout->p_sys->sig_usr2, NULL ); tcsetattr(0, 0, &p_vout->p_sys->old_termios); TextMode( p_sys->i_tty ); free( p_vout->p_sys ); return VLC_EGENERIC; } memcpy( &vt_mode, &p_vout->p_sys->vt_mode, sizeof( vt_mode ) ); vt_mode.mode = VT_PROCESS; vt_mode.waitv = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -