Commit 3e2e54bc authored by Steve Lhomme's avatar Steve Lhomme Committed by Thomas Guillem

core: add demux filters that are similar in API to regular demuxers

Signed-off-by: Thomas Guillem's avatarThomas Guillem <thomas@gllm.fr>
parent 9350aedb
......@@ -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.
......
......@@ -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 */
......
......@@ -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;
}
......@@ -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
......@@ -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 )
......
......@@ -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 */
......
......@@ -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 )
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment