📄 osdmenu.c
字号:
p_filter->pf_sub_filter = Filter; es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_FOURCC( 's','p','u',' ' ) ); p_filter->fmt_out.i_priority = 0; msg_Dbg( p_filter, "successfully loaded osdmenu filter" ); return VLC_SUCCESS;error: msg_Err( p_filter, "osdmenu filter discarded" ); vlc_mutex_destroy( &p_filter->p_sys->lock ); if( p_filter->p_sys->p_menu ) { osd_MenuDelete( p_this, p_filter->p_sys->p_menu ); p_filter->p_sys->p_menu = NULL; } if( p_filter->p_sys->psz_file ) free( p_filter->p_sys->psz_file ); if( p_filter->p_sys ) free( p_filter->p_sys ); return VLC_EGENERIC; }/***************************************************************************** * DestroyFilter: Make a clean exit of this plugin *****************************************************************************/static void DestroyFilter( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t*)p_this; filter_sys_t *p_sys = p_filter->p_sys; var_Destroy( p_this, OSD_CFG "file" ); var_Destroy( p_this, OSD_CFG "x" ); var_Destroy( p_this, OSD_CFG "y" ); var_Destroy( p_this, OSD_CFG "position" ); var_Destroy( p_this, OSD_CFG "timeout" ); var_Destroy( p_this, OSD_CFG "update" ); var_DelCallback( p_sys->p_menu, "osd-menu-update", OSDMenuUpdateEvent, p_filter ); var_DelCallback( p_sys->p_menu, "osd-menu-visible", OSDMenuVisibleEvent, p_filter ); osd_MenuDelete( p_filter, p_sys->p_menu ); vlc_mutex_destroy( &p_filter->p_sys->lock ); if( p_sys->psz_file) free( p_sys->psz_file ); if( p_sys ) free( p_sys ); msg_Dbg( p_filter, "osdmenu filter destroyed" );}/***************************************************************************** * OSDMenuEvent: callback for OSD Menu events *****************************************************************************/static int OSDMenuVisibleEvent( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ filter_t *p_filter = (filter_t *) p_data; p_filter->p_sys->b_visible = VLC_TRUE; return VLC_SUCCESS;}static int OSDMenuUpdateEvent( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ filter_t *p_filter = (filter_t *) p_data; p_filter->p_sys->b_update = VLC_TRUE; p_filter->p_sys->i_end_date = (mtime_t) 0; return VLC_SUCCESS;}#if 0/***************************************************************************** * create_text_region : compose a text region SPU *****************************************************************************/static subpicture_region_t *create_text_region( filter_t *p_filter, subpicture_t *p_spu, int i_width, int i_height, const char *psz_text ){ subpicture_region_t *p_region; video_format_t fmt; /* Create new SPU region */ memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_chroma = VLC_FOURCC( 'T','E','X','T' ); fmt.i_aspect = VOUT_ASPECT_FACTOR; fmt.i_sar_num = fmt.i_sar_den = 1; fmt.i_width = fmt.i_visible_width = i_width; fmt.i_height = fmt.i_visible_height = i_height; fmt.i_x_offset = fmt.i_y_offset = 0; p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt ); if( !p_region ) { msg_Err( p_filter, "cannot allocate another SPU region" ); return NULL; } p_region->psz_text = strdup( psz_text ); p_region->i_x = 0; p_region->i_y = 40;#if 1 msg_Dbg( p_filter, "SPU text region position (%d,%d) (%d,%d) [%s]", p_region->i_x, p_region->i_y, p_region->fmt.i_width, p_region->fmt.i_height, p_region->psz_text );#endif return p_region;}#endif/***************************************************************************** * create_picture_region : compose a picture region SPU *****************************************************************************/static subpicture_region_t *create_picture_region( filter_t *p_filter, subpicture_t *p_spu, int i_width, int i_height, picture_t *p_pic ){ subpicture_region_t *p_region; video_format_t fmt; if( !p_spu ) return NULL; /* Create new SPU region */ memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_chroma = (p_pic == NULL) ? VLC_FOURCC('Y','U','V','P') : VLC_FOURCC('Y','U','V','A'); fmt.i_aspect = VOUT_ASPECT_FACTOR; fmt.i_sar_num = fmt.i_sar_den = 1; fmt.i_width = fmt.i_visible_width = i_width; fmt.i_height = fmt.i_visible_height = i_height; fmt.i_x_offset = fmt.i_y_offset = 0; p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt ); if( !p_region ) { msg_Err( p_filter, "cannot allocate SPU region" ); p_filter->pf_sub_buffer_del( p_filter, p_spu ); return NULL; } if( !p_pic && ( fmt.i_chroma == VLC_FOURCC('Y','U','V','P') ) ) { p_region->fmt.p_palette->i_entries = 0; p_region->fmt.i_width = p_region->fmt.i_visible_width = 0; p_region->fmt.i_height = p_region->fmt.i_visible_height = 0; } if( p_pic != NULL ) vout_CopyPicture( p_filter, &p_region->picture, p_pic ); p_region->i_x = 0; p_region->i_y = 0;#if 0 msg_Dbg( p_filter, "SPU picture region position (%d,%d) (%d,%d) [%p]", p_region->i_x, p_region->i_y, p_region->fmt.i_width, p_region->fmt.i_height, p_pic );#endif return p_region;}/**************************************************************************** * Filter: the whole thing **************************************************************************** * This function outputs subpictures at regular time intervals. ****************************************************************************/static subpicture_t *Filter( filter_t *p_filter, mtime_t i_date ){ filter_sys_t *p_sys = p_filter->p_sys; subpicture_t *p_spu; subpicture_region_t *p_region; if( !p_sys->b_update ) return NULL; /* Am I too early? */ if( ( ( p_sys->i_last_date + p_sys->i_update ) > i_date ) && ( p_sys->i_end_date > 0 ) ) return NULL; /* we are too early, so wait */ /* Allocate the subpicture internal data. */ p_spu = p_filter->pf_sub_buffer_new( p_filter ); if( !p_spu ) return NULL; p_spu->b_ephemer = VLC_TRUE; p_spu->b_fade = VLC_TRUE; p_spu->b_absolute = p_sys->b_absolute; p_spu->i_flags = p_sys->position; /* Determine the duration of the subpicture */ if( p_sys->i_end_date > 0 ) { /* Display the subpicture again. */ p_spu->i_stop = p_sys->i_end_date - i_date; if( ( i_date + p_sys->i_update ) >= p_sys->i_end_date ) p_sys->b_update = VLC_FALSE; } else { /* There is a new OSD picture to display */ p_spu->i_stop = i_date + p_sys->i_timeout; p_sys->i_end_date = p_spu->i_stop; } p_sys->i_last_date = i_date; p_spu->i_start = p_sys->i_last_date = i_date; /* Send an empty subpicture to clear the display * when OSD menu should be hidden and menu picture is not allocated. */ if( !p_filter->p_sys->p_menu->p_state->p_pic || ( p_filter->p_sys->b_visible == VLC_FALSE ) ) { /* Create new spu regions and allocate an empty picture in it. */ p_region = create_picture_region( p_filter, p_spu, p_filter->p_sys->p_menu->p_state->i_width, p_filter->p_sys->p_menu->p_state->i_height, NULL ); /* proper positioning of OSD menu image */ p_spu->i_x = p_filter->p_sys->p_menu->p_state->i_x; p_spu->i_y = p_filter->p_sys->p_menu->p_state->i_y; p_spu->p_region = p_region; p_spu->i_alpha = 0xFF; /* Picture is completely transparent. */ return p_spu; } /* Create new spu regions */ p_region = create_picture_region( p_filter, p_spu, p_filter->p_sys->p_menu->p_state->i_width, p_filter->p_sys->p_menu->p_state->i_height, p_filter->p_sys->p_menu->p_state->p_pic );#if 0 p_region->p_next = create_text_region( p_filter, p_spu, p_filter->p_sys->p_menu->p_state->i_width, p_filter->p_sys->p_menu->p_state->i_height, p_filter->p_sys->p_menu->p_state->p_visible->psz_action );#endif /* proper positioning of OSD menu image */ p_spu->i_x = p_filter->p_sys->p_menu->p_state->i_x; p_spu->i_y = p_filter->p_sys->p_menu->p_state->i_y; p_spu->p_region = p_region; return p_spu;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -