vlc | branch: master | Thomas Guillem <[email protected]> | Fri May 26 13:50:07 2017 +0200| [d10136b3885b337badbb7526e13bb5ee49cdd592] | committer: Jean-Baptiste Kempf
video_chroma: chain: add a video filter This new "chain" video filter will try to add a video converter before the requested video filter. Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d10136b3885b337badbb7526e13bb5ee49cdd592 --- modules/video_chroma/chain.c | 115 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/modules/video_chroma/chain.c b/modules/video_chroma/chain.c index 13ea543c9a..3cd4e9f544 100644 --- a/modules/video_chroma/chain.c +++ b/modules/video_chroma/chain.c @@ -1,7 +1,7 @@ /***************************************************************************** * chain.c : chain multiple video filter modules as a last resort solution ***************************************************************************** - * Copyright (C) 2007-2008 VLC authors and VideoLAN + * Copyright (C) 2007-2017 VLC authors and VideoLAN * $Id$ * * Authors: Antoine Cellerier <dionoea at videolan dot org> @@ -37,13 +37,17 @@ /***************************************************************************** * Module descriptor *****************************************************************************/ -static int Activate ( vlc_object_t * ); -static void Destroy ( vlc_object_t * ); +static int ActivateConverter ( vlc_object_t * ); +static int ActivateFilter ( vlc_object_t * ); +static void Destroy ( vlc_object_t * ); vlc_module_begin () set_description( N_("Video filtering using a chain of video filter modules") ) set_capability( "video converter", 1 ) - set_callbacks( Activate, Destroy ) + set_callbacks( ActivateConverter, Destroy ) + add_submodule () + set_capability( "video filter", 0 ) + set_callbacks( ActivateFilter, Destroy ) vlc_module_end () /***************************************************************************** @@ -54,6 +58,7 @@ static picture_t *Chain ( filter_t *, picture_t * ); static int BuildTransformChain( filter_t *p_filter ); static int BuildChromaResize( filter_t * ); static int BuildChromaChain( filter_t *p_filter ); +static int BuildFilterChain( filter_t *p_filter ); static int CreateChain( filter_t *p_parent, es_format_t *p_fmt_mid ); static filter_t * AppendTransform( filter_chain_t *p_chain, es_format_t *p_fmt_in, es_format_t *p_fmt_out ); @@ -93,20 +98,11 @@ static picture_t *BufferNew( filter_t *p_filter ) ***************************************************************************** * This function allocates and initializes a chroma function *****************************************************************************/ -static int Activate( vlc_object_t *p_this ) +static int Activate( filter_t *p_filter, int (*pf_build)(filter_t *) ) { - filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; int i_ret = VLC_EGENERIC; - const bool b_chroma = p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma; - const bool b_resize = p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width || - p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height; - const bool b_transform = p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation; - - if( !b_chroma && !b_resize && !b_transform) - return VLC_EGENERIC; - p_sys = p_filter->p_sys = calloc( 1, sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; @@ -136,12 +132,8 @@ static int Activate( vlc_object_t *p_this ) int level = var_GetInteger( p_filter, MODULE_STRING "-level" ); if( level < 0 || level > CHAIN_LEVEL_MAX ) msg_Err( p_filter, "Too high level of recursion (%d)", level ); - else if( b_transform ) - i_ret = BuildTransformChain( p_filter ); - else if( b_chroma && b_resize ) - i_ret = BuildChromaResize( p_filter ); - else if( b_chroma ) - i_ret = BuildChromaChain( p_filter ); + else + i_ret = pf_build( p_filter ); if( i_ret ) { @@ -156,6 +148,36 @@ static int Activate( vlc_object_t *p_this ) return VLC_SUCCESS; } +static int ActivateConverter( vlc_object_t *p_this ) +{ + filter_t *p_filter = (filter_t *)p_this; + + const bool b_chroma = p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma; + const bool b_resize = p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width || + p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height; + + const bool b_chroma_resize = b_chroma && b_resize; + const bool b_transform = p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation; + + if( !b_chroma && !b_chroma_resize && !b_transform) + return VLC_EGENERIC; + + return Activate( p_filter, b_transform ? BuildTransformChain : + b_chroma_resize ? BuildChromaResize : + BuildChromaChain ); +} + +static int ActivateFilter( vlc_object_t *p_this ) +{ + filter_t *p_filter = (filter_t *)p_this; + + if( !p_filter->b_allow_fmt_out_change || p_filter->psz_name == NULL ) + return VLC_EGENERIC; + + /* Try to add a converter before the requested filter */ + return Activate( p_filter, BuildFilterChain ); +} + static void Destroy( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; @@ -262,6 +284,59 @@ static int BuildChromaChain( filter_t *p_filter ) return i_ret; } +static int BuildFilterChain( filter_t *p_filter ) +{ + es_format_t fmt_mid; + int i_ret = VLC_EGENERIC; + + /* Now try chroma format list */ + for( int i = 0; pi_allowed_chromas[i]; i++ ) + { + filter_chain_Reset( p_filter->p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out ); + + const vlc_fourcc_t i_chroma = pi_allowed_chromas[i]; + if( i_chroma == p_filter->fmt_in.i_codec || + i_chroma == p_filter->fmt_out.i_codec ) + continue; + + msg_Dbg( p_filter, "Trying to use chroma %4.4s as middle man", + (char*)&i_chroma ); + + es_format_Copy( &fmt_mid, &p_filter->fmt_in ); + fmt_mid.i_codec = + fmt_mid.video.i_chroma = i_chroma; + fmt_mid.video.i_rmask = 0; + fmt_mid.video.i_gmask = 0; + fmt_mid.video.i_bmask = 0; + video_format_FixRgb(&fmt_mid.video); + + if( filter_chain_AppendConverter( p_filter->p_sys->p_chain, + NULL, &fmt_mid ) == VLC_SUCCESS ) + { + if( filter_chain_AppendFilter( p_filter->p_sys->p_chain, + p_filter->psz_name, p_filter->p_cfg, + &fmt_mid, &fmt_mid ) ) + { + es_format_Clean( &fmt_mid ); + i_ret = VLC_SUCCESS; + break; + } + } + es_format_Clean( &fmt_mid ); + } + if (i_ret == VLC_SUCCESS) + { + es_format_Clean( &p_filter->fmt_out ); + es_format_Copy( &p_filter->fmt_out, + filter_chain_GetFmtOut( p_filter->p_sys->p_chain ) ); + } + else + filter_chain_Reset( p_filter->p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out ); + + var_Destroy( p_filter, MODULE_STRING "-level" ); + return i_ret; +} + /***************************************************************************** * *****************************************************************************/ _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
