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 ...@@ -53,17 +53,18 @@ struct stream_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
/* Module properties */ /* Module properties for stream filter */
module_t *p_module; module_t *p_module;
/* For stream filter they will hold an array of stream sources */ /* Stream source for stream filter */
int i_source; stream_t *p_source;
stream_t **pp_source;
/* */ /* */
int (*pf_read) ( stream_t *, void *p_read, unsigned int i_read ); 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_peek) ( stream_t *, const uint8_t **pp_peek, unsigned int i_peek );
int (*pf_control)( stream_t *, int i_query, va_list ); int (*pf_control)( stream_t *, int i_query, va_list );
/* */
void (*pf_destroy)( stream_t *); void (*pf_destroy)( stream_t *);
/* Private data for module */ /* Private data for module */
...@@ -95,10 +96,14 @@ enum stream_query_e ...@@ -95,10 +96,14 @@ enum stream_query_e
STREAM_CONTROL_ACCESS, /* arg1= int i_access_query, args res: can fail STREAM_CONTROL_ACCESS, /* arg1= int i_access_query, args res: can fail
if access unreachable or access control answer */ 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 */ 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 */ 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 = \ ...@@ -327,6 +327,7 @@ SOURCES_libvlc_common = \
input/vlm_internal.h \ input/vlm_internal.h \
input/stream.c \ input/stream.c \
input/stream_demux.c \ input/stream_demux.c \
input/stream_filter.c \
input/stream_memory.c \ input/stream_memory.c \
input/subtitles.c \ input/subtitles.c \
input/var.c \ input/var.c \
......
...@@ -1933,8 +1933,8 @@ static bool Control( input_thread_t *p_input, int i_type, ...@@ -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 ); es_out_SetTime( p_input->p->p_es_out, -1 );
access_Control( p_access, ACCESS_SET_TITLE, i_title ); stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
stream_AccessReset( p_input->p->input.p_stream ); ACCESS_SET_TITLE, i_title );
} }
} }
break; break;
...@@ -2012,9 +2012,8 @@ static bool Control( input_thread_t *p_input, int i_type, ...@@ -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 ); es_out_SetTime( p_input->p->p_es_out, -1 );
access_Control( p_access, ACCESS_SET_SEEKPOINT, stream_Control( p_input->p->input.p_stream, STREAM_CONTROL_ACCESS,
i_seekpoint ); ACCESS_SET_SEEKPOINT, i_seekpoint );
stream_AccessReset( p_input->p->input.p_stream );
} }
} }
break; break;
...@@ -2256,7 +2255,7 @@ static int UpdateTitleSeekpointFromAccess( input_thread_t *p_input ) ...@@ -2256,7 +2255,7 @@ static int UpdateTitleSeekpointFromAccess( input_thread_t *p_input )
{ {
input_SendEventTitle( p_input, p_access->info.i_title ); 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; p_access->info.i_update &= ~INPUT_UPDATE_TITLE;
} }
...@@ -2515,6 +2514,10 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2515,6 +2514,10 @@ static int InputSourceInit( input_thread_t *p_input,
var_Set( p_input, "can-seek", val ); 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 */ /* Autodetect extra files if none specified */
char *psz_input_list = var_CreateGetNonEmptyString( p_input, "input-list" ); char *psz_input_list = var_CreateGetNonEmptyString( p_input, "input-list" );
if( !psz_input_list ) if( !psz_input_list )
...@@ -2528,7 +2531,7 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2528,7 +2531,7 @@ static int InputSourceInit( input_thread_t *p_input,
/* Create the stream_t */ /* Create the stream_t */
in->p_stream = stream_AccessNew( in->p_access, p_input->b_preparsing ); in->p_stream = stream_AccessNew( in->p_access, p_input->b_preparsing );
/* Restor old value */ /* Restore old value */
if( !psz_input_list ) if( !psz_input_list )
var_SetString( p_input, "input-list", "" ); var_SetString( p_input, "input-list", "" );
free( psz_input_list ); free( psz_input_list );
...@@ -2539,6 +2542,37 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -2539,6 +2542,37 @@ static int InputSourceInit( input_thread_t *p_input,
goto error; 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 */ /* Open a demuxer */
if( *psz_demux == '\0' && *in->p_access->psz_demux ) if( *psz_demux == '\0' && *in->p_access->psz_demux )
{ {
...@@ -2597,7 +2631,7 @@ static int InputSourceInit( input_thread_t *p_input, ...@@ -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 ) ) if( demux_Control( in->p_demux, DEMUX_CAN_RECORD, &in->b_can_stream_record ) )
in->b_can_stream_record = false; in->b_can_stream_record = false;
#ifdef ENABLE_SOUT #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; in->b_can_stream_record = false;
var_SetBool( p_input, "can-record", true ); var_SetBool( p_input, "can-record", true );
#else #else
......
...@@ -531,9 +531,9 @@ static void UStreamDestroy( stream_t *s ) ...@@ -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; stream_sys_t *p_sys = s->p_sys;
...@@ -578,9 +578,9 @@ void stream_AccessReset( stream_t *s ) ...@@ -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; stream_sys_t *p_sys = s->p_sys;
...@@ -657,16 +657,27 @@ static int AStreamControl( stream_t *s, int i_query, va_list args ) ...@@ -657,16 +657,27 @@ static int AStreamControl( stream_t *s, int i_query, va_list args )
return VLC_EGENERIC; return VLC_EGENERIC;
case STREAM_CONTROL_ACCESS: case STREAM_CONTROL_ACCESS:
{
i_int = (int) va_arg( args, int ); i_int = (int) va_arg( args, int );
if( i_int != ACCESS_SET_PRIVATE_ID_STATE && if( i_int != ACCESS_SET_PRIVATE_ID_STATE &&
i_int != ACCESS_SET_PRIVATE_ID_CA && 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 ?" msg_Err( s, "Hey, what are you thinking ?"
"DON'T USE STREAM_CONTROL_ACCESS !!!" ); "DON'T USE STREAM_CONTROL_ACCESS !!!" );
return VLC_EGENERIC; 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: case STREAM_GET_CONTENT_TYPE:
return access_Control( p_access, ACCESS_GET_CONTENT_TYPE, return access_Control( p_access, ACCESS_GET_CONTENT_TYPE,
......
...@@ -46,9 +46,10 @@ void stream_CommonDelete( stream_t * ); ...@@ -46,9 +46,10 @@ void stream_CommonDelete( stream_t * );
/* */ /* */
stream_t *stream_AccessNew( access_t *p_access, bool ); 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 #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 ) ...@@ -488,10 +488,14 @@ void input_ConfigVarInit ( input_thread_t *p_input )
var_Create( p_input, "cache", VLC_VAR_FLOAT ); var_Create( p_input, "cache", VLC_VAR_FLOAT );
var_SetFloat( p_input, "cache", 0.0 ); 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-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "access", 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, "demux", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "stream-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
/* Meta */ /* Meta */
var_Create( p_input, "meta-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 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