Commit 584da504 authored by Laurent Aimar's avatar Laurent Aimar

Support for auto and user requested stream_filter.

parent 7a0f1546
......@@ -53,17 +53,18 @@ struct stream_t
{
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 */
......@@ -95,10 +96,14 @@ enum stream_query_e
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 */
};
......
......@@ -327,6 +327,7 @@ SOURCES_libvlc_common = \
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 \
......
......@@ -1933,8 +1933,8 @@ static bool Control( input_thread_t *p_input, int i_type,
{
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;
......@@ -2012,9 +2012,8 @@ static bool Control( input_thread_t *p_input, int i_type,
{
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;
......@@ -2256,7 +2255,7 @@ static int UpdateTitleSeekpointFromAccess( input_thread_t *p_input )
{
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;
}
......@@ -2515,6 +2514,10 @@ static int InputSourceInit( input_thread_t *p_input,
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 )
......@@ -2528,7 +2531,7 @@ static int InputSourceInit( input_thread_t *p_input,
/* 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 );
......@@ -2539,6 +2542,37 @@ static int InputSourceInit( input_thread_t *p_input,
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 )
{
......@@ -2597,7 +2631,7 @@ static int InputSourceInit( input_thread_t *p_input,
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
......
......@@ -531,9 +531,9 @@ static void UStreamDestroy( stream_t *s )
}
/****************************************************************************
* stream_AccessReset:
* AStreamControlReset:
****************************************************************************/
void stream_AccessReset( stream_t *s )
static void AStreamControlReset( stream_t *s )
{
stream_sys_t *p_sys = s->p_sys;
......@@ -578,9 +578,9 @@ void stream_AccessReset( stream_t *s )
}
/****************************************************************************
* stream_AccessUpdate:
* AStreamControlUpdate:
****************************************************************************/
void stream_AccessUpdate( stream_t *s )
static void AStreamControlUpdate( stream_t *s )
{
stream_sys_t *p_sys = s->p_sys;
......@@ -657,16 +657,27 @@ static int AStreamControl( stream_t *s, int i_query, va_list args )
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,
......
......@@ -46,9 +46,10 @@ void stream_CommonDelete( stream_t * );
/* */
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
/*****************************************************************************
* 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 );
}
......@@ -488,10 +488,14 @@ void input_ConfigVarInit ( input_thread_t *p_input )
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 );
......
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