[vlc-devel] [PATCH 04/11] [RFC] add demux filters that are similar in API to regular demuxers
Steve Lhomme
robux4 at videolabs.io
Mon Jun 6 16:50:00 CEST 2016
---
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 */
+ 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 ),
+ 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;
+
+ 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 );
--
2.7.0
More information about the vlc-devel
mailing list