📄 osdmenu.c
字号:
#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 0 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 = NULL; 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 ) vout_CopyPicture( p_filter, &p_region->picture, p_pic ); p_region->i_x = 0; p_region->i_y = 0; p_region->i_align = p_filter->p_sys->i_position; p_region->i_alpha = p_filter->p_sys->i_alpha;#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 = NULL; subpicture_region_t *p_region = NULL; if( !p_sys->b_update || (p_sys->i_update <= 0) ) 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 = filter_NewSubpicture( p_filter ); if( !p_spu ) return NULL; p_spu->b_ephemer = true; p_spu->b_fade = true; if( p_filter->p_sys->p_menu->i_style == OSD_MENU_STYLE_CONCAT ) p_spu->b_absolute = true; else p_spu->b_absolute = p_sys->b_absolute; p_spu->i_flags = p_sys->i_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 = 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 == 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 non transparent. */ return p_spu; } if( p_sys->p_vout && p_sys->b_clicked ) { p_sys->b_clicked = false; osd_MenuActivate( p_filter ); } /* 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( !p_region ) { p_filter->pf_sub_buffer_del( p_filter, p_spu ); return NULL; } p_spu->i_width = p_region->fmt.i_visible_width; p_spu->i_height = p_region->fmt.i_visible_height; p_spu->i_alpha = p_filter->p_sys->i_alpha; /* proper positioning of OSD menu image */ if( p_filter->p_sys->p_menu->i_style == OSD_MENU_STYLE_CONCAT ) { p_spu->i_x = p_filter->p_sys->p_menu->p_button->i_x; p_spu->i_y = p_filter->p_sys->p_menu->p_button->i_y; } else { 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; } if( p_filter->p_sys->p_menu->i_style == OSD_MENU_STYLE_CONCAT ) { subpicture_region_t *p_region_list = NULL; subpicture_region_t *p_region_tail = NULL; osd_menu_t *p_osd = p_filter->p_sys->p_menu; osd_button_t *p_button = p_osd->p_button; /* Construct the entire OSD from individual images */ while( p_button != NULL ) { osd_button_t *p_tmp = NULL; subpicture_region_t *p_new = NULL; p_new = create_picture_region( p_filter, p_spu, p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, p_button->p_current_state->p_pic ); if( !p_new ) { /* Cleanup when bailing out */ subpicture_region_t *p_tmp = NULL; while( p_region_list ) { p_tmp = p_region_list->p_next; p_spu->pf_destroy_region( VLC_OBJECT(p_filter), p_region_list ); }; p_spu->pf_destroy_region( VLC_OBJECT(p_filter), p_region ); p_filter->pf_sub_buffer_del( p_filter, p_spu ); return NULL; } p_spu->i_width += p_new->fmt.i_visible_width; p_spu->i_height += p_new->fmt.i_visible_height; if( !p_region_list ) { p_region_list = p_new; p_region_tail = p_new; } else { p_new->i_x = p_region_tail->fmt.i_visible_width; p_new->i_y = p_button->i_y; p_region_tail->p_next = p_new; p_region_tail = p_new; } p_tmp = p_button->p_next; p_button = p_tmp; }; p_region->p_next = p_region_list; }#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 p_spu->p_region = p_region; return p_spu;}static int OSDMenuCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(p_this); VLC_UNUSED(oldval); filter_sys_t *p_sys = (filter_sys_t *) p_data; if( !p_sys ) return VLC_SUCCESS; if( !strncmp( psz_var, OSD_CFG"position", 16) ) {#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) unsigned int i; for( i=0; i < ARRAY_SIZE(pi_pos_values); i++ ) { if( newval.i_int == pi_pos_values[i] ) { p_sys->i_position = newval.i_int % 11; break; } }#undef ARRAY_SIZE } else if( !strncmp( psz_var, OSD_CFG"x", 9) || !strncmp( psz_var, OSD_CFG"y", 9)) { p_sys->b_absolute = true; if( (p_sys->i_x < 0) || (p_sys->i_y < 0) ) { p_sys->b_absolute = false; p_sys->p_menu->i_x = 0; p_sys->p_menu->i_y = 0; } else if( (p_sys->i_x >= 0) || (p_sys->i_y >= 0) ) { p_sys->p_menu->i_x = p_sys->i_x; p_sys->p_menu->i_y = p_sys->i_y; } } else if( !strncmp( psz_var, OSD_CFG"update", 14) ) p_sys->i_update = (mtime_t)(newval.i_int * 1000); else if( !strncmp( psz_var, OSD_CFG"timeout", 15) ) p_sys->i_update = newval.i_int % 1000; else if( !strncmp( psz_var, OSD_CFG"alpha", 13) ) p_sys->i_alpha = newval.i_int % 256; p_sys->b_update = p_sys->b_visible ? true : false; return VLC_SUCCESS;}/***************************************************************************** * MouseEvent: callback for mouse events *****************************************************************************/static int MouseEvent( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(oldval); VLC_UNUSED(newval); filter_sys_t *p_sys = (filter_sys_t *)p_data; vout_thread_t *p_vout = (vout_thread_t*)p_sys->p_vout; int i_x, i_y; int i_v;#define MOUSE_DOWN 1#define MOUSE_CLICKED 2#define MOUSE_MOVE_X 4#define MOUSE_MOVE_Y 8#define MOUSE_MOVE 12 uint8_t mouse= 0; int v_h = p_vout->output.i_height; int v_w = p_vout->output.i_width; if( psz_var[6] == 'x' ) mouse |= MOUSE_MOVE_X; if( psz_var[6] == 'y' ) mouse |= MOUSE_MOVE_Y; if( psz_var[6] == 'c' ) mouse |= MOUSE_CLICKED; i_v = var_GetInteger( p_sys->p_vout, "mouse-button-down" ); if( i_v & 0x1 ) mouse |= MOUSE_DOWN; i_y = var_GetInteger( p_sys->p_vout, "mouse-y" ); i_x = var_GetInteger( p_sys->p_vout, "mouse-x" ); if( i_y < 0 || i_x < 0 || i_y >= v_h || i_x >= v_w ) return VLC_SUCCESS; if( mouse & MOUSE_CLICKED ) { int i_scale_width, i_scale_height; osd_button_t *p_button = NULL; i_scale_width = p_vout->fmt_out.i_visible_width * 1000 / p_vout->fmt_in.i_visible_width; i_scale_height = p_vout->fmt_out.i_visible_height * 1000 / p_vout->fmt_in.i_visible_height; p_button = osd_ButtonFind( p_this, i_x, i_y, v_h, v_w, i_scale_width, i_scale_height ); if( p_button ) { osd_ButtonSelect( p_this, p_button ); p_sys->b_update = p_sys->b_visible ? true : false; p_sys->b_clicked = true; msg_Dbg( p_this, "mouse clicked %s (%d,%d)\n", p_button->psz_name, i_x, i_y ); } } return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -