From: Laurent Aimar Date: Tue, 29 Mar 2005 16:01:23 +0000 (+0000) Subject: * access.* input/*: added access_filter architecture (same API as a X-Git-Tag: 0.8.2~698 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=02d6384dce7b4c44760f643c7b3d24115910a613;p=vlc * access.* input/*: added access_filter architecture (same API as a standard access_t except that it reads from an access_t). * timeshift.c: timeshift access filter. It works with udp/dvb streams (tested under linux/windows). It allows to pause and to fast/slow forward. To try it, use --access-filter timeshift. --- diff --git a/include/configuration.h b/include/configuration.h index bbdda91e26..cb853b0d76 100644 --- a/include/configuration.h +++ b/include/configuration.h @@ -81,11 +81,12 @@ #define CAT_INPUT 4 #define SUBCAT_INPUT_ACCESS 401 - #define SUBCAT_INPUT_DEMUX 402 - #define SUBCAT_INPUT_VCODEC 403 - #define SUBCAT_INPUT_ACODEC 404 - #define SUBCAT_INPUT_SCODEC 405 - #define SUBCAT_INPUT_ADVANCED 406 + #define SUBCAT_INPUT_ACCESS_FILTER 402 + #define SUBCAT_INPUT_DEMUX 403 + #define SUBCAT_INPUT_VCODEC 404 + #define SUBCAT_INPUT_ACODEC 405 + #define SUBCAT_INPUT_SCODEC 406 + #define SUBCAT_INPUT_ADVANCED 407 #define CAT_SOUT 5 #define SUBCAT_SOUT_GENERAL 501 diff --git a/include/vlc_access.h b/include/vlc_access.h index a285d3e3b5..a1b4212b6f 100644 --- a/include/vlc_access.h +++ b/include/vlc_access.h @@ -70,6 +70,8 @@ struct access_t char *psz_access; /* Access path/url/filename/.... */ char *psz_path; + /* Access source for access_filter (NULL for regular access) */ + access_t *p_source; /* Access can fill this entry to force a demuxer * XXX: fill it once you know for sure you will succed @@ -107,6 +109,7 @@ struct access_t #define access2_New( a, b, c, d, e ) __access2_New(VLC_OBJECT(a), b, c, d, e ) VLC_EXPORT( access_t *, __access2_New, ( vlc_object_t *p_obj, char *psz_access, char *psz_demux, char *psz_path, vlc_bool_t b_quick ) ); +VLC_EXPORT( access_t *, access2_FilterNew, ( access_t *p_source, char *psz_access_filter ) ); VLC_EXPORT( void, access2_Delete, ( access_t * ) ); static inline int access2_vaControl( access_t *p_access, int i_query, va_list args ) diff --git a/include/vlc_config_cat.h b/include/vlc_config_cat.h index 2fd0a3ec64..abb92c6ec2 100644 --- a/include/vlc_config_cat.h +++ b/include/vlc_config_cat.h @@ -101,6 +101,10 @@ "Common settings you may want to alter are HTTP proxy or " \ "caching settings." ) +#define ACCESS_FILTER_TITLE N_( "Access filter modules" ) +#define ACCESS_FILTER_HELP N_( \ + "Settings related to the various access filter used by VLC.\n" ) + #define DEMUX_TITLE N_("Demuxers") #define DEMUX_HELP N_( "Demuxers are used to separate audio and video streams" ) @@ -297,6 +301,7 @@ static struct config_category_t categories_array[] = { CAT_INPUT, INPUT_TITLE, INPUT_HELP }, { SUBCAT_INPUT_ACCESS, ACCESS_TITLE, ACCESS_HELP }, + { SUBCAT_INPUT_ACCESS_FILTER, ACCESS_FILTER_TITLE, ACCESS_FILTER_HELP }, { SUBCAT_INPUT_DEMUX, DEMUX_TITLE, DEMUX_HELP }, { SUBCAT_INPUT_VCODEC, VDEC_TITLE, VDEC_HELP }, { SUBCAT_INPUT_ACODEC, ADEC_TITLE, ADEC_HELP }, diff --git a/modules/access_filter/Modules.am b/modules/access_filter/Modules.am new file mode 100755 index 0000000000..88e20b934c --- /dev/null +++ b/modules/access_filter/Modules.am @@ -0,0 +1 @@ +SOURCES_access_filter_timeshift = timeshift.c diff --git a/modules/access_filter/timeshift.c b/modules/access_filter/timeshift.c new file mode 100755 index 0000000000..19f1d63977 --- /dev/null +++ b/modules/access_filter/timeshift.c @@ -0,0 +1,459 @@ +/***************************************************************************** + * timeshift.c + ***************************************************************************** + * Copyright (C) 2005 VideoLAN + * $Id: demux.c 7546 2004-04-29 13:53:29Z gbazin $ + * + * Author: Laurent Aimar + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include + +#include +#include +#include + +/***************************************************************************** + * Module descriptor + *****************************************************************************/ +static int Open ( vlc_object_t * ); +static void Close( vlc_object_t * ); + +vlc_module_begin(); + set_description( _("Timeshift") ); + set_category( CAT_INPUT ); + set_subcategory( SUBCAT_INPUT_ACCESS_FILTER ); + set_capability( "access_filter", 0 ); + add_shortcut( "timeshift" ); + set_callbacks( Open, Close ); +vlc_module_end(); + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + +static block_t *Block ( access_t *p_access ); +static int Control( access_t *, int i_query, va_list args ); +static void Thread ( access_t * ); + +#define TIMESHIFT_FIFO_MAX (4*1024*1024) +#define TIMESHIFT_FIFO_MIN (TIMESHIFT_FIFO_MAX/4) + +struct access_sys_t +{ + block_fifo_t *p_fifo; + + vlc_bool_t b_opened; + + FILE *t1, *t2; + + char *psz_tmp1; + char *psz_tmp2; + + FILE *w; + int i_w; + + FILE *r; +}; + +/***************************************************************************** + * Open: + *****************************************************************************/ +static int Open( vlc_object_t *p_this ) +{ + access_t *p_access = (access_t*)p_this; + access_t *p_src = p_access->p_source; + access_sys_t *p_sys; + vlc_bool_t b_bool; +#ifdef WIN32 + char buffer[4096]; + int i_size; +#endif + + /* Only work with not pace controled access */ + if( access2_Control( p_src, ACCESS_CAN_CONTROL_PACE, &b_bool ) || b_bool ) + { + msg_Dbg( p_src, "ACCESS_CAN_CONTROL_PACE" ); + return VLC_EGENERIC; + } + /* Refuse access that can be paused */ + if( access2_Control( p_src, ACCESS_CAN_PAUSE, &b_bool ) || b_bool ) + { + msg_Dbg( p_src, "ACCESS_CAN_PAUSE: timeshift useless" ); + return VLC_EGENERIC; + } + + /* */ + p_access->pf_read = NULL; + p_access->pf_block = Block; + p_access->pf_seek = NULL; + p_access->pf_control = Control; + + p_access->info = p_src->info; + + p_access->p_sys = p_sys = malloc( sizeof( access_sys_t ) ); + + /* */ + p_sys->p_fifo = block_FifoNew( p_access ); + p_sys->b_opened = VLC_FALSE; + p_sys->t1 = p_sys->t2 = NULL; + p_sys->w = p_sys->r = NULL; + p_sys->i_w = 0; + +#ifdef WIN32 + i_size = GetTempPath( 4095, buffer ); + if( i_size <= 0 || i_size >= 4095 ) + { + if( getcwd( buffer, 4095 ) == NULL ) + strcpy( buffer, "c:" ); + } + /* remove last \\ if any */ + if( buffer[strlen(buffer)-1] == '\\' ) + buffer[strlen(buffer)-1] = '\0'; + + asprintf( &p_sys->psz_tmp1, "%s\\vlc-timeshift-%d-%d-1.dat", + buffer, GetCurrentProcessId(), p_access->i_object_id ); + asprintf( &p_sys->psz_tmp2, "%s\\vlc-timeshift-%d-%d-2.dat", + buffer, GetCurrentProcessId(), p_access->i_object_id ); +#else + asprintf( &p_sys->psz_tmp1, "/tmp/vlc-timeshift-%d-%d-1.dat", + getpid(), p_access->i_object_id ); + asprintf( &p_sys->psz_tmp2, "/tmp/vlc-timeshift-%d-%d-2.dat", + getpid(), p_access->i_object_id ); +#endif + + if( vlc_thread_create( p_access, "timeshift thread", Thread, + VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) + { + msg_Err( p_access, "cannot spawn timeshift access thread" ); + return VLC_EGENERIC; + } + + return VLC_SUCCESS; +} + +/***************************************************************************** + * Close: + *****************************************************************************/ +static void Close( vlc_object_t *p_this ) +{ + access_t *p_access = (access_t*)p_this; + access_sys_t *p_sys = p_access->p_sys; + + /* */ + msg_Dbg( p_access, "timeshift close called" ); + vlc_thread_join( p_access ); + + if( p_sys->b_opened ) + { + if( p_sys->t1 ) fclose( p_sys->t1 ); + if( p_sys->t2 ) fclose( p_sys->t2 ); + unlink( p_sys->psz_tmp1 ); + unlink( p_sys->psz_tmp2 ); + } + + free( p_sys->psz_tmp1 ); + free( p_sys->psz_tmp2 ); + + block_FifoRelease( p_sys->p_fifo ); + free( p_sys ); +} + +/***************************************************************************** + * + *****************************************************************************/ +static block_t *Block( access_t *p_access ) +{ + access_sys_t *p_sys = p_access->p_sys; + + if( p_access->b_die ) + { + p_access->info.b_eof = VLC_TRUE; + return NULL; + } + + return block_FifoGet( p_sys->p_fifo ); +} + +/***************************************************************************** + * + *****************************************************************************/ +static int Control( access_t *p_access, int i_query, va_list args ) +{ + access_t *p_src = p_access->p_source; + + vlc_bool_t *pb_bool; + int *pi_int; + int64_t *pi_64; + + switch( i_query ) + { + /* */ + case ACCESS_CAN_SEEK: + case ACCESS_CAN_FASTSEEK: + pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); + *pb_bool = VLC_FALSE; + break; + + case ACCESS_CAN_CONTROL_PACE: /* Not really true */ + case ACCESS_CAN_PAUSE: + pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); + *pb_bool = VLC_TRUE; + break; + + /* */ + case ACCESS_GET_MTU: + pi_int = (int*)va_arg( args, int * ); + *pi_int = 0; + break; + + case ACCESS_GET_PTS_DELAY: + pi_64 = (int64_t*)va_arg( args, int64_t * ); + return access2_Control( p_src, ACCESS_GET_PTS_DELAY, pi_64 ); + /* */ + case ACCESS_SET_PAUSE_STATE: + return VLC_SUCCESS; + + case ACCESS_GET_TITLE_INFO: + case ACCESS_SET_TITLE: + case ACCESS_SET_SEEKPOINT: + case ACCESS_GET_META: + return VLC_EGENERIC; + + case ACCESS_SET_PRIVATE_ID_STATE: + case ACCESS_GET_PRIVATE_ID_STATE: + case ACCESS_SET_PRIVATE_ID_CA: + return access2_vaControl( p_src, i_query, args ); + + default: + msg_Warn( p_access, "unimplemented query in control" ); + return VLC_EGENERIC; + + } + return VLC_SUCCESS; +} + +/***************************************************************************** + * + *****************************************************************************/ +static void Thread( access_t *p_access ) +{ + access_sys_t *p_sys = p_access->p_sys; + access_t *p_src = p_access->p_source; + int i_loop = 0; + + while( !p_access->b_die ) + { + block_t *p_block; + + /* Get a new block */ + if( p_src->pf_block ) + { + p_block = p_src->pf_block( p_src ); + + if( p_block == NULL ) + { + if( p_src->info.b_eof ) + break; + + msleep( 1000 ); + continue; + } + } + else + { + if( ( p_block = block_New( p_access, 2048 ) ) == NULL ) + break; + + p_block->i_buffer = p_src->pf_read( p_src, p_block->p_buffer, 2048); + if( p_block->i_buffer < 0 ) + { + block_Release( p_block ); + if( p_block->i_buffer == 0 ) + break; + msleep( 1000 ); + continue; + } + } + + /* Open dump files if we need them */ + if( p_sys->p_fifo->i_size >= TIMESHIFT_FIFO_MAX && !p_sys->b_opened ) + { + msg_Dbg( p_access, "opening first temporary files (%s)", + p_sys->psz_tmp1 ); + + p_sys->b_opened = VLC_TRUE; + p_sys->t1 = p_sys->t2 = NULL; + p_sys->w = p_sys->r = NULL; + + p_sys->t1 = fopen( p_sys->psz_tmp1, "w+b" ); + if( p_sys->t1 ) + { + msg_Dbg( p_access, "opening second temporary files (%s)", + p_sys->psz_tmp2 ); + + p_sys->t2 = fopen( p_sys->psz_tmp2, "w+b" ); + if( p_sys->t2 ) + { + p_sys->w = p_sys->t1; + p_sys->i_w = 0; + + msg_Dbg( p_access, "start writing into temporary file" ); + } + else + { + msg_Err( p_access, "cannot open temporary file '%s' (%s)", + p_sys->psz_tmp2, strerror(errno) ); + fclose( p_sys->t1 ); + p_sys->t1 = NULL; + } + } + else + { + msg_Err( p_access, "cannot open temporary file '%s' (%s)", + p_sys->psz_tmp1, strerror(errno) ); + } + } + + if( p_sys->w ) + { + int i_write; + + /* Dump the block */ + i_write = fwrite( p_block->p_buffer, 1, p_block->i_buffer, + p_sys->w ); + block_Release( p_block ); + + if( i_write > 0 ) + p_sys->i_w += i_write; + else + msg_Warn( p_access, "cannot write data" ); + + /* Start reading from a file if fifo isn't at 25% */ + if( p_sys->p_fifo->i_size < TIMESHIFT_FIFO_MIN && !p_sys->r ) + { + msg_Dbg( p_access, "start reading from temporary file (dumped=%d)", p_sys->i_w ); + + p_sys->r = p_sys->w; + fseek( p_sys->r, 0, SEEK_SET ); + + p_sys->w = p_sys->t2; + p_sys->i_w = 0; + } + + if( p_sys->r ) + { + while( p_sys->p_fifo->i_size < TIMESHIFT_FIFO_MIN ) + { + p_block = block_New( p_access, 4096 ); + p_block->i_buffer = fread( p_block->p_buffer, 1, 4096, + p_sys->r ); + + if( p_block->i_buffer > 0 ) + { + block_FifoPut( p_sys->p_fifo, p_block ); + } + else if( p_sys->i_w > 32*1024) + { + FILE *tmp; + block_Release( p_block ); + + msg_Dbg( p_access, "switching temporary files (dumped=%d)", p_sys->i_w ); + + /* Switch read/write */ + tmp = p_sys->r; + + p_sys->r = p_sys->w; + fseek( p_sys->r, 0, SEEK_SET ); + + p_sys->w = tmp; + fseek( p_sys->w, 0, SEEK_SET ); + ftruncate( fileno(p_sys->w), 0 ); + p_sys->i_w = 0; + } + else + { + msg_Dbg( p_access, "removing temporary files" ); + + /* We will remove the need of tmp files */ + if( p_sys->i_w > 0 ) + { + msg_Dbg( p_access, "loading temporary file" ); + fseek( p_sys->w, 0, SEEK_SET ); + for( ;; ) + { + p_block = block_New( p_access, 4096 ); + p_block->i_buffer = fread( p_block->p_buffer, + 1, 4096, + p_sys->w ); + if( p_block->i_buffer <= 0 ) + { + block_Release( p_block ); + break; + } + block_FifoPut( p_sys->p_fifo, p_block ); + } + } + + p_sys->b_opened = VLC_FALSE; + + fclose( p_sys->t1 ); + fclose( p_sys->t2 ); + + p_sys->t1 = p_sys->t2 = NULL; + p_sys->w = p_sys->r = NULL; + + unlink( p_sys->psz_tmp1 ); + unlink( p_sys->psz_tmp2 ); + break; + } + } + } + } + else if( p_sys->p_fifo->i_size < TIMESHIFT_FIFO_MAX ) + { + block_FifoPut( p_sys->p_fifo, p_block ); + } + else + { + /* We failed to opened files so trash new data */ + block_Release( p_block ); + } +#if 0 + if( (i_loop % 400) == 0 ) + msg_Dbg( p_access, "timeshift: buff=%d", p_sys->p_fifo->i_size ); +#endif + i_loop++; + } + + msg_Warn( p_access, "timeshift: EOF" ); + + /* Send dummy packet to avoid deadlock in TShiftBlock */ + for( i_loop = 0; i_loop < 2; i_loop++ ) + { + block_t *p_dummy = block_New( p_access, 128 ); + + p_dummy->i_flags |= BLOCK_FLAG_DISCONTINUITY; + memset( p_dummy->p_buffer, 0, p_dummy->i_buffer ); + + block_FifoPut( p_sys->p_fifo, p_dummy ); + } +} + diff --git a/modules/demux/ts.c b/modules/demux/ts.c index 5186722ab9..e8fa2162fb 100644 --- a/modules/demux/ts.c +++ b/modules/demux/ts.c @@ -1482,8 +1482,8 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) else if( i_diff != 0 ) { /* FIXME what to do when discontinuity_indicator is set ? */ - msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x", - i_cc, ( pid->i_cc + 1 )&0x0f ); + msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)", + i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid ); pid->i_cc = i_cc; diff --git a/modules/mux/mpeg/ts.c b/modules/mux/mpeg/ts.c index 4a11295138..9b6d97347c 100644 --- a/modules/mux/mpeg/ts.c +++ b/modules/mux/mpeg/ts.c @@ -1456,7 +1456,7 @@ static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, p_ts->p_buffer[7] = ( 0 )&0xff; p_ts->p_buffer[8] = ( 0 )&0xff; p_ts->p_buffer[9] = ( 0 )&0xff; - p_ts->p_buffer[10]= ( 0 )&0x80; + p_ts->p_buffer[10]= ( ( 0 )&0x80 ) | 0x7e; p_ts->p_buffer[11]= 0; for( i = 12; i < 12 + i_stuffing; i++ ) diff --git a/src/input/access.c b/src/input/access.c index dabe394eb4..f32fdc6784 100644 --- a/src/input/access.c +++ b/src/input/access.c @@ -28,11 +28,12 @@ #include "input_internal.h" /***************************************************************************** - * access2_New: + * access2_InternalNew: *****************************************************************************/ -access_t *__access2_New( vlc_object_t *p_obj, - char *psz_access, char *psz_demux, char *psz_path, - vlc_bool_t b_quick ) +static access_t *access2_InternalNew( vlc_object_t *p_obj, + char *psz_access, char *psz_demux, char *psz_path, + access_t *p_source, + vlc_bool_t b_quick ) { access_t *p_access = vlc_object_create( p_obj, VLC_OBJECT_ACCESS ); @@ -43,13 +44,21 @@ access_t *__access2_New( vlc_object_t *p_obj, } /* Parse URL */ - p_access->psz_access = b_quick ? strdup( "file" ) : strdup( psz_access ); - p_access->psz_path = strdup( psz_path ); - p_access->psz_demux = strdup( "" ); - - if( !b_quick ) + p_access->p_source = p_source; + if( p_source ) + { + msg_Dbg( p_obj, "creating access filter '%s'", psz_access ); + p_access->psz_access = strdup( p_source->psz_access ); + p_access->psz_path = strdup( p_source->psz_path ); + } + else if( !b_quick ) + { msg_Dbg( p_obj, "creating access '%s' path='%s'", - p_access->psz_access, p_access->psz_path ); + psz_access, psz_path ); + p_access->psz_access = b_quick ? strdup( "file" ) : strdup( psz_access ); + p_access->psz_path = strdup( psz_path ); + } + p_access->psz_demux = strdup( "" ); p_access->pf_read = NULL; p_access->pf_block = NULL; @@ -67,9 +76,17 @@ access_t *__access2_New( vlc_object_t *p_obj, /* Before module_Need (for var_Create...) */ vlc_object_attach( p_access, p_obj ); - p_access->p_module = - module_Need( p_access, "access2", p_access->psz_access, - b_quick ? VLC_TRUE : VLC_FALSE ); + if( p_source ) + { + p_access->p_module = + module_Need( p_access, "access_filter", psz_access, VLC_FALSE ); + } + else + { + p_access->p_module = + module_Need( p_access, "access2",p_access->psz_access, + b_quick ? VLC_TRUE : VLC_FALSE ); + } if( p_access->p_module == NULL ) { @@ -85,7 +102,27 @@ access_t *__access2_New( vlc_object_t *p_obj, } /***************************************************************************** - * demux2_Delete: + * access2_New: + *****************************************************************************/ +access_t *__access2_New( vlc_object_t *p_obj, + char *psz_access, char *psz_demux, char *psz_path, + vlc_bool_t b_quick ) +{ + return access2_InternalNew( p_obj, psz_access, psz_demux, psz_path, NULL, b_quick ); +} + +/***************************************************************************** + * access2_FilterNew: + *****************************************************************************/ +access_t *access2_FilterNew( access_t *p_source, char *psz_access_filter ) +{ + return access2_InternalNew( VLC_OBJECT(p_source), + psz_access_filter, NULL, NULL, + p_source, VLC_FALSE ); +} + +/***************************************************************************** + * access2_Delete: *****************************************************************************/ void access2_Delete( access_t *p_access ) { @@ -96,5 +133,11 @@ void access2_Delete( access_t *p_access ) free( p_access->psz_path ); free( p_access->psz_demux ); + if( p_access->p_source ) + { + access2_Delete( p_access->p_source ); + } + vlc_object_destroy( p_access ); } + diff --git a/src/input/input.c b/src/input/input.c index 1df1b61160..8c3c2d24f0 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -1912,6 +1912,7 @@ static int InputSourceInit( input_thread_t *p_input, char *psz_access; char *psz_demux; char *psz_path; + char *psz; vlc_value_t val; /* Split uri */ @@ -2021,6 +2022,23 @@ static int InputSourceInit( input_thread_t *p_input, goto error; } + /* */ + psz = var_GetString( p_input, "access-filter" ); + if( *psz ) + { + access_t *p_access = in->p_access; + + /* TODO support chained access-filter */ + in->p_access = access2_FilterNew( in->p_access, psz ); + if( in->p_access == NULL ) + { + in->p_access = p_access; + msg_Warn( p_input, "failed to insert access filter %s", + psz ); + } + } + free( psz ); + /* Get infos from access */ if( !b_quick ) { diff --git a/src/input/var.c b/src/input/var.c index 48c9d5036d..40127c63c8 100644 --- a/src/input/var.c +++ b/src/input/var.c @@ -439,6 +439,9 @@ void input_ConfigVarInit ( input_thread_t *p_input ) var_Create( p_input, "input-slave", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); + /* */ + var_Create( p_input, "access-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); + /* Meta */ var_Create( p_input, "meta-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_input, "meta-author", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); diff --git a/src/libvlc.h b/src/libvlc.h index f71ab07bb2..fde8f6143d 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -663,6 +663,10 @@ static char *ppsz_clock_descriptions[] = #define ACCESS_LONGTEXT N_( \ "This is a legacy entry to let you configure access modules.") +#define ACCESS_FILTER_TEXT N_("Access filter module") +#define ACCESS_FILTER_LONGTEXT N_( \ + "This is a legacy entry to let you configure access filter modules.") + #define DEMUX_TEXT N_("Demux module") #define DEMUX_LONGTEXT N_( \ "This is a legacy entry to let you configure demux modules.") @@ -1012,6 +1016,12 @@ vlc_module_begin(); add_category_hint( N_("Input"), INPUT_CAT_LONGTEXT , VLC_FALSE ); add_module( "access", "access2", NULL, NULL, ACCESS_TEXT, ACCESS_LONGTEXT, VLC_TRUE ); + + set_subcategory( SUBCAT_INPUT_ACCESS_FILTER ); + add_module_list_cat( "access-filter", SUBCAT_INPUT_ACCESS_FILTER, NULL, NULL, + ACCESS_FILTER_TEXT, ACCESS_FILTER_LONGTEXT, VLC_FALSE ); + + set_subcategory( SUBCAT_INPUT_DEMUX ); add_module( "demux", "demux2", NULL, NULL, DEMUX_TEXT, DEMUX_LONGTEXT, VLC_TRUE );