📄 fb.c
字号:
vt_mode.relsig = SIGUSR1; vt_mode.acqsig = SIGUSR2; if( -1 == ioctl( p_sys->i_tty, VT_SETMODE, &vt_mode ) ) { msg_Err( p_vout, "cannot set 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; } } if( OpenDisplay( p_vout ) ) { if( p_sys->b_tty ) { ioctl( p_sys->i_tty, VT_SETMODE, &p_vout->p_sys->vt_mode ); 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; } return VLC_SUCCESS;}/***************************************************************************** * Destroy: destroy FB video thread output method ***************************************************************************** * Terminate an output method created by Create *****************************************************************************/static void Destroy( vlc_object_t *p_this ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; CloseDisplay( p_vout ); if( p_vout->p_sys->b_tty ) { /* Reset the terminal */ 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 );}/***************************************************************************** * NewPicture: allocate a picture ***************************************************************************** * Returns 0 on success, -1 otherwise *****************************************************************************/static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic ){ /* We know the chroma, allocate a buffer which will be used * directly by the decoder */ p_pic->p_sys = malloc( sizeof( picture_sys_t ) ); if( p_pic->p_sys == NULL ) { return VLC_ENOMEM; } /* Fill in picture_t fields */ vout_InitPicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma, p_vout->output.i_width, p_vout->output.i_height, p_vout->output.i_aspect ); p_pic->p_sys->p_data = malloc( p_vout->p_sys->i_page_size ); if( !p_pic->p_sys->p_data ) { free( p_pic->p_sys ); p_pic->p_sys = NULL; return VLC_ENOMEM; } p_pic->p->p_pixels = (uint8_t*) p_pic->p_sys->p_data; p_pic->p->i_pixel_pitch = p_vout->p_sys->i_bytes_per_pixel; p_pic->p->i_lines = p_vout->p_sys->var_info.yres; p_pic->p->i_visible_lines = p_vout->p_sys->var_info.yres; if( p_vout->p_sys->var_info.xres_virtual ) { p_pic->p->i_pitch = p_vout->p_sys->var_info.xres_virtual * p_vout->p_sys->i_bytes_per_pixel; } else { p_pic->p->i_pitch = p_vout->p_sys->var_info.xres * p_vout->p_sys->i_bytes_per_pixel; } p_pic->p->i_visible_pitch = p_vout->p_sys->var_info.xres * p_vout->p_sys->i_bytes_per_pixel; p_pic->i_planes = 1; return VLC_SUCCESS;}/***************************************************************************** * FreePicture: destroy a picture allocated with NewPicture ***************************************************************************** * Destroy Image AND associated data. *****************************************************************************/static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic ){ free( p_pic->p_sys->p_data ); free( p_pic->p_sys ); p_pic->p_sys = NULL;}/***************************************************************************** * Init: initialize framebuffer video thread output method *****************************************************************************/static int Init( vout_thread_t *p_vout ){ vout_sys_t *p_sys = p_vout->p_sys; int i_index; picture_t *p_pic = NULL; I_OUTPUTPICTURES = 0; p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_aspect = p_vout->render.i_aspect; p_vout->fmt_out = p_vout->fmt_in; if( p_sys->i_chroma == 0 ) { /* Initialize the output structure: RGB with square pixels, whatever * the input format is, since it's the only format we know */ switch( p_sys->var_info.bits_per_pixel ) { case 8: /* FIXME: set the palette */ p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); break; case 15: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); break; case 16: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); break; case 24: p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); break; case 32: p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); break; default: msg_Err( p_vout, "unknown screen depth %i", p_vout->p_sys->var_info.bits_per_pixel ); return VLC_EGENERIC; } if( p_sys->var_info.bits_per_pixel != 8 ) { p_vout->output.i_rmask = ( (1 << p_sys->var_info.red.length) - 1 ) << p_sys->var_info.red.offset; p_vout->output.i_gmask = ( (1 << p_sys->var_info.green.length) - 1 ) << p_sys->var_info.green.offset; p_vout->output.i_bmask = ( (1 << p_sys->var_info.blue.length) - 1 ) << p_sys->var_info.blue.offset; } } else { p_vout->output.i_chroma = p_sys->i_chroma; } p_vout->fmt_out.i_chroma = p_vout->output.i_chroma; p_vout->output.i_width = p_vout->fmt_out.i_width = p_vout->fmt_out.i_visible_width = p_sys->i_width; p_vout->output.i_height = p_vout->fmt_out.i_height = p_vout->fmt_out.i_visible_height = p_sys->i_height; /* Assume we have square pixels */ if( p_sys->i_aspect < 0 ) { p_vout->output.i_aspect = ( p_sys->i_width * VOUT_ASPECT_FACTOR ) / p_sys->i_height; } else p_vout->output.i_aspect = p_sys->i_aspect; p_vout->fmt_out.i_sar_num = p_vout->fmt_out.i_sar_den = 1; p_vout->fmt_out.i_aspect = p_vout->render.i_aspect = p_vout->output.i_aspect; p_vout->fmt_out.i_x_offset= p_vout->fmt_out.i_y_offset = 0; /* Clear the screen */ memset( p_sys->p_video, 0, p_sys->i_page_size ); if( !p_sys->b_hw_accel ) { /* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */ while( I_OUTPUTPICTURES < MAX_DIRECTBUFFERS ) { p_pic = NULL; /* Find an empty picture slot */ for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) { if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) { p_pic = p_vout->p_picture + i_index; break; } } /* Allocate the picture */ if( p_pic == NULL || NewPicture( p_vout, p_pic ) ) { break; } p_pic->i_status = DESTROYED_PICTURE; p_pic->i_type = DIRECT_PICTURE; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; I_OUTPUTPICTURES++; } } else { /* Try to initialize 1 direct buffer */ p_pic = NULL; /* Find an empty picture slot */ for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) { if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) { p_pic = p_vout->p_picture + i_index; break; } } /* Allocate the picture */ if( p_pic == NULL ) { return VLC_EGENERIC; } /* We know the chroma, allocate a buffer which will be used * directly by the decoder */ p_pic->p->p_pixels = p_vout->p_sys->p_video; p_pic->p->i_pixel_pitch = p_vout->p_sys->i_bytes_per_pixel; p_pic->p->i_lines = p_vout->p_sys->var_info.yres; p_pic->p->i_visible_lines = p_vout->p_sys->var_info.yres; if( p_vout->p_sys->var_info.xres_virtual ) { p_pic->p->i_pitch = p_vout->p_sys->var_info.xres_virtual * p_vout->p_sys->i_bytes_per_pixel; } else { p_pic->p->i_pitch = p_vout->p_sys->var_info.xres * p_vout->p_sys->i_bytes_per_pixel; } p_pic->p->i_visible_pitch = p_vout->p_sys->var_info.xres * p_vout->p_sys->i_bytes_per_pixel; p_pic->i_planes = 1; p_pic->i_status = DESTROYED_PICTURE; p_pic->i_type = DIRECT_PICTURE; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; I_OUTPUTPICTURES++; } return VLC_SUCCESS;}/***************************************************************************** * End: terminate framebuffer video thread output method *****************************************************************************/static void End( vout_thread_t *p_vout ){ if( !p_vout->p_sys->b_hw_accel ) { int i_index; /* Free the direct buffers we allocated */ for( i_index = I_OUTPUTPICTURES ; i_index ; ) { i_index--; FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] ); } } /* Clear the screen */ memset( p_vout->p_sys->p_video, 0, p_vout->p_sys->i_page_size );}/***************************************************************************** * Control: control facility for the vout *****************************************************************************/static int Control( vout_thread_t *p_vout, int i_query, va_list args ){ switch( i_query ) { default: return vout_vaControlDefault( p_vout, i_query, args ); }}/***************************************************************************** * 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': vlc_object_kill( p_vout->p_libvlc ); break; default: break; } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -