[vlc-devel] [PATCH 04/11] [RFC] add demux filters that are similar in API to regular demuxers
Rémi Denis-Courmont
remi at remlab.net
Mon Jun 6 18:45:20 CEST 2016
Le 2016-06-06 16:50, Steve Lhomme a écrit :
> ---
> NEWS | 3 ++
> include/vlc_demux.h | 3 ++
> src/input/demux.c | 103
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/input/demux.h | 2 +
> src/input/input.c | 9 +++++
> src/input/var.c | 1 +
> src/libvlc-module.c | 5 +++
> src/playlist/engine.c | 1 +
> 8 files changed, 127 insertions(+)
>
> diff --git a/NEWS b/NEWS
> index 1d7f62b..8ecd09b 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -101,6 +101,9 @@ Stream filter:
> * Added stream prebuffering plugin
> * Removed HTTP Live streaming stream filter
> * Added zlib (a.k.a. deflate) decompression filter
> +
> +Demux filter:
> + * Added a demuxer filter chain to filter or intercept control
> commands and demuxing
>
> Audio output:
> * Complete rewrite of the AudioTrack Android module. This is now
> the default.
> diff --git a/include/vlc_demux.h b/include/vlc_demux.h
> index 8416cad..67b2d79 100644
> --- a/include/vlc_demux.h
> +++ b/include/vlc_demux.h
> @@ -77,6 +77,9 @@ struct demux_t
>
> /* Weak link to parent input */
> input_thread_t *p_input;
> +
> + /* demux_t filter chaining */
> + demux_t *p_next;
> };
>
> /* pf_demux return values */
> diff --git a/src/input/demux.c b/src/input/demux.c
> index 9178928..1874ee3 100644
> --- a/src/input/demux.c
> +++ b/src/input/demux.c
> @@ -133,6 +133,7 @@ demux_t *demux_NewAdvanced( vlc_object_t *p_obj,
> input_thread_t *p_parent_input,
>
> p_demux->pf_demux = NULL;
> p_demux->pf_control = NULL;
> + p_demux->p_next = NULL;
> p_demux->p_sys = NULL;
> p_demux->info.i_update = 0;
> p_demux->info.i_title = 0;
> @@ -342,6 +343,13 @@ void demux_Delete( demux_t *p_demux )
> {
> stream_t *s;
>
> + demux_t *p_next = p_demux->p_next;
> + if ( p_next != NULL )
> + {
> + p_next->s = NULL; /* demux fiters don't own the stream */
Nit.
> + demux_Delete( p_next );
> + }
> +
> module_unneed( p_demux, p_demux->p_module );
> free( p_demux->psz_file );
> free( p_demux->psz_location );
> @@ -737,3 +745,98 @@ int demux_GetSeekpoint( demux_t *p_demux )
> return i_seekpoint;
> return 0;
> }
> +
> +static demux_t *demux_FilterNew( demux_t *p_next, const char *p_name
> )
> +{
> + demux_t *p_demux = vlc_custom_create( VLC_OBJECT( p_next ),
VLC_OBJECT is not needed here.
> + sizeof( demux_t ),
> "demux_filter" );
> + if( unlikely(p_demux == NULL) )
> + return NULL;
> +
> + /* elements from the next demuxer pushed to the top of the chain
> */
> + p_demux->s = p_next->s;
> +
> + p_demux->p_input = NULL;
> + p_demux->pf_control = NULL;
> + p_demux->p_sys = NULL;
> + p_demux->psz_access = NULL;
> + p_demux->psz_demux = NULL;
> + p_demux->psz_location = NULL;
> + p_demux->psz_file = NULL;
> + p_demux->out = NULL;
> + p_demux->p_module =
> + module_need( p_demux, "demux_filter", p_name, p_name != NULL
> );
> +
> + if( p_demux->p_module == NULL )
> + goto error;
> +
> + p_demux->p_next = p_next;
Should be set before module_need().
> +
> + return p_demux;
> +error:
> + vlc_object_release( p_demux );
> + return NULL;
> +}
> +
> +demux_t *demux_FilterChainNew( demux_t *p_demux, const char
> *psz_chain )
> +{
> + if( !psz_chain || !*psz_chain )
> + return NULL;
> +
> + char *psz_parser = strdup(psz_chain);
> + if(!psz_parser)
> + return NULL;
> +
> + vlc_array_t name;
> + vlc_array_init(&name);
> +
> + /* parse chain */
> + while(psz_parser)
> + {
> + config_chain_t *p_cfg;
> + char *psz_name;
> + char *psz_rest_chain = config_ChainCreate( &psz_name,
> &p_cfg, psz_parser );
> + free( psz_parser );
> + psz_parser = psz_rest_chain;
> +
> + vlc_array_append(&name, psz_name);
> + config_ChainDestroy(p_cfg);
> + }
> +
> + int i = vlc_array_count(&name);
> + vlc_array_t module;
> + vlc_array_init(&module);
> + while(i--)
> + {
> + const char *p_name = vlc_array_item_at_index(&name, i);
> + demux_t *p_next = demux_FilterNew( p_demux, p_name );
> + if(!p_next)
> + goto error;
> +
> + vlc_array_append(&module, p_next);
> + p_demux = p_next;
> + }
> +
> + vlc_array_clear(&name);
> + vlc_array_clear(&module);
> +
> + return p_demux;
> + error:
> + i++; /* last module couldn't be created */
> +
> + /* destroy all modules created, starting with the last one */
> + int modules = vlc_array_count(&module);
> + while(modules--)
> + demux_Delete(vlc_array_item_at_index(&module, modules));
> + vlc_array_clear(&module);
> +
> + /* then destroy all names and config which weren't destroyed by
> + * sout_StreamDelete */
> + while(i--)
> + {
> + free(vlc_array_item_at_index(&name, i));
> + }
> + vlc_array_clear(&name);
> +
> + return NULL;
> +}
> diff --git a/src/input/demux.h b/src/input/demux.h
> index 2e5b01a..95f9750 100644
> --- a/src/input/demux.h
> +++ b/src/input/demux.h
> @@ -45,4 +45,6 @@ void demux_ResetUpdateFlags( demux_t *, int );
> int demux_GetTitle( demux_t * );
> int demux_GetSeekpoint( demux_t * );
>
> +demux_t *demux_FilterChainNew( demux_t *p_demux, const char
> *psz_name );
> +
> #endif
> diff --git a/src/input/input.c b/src/input/input.c
> index 92a433c..bd063bd 100644
> --- a/src/input/input.c
> +++ b/src/input/input.c
> @@ -2342,6 +2342,15 @@ static input_source_t *InputSourceNew(
> input_thread_t *p_input,
> return NULL;
> }
>
> + char *psz_demux_chain = var_GetNonEmptyString(p_input,
> "demux-filter");
> + /* add the chain of demux filters */
> + demux_t *p_filtered_demux = demux_FilterChainNew( in->p_demux,
> psz_demux_chain );
> + if ( p_filtered_demux != NULL )
> + in->p_demux = p_filtered_demux;
> + else if ( psz_demux_chain != NULL )
> + msg_Dbg(p_input, "Failed to create demux filter %s",
> psz_demux_chain);
> + free( psz_demux_chain );
> +
> /* Get infos from (access_)demux */
> bool b_can_seek;
> if( demux_Control( in->p_demux, DEMUX_CAN_SEEK, &b_can_seek ) )
> diff --git a/src/input/var.c b/src/input/var.c
> index 6534603..437c614 100644
> --- a/src/input/var.c
> +++ b/src/input/var.c
> @@ -513,6 +513,7 @@ void input_ConfigVarInit ( input_thread_t
> *p_input )
> /* */
> var_Create( p_input, "access", VLC_VAR_STRING |
> VLC_VAR_DOINHERIT );
> var_Create( p_input, "demux", VLC_VAR_STRING | VLC_VAR_DOINHERIT
> );
> + var_Create( p_input, "demux-filter", VLC_VAR_STRING |
> VLC_VAR_DOINHERIT );
> var_Create( p_input, "stream-filter", VLC_VAR_STRING |
> VLC_VAR_DOINHERIT );
>
> /* Meta */
> diff --git a/src/libvlc-module.c b/src/libvlc-module.c
> index 0fee435..ee9566d 100644
> --- a/src/libvlc-module.c
> +++ b/src/libvlc-module.c
> @@ -993,6 +993,10 @@ static const char *const ppsz_prefres[] = {
> #define STREAM_FILTER_LONGTEXT N_( \
> "Stream filters are used to modify the stream that is being
> read. " )
>
> +#define DEMUX_FILTER_TEXT N_("Demux filter module")
> +#define DEMUX_FILTER_LONGTEXT N_( \
> + "Demux filters are used to modify/control the stream that is
> being read. " )
> +
> #define DEMUX_TEXT N_("Demux module")
> #define DEMUX_LONGTEXT N_( \
> "Demultiplexers are used to separate the \"elementary\" streams
> " \
> @@ -1888,6 +1892,7 @@ vlc_module_begin ()
> add_module_list( "stream-filter", "stream_filter", NULL,
> STREAM_FILTER_TEXT, STREAM_FILTER_LONGTEXT,
> false )
>
> + add_string( "demux-filter", NULL, DEMUX_FILTER_TEXT,
> DEMUX_FILTER_LONGTEXT, true )
>
> /* Stream output options */
> set_category( CAT_SOUT )
> diff --git a/src/playlist/engine.c b/src/playlist/engine.c
> index 9f3abf0..1ff64c7 100644
> --- a/src/playlist/engine.c
> +++ b/src/playlist/engine.c
> @@ -472,6 +472,7 @@ static void VariablesInit( playlist_t *p_playlist
> )
>
> /* sout variables */
> var_Create( p_playlist, "sout", VLC_VAR_STRING |
> VLC_VAR_DOINHERIT );
> + var_Create( p_playlist, "demux-filter", VLC_VAR_STRING |
> VLC_VAR_DOINHERIT );
>
> /* */
> var_Create( p_playlist, "album-art", VLC_VAR_INTEGER |
> VLC_VAR_DOINHERIT );
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list