📄 logo.c
字号:
{ vlc_value_t valy; var_Get( p_vout->p_sys->p_vout, "mouse-y", &valy ); if( newval.i_int >= (int)p_sys->posx && valy.i_int >= (int)p_sys->posy && newval.i_int <= (int)(p_sys->posx + p_sys->i_width) && valy.i_int <= (int)(p_sys->posy + p_sys->i_height) ) { p_sys->posx = __MIN( __MAX( p_sys->posx + i_delta, 0 ), p_vout->output.i_width - p_sys->i_width ); } } else if( psz_var[6] == 'y' ) { vlc_value_t valx; var_Get( p_vout->p_sys->p_vout, "mouse-x", &valx ); if( valx.i_int >= (int)p_sys->posx && newval.i_int >= (int)p_sys->posy && valx.i_int <= (int)(p_sys->posx + p_sys->i_width) && newval.i_int <= (int)(p_sys->posy + p_sys->i_height) ) { p_sys->posy = __MIN( __MAX( p_sys->posy + i_delta, 0 ), p_vout->output.i_height - p_sys->i_height ); } } return VLC_SUCCESS;}/***************************************************************************** * Control: control facility for the vout (forwards to child vout) *****************************************************************************/static int Control( vout_thread_t *p_vout, int i_query, va_list args ){ return vout_vaControl( p_vout->p_sys->p_vout, i_query, args );}/***************************************************************************** * SendEventsToChild: forward events to the child/children vout *****************************************************************************/static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; var_Set( p_vout->p_sys->p_vout, psz_var, newval ); return VLC_SUCCESS;}/***************************************************************************** * filter_sys_t: logo filter descriptor *****************************************************************************/struct filter_sys_t{ logo_list_t *p_logo_list; int pos, posx, posy; vlc_bool_t b_absolute; mtime_t i_last_date; /* On the fly control variable */ vlc_bool_t b_need_update;};static subpicture_t *Filter( filter_t *, mtime_t );/***************************************************************************** * CreateFilter: allocates logo video filter *****************************************************************************/static int CreateFilter( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; logo_list_t *p_logo_list; /* Allocate structure */ p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) ); if( p_sys == NULL ) { msg_Err( p_filter, "out of memory" ); return VLC_ENOMEM; } p_logo_list = p_sys->p_logo_list = malloc( sizeof( logo_list_t ) ); if( p_logo_list == NULL ) { msg_Err( p_filter, "out of memory" ); free( p_sys ); return VLC_ENOMEM; } /* Hook used for callback variables */ p_logo_list->psz_filename = var_CreateGetString( p_filter->p_libvlc , "logo-file" ); if( !p_logo_list->psz_filename || !*p_logo_list->psz_filename ) { msg_Err( p_this, "logo file not specified" ); free( p_sys ); free( p_logo_list ); return VLC_EGENERIC; } p_sys->posx = var_CreateGetInteger( p_filter->p_libvlc , "logo-x" ); p_sys->posy = var_CreateGetInteger( p_filter->p_libvlc , "logo-y" ); p_sys->pos = var_CreateGetInteger( p_filter->p_libvlc , "logo-position" ); p_logo_list->i_alpha = __MAX( __MIN( var_CreateGetInteger( p_filter->p_libvlc, "logo-transparency"), 255 ), 0 ); p_logo_list->i_delay = var_CreateGetInteger( p_filter->p_libvlc , "logo-delay" ); p_logo_list->i_repeat = var_CreateGetInteger( p_filter->p_libvlc , "logo-repeat" ); var_AddCallback( p_filter->p_libvlc, "logo-file", LogoCallback, p_sys ); var_AddCallback( p_filter->p_libvlc, "logo-x", LogoCallback, p_sys ); var_AddCallback( p_filter->p_libvlc, "logo-y", LogoCallback, p_sys ); var_AddCallback( p_filter->p_libvlc, "logo-position", LogoCallback, p_sys ); var_AddCallback( p_filter->p_libvlc, "logo-transparency", LogoCallback, p_sys ); var_AddCallback( p_filter->p_libvlc, "logo-repeat", LogoCallback, p_sys ); vlc_mutex_init( p_filter, &p_logo_list->lock ); vlc_mutex_lock( &p_logo_list->lock ); LoadLogoList( p_this, p_logo_list ); vlc_mutex_unlock( &p_logo_list->lock ); /* Misc init */ p_filter->pf_sub_filter = Filter; p_sys->b_need_update = VLC_TRUE; p_sys->i_last_date = 0; return VLC_SUCCESS;}/***************************************************************************** * DestroyFilter: destroy logo video filter *****************************************************************************/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; vlc_mutex_destroy( &p_sys->p_logo_list->lock ); FreeLogoList( p_sys->p_logo_list ); free( p_sys->p_logo_list ); free( p_sys ); /* Delete the logo variables from INPUT */ var_Destroy( p_filter->p_libvlc , "logo-file" ); var_Destroy( p_filter->p_libvlc , "logo-x" ); var_Destroy( p_filter->p_libvlc , "logo-y" ); var_Destroy( p_filter->p_libvlc , "logo-delay" ); var_Destroy( p_filter->p_libvlc , "logo-repeat" ); var_Destroy( p_filter->p_libvlc , "logo-position" ); var_Destroy( p_filter->p_libvlc , "logo-transparency" );}/***************************************************************************** * Filter: the whole thing ***************************************************************************** * This function outputs subpictures at regular time intervals. *****************************************************************************/static subpicture_t *Filter( filter_t *p_filter, mtime_t date ){ filter_sys_t *p_sys = p_filter->p_sys; logo_list_t *p_logo_list = p_sys->p_logo_list; subpicture_t *p_spu; subpicture_region_t *p_region; video_format_t fmt; picture_t *p_pic; logo_t *p_logo; vlc_mutex_lock( &p_logo_list->lock ); /* Basic test: b_need_update occurs on a dynamic change, & i_next_pic is the general timer, when to look at updating the logo image */ if( ( ( !p_sys->b_need_update ) && ( p_logo_list->i_next_pic > date ) ) || !p_logo_list->i_repeat ) { vlc_mutex_unlock( &p_logo_list->lock ); return 0; } /* prior code tested on && p_sys->i_last_date +5000000 > date ) return 0; */ /* adjust index to the next logo */ p_logo_list->i_counter = ( p_logo_list->i_counter + 1 )%p_logo_list->i_count; p_logo = &p_logo_list->p_logo[p_logo_list->i_counter]; p_pic = p_logo->p_pic; /* Allocate the subpicture internal data. */ p_spu = p_filter->pf_sub_buffer_new( p_filter ); if( !p_spu ) { vlc_mutex_unlock( &p_logo_list->lock ); return NULL; } p_spu->b_absolute = p_sys->b_absolute; p_spu->i_start = p_sys->i_last_date = date; p_spu->i_stop = 0; p_spu->b_ephemer = VLC_TRUE; p_sys->b_need_update = VLC_FALSE; p_logo_list->i_next_pic = date + ( p_logo->i_delay != -1 ? p_logo->i_delay : p_logo_list->i_delay ) * 1000; if( p_logo_list->i_repeat != -1 && p_logo_list->i_counter == 0 ) { p_logo_list->i_repeat--; if( p_logo_list->i_repeat == 0 ) { vlc_mutex_unlock( &p_logo_list->lock ); return p_spu; } } if( !p_pic || !p_logo->i_alpha || ( p_logo->i_alpha == -1 && !p_logo_list->i_alpha ) ) { /* Send an empty subpicture to clear the display */ vlc_mutex_unlock( &p_logo_list->lock ); return p_spu; } /* Create new SPU region */ memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_chroma = 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 = p_pic->p[Y_PLANE].i_visible_pitch; fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines; 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 ); vlc_mutex_unlock( &p_logo_list->lock ); return NULL; } vout_CopyPicture( p_filter, &p_region->picture, p_pic ); vlc_mutex_unlock( &p_logo_list->lock ); /* where to locate the logo: */ if( p_sys->posx < 0 || p_sys->posy < 0 ) { /* set to one of the 9 relative locations */ p_spu->i_flags = p_sys->pos; p_spu->i_x = 0; p_spu->i_y = 0; p_spu->b_absolute = VLC_FALSE; } else { /* set to an absolute xy, referenced to upper left corner */ p_spu->i_flags = OSD_ALIGN_LEFT | OSD_ALIGN_TOP; p_spu->i_x = p_sys->posx; p_spu->i_y = p_sys->posy; p_spu->b_absolute = VLC_TRUE; } p_spu->p_region = p_region; p_spu->i_alpha = ( p_logo->i_alpha != -1 ? p_logo->i_alpha : p_logo_list->i_alpha ); return p_spu;}/***************************************************************************** * Callback to update params on the fly *****************************************************************************/static int LogoCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ filter_sys_t *p_sys = (filter_sys_t *)p_data; logo_list_t *p_logo_list = p_sys->p_logo_list; if( !strncmp( psz_var, "logo-file", 6 ) ) { vlc_mutex_lock( &p_logo_list->lock ); FreeLogoList( p_logo_list ); p_logo_list->psz_filename = strdup( newval.psz_string ); LoadLogoList( p_this, p_logo_list ); vlc_mutex_unlock( &p_logo_list->lock ); p_sys->b_need_update = VLC_TRUE; } else if ( !strncmp( psz_var, "logo-x", 6 ) ) { p_sys->posx = newval.i_int; } else if ( !strncmp( psz_var, "logo-y", 6 ) ) { p_sys->posy = newval.i_int; } else if ( !strncmp( psz_var, "logo-position", 12 ) ) { p_sys->pos = newval.i_int; } else if ( !strncmp( psz_var, "logo-transparency", 9 ) ) { vlc_mutex_lock( &p_logo_list->lock ); p_logo_list->i_alpha = __MAX( __MIN( newval.i_int, 255 ), 0 ); vlc_mutex_unlock( &p_logo_list->lock ); } else if ( !strncmp( psz_var, "logo-repeat", 11 ) ) { vlc_mutex_lock( &p_logo_list->lock ); p_logo_list->i_repeat = newval.i_int; vlc_mutex_unlock( &p_logo_list->lock ); } p_sys->b_need_update = VLC_TRUE; return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -