{
VLC_COMMON_MEMBERS
- /* Module properties */
+ /* Module properties for stream filter */
module_t *p_module;
- /* For stream filter they will hold an array of stream sources */
- int i_source;
- stream_t **pp_source;
+ /* Stream source for stream filter */
+ stream_t *p_source;
/* */
int (*pf_read) ( stream_t *, void *p_read, unsigned int i_read );
int (*pf_peek) ( stream_t *, const uint8_t **pp_peek, unsigned int i_peek );
int (*pf_control)( stream_t *, int i_query, va_list );
+
+ /* */
void (*pf_destroy)( stream_t *);
/* Private data for module */
STREAM_CONTROL_ACCESS, /* arg1= int i_access_query, args res: can fail
if access unreachable or access control answer */
+ /* You should update size of source if any and then update size
+ * FIXME find a way to avoid it */
+ STREAM_UPDATE_SIZE,
+
+ /* */
STREAM_GET_CONTENT_TYPE, /**< arg1= char ** res=can fail */
- /* SET_RECORD:
- * XXX only data read through stream_Read/Block will be recorded */
+ /* XXX only data read through stream_Read/Block will be recorded */
STREAM_SET_RECORD_STATE, /**< arg1=bool, arg2=const char *psz_ext (if arg1 is true) res=can fail */
};
input/vlm_internal.h \
input/stream.c \
input/stream_demux.c \
+ input/stream_filter.c \
input/stream_memory.c \
input/subtitles.c \
input/var.c \
{
es_out_SetTime( p_input->p->p_es_out, -1 );
- access_Control( p_access, ACCESS_SET_TITLE, i_title );
- stream_AccessReset( p_input->p->input.p_stream );
+ stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
+ ACCESS_SET_TITLE, i_title );
}
}
break;
{
es_out_SetTime( p_input->p->p_es_out, -1 );
- access_Control( p_access, ACCESS_SET_SEEKPOINT,
- i_seekpoint );
- stream_AccessReset( p_input->p->input.p_stream );
+ stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
+ ACCESS_SET_SEEKPOINT, i_seekpoint );
}
}
break;
{
input_SendEventTitle( p_input, p_access->info.i_title );
- stream_AccessUpdate( p_input->p->input.p_stream );
+ stream_Control( p_input->p->input.p_stream, STREAM_UPDATE_SIZE );
p_access->info.i_update &= ~INPUT_UPDATE_TITLE;
}
var_Set( p_input, "can-seek", val );
}
+ /* TODO (maybe)
+ * do not let stream_AccessNew access input-list
+ * but give it a list of access ? */
+
/* Autodetect extra files if none specified */
char *psz_input_list = var_CreateGetNonEmptyString( p_input, "input-list" );
if( !psz_input_list )
/* Create the stream_t */
in->p_stream = stream_AccessNew( in->p_access, p_input->b_preparsing );
- /* Restor old value */
+ /* Restore old value */
if( !psz_input_list )
var_SetString( p_input, "input-list", "" );
free( psz_input_list );
goto error;
}
+ /* Add auto stream filter */
+ for( ;; )
+ {
+ stream_t *p_filter = stream_FilterNew( in->p_stream, NULL );
+ if( !p_filter )
+ break;
+
+ msg_Dbg( p_input, "Inserted a stream filter" );
+ in->p_stream = p_filter;
+ }
+
+ /* Add user stream filter */
+ psz_tmp = psz = var_GetNonEmptyString( p_input, "stream-filter" );
+ while( psz && *psz )
+ {
+ stream_t *p_filter;
+ char *psz_end = strchr( psz, ':' );
+
+ if( psz_end )
+ *psz_end++ = '\0';
+
+ p_filter = stream_FilterNew( in->p_stream, psz );
+ if( p_filter )
+ in->p_stream = p_filter;
+ else
+ msg_Warn( p_input, "failed to insert stream filter %s", psz );
+
+ psz = psz_end;
+ }
+ free( psz_tmp );
+
/* Open a demuxer */
if( *psz_demux == '\0' && *in->p_access->psz_demux )
{
if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_stream_record ) )
in->b_can_stream_record = false;
#ifdef ENABLE_SOUT
- if( !var_CreateGetBool( p_input, "input-record-native" ) )
+ if( !var_GetBool( p_input, "input-record-native" ) )
in->b_can_stream_record = false;
var_SetBool( p_input, "can-record", true );
#else
}
/****************************************************************************
- * stream_AccessReset:
+ * AStreamControlReset:
****************************************************************************/
-void stream_AccessReset( stream_t *s )
+static void AStreamControlReset( stream_t *s )
{
stream_sys_t *p_sys = s->p_sys;
}
/****************************************************************************
- * stream_AccessUpdate:
+ * AStreamControlUpdate:
****************************************************************************/
-void stream_AccessUpdate( stream_t *s )
+static void AStreamControlUpdate( stream_t *s )
{
stream_sys_t *p_sys = s->p_sys;
return VLC_EGENERIC;
case STREAM_CONTROL_ACCESS:
+ {
i_int = (int) va_arg( args, int );
if( i_int != ACCESS_SET_PRIVATE_ID_STATE &&
i_int != ACCESS_SET_PRIVATE_ID_CA &&
- i_int != ACCESS_GET_PRIVATE_ID_STATE )
+ i_int != ACCESS_GET_PRIVATE_ID_STATE &&
+ i_int != ACCESS_SET_TITLE &&
+ i_int != ACCESS_SET_SEEKPOINT )
{
msg_Err( s, "Hey, what are you thinking ?"
"DON'T USE STREAM_CONTROL_ACCESS !!!" );
return VLC_EGENERIC;
}
- return access_vaControl( p_access, i_int, args );
+ int i_ret = access_vaControl( p_access, i_int, args );
+ if( i_int == ACCESS_SET_TITLE || i_int == ACCESS_SET_SEEKPOINT )
+ AStreamControlReset( s );
+ return i_ret;
+ }
+
+ case STREAM_UPDATE_SIZE:
+ AStreamControlUpdate( s );
+ return VLC_SUCCESS;
case STREAM_GET_CONTENT_TYPE:
return access_Control( p_access, ACCESS_GET_CONTENT_TYPE,
/* */
stream_t *stream_AccessNew( access_t *p_access, bool );
-void stream_AccessDelete( stream_t *s );
-void stream_AccessReset( stream_t *s );
-void stream_AccessUpdate( stream_t *s );
+
+/* */
+stream_t *stream_FilterNew( stream_t *p_source,
+ const char *psz_stream_filter );
#endif
--- /dev/null
+/*****************************************************************************
+ * stream_filter.c
+ *****************************************************************************
+ * Copyright (C) 2008 Laurent Aimar
+ * $Id$
+ *
+ * Author: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_stream.h>
+#include <libvlc.h>
+
+#include "stream.h"
+
+static void StreamDelete( stream_t * );
+
+stream_t *stream_FilterNew( stream_t *p_source,
+ const char *psz_stream_filter )
+{
+ stream_t *s;
+
+ s = stream_CommonNew( VLC_OBJECT( p_source ) );
+ if( s == NULL )
+ return NULL;
+
+ /* */
+ s->p_source = p_source;
+
+ /* */
+ vlc_object_attach( s, p_source );
+
+ s->p_module = module_need( s, "stream_filter", psz_stream_filter, true );
+
+ if( !s->p_module )
+ {
+ stream_CommonDelete( s );
+ return NULL;
+ }
+
+ s->pf_destroy = StreamDelete;
+
+ return s;
+}
+
+static void StreamDelete( stream_t *s )
+{
+ module_unneed( s, s->p_module );
+
+ if( s->p_source )
+ stream_Delete( s->p_source );
+
+ stream_CommonDelete( s );
+}
+
var_Create( p_input, "cache", VLC_VAR_FLOAT );
var_SetFloat( p_input, "cache", 0.0 );
+ /* */
+ var_Create( p_input, "input-record-native", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
+
/* */
var_Create( p_input, "access-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
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, "stream-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Meta */
var_Create( p_input, "meta-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );