int (* pf_set_program )( input_thread_t *, pgrm_descriptor_t * );
int (* pf_set_area )( input_thread_t *, input_area_t * );
void (* pf_seek ) ( input_thread_t *, off_t );
+ int (* pf_access_control )( input_thread_t *, int, va_list );
access_sys_t * p_access_data;
size_t i_mtu;
int i_pts_delay; /* internal caching */
ES_OUT_SET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t */
ES_OUT_GET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t* */
- /* XXX XXX XXX Don't use them YET !!! */
+ /* PCR handling, by default dts/pts will be automatically computed using thoses PCR */
ES_OUT_SET_PCR, /* arg1=int64_t i_pcr(microsecond!) (using default group 0)*/
ES_OUT_SET_GROUP_PCR, /* arg1= int i_group, arg2=int64_t i_pcr(microsecond!)*/
- ES_OUT_RESET_PCR /* no arg */
+ ES_OUT_RESET_PCR, /* no arg */
+
+ /* ByBass automatic stream timestamp to absolute timestamp using pcr (and disable the automatic mode XXX:for all groups) */
+ ES_OUT_CONVERT_TIMESTAMP, /* arg1=int64_t *pi_ts(microsecond!) */
+ ES_OUT_CONVERT_GROUP_TIMESTAMP, /* arg1=int i_group, arg2=int64_t *pi_ts(microsecond!)*/
+
};
struct es_out_t
va_end( args );
return i_result;
}
+/**
+ * \defgroup access Access
+ * @{
+ */
+
+enum access_query_e
+{
+ /* capabilities */
+ ACCESS_CAN_FASTSEEK, /* arg1= vlc_bool_t* cannot fail */
+ ACCESS_CAN_PAUSE, /* arg1= vlc_bool_t* cannot fail */
+ ACCESS_CAN_CONTROL_PACE,/* arg1= vlc_bool_t* cannot fail */
+
+ /* */
+ ACCESS_GET_MTU, /* arg1= int* cannot fail (0 if no sense) */
+ ACCESS_GET_SIZE, /* arg1= int64_t* cannot fail (0 if unknown) */
+ ACCESS_GET_POS, /* arg1= int64_t* cannot fail */
+
+ /* */
+ ACCESS_SET_PAUSE_STATE /* arg1= vlc_bool_t can fail if unsuported */
+};
+
+struct access_t
+{
+ VLC_COMMON_MEMBERS
+
+ /* Module properties */
+ module_t *p_module;
+
+ /* Access name (empty if non forced) */
+ char *psz_access;
+ char *psz_path;
+ /* Access can fill this entry to force a deluxer */
+ char *psz_demux;
+
+ /* set by access (only one of pf_read/pf_block may be filled) */
+ int (*pf_read) ( access_t *, uint8_t *, int ); /* Return -1 if no data yet, 0 if no more data, else real data read */
+ block_t *(*pf_block)( access_t * ); /* return a block of data in his 'natural' size */
+ int (*pf_seek) ( access_t *, int64_t );
+
+ int (*pf_control)( access_t *, int i_query, va_list args);
+ access_sys_t *p_sys;
+};
+
+#define access2_New( a, b, c, d ) __acess2_New(VLC_OBJECT(a), b, c, d)
+VLC_EXPORT( demux_t *, __access2_New, ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
+VLC_EXPORT( void, access2_Delete, ( demux_t * ) );
+
+static inline int access2_vaControl( access_t *p_access, int i_query, va_list args )
+{
+ return p_access->pf_control( p_access, i_query, args );
+}
+static inline int access2_Control( access_t *p_access, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+
+ va_start( args, i_query );
+ i_result = access2_vaControl( p_access, i_query, args );
+ va_end( args );
+ return i_result;
+}
+
+/**
+ * @}
+ */
/**
* \defgroup stream Stream
VLC_EXPORT( int, demux_vaControlDefault, ( input_thread_t *, int i_query, va_list ) );
+/* Access */
+VLC_EXPORT( int, access_vaControl, ( input_thread_t *, int i_query, va_list ) );
+VLC_EXPORT( int, access_Control, ( input_thread_t *, int i_query, ... ) );
+VLC_EXPORT( int, access_vaControlDefault,( input_thread_t *, int i_query, va_list ) );
+
-/* New demux arch: don't touch that */
/* stream_t *s could be null and then it mean a access+demux in one */
#define demux2_New( a, b, c, d ) __demux2_New(VLC_OBJECT(a), b, c, d)
VLC_EXPORT( demux_t *, __demux2_New, ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
typedef struct es_out_id_t es_out_id_t;
typedef struct es_out_sys_t es_out_sys_t;
typedef struct demux_t demux_t;
+typedef struct access_t access_t;
/* Audio */
typedef struct aout_instance_t aout_instance_t;
#define VLC_OBJECT_VLM (-16)
#define VLC_OBJECT_ANNOUNCE (-17)
#define VLC_OBJECT_DEMUX (-18)
+#define VLC_OBJECT_ACCESS (-19)
#define VLC_OBJECT_GENERIC (-666)
--- /dev/null
+/*****************************************************************************
+ * access.c
+ *****************************************************************************
+ * Copyright (C) 1999-2004 VideoLAN
+ * $Id: demux.c 7546 2004-04-29 13:53:29Z gbazin $
+ *
+ * Author: Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * 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.
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "ninput.h"
+
+int access_vaControl( input_thread_t *p_input, int i_query, va_list args )
+{
+ if( p_input->pf_access_control )
+ {
+ return p_input->pf_access_control( p_input, i_query, args );
+ }
+ return VLC_EGENERIC;
+}
+
+int access_Control( input_thread_t *p_input, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+
+ va_start( args, i_query );
+ i_result = access_vaControl( p_input, i_query, args );
+ va_end( args );
+
+ return i_result;
+}
+
+int access_vaControlDefault( input_thread_t *p_input, int i_query, va_list args )
+{
+ return VLC_EGENERIC;
+}
+
+/*****************************************************************************
+ * access2_New:
+ *****************************************************************************/
+access_t *__access2_New( vlc_object_t *p_obj,
+ char *psz_mrl, stream_t *s, es_out_t *out )
+{
+ msg_Err( p_obj, "access2_New not yet implemented" );
+ return NULL;
+#if 0
+ access_t *p_access = vlc_object_create( p_obj, VLC_OBJECT_ACCESS );
+
+ char *psz_dup = strdup( psz_mrl ? psz_mrl : "" );
+ char *psz = strchr( psz_dup, ':' );
+ char *psz_module;
+
+ if( p_demux == NULL )
+ {
+ free( psz_dup );
+ return NULL;
+ }
+
+ /* Parse URL */
+ p_demux->psz_access = NULL;
+ p_demux->psz_demux = NULL;
+ p_demux->psz_path = NULL;
+
+ if( psz )
+ {
+ *psz++ = '\0';
+
+ if( psz[0] == '/' && psz[1] == '/' )
+ {
+ psz += 2;
+ }
+ p_demux->psz_path = strdup( psz );
+
+ psz = strchr( psz_dup, '/' );
+ if( psz )
+ {
+ *psz++ = '\0';
+ p_demux->psz_access = strdup( psz_dup );
+ p_demux->psz_demux = strdup( psz );
+ }
+ }
+ else
+ {
+ p_demux->psz_path = strdup( psz_mrl );
+ }
+ free( psz_dup );
+
+
+ if( p_demux->psz_access == NULL )
+ {
+ p_demux->psz_access = strdup( "" );
+ }
+ if( p_demux->psz_demux == NULL )
+ {
+ p_demux->psz_demux = strdup( "" );
+ }
+ if( p_demux->psz_path == NULL )
+ {
+ p_demux->psz_path = strdup( "" );
+ }
+ msg_Dbg( p_obj, "demux2_New: '%s' -> access='%s' demux='%s' path='%s'",
+ psz_mrl,
+ p_demux->psz_access, p_demux->psz_demux, p_demux->psz_path );
+
+ p_demux->s = s;
+ p_demux->out = out;
+
+ p_demux->pf_demux = NULL;
+ p_demux->pf_control = NULL;
+ p_demux->p_sys = NULL;
+
+ psz_module = p_demux->psz_demux;
+ if( *psz_module == '\0' && strrchr( p_demux->psz_path, '.' ) )
+ {
+ /* XXX: add only file without any problem here and with strong detection.
+ * - no .mp3, .a52, ... (aac is added as it works only by file ext anyway
+ * - wav can't be added 'cause of a52 and dts in them as raw audio
+ */
+ static struct { char *ext; char *demux; } exttodemux[] =
+ {
+ { "aac", "aac" },
+ { "aiff", "aiff" },
+ { "asf", "asf" }, { "wmv", "asf" }, { "wma", "asf" },
+ { "avi", "avi" },
+ { "au", "au" },
+ { "flac", "flac" },
+ { "dv", "dv" },
+ { "m3u", "m3u" },
+ { "mkv", "mkv" }, { "mka", "mkv" }, { "mks", "mkv" },
+ { "mp4", "mp4" }, { "m4a", "mp4" }, { "mov", "mp4" }, { "moov", "mp4" },
+ { "mod", "mod" }, { "xm", "mod" },
+ { "nsv", "nsv" },
+ { "ogg", "ogg" }, { "ogm", "ogg" },
+ { "pva", "pva" },
+ { "rm", "rm" },
+ { "", "" },
+ };
+
+ char *psz_ext = strrchr( p_demux->psz_path, '.' ) + 1;
+ int i;
+
+ for( i = 0; exttodemux[i].ext != NULL; i++ )
+ {
+ if( !strcasecmp( psz_ext, exttodemux[i].ext ) )
+ {
+ psz_module = exttodemux[i].demux;
+ break;
+ }
+ }
+ }
+
+ /* Before module_Need (for var_Create...) */
+ vlc_object_attach( p_demux, p_obj );
+
+ p_demux->p_module =
+ module_Need( p_demux, "demux2", psz_module,
+ !strcmp( psz_module, p_demux->psz_demux ) ? VLC_TRUE : VLC_FALSE );
+
+ if( p_demux->p_module == NULL )
+ {
+ vlc_object_detach( p_demux );
+ free( p_demux->psz_path );
+ free( p_demux->psz_demux );
+ free( p_demux->psz_access );
+ vlc_object_destroy( p_demux );
+ return NULL;
+ }
+
+ return p_demux;
+#endif
+}
+
+/*****************************************************************************
+ * demux2_Delete:
+ *****************************************************************************/
+void access2_Delete( access_t *p_access )
+{
+ module_Unneed( p_access, p_access->p_module );
+ vlc_object_detach( p_access );
+
+ free( p_access->psz_access );
+ free( p_access->psz_path );
+ free( p_access->psz_demux );
+
+ vlc_object_destroy( p_access );
+}
struct es_out_sys_t
{
input_thread_t *p_input;
- vlc_bool_t b_pcr_set;
+ vlc_bool_t b_convert_ts_auto; /* automatically convert TimeStamp */
/* all es */
int i_id;
out->p_sys = p_sys;
p_sys->p_input = p_input;
- p_sys->b_pcr_set = VLC_FALSE;
+ p_sys->b_convert_ts_auto = VLC_TRUE;
p_sys->b_active = VLC_FALSE;
p_sys->i_mode = ES_OUT_MODE_AUTO;
static pgrm_descriptor_t *EsOutAddProgram( es_out_t *out, int i_group )
{
input_thread_t *p_input = out->p_sys->p_input;
- pgrm_descriptor_t *p_prgm;
+ pgrm_descriptor_t *p_pgrm;
es_descriptor_t *p_pmt;
/* FIXME we should use a object variable but a lot of place in src/input
int i_select = config_GetInt( p_input, "program" );
/* create it */
- p_prgm = input_AddProgram( p_input, i_group, 0 );
+ p_pgrm = input_AddProgram( p_input, i_group, 0 );
/* XXX welcome to kludge, add a dummy es, if you want to understand
* why have a look at input_SetProgram. Basicaly, it assume the first
* es to be the PMT, how that is stupid, nevertheless it is needed for
* the old ts demuxer */
- p_pmt = input_AddES( p_input, p_prgm, 0, UNKNOWN_ES, NULL, 0 );
+ p_pmt = input_AddES( p_input, p_pgrm, 0, UNKNOWN_ES, NULL, 0 );
p_pmt->i_fourcc = VLC_FOURCC( 'n', 'u', 'l', 'l' );
/* Select i_select or the first by default */
if( p_input->stream.p_selected_program == NULL &&
( i_select <= 0 || i_select == i_group ) )
{
- p_input->stream.p_selected_program = p_prgm;
+ p_input->stream.p_selected_program = p_pgrm;
}
- return p_prgm;
+ return p_pgrm;
}
/**
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
es_out_id_t *es = malloc( sizeof( es_out_id_t ) );
- pgrm_descriptor_t *p_prgm = NULL;
+ pgrm_descriptor_t *p_pgrm = NULL;
char psz_cat[sizeof( _("Stream ") ) + 10];
char *psz_description;
if( fmt->i_group >= 0 )
{
/* search program */
- p_prgm = input_FindProgram( p_input, fmt->i_group );
+ p_pgrm = input_FindProgram( p_input, fmt->i_group );
- if( p_prgm == NULL )
+ if( p_pgrm == NULL )
{
/* Create it */
- p_prgm = EsOutAddProgram( out, fmt->i_group );
+ p_pgrm = EsOutAddProgram( out, fmt->i_group );
}
}
if( fmt->i_id < 0 )
}
psz_description = LanguageGetName( fmt->psz_language );
- es->p_es = input_AddES( p_input, p_prgm, fmt->i_id + 1,
+ es->p_es = input_AddES( p_input, p_pgrm, fmt->i_id + 1,
fmt->i_cat, psz_description, 0 );
es->p_es->i_stream_id = fmt->i_id;
es->p_es->i_fourcc = fmt->i_codec;
{
es_out_sys_t *p_sys = out->p_sys;
- if( p_sys->b_pcr_set )
+ if( p_sys->b_convert_ts_auto )
{
pgrm_descriptor_t *p_pgrm = es->p_es->p_pgrm;
input_thread_t *p_input = p_sys->p_input;
case ES_OUT_SET_PCR:
case ES_OUT_SET_GROUP_PCR:
{
- pgrm_descriptor_t *p_prgm = NULL;
+ pgrm_descriptor_t *p_pgrm = NULL;
int64_t i_pcr;
if( i_query == ES_OUT_SET_PCR )
{
- p_prgm = p_sys->p_input->stream.p_selected_program;
+ p_pgrm = p_sys->p_input->stream.p_selected_program;
}
else
{
int i_group = (int)va_arg( args, int );
- p_prgm = input_FindProgram( p_sys->p_input, i_group );
- if( p_prgm == NULL )
+ p_pgrm = input_FindProgram( p_sys->p_input, i_group );
+ if( p_pgrm == NULL )
{
/* we create the requested program */
- p_prgm = EsOutAddProgram( out, i_group );
+ p_pgrm = EsOutAddProgram( out, i_group );
}
}
i_pcr = (int64_t)va_arg( args, int64_t );
/* search program */
- if( p_prgm )
+ if( p_pgrm )
{
/* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
- input_ClockManageRef( p_sys->p_input, p_prgm, (i_pcr + 11 ) * 9 / 100);
+ input_ClockManageRef( p_sys->p_input, p_pgrm, (i_pcr + 11 ) * 9 / 100);
}
- p_sys->b_pcr_set = VLC_TRUE;
return VLC_SUCCESS;
}
SYNCHRO_REINIT;
p_sys->p_input->stream.pp_programs[i]->last_pts = 0;
}
- p_sys->b_pcr_set = VLC_TRUE;
return VLC_SUCCESS;
+ case ES_OUT_CONVERT_TIMESTAMP:
+ case ES_OUT_CONVERT_GROUP_TIMESTAMP:
+ {
+ pgrm_descriptor_t *p_pgrm = NULL;
+
+ if( i_query == ES_OUT_CONVERT_TIMESTAMP )
+ {
+ p_pgrm = p_sys->p_input->stream.p_selected_program;
+ }
+ else
+ {
+ int i_group = (int)va_arg( args, int );
+ p_pgrm = input_FindProgram( p_sys->p_input, i_group );
+ }
+ if( p_pgrm )
+ {
+ int64_t *pi_ts = (int64_t*)va_arg( args, int64_t* );
+
+ *pi_ts = input_ClockGetTS( p_sys->p_input, p_pgrm, ( *pi_ts + 11 ) * 9 / 100 );
+ }
+ p_sys->b_convert_ts_auto = VLC_FALSE;
+ return VLC_SUCCESS;
+ }
+
default:
msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
return VLC_EGENERIC;
case VLC_OBJECT_VLM: psz_object = "vlm"; break;
case VLC_OBJECT_ANNOUNCE: psz_object = "announce handler"; break;
case VLC_OBJECT_DEMUX: psz_object = "demuxer"; break;
+ case VLC_OBJECT_ACCESS: psz_object = "access"; break;
}
#ifdef UNDER_CE
i_size = sizeof(demux_t);
psz_type = "demux";
break;
+ case VLC_OBJECT_ACCESS:
+ i_size = sizeof(access_t);
+ psz_type = "access";
+ break;
case VLC_OBJECT_DECODER:
i_size = sizeof(decoder_t);
psz_type = "decoder";