vlc | branch: master | Steve Lhomme <[email protected]> | Sun Jun 12 08:22:00 2016 +0200| [3e2e54bc6a09e9b09d2749b5da3b1a02d5210937] | committer: Thomas Guillem
core: add demux filters that are similar in API to regular demuxers Signed-off-by: Thomas Guillem <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3e2e54bc6a09e9b09d2749b5da3b1a02d5210937 --- NEWS | 3 ++ include/vlc_demux.h | 3 ++ src/input/demux.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ src/input/demux.h | 2 ++ src/input/input.c | 15 ++++++++ src/input/var.c | 1 + src/libvlc-module.c | 5 +++ src/playlist/engine.c | 1 + 8 files changed, 125 insertions(+) diff --git a/NEWS b/NEWS index 69bde4c..3d46f2e 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 8f7ebec..a520c52 100644 --- a/include/vlc_demux.h +++ b/include/vlc_demux.h @@ -79,6 +79,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 9d962f5..3f5d0c9 100644 --- a/src/input/demux.c +++ b/src/input/demux.c @@ -134,6 +134,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; @@ -343,6 +344,10 @@ void demux_Delete( demux_t *p_demux ) { stream_t *s; + demux_t *p_next = p_demux->p_next; + if ( p_next != NULL ) + demux_Delete( p_next ); + module_unneed( p_demux, p_demux->p_module ); free( p_demux->psz_file ); free( p_demux->psz_location ); @@ -682,3 +687,93 @@ int demux_GetSeekpoint( demux_t *p_demux ) return i_seekpoint; return p_demux->info.i_seekpoint; } + +static demux_t *demux_FilterNew( demux_t *p_next, const char *p_name ) +{ + demux_t *p_demux = vlc_custom_create( p_next, sizeof( demux_t ), "demux_filter" ); + if( unlikely(p_demux == NULL) ) + return NULL; + + p_demux->p_next = p_next; + p_demux->s = NULL; + p_demux->p_input = 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; + + 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 5b75cbc..c981a8d 100644 --- a/src/input/demux.h +++ b/src/input/demux.h @@ -44,4 +44,6 @@ unsigned demux_TestAndClearFlags( demux_t *, unsigned ); 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 6fa10f0..ff287fd 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -682,6 +682,8 @@ static void MainLoop( input_thread_t *p_input, bool b_interactive ) var_InheritBool( p_input, "play-and-pause" ); demux_t *p_demux = p_input->p->master->p_demux; + while (p_demux->p_next) + p_demux = p_demux->p_next; const bool b_can_demux = p_demux->pf_demux != NULL; while( !input_Stopped( p_input ) && p_input->p->i_state != ERROR_S ) @@ -1858,6 +1860,8 @@ static bool Control( input_thread_t *p_input, { demux_t *p_demux = p_input->p->master->p_demux; int i_ret = VLC_EGENERIC; + while (p_demux->p_next) + p_demux = p_demux->p_next; if( p_demux->s == NULL ) { @@ -2304,6 +2308,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 ) ) @@ -2315,6 +2328,8 @@ static input_source_t *InputSourceNew( input_thread_t *p_input, in->b_can_pace_control = false; demux_t *p_demux = in->p_demux; + while (p_demux->p_next) + p_demux = p_demux->p_next; assert( p_demux->pf_demux != NULL || !in->b_can_pace_control ); if( p_demux->s != NULL ) 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 ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
