X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fvout_subpictures.c;h=5491fe983dbb3b0f5ce06a55527d9815e22883f1;hb=a1bd8b94477962ef495117ea161246172ce83859;hp=8f58dad36cb384401d102f9359fa205cc92accc6;hpb=449fd28aaf007c6411251dae9d0dbfdc65b135d1;p=vlc diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index 8f58dad36c..5491fe983d 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -30,7 +30,7 @@ # include "config.h" #endif -#include +#include #include #include #include @@ -54,10 +54,11 @@ static picture_t *spu_new_video_buffer( filter_t * ); static void spu_del_video_buffer( filter_t *, picture_t * ); static int spu_ParseChain( spu_t * ); -static void spu_DeleteChain( spu_t * ); static int SubFilterCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); +static int sub_filter_allocation_init( filter_t *, void * ); +static void sub_filter_allocation_clear( filter_t * ); struct filter_owner_sys_t { spu_t *p_spu; @@ -69,6 +70,7 @@ enum { SCALE_TEXT, SCALE_SIZE }; + /** * Creates the subpicture unit * @@ -88,16 +90,19 @@ spu_t *__spu_Create( vlc_object_t *p_this ) p_spu->p_blend = NULL; p_spu->p_text = NULL; p_spu->p_scale = NULL; - p_spu->i_filter = 0; p_spu->pf_control = spu_vaControlDefault; /* Register the default subpicture channel */ p_spu->i_channel = 2; - vlc_mutex_init( p_this, &p_spu->subpicture_lock ); + vlc_mutex_init( &p_spu->subpicture_lock ); vlc_object_attach( p_spu, p_this ); + p_spu->p_chain = filter_chain_New( p_spu, "sub filter", false, + sub_filter_allocation_init, + sub_filter_allocation_clear, + p_spu ); return p_spu; } @@ -125,57 +130,14 @@ int spu_Init( spu_t *p_spu ) int spu_ParseChain( spu_t *p_spu ) { - char *psz_parser; - vlc_value_t val; - var_Get( p_spu, "sub-filter", &val ); - psz_parser = val.psz_string; - - while( psz_parser && *psz_parser ) + char *psz_parser = var_GetString( p_spu, "sub-filter" ); + if( filter_chain_AppendFromString( p_spu->p_chain, psz_parser ) < 0 ) { - config_chain_t *p_cfg; - char *psz_name; - - psz_parser = config_ChainCreate( &psz_name, &p_cfg, psz_parser ); - - msg_Dbg( p_spu, "adding sub-filter: %s", psz_name ); - - p_spu->pp_filter[p_spu->i_filter] = - vlc_object_create( p_spu, VLC_OBJECT_FILTER ); - vlc_object_attach( p_spu->pp_filter[p_spu->i_filter], p_spu ); - p_spu->pp_filter[p_spu->i_filter]->pf_sub_buffer_new = sub_new_buffer; - p_spu->pp_filter[p_spu->i_filter]->pf_sub_buffer_del = sub_del_buffer; - p_spu->pp_filter[p_spu->i_filter]->p_cfg = p_cfg; - p_spu->pp_filter[p_spu->i_filter]->p_module = - module_Need( p_spu->pp_filter[p_spu->i_filter], - "sub filter", psz_name, true ); - if( p_spu->pp_filter[p_spu->i_filter]->p_module ) - { - filter_owner_sys_t *p_sys = malloc( sizeof(filter_owner_sys_t) ); - if( p_sys ) - { - p_spu->pp_filter[p_spu->i_filter]->p_owner = p_sys; - spu_Control( p_spu, SPU_CHANNEL_REGISTER, &p_sys->i_channel ); - p_sys->p_spu = p_spu; - p_spu->i_filter++; - } - } - else - { - msg_Dbg( p_spu, "no sub filter found" ); - config_ChainDestroy( p_spu->pp_filter[p_spu->i_filter]->p_cfg ); - vlc_object_detach( p_spu->pp_filter[p_spu->i_filter] ); - vlc_object_release( p_spu->pp_filter[p_spu->i_filter] ); - } - - if( p_spu->i_filter >= 10 ) - { - msg_Dbg( p_spu, "can't add anymore filters" ); - } - - free( psz_name ); + free( psz_parser ); + return VLC_EGENERIC; } - free( val.psz_string ); + free( psz_parser ); return VLC_SUCCESS; } @@ -188,8 +150,6 @@ void spu_Destroy( spu_t *p_spu ) { int i_index; - vlc_object_detach( p_spu ); - /* Destroy all remaining subpictures */ for( i_index = 0; i_index < VOUT_MAX_SUBPICTURES; i_index++ ) { @@ -226,27 +186,12 @@ void spu_Destroy( spu_t *p_spu ) vlc_object_release( p_spu->p_scale ); } - spu_DeleteChain( p_spu ); + filter_chain_Delete( p_spu->p_chain ); vlc_mutex_destroy( &p_spu->subpicture_lock ); vlc_object_release( p_spu ); } -static void spu_DeleteChain( spu_t *p_spu ) -{ - if( p_spu->i_filter ) - while( p_spu->i_filter ) - { - p_spu->i_filter--; - module_Unneed( p_spu->pp_filter[p_spu->i_filter], - p_spu->pp_filter[p_spu->i_filter]->p_module ); - free( p_spu->pp_filter[p_spu->i_filter]->p_owner ); - config_ChainDestroy( p_spu->pp_filter[p_spu->i_filter]->p_cfg ); - vlc_object_detach( p_spu->pp_filter[p_spu->i_filter] ); - vlc_object_release( p_spu->pp_filter[p_spu->i_filter] ); - } -} - /** * Attach/Detach the SPU from any input * @@ -582,7 +527,10 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, /* Load the blending module */ if( !p_spu->p_blend && p_region ) { - p_spu->p_blend = vlc_object_create( p_spu, VLC_OBJECT_FILTER ); + static const char typename[] = "blend"; + p_spu->p_blend = + vlc_custom_create( p_spu, sizeof(filter_t), VLC_OBJECT_GENERIC, + typename ); vlc_object_attach( p_spu->p_blend, p_spu ); p_spu->p_blend->fmt_out.video.i_x_offset = p_spu->p_blend->fmt_out.video.i_y_offset = 0; @@ -601,9 +549,12 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, * probably want it sooner or later. */ if( !p_spu->p_text && p_region ) { + static const char typename[] = "spu text"; char *psz_modulename = NULL; - p_spu->p_text = vlc_object_create( p_spu, VLC_OBJECT_FILTER ); + p_spu->p_text = + vlc_custom_create( p_spu, sizeof(filter_t), VLC_OBJECT_GENERIC, + typename ); vlc_object_attach( p_spu->p_text, p_spu ); p_spu->p_text->fmt_out.video.i_width = @@ -745,7 +696,10 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt, (((pi_scale_width[ SCALE_DEFAULT ] > 0) || (pi_scale_height[ SCALE_DEFAULT ] > 0)) && ((pi_scale_width[ SCALE_DEFAULT ] != 1000) || (pi_scale_height[ SCALE_DEFAULT ] != 1000)))) ) { - p_spu->p_scale = vlc_object_create( p_spu, VLC_OBJECT_FILTER ); + static const char typename[] = "scale"; + p_spu->p_scale = + vlc_custom_create( p_spu, sizeof(filter_t), VLC_OBJECT_GENERIC, + typename ); vlc_object_attach( p_spu->p_scale, p_spu ); p_spu->p_scale->fmt_out.video.i_chroma = p_spu->p_scale->fmt_in.video.i_chroma = @@ -1114,16 +1068,7 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date, mtime_t ephemer_date; /* Run subpicture filters */ - for( i_index = 0; i_index < p_spu->i_filter; i_index++ ) - { - subpicture_t *p_subpic_filter; - p_subpic_filter = p_spu->pp_filter[i_index]-> - pf_sub_filter( p_spu->pp_filter[i_index], display_date ); - if( p_subpic_filter ) - { - spu_DisplaySubpicture( p_spu, p_subpic_filter ); - } - } + filter_chain_SubFilter( p_spu->p_chain, display_date ); /* We get an easily parsable chained list of subpictures which * ends with NULL since p_subpic was initialized to NULL. */ @@ -1204,12 +1149,13 @@ subpicture_t *spu_SortSubpictures( spu_t *p_spu, mtime_t display_date, * This function destroys the subpictures which belong to the spu channel * corresponding to i_channel_id. *****************************************************************************/ -static void SpuClearChannel( spu_t *p_spu, int i_channel ) +static void SpuClearChannel( spu_t *p_spu, int i_channel, bool b_locked ) { int i_subpic; /* subpicture index */ subpicture_t *p_subpic = NULL; /* first free subpicture */ - vlc_mutex_lock( &p_spu->subpicture_lock ); + if( !b_locked ) + vlc_mutex_lock( &p_spu->subpicture_lock ); for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ ) { @@ -1235,7 +1181,8 @@ static void SpuClearChannel( spu_t *p_spu, int i_channel ) } } - vlc_mutex_unlock( &p_spu->subpicture_lock ); + if( !b_locked ) + vlc_mutex_unlock( &p_spu->subpicture_lock ); } /***************************************************************************** @@ -1254,7 +1201,7 @@ static int spu_vaControlDefault( spu_t *p_spu, int i_query, va_list args ) case SPU_CHANNEL_CLEAR: i = (int)va_arg( args, int ); - SpuClearChannel( p_spu, i ); + SpuClearChannel( p_spu, i, false ); break; default: @@ -1401,8 +1348,32 @@ static int SubFilterCallback( vlc_object_t *p_object, char const *psz_var, spu_t *p_spu = (spu_t *)p_data; vlc_mutex_lock( &p_spu->subpicture_lock ); - spu_DeleteChain( p_spu ); + filter_chain_Reset( p_spu->p_chain, NULL, NULL ); spu_ParseChain( p_spu ); vlc_mutex_unlock( &p_spu->subpicture_lock ); return VLC_SUCCESS; } + +static int sub_filter_allocation_init( filter_t *p_filter, void *p_data ) +{ + spu_t *p_spu = (spu_t *)p_data; + + p_filter->pf_sub_buffer_new = sub_new_buffer; + p_filter->pf_sub_buffer_del = sub_del_buffer; + + filter_owner_sys_t *p_sys = malloc( sizeof(filter_owner_sys_t) ); + if( !p_sys ) return VLC_EGENERIC; + + p_filter->p_owner = p_sys; + spu_Control( p_spu, SPU_CHANNEL_REGISTER, &p_sys->i_channel ); + p_sys->p_spu = p_spu; + + return VLC_SUCCESS; +} + +static void sub_filter_allocation_clear( filter_t *p_filter ) +{ + filter_owner_sys_t *p_sys = p_filter->p_owner; + SpuClearChannel( p_sys->p_spu, p_sys->i_channel, true ); + free( p_filter->p_owner ); +}